## 4:FLASH操作
### 4.1:flash説明
![image-20240716153824296](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716153824296.png)
![image-20240716155759579](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716155759579.png)
![image-20240716155823792](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716155823792.png)
![image-20240716155857648](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716155857648.png)
顾名思义,单片机的flash有512个字节,有2个存储库,分别为256个字节,前面在做擦除操作的时候,后面可以进行写入擦做,每个扇区大小为8,共64个扇区。现在的单片机越来越强大,功能也越来越多,这里先使用熟悉传统的读写操作。
其中FLASH操作函数为:
```C
HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)QuadWord))
```
每次写入数据为16个字节,128位。参考函数定义说明:
```C
/**
*
@brief Program a quad-word at a specified address.
* @paramTypeProgram Indicate the way to program at a specified address.
* This parameter can be a value of
@ref FLASH_Type_Program
* @paramFlashAddress specifies the address to be programmed.
* This parameter shall be aligned to the Flash word (128-bit)
* @paramDataAddress specifies the address of data to be programmed
* This parameter shall be 32-bit aligned
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
```
FLASH读写程序:
```
/*在更新内部Flash时候禁用指令缓存*/
if (HAL_ICACHE_Disable() != HAL_OK)
{
Error_Handler();
}
/*解锁Flash以启用对Flash控制寄存器的访问*/
HAL_FLASH_Unlock();
/* 擦除用户Flash区域*/
/*(由Flash USER START ADDR和FLASH USER END _ADDR定义的区域)*/
/* Get the 1st sector to erase */
FirstSector = GetSector(FLASH_USER_START_ADDR);
gpio_port_set();
setSysRunState(STATE_RUN); //开始运行
uart_device_init(DEV_UART2); // 使能DMA接收
__HAL_LINKDMA(&huart2, hdmatx, handle_GPDMA1_Channel1);// 使能串口 DMA 发送
printf("init_ok\r\n");
setSysUpdateState(INIT);
printf("FLASH_BANK_SIZE=%d\r\n",FLASH_BANK_SIZE/1024);
/* Get the 1st sector to erase */
FirstSector = GetSector(FLASH_USER_START_ADDR);
printf("FirstSector=%d\r\n",FirstSector);
/* Get the number of sector to erase from 1st sector*/
NbOfSectors = GetSector(FLASH_USER_END_ADDR) - FirstSector + 1;
printf("NbOfSectors=%d\r\n",NbOfSectors);
/* Get the bank */
BankNumber = GetBank(FLASH_USER_START_ADDR);
printf("BankNumber=%d",BankNumber);
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; //擦除类型
EraseInitStruct.Banks = BankNumber;
EraseInitStruct.Sector = FirstSector;
EraseInitStruct.NbSectors = NbOfSectors;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
{
while (1)
{
Error_Handler();
}
}
Address = FLASH_USER_START_ADDR;
while (Address < FLASH_USER_END_ADDR)
{
/*往Flash里面写数据*/
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)QuadWord)) == HAL_OK)
{
Address = Address + 16;
}
else
{
while (1)
{
Error_Handler();
}
}
}
/* 锁定Flash以禁止对Flash控制寄存器的访问 (建议用于保护FLASH存储器免受可能的意外操作) */
HAL_FLASH_Lock();
/* Re-enable instruction cache */
if(HAL_ICACHE_Enable() != HAL_OK)
{
Error_Handler();
}
MemoryProgramStatus = Check_Program(FLASH_USER_START_ADDR, FLASH_USER_END_ADDR, QuadWord);
/*Check if there is an issue to program data*/
if(MemoryProgramStatus != 0)
{
printf("Flash_Write_Read_Failure\r\n");
}
else
{
printf("Flash_Write_Read_Success\r\n");
}
```
### 4.2:FLASH设置
IAP程序设置
![image-20240730225734670](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240730225734670.png)
APP地址和标志位地址设置:
```
#define APP_START_ADDR 0x0800C000
#define APP_END_ADDR 0x08040000
#define IAP_UPGRADE_FLAG_ADDR (APP_END_ADDR-8192) //一个扇区有8K
```
APP程序设置
![image-20240730225758164](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240730225758164.png)
代码设置:
```C
SCB->VTOR = FLASH_BASE | 0xC000; //重映射向量表
```
APP跳转处理
```C
void iap_load_app(uint32_tappxaddr)
{
__disable_irq ();//关闭总中断
JumpAddress = *(__IO uint32_t*) (appxaddr + 4);
JumpToApplication = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) appxaddr);//设置MSP堆栈指针值
JumpToApplication();
}
```
### 4.3:自定义通讯协议
| 名称 | 帧头 | 长度 | 具体数据 | 校验CRC16 |
| ---- | ------ | ------ | ------------------------ | --------- |
| 长度 | 2 | 2 | N | 2 |
| 值 | 0x55AA | 0x0101 | 包含命令,地址,数据等等 | 0x0102 |
### 4.4:上位机界面
![image-20240730230748526](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240730230748526.png)
### 4.5:实现过程
https://www.bilibili.com/video/BV1VFvCexEud/?vd_source=d89384d7551b55d1559dd2bf89310863