【中移芯昇】5. spi接口测试tf卡

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。
详见https://gitee.com/CMIOT-XinShengTech/CMIOT.CM32M4xxR_Library/blob/main/Projects/CM32M4xxR_LQFP128_STB/BSP/Include/log.h。

使用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 <main.h>
#include <stdio.h>
#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 */


/**
 * @brief  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-----------------------------------\r\n");
	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 ok\r\n");
    else
    	printf("fatfs init error\r\n");

    delay_ms(500);

    ret = f_mount((FATFS*)&fs, "", 0);
    printf("mount = %d\r\n",ret);
    if( ret != FR_OK)
    {
    	printf("error %s,line %d\r\n",__FILE__, __LINE__);
    }

    /* Open file to write */
    ret = f_open((FIL*)&fil, "first.txt", FA_OPEN_APPEND | FA_READ | FA_WRITE);
    printf("open = %d\r\n",ret);
    if(ret != FR_OK)
    {
    	printf("error %s,line %d\r\n",__FILE__, __LINE__);
    }

    /* Check freeSpace space */
   	if(f_getfree("", (DWORD*)&fre_clust, (FATFS **)&pfs) != FR_OK)
    {
    	printf("error %s,line %d\r\n",__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 %d\r\n",__FILE__, __LINE__);
    }

    /* Writing text */
    f_puts("XinSheng Tech SD Card I/O Example via SPI\n", (FIL*)&fil);
    f_puts("test!!!\n", (FIL*)&fil);

    /* Close file */
    if(f_close((FIL*)&fil) != FR_OK)
    {
    	printf("error %s,line %d\r\n",__FILE__, __LINE__);
    }

    /* Open file to read */
    if(f_open((FIL*)&fil, "first.txt", FA_READ) != FR_OK)
    {
    	printf("error %s,line %d\r\n",__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 %d\r\n",__FILE__, __LINE__);
    }

    /* Unmount SDCARD */
    if(f_mount(NULL, "", 1) != FR_OK)
    {
    	printf("error %s,line %d\r\n",__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卡中读取到确认写入成功。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在STM32上使用SPI接口往TF写入数据的过程如下: 1. 首先,确保已经正确配置了SPI控制器,包括选择合适的时钟源、设置SPI模式(主从模式)、设置数据传输速率等。根据TF的规格,设置SPI的传输位序(MSB-first或LSB-first)。 2. 初始化TFTF是通过SPI接口与主控器通信的,需要根据TF的规格进行初始化。具体操作包括发送初始化命令,等待TF响应,检查响应是否符合预期等。 3. 选择TF并发送写命令。通过SPI接口选择TF,并发送写命令。在发送命令时,需要注意命令的格式,包括命令码、命令参数等。 4. 发送数据。使用SPI接口向TF发送要写入的数据。数据可以分为多个数据包发送,每个包的大小取决于SPI的FIFO缓冲区大小和TF的规格。在发送数据之前,需要等待SPI控制器空闲,以确保上一个数据已经传输完毕。 5. 等待TF的响应。在每个数据包发送完毕后,需要等待TF的响应。响应有多种形式,如数据接收完成的响应或错误响应。根据相应的响应来确定是否继续发送下一个数据包或进行错误处理。 6. 结束写操作。所有的数据写入完成后,根据TF的规格发送结束写操作的命令,确保数据被正确写入。然后可以关闭SPI接口,结束写操作。 需要注意的是,在使用SPI接口往TF写入数据时,需要确保SPI控制器的时钟与TF的时钟同步,SPI的主从模式与TF的工作模式匹配,同时要考虑到数据传输速率的合理设置。此外,需要根据TF的规格和操作命令的要求,正确处理命令和数据的格式、传输顺序等。为了确保数据的可靠性,还应该考虑错误处理和重传机制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值