admin管理员组

文章数量:1582962

说明:

1.本例程参考正点原子的IAP的代码。
2.本例程基于STM32F103C8T6单片机编写。
3.本例程使用USART1进行程序下载,波特率115200
4.串口输出”Bootloder“字样后,请在3s内通过串口将APP的.bin文件传入单片机,之后会自动烧写并启动APP。若3s内未传入.bin文件或传入的文件有误,则会自动原来的启动APP。.bin文件最大只能15KByte
5.STM32F103C8T6拥有128KByte的flash20KByte的sram。本程序将0x0800 0000 - 0x0800 FFFF作为Bootloder空间,将0x0801 0000 - 0x0801 FFFF作为APP空间。
6.APP程序需要将flash中的向量表偏移0x10000


工程源码下载(fci5), 工程使用 Keil uVision5 创建 ,密码 fci5 。

XCOM V2.6下载(48cm),密码 48cm 。



程序源码:

  • main.c
#include "delay.h"
#include "usart.h"
#include "flash.h"
#include "iap.h"


/***********************************************
*         支持最大15KByte的APP                 *
*				                                       *
*		0x0800 0000 - 0x0800 FFFF 为Bootloder空间  *
*   0x0801 0000 - 0x0801 FFFF 为APP空间        *
*                                              *
***********************************************/

int main ()
{
   
	u8 flag_update = 0; //升级完成后置1
	u16 t = 0;
	u16 oldcount = 0;
	u16 applen = 0;
		
	//初始化
	delay_init();
	USART1_Init(115200);
	delay_ms(20);
	printf("Bootloder\r\n");
	
	while(1)
	{
   
		if(USART1_RX_CNT) //如果接收到了数据
		{
   
			if(oldcount == USART1_RX_CNT) //如果新周期内没收到数据,则认为接收完成
			{
   
				applen = USART1_RX_CNT;
				oldcount = 0;
				USART1_RX_CNT = 0;
				
				if(((*(vu32*)(0x20001000+4)) & 0xFF000000) == 0x08000000) //判断是否为0x08XXXXXX,(是否为APP数据)
				{
   
					printf("APP len : %d\r\n",applen);
					
					//开始升级APP
					printf("Updating...\r\n");
					iap_write_appbin(FLASH_APP1_ADDR,USART1_RX_BUF,applen); //写入flash
					flag_update = 1;
					printf("Updae success !!!\r\n");
				}
				else printf("APP data error!!!\r\n");
			}
			else oldcount = USART1_RX_CNT; //更新接收到的字节数
		}	
		
		if(flag_update || (t == 300 & USART1_RX_CNT == 0)) //如果升级APP完成或3s内没收到正确的APP数据,则启动APP
		{
   
			printf("APP Start\r\n\r\n");
			iap_load_app(FLASH_APP1_ADDR);
		}		
		t++;
		delay_ms(10); 
	}	
}


  • delay.h
#ifndef _DELAY_H
#define _DELAY_H
#include "stm32f10x.h"

void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);

#endif


  • delay.c
#include "delay.h"

static u8 fac_us = 0;     //us延时倍乘数
static u16 fac_ms = 0;    //ms延时倍乘数

void delay_init(void)
{
   
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);  	//选择外部时钟 HCL/8
	fac_us = SystemCoreClock/8000000;                      	//为系统时钟的1/8
	fac_ms = (u16)fac_us * 1000;
}

void delay_us(u32 nus)
{
   
	u32 temp;
	SysTick->LOAD = nus * fac_us;//时间加数
	SysTick->VAL = 0x00;//清空计数器
	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;//开始倒数
	
	do
	{
   
		temp = SysTick->CTRL;
	}while((temp & 0x01) &&! (temp & (1<<16))); //等待时间到达
	
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;//关闭计数器、
	SysTick->VAL = 0x00;//清空计数器
}

void delay_ms(u16 nms)
{
   
	u32 temp;
	SysTick->LOAD = (u32)nms * fac_ms;//时间加载(SysTick->LOAD为24bit)
	SysTick

本文标签: 下载链接源码程序百度网Bootloder