【前言】
STM32H7S78-DK板载了SD卡读卡器,而使用大容量SD卡来储存数据也是非常重要的一环,所以驱动SD卡非常重要。本篇分享如何使用STM32CubeMX来配置SDMMC同在在TouchGFX上读取卡的信息并与以展示。
【实现步骤】
1、创建一个空白TouchGFX工程。
2、使用STM32CubeMX打开工程,并配置SDMMC,如下图所示:

根据开发板原理图,使用4线传输,采用下降沿时钟采样,时钟分频配置为1。
同时开启中断。
配置好后生成mdk工程。
2、打开sdmmc.c添加自定义代码
/* USER CODE BEGIN SDMMC1_MspInit 1 */
/* SDMMC Clk on PLL1S: (64 / 4 * 25 / 2) = 200MHz */
/* Activate PLL1 with HSI as source (HSI is ON at reset) */
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL1.PLLM = 16;
RCC_OscInitStruct.PLL1.PLLN = 275;
RCC_OscInitStruct.PLL1.PLLP = 2;
RCC_OscInitStruct.PLL1.PLLQ = 2;
RCC_OscInitStruct.PLL1.PLLR = 2;
RCC_OscInitStruct.PLL1.PLLS = 2;
RCC_OscInitStruct.PLL1.PLLT = 2;
RCC_OscInitStruct.PLL1.PLLFractional = 0;
RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization error */
while(1);
}
/*##-1- Enable peripherals and GPIO Clocks #################################*/
__HAL_RCC_SDMMC1_FORCE_RESET();
__HAL_RCC_SDMMC1_RELEASE_RESET();
/* NVIC configuration for SDMMC interrupts */
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
/* USER CODE END SDMMC1_MspInit 1 */配置为高速时钟。
3、由于Touchgfx配置TIM6为时钟为Tick,所以需要工程HAL_Delay是获了不到时钟的tick数据的,所以需要添加自定的delay,重写HAL_Delay。
void HAL_Delay(uint32_t nms)
{
uint32_t temp;
SysTick->LOAD =nms*fac_ms; //设置加载的值,比如1us就要计数9次。nus传入1,CALIB=1*9=9,最后就是1us
SysTick->VAL =0x00; //清空计数器中的值,LOAD里的值不是写入后就会加载,而是在systick使能且VAL值为0时才加载
SysTick->CTRL |=SysTick_CTRL_ENABLE_Msk; //使能时钟,开始计时
do
{
temp=SysTick->CTRL; //查询是否计数完成
}while((temp&0x01)&&!(temp&(1<<16))); //先判断定时器是否在运行,再判断是否计数完成
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}4、在TouchGFX Designer添加读取SD的按键与信息展示的文本框:

5、添加代码如下:
void Screen1View::fungetsdinfo()
{
HAL_SD_CardInfoTypeDef pCardInfo = {0};
HAL_StatusTypeDef ret = HAL_SD_GetCardInfo(&hsd1,&pCardInfo);
Unicode::snprintf(textCardInfoBuffer, TEXTCARDINFO_SIZE, "CardType=%d\nCardVersion=%d\nBlockSize=%dk\n",
pCardInfo.CardType,pCardInfo.CardVersion,pCardInfo.BlockSize);
textCardInfo.invalidate();
}【实验效果】

【总结】
使用STM32CubeMX结合开发板的例程可以快速实现,但是由于HAL_Delay的问题,排查了许久才成功。如果使用freertos,需要特别注意这个问题。
我要赚赏金
