【前言】
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,需要特别注意这个问题。