STM32F103C8T6通过串口加载固件

本文详细介绍了如何使用STM32F103C8T6通过串口加载固件,包括Flash写入程序、上位机与单片机串口接收程序的实现步骤,以及整个通讯协议的设计和过程。通过创建工程、编写读写Flash的函数和上位机交互,实现了固件的串口更新。
摘要由CSDN通过智能技术生成

STM32F103C8T6通过串口加载固件

之前写了简单的Bootloader,只实现了程序跳转的功能。但是作为一个Bootloader,只能完成程序跳转感觉缺了点啥。那就继续添加可以加载固件的功能吧。

加载固件的途径有很多,常见的就有串口、可移动存储设备、网络等等。这里就从最简单的开始吧,先做串口的。

整个程序的思路如下:

  1. 上位机与单片机进行握手,并传输一些必要的信息。
  2. 上位机发送固件的一部分到单片机(这里描述为一个块数据)。
  3. 单片机接收到一块数据后,将其保存到RAM中。然后向上位机返回这块数据的校验和。
  4. 上位机检查单片机返回的校验和是否正确,正确则重复步骤2和步骤3,直到整个固件发送完成。不正确则结束传输。

要完成整个加载的过程,起码要有几个方面的工作要做:

  1. 串口接收程序。
  2. Flash写入程序。
  3. 解析二进制文件并发送到串口的上位机程序。

串口接收程序需要和上位机程序一起说明,留到后面再说。现在先看下如何操作Flash。

1 Flash写入程序

1.0 目标

将一块RAM中的数据写入到Flash。

1.1 准备硬件

依然是淘宝上随处可见的STM32F103C8T6核心板,以及烧录和调试需要用到的STLINK。

1.2 理论基础

Flash简介之类的东西就不写了,上网查一下都有。这里主要写这款硬件相关的吧。这里主要参考ST的PM0075文档《STM32F10xxx Flash memory microcontrollers》,感兴趣的可以去看原文。

F103C8属于STMF1系列中的中等容量单片机,Flash容量为64KB,占用地址为:0x08000000~0x0800FFFF。这块64KB的Flash被分为64个1KB的页。这就意味着擦除的最小单位为1KB。

在这里插入图片描述

了解完Flash的组织结构后,再来了解一下Flash的读写操作。

读操作相对简单,直接声明一个指向要读取数据的指针就可以直接读取数据了。

写操作相对繁琐,ST官方PM0075文档中有如下流程图:

在这里插入图片描述

对照着流程图,这里稍作一点解释。

  1. STM32F103内部有一组寄存器(FPEC)是实现Flash控制的。上电后,FPEC寄存器组处于锁定状态,不可操作。因此在操作Flash之前,需要读取锁定状态位,如果FPEC锁定了,则需要解锁。
  2. 解锁Flash的方法很简单,就是依次先后将KEY1 = 0x45670123、KEY2 = 0xCDEF89AB 写入FLASH_KEYR寄存器即可。
  3. 解锁后,将FLASH_CR寄存器的PG位置为1。然后向目标地址写入一个半字(16bit)。
  4. 检查FLASH_SR寄存器的BSY位。等待BSY位变为0,从目标地址中读取一个半字,与写入的数据进行比较,检查是否真正写入。

实际上,HAL库会提供操作Flash的API函数,上述步骤只是了解就行,实际使用起来还是直接使用HAL库。

还有一点需要注意的。Flash操作的带宽为16位(16bit)。这意味着我们每次写入的时候都只能是16位的倍数。但是HAL库会提供写8位的函数,实际上这个函数是把高八位设定为0而已,本质上还是写入16位。

1.3 创建工程

创建工程就比较简单了。由于HAL库的工程会带有Flash操作的函数库,所以我们正常创建一个LED闪烁的工程即可。如下图所示:

在这里插入图片描述

1.3.1 简单测试

首先简单测试一下上面提到的读写操作是否有问题。

读操作:

/*
 *
 * 从Flash的某个地址中读取一个半字(16bit)
 * 
 */
uint16_t FLASH_ReadHalfWord(uint32_t addr)
{
   
  return *(volatile uint16_t *)addr;
}

由于写入是半字写入,那读取也写成一致的半字读取。需要字读取的可以在半字读取的基础上进行改写。

写操作函数不需要自己写,Hal库有提供。但是需要注意,执行的操作还是要按照上述流程图的顺序来执行的。

下面是Hal库提供的函数。

HAL_StatusTypeDef HAL_FLASH_Unlock(void);	//解锁
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);	//编程
HAL_StatusTypeDef HAL_FLASH_Lock(void);	//上锁

使用上述的函数,可以完成写入半字的操作,如下:

/*
 *
 * 按照官方文档的写入序列,向Flash的某个地址写入半字(16bit)
 * 
 */
uint8_t Flash_WriteHalfWord(uint32_t addr, uint16_t data)
{
   

  HAL_StatusTypeDef ret;    //操作返回值
  
  /* 1、解锁 */
  ret = HAL_FLASH_Unlock<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值