1 前言
本章测试spi tf卡示例,实现txt文件的读写。
2 源码 源码路径: https://gitee.com/CMIOT-XinShengTech/CMIOT.CM32M4xxR_Library/tree/main/Projects/CM32M4xxR_LQFP128_STB/Examples/SPI/SPI_SD_CARD
注意一下,这里用的是CM32M4xxR_LQFP128_STB,而开发板是CM32M433R-START,对比了一下两者代码,差异不大,其中uart串口打印log使用不同口,START用的是uart4,而LQFP128_STB是uart5。 如果你在创建项目使用的是CM32M433R-START,则可以忽略这个串口差异。如果你用CM32M4xxR_LQFP128_STB,那需要使用uart5,对应的口是pin8、9。
使用CM32M4xxR_LQFP128_STB创建时可以选择spi相关的示例,然后将sdcard的main文件内容复制过去即可。
此外还要复制一下FatFs_User和FatFs文件夹到Application同级目录下。
3 添加头文件
根据上图添加头文件,即可完成编译,否则会报h文件找不到。
4 硬件
spi sdcard示例使用的是spi1。
注意不要将线接错了,如果接错了f_open会返回错误状态,比如返回3则是The physical drive cannot work。
详见ff.h中的FRESULT。
5 代码
代码就是spi sdcard示例,只是加了两个返回值判断便于分析错误。
main.c
- #include
- #include
- #include "log.h"
- #include "fatfs.h"
- #include "user_diskio.h" /* defines USER_Driver as external */
- /** @addtogroup CM32M4xxR_StdPeriph_Examples
- * @{
- */
- /** @addtogroup SPI_CRC
- * @{
- */
- #define BufferSize (32)
- #define SPICRC
- volatile SPI_InitType SPI_InitStructure;
- void RCC_Configuration(void);
- void GPIO_Configuration(void);
- volatile FATFS fs;
- volatile FATFS *pfs;
- volatile FIL fil;
- volatile FRESULT fres;
- volatile DWORD fre_clust;
- volatile uint32_t totalSpace, freeSpace;
- volatile char buffer[100];
- volatile char USERPath[4]; /* USER logical drive path */
- /**
- * [url=home.php?mod=space&uid=2666770]@Brief[/url] Main function.
- */
- int main(void)
- {
- /*!< At this stage the microcontroller clock setting is already configured,
- this is done through SystemInit() function which is called from startup
- file (startup_cm32m4xxr.s) before to branch to application main.
- To reconfigure the default setting of SystemInit() function, refer to
- system_cm32m4xxr.c file
- */
- log_init();
- log_info("This is a SPI_SD_CARD demo-----------------------------------rn");
- SysTick_Config(144000000/100);
- /* System clocks configuration ---------------------------------------------*/
- RCC_Configuration();
- /* GPIO configuration ------------------------------------------------------*/
- GPIO_Configuration();
- /* SPI1 configuration ------------------------------------------------------*/
- SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
- SPI_InitStructure.SpiMode = SPI_MODE_MASTER;
- SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;
- SPI_InitStructure.CLKPOL = SPI_CLKPOL_LOW;
- SPI_InitStructure.CLKPHA = SPI_CLKPHA_FIRST_EDGE;
- SPI_InitStructure.NSS = SPI_NSS_SOFT;
- SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_16;
- SPI_InitStructure.FirstBit = SPI_FB_MSB;
- SPI_InitStructure.CRCPoly = 0x0007;
- SPI_Init(SPI1, (SPI_InitType*)&SPI_InitStructure);
- /* Enable SPI1 */
- SPI_Enable(SPI1, ENABLE);
- uint8_t ret = 1;
- ret = FATFS_LinkDriver((Diskio_drvTypeDef*)&USER_Driver, (char*)USERPath);
- if(ret == 0)
- printf("fatfs init okrn");
- else
- printf("fatfs init errorrn");
- delay_ms(500);
- ret = f_mount((FATFS*)&fs, "", 0);
- printf("mount = %drn",ret);
- if( ret != FR_OK)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- /* Open file to write */
- ret = f_open((FIL*)&fil, "first.txt", FA_OPEN_APPEND | FA_READ | FA_WRITE);
- printf("open = %drn",ret);
- if(ret != FR_OK)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- /* Check freeSpace space */
- if(f_getfree("", (DWORD*)&fre_clust, (FATFS **)&pfs) != FR_OK)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- totalSpace = (uint32_t)((pfs->n_fatent - 2) * pfs->csize * 0.5);
- freeSpace = (uint32_t)(fre_clust * pfs->csize * 0.5);
- /* free space is less than 1kb */
- if(freeSpace < 1)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- /* Writing text */
- f_puts("XinSheng Tech SD Card I/O Example via SPIn", (FIL*)&fil);
- f_puts("test!!!n", (FIL*)&fil);
- /* Close file */
- if(f_close((FIL*)&fil) != FR_OK)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- /* Open file to read */
- if(f_open((FIL*)&fil, "first.txt", FA_READ) != FR_OK)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- while(f_gets((char*)buffer, sizeof(buffer), (FIL*)&fil))
- {
- /* SWV output */
- printf("%s", buffer);
- fflush(stdout);
- }
- /* Close file */
- if(f_close((FIL*)&fil) != FR_OK)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- /* Unmount SDCARD */
- if(f_mount(NULL, "", 1) != FR_OK)
- {
- printf("error %s,line %drn",__FILE__, __LINE__);
- }
- while (1)
- {
- }
- }
- /**
- * @brief Configures the different system clocks.
- */
- void RCC_Configuration(void)
- {
- /* Enable peripheral clocks --------------------------------------------------*/
- /* GPIOA, GPIOB and SPI1 clock enable */
- RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_SPI1, ENABLE);
- /* SPI2 Periph clock enable */
- RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_SPI2, ENABLE);
- }
- /**
- * @brief Configures the different GPIO ports.
- */
- void GPIO_Configuration(void)
- {
- GPIO_InitType GPIO_InitStructure;
- /* Configure SPI1 pins: SCK, MISO and MOSI ---------------------------------*/
- /* Confugure SCK and MOSI pins as Alternate Function Push Pull */
- GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /* Confugure MISO pin as Input Floating */
- GPIO_InitStructure.Pin = GPIO_PIN_6;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /* Confugure NSS pin as Output Push Pull */
- GPIO_InitStructure.Pin = GPIO_PIN_4;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
复制代码
6 结果
从log来看文件读取成功,从sd卡中读取到确认写入成功。
|