STM32F103C8T6通过SD卡加载固件

STM32F103C8T6通过SD卡加载固件

前面写了通过Uart加载固件,这次就使用SD卡来尝试一下加载固件吧。

要实现SD卡加载固件的功能,需要完成以下三项工作:

  1. 能够对单片机内部FLASH进行编程。(前面写串口加载固件的时候写了)
  2. 完成SD卡驱动。
  3. 移植FATFS文件系统。

有了这三项的支持,编写从SD卡加载固件的程序就很简单了。程序思路如下:

  1. 初始化SD卡,挂载文件系统。
  2. 只读方式打开"download.bin"文件,获取文件描述符。
  3. 以512字节为单位,循环读取"download.bin"文件的内容,并写入APP程序的地址中。
  4. 跳转到APP程序。

1 对FLASH编程

这个前面的文章详细地写了,这里不展开,直接引用以前的代码即可。

2 编写SD卡驱动

2.0 准备硬件

由于STM32F103C8核心板上没有SD卡槽,需要买一个SD卡槽,需要买一个集成的模块。记住要买TF小卡的,日常使用小卡比较多。

STM32F103C8T6通过SD卡加载固件_第1张图片

还有就是需要一张TF卡,要支持HC协议的。一般不超过32G的卡都支持HC协议,在卡的表面丝印也会注明HC。

STM32F103C8T6通过SD卡加载固件_第2张图片

准备好硬件后可以看以下SD卡的协议和读写规范。粗略阅读后,还是建议从网上下载一份代码,移植到自己的工程。当然,时间充足的话,从头开始动手写没什么不好的。

2.1 创建工程

中等容量系列的C8T6是没有SDIO接口的,所以只能用SPI接口去驱动SD卡,缺点就是慢。在CUBEMX里面初始化一个SPI接口,如下图所示:

STM32F103C8T6通过SD卡加载固件_第3张图片

SPI设置为:全双工主机、软件NSS信号、Motorola帧协议、数据宽度8位、MSB格式、速率18MBit(在程序中会修改)、空闲状态为高电平、时钟相位为第2个时钟边缘、不使能CRC。这些设置可以从SD卡的读写时序得到,也可以简单地从别人的代码中得到。

配置完成后生成工程。

2.2 移植驱动代码

这里选择移植正点原子的SD卡驱动代码。因为这份代码写得很容易移植,工程里面的SD卡驱动和底层的SPI代码是分开的,因此我们只需要用HAL库SPI外设的代码去实现spi.c这个文件的接口就行。

#include "spi.h"

extern SPI_HandleTypeDef hspi1;

/*
 * description : 初始化SPI
 * param : none
 * return : none
 */
void SPI1_Init(void)
{
   
    SPI1_ReadWriteByte(0xff);   //启动传输	
}


/*
 * description : 发送&接收
 * param - TxData : 要发送的数据
 * return : 接收到的数据
 */
uint8_t SPI1_ReadWriteByte(uint8_t TxData)
{
   
    uint8_t rxData;
    HAL_SPI_TransmitReceive(&hspi1, &TxData, &rxData, 1, 10);
    return rxData;
}

/*
 * description : 设置传输速度
 * param - SpeedSet : SPI_BAUDRATEPRESCALER_2   = 2分频   = 36M(不可选)
 *                    SPI_BAUDRATEPRESCALER_4   = 4分频   = 18M
 *                    SPI_BAUDRATEPRESCALER_8   = 8分频   = 9M
 *                    SPI_BAUDRATEPRESCALER_16  = 16分频  = 4.5M
 *                    SPI_BAUDRATEPRESCALER_256 = 256分频 = 281.25K
 * return : none
 */
void SPI1_SetSpeed(uint32_t SpeedSet)
{
   
    hspi1.Init.BaudRatePrescaler = SpeedSet;
    HAL_SPI_Init(&hspi1);
}

至于MMC_SD.C这里面的代码,基本不需要改动。只需要把代码中使用的u8、u16、u32替换成uin8_t、uint16_t、uint32_t即可。当然自己在头文件中手动定义一下u8、u16、u32也可以。

在main()中简单测试一下驱动:

int main(void)
{
   
  /* USER CODE BEGIN 1 */
  uint32_t sdSectorCount;
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  while(SD_Initialize())//检测不到SD卡
  {
   
    HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    HAL_Delay(100)

你可能感兴趣的:(单片机,嵌入式)