写一个stm32c8t6串口IAP升级程序
时间: 2023-08-10 20:05:41 浏览: 169
STM32C8T6USB虚拟串口,stm32f103c8t6串口,C,C++
5星 · 资源好评率100%
好的,下面是使用STM32C8T6实现串口IAP升级程序的示例代码,仅供参考:
```c
#include "stm32c8t6.h"
#include <stdio.h>
#define APP_FLASH_BASE_ADDR 0x08008000 // App程序存储地址
#define IAP_FLASH_BASE_ADDR 0x08000000 // IAP程序存储地址
#define FLASH_PAGE_SIZE 1024 // Flash的页大小
/* 函数声明 */
void USART1_Config(void);
void Flash_Erase(uint32_t addr);
void Flash_Write(uint32_t addr, uint8_t *data, uint32_t size);
int main(void)
{
USART1_Config(); // 配置串口
printf("IAP Program Start\r\n");
uint8_t data = 0;
uint32_t iap_addr = IAP_FLASH_BASE_ADDR; // IAP程序存储地址
while(1)
{
// 从串口接收数据
while((USART1->SR & USART_SR_RXNE) == 0);
data = USART1->DR;
// 如果接收到的数据为0x7F,表示开始IAP升级
if(data == 0x7F)
{
printf("Start IAP Program\r\n");
// 擦除App程序
Flash_Erase(APP_FLASH_BASE_ADDR);
// 从IAP程序读取数据并写入App程序
uint8_t buffer[FLASH_PAGE_SIZE];
while(1)
{
for(uint32_t i = 0; i < FLASH_PAGE_SIZE; i++)
{
while((USART1->SR & USART_SR_RXNE) == 0);
buffer[i] = USART1->DR;
}
Flash_Write(APP_FLASH_BASE_ADDR, buffer, FLASH_PAGE_SIZE);
iap_addr += FLASH_PAGE_SIZE;
// 如果读取到的数据结尾为0x7F,表示IAP升级结束
if(buffer[FLASH_PAGE_SIZE - 1] == 0x7F)
{
printf("IAP Program End\r\n");
// 跳转到App程序
void (*app_entry)(void) = (void (*)(void))(APP_FLASH_BASE_ADDR + 4);
app_entry();
}
}
}
}
}
/* USART1配置函数 */
void USART1_Config(void)
{
RCC->APBENR |= RCC_APBENR_USART1EN; // 使能USART1时钟
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // 使能SYSCFG时钟
SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_USART1TX_DMA_RMP; // 关闭USART1 DMA传输映射
// 配置USART1引脚
GPIOA->MODER &= ~(GPIO_MODER_MODE9 | GPIO_MODER_MODE10);
GPIOA->MODER |= GPIO_MODER_MODE9_1 | GPIO_MODER_MODE10_1;
GPIOA->AFR[1] &= ~(GPIO_AFRH_AFSEL9 | GPIO_AFRH_AFSEL10);
GPIOA->AFR[1] |= (1 << (1 * 4)) | (1 << (2 * 4));
// 配置USART1
USART1->CR1 &= ~USART_CR1_UE;
USART1->CR1 &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS);
USART1->CR2 &= ~USART_CR2_STOP;
USART1->CR1 &= ~USART_CR1_OVER8;
USART1->BRR = 4000000 / 115200;
USART1->CR1 |= USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}
/* Flash擦除函数 */
void Flash_Erase(uint32_t addr)
{
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = addr;
FLASH->CR |= FLASH_CR_STRT;
while((FLASH->SR & FLASH_SR_BSY) != 0);
FLASH->CR &= ~FLASH_CR_PER;
}
/* Flash写入函数 */
void Flash_Write(uint32_t addr, uint8_t *data, uint32_t size)
{
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
FLASH->CR |= FLASH_CR_PG;
for(uint32_t i = 0; i < size; i++)
{
*(volatile uint8_t*)(addr + i) = data[i];
while((FLASH->SR & FLASH_SR_BSY) != 0);
if(*(volatile uint8_t*)(addr + i) != data[i])
{
printf("Flash Write Error: Addr=0x%08X, Data=0x%02X\r\n", addr + i, data[i]);
return;
}
}
FLASH->CR &= ~FLASH_CR_PG;
}
```
这是一个简单的串口IAP升级程序,通过USART1接收IAP程序数据并写入Flash,最后跳转到App程序。需要注意的是,此代码仅作为示例,具体实现需要根据实际需求进行修改和优化。
阅读全文