一、程序代码
1、Bootloader程序 (1)主函数
#include \
//中断向量重映射
__root const long reintvec[]@\{
0x82008080,0x8200B804,0x8200B808,0x8200B80c,
0x8200B810,0x8200B814,0x8200B818,0x8200B81c,
0x8200B820,0x8200B824,0x8200B828,0x8200B82c,
0x8200B830,0x8200B834,0x8200B838,0x8200B83c,
0x8200B840,0x8200B844,0x8200B848,0x8200B84c,
0x8200B850,0x8200B854,0x8200B858,0x8200B85c,
0x8200B860,0x8200B864,0x8200B868,0x8200B86c,
0x8200B870,0x8200B874,0x8200B878,0x8200B87c, };
#ifdef TEST
u32 addresss=0xa090;
u8 temp[8]={1,2,3,4,5,6,7,8};
u8 temp_Valid_flag[4]={0}; #endif
void Clk_Init(void) {
CLK_SWR = 0x01; //HSI selected as system clock source CLK_CKDIVR = 0x00; //System clock source/1 }
void Delayus(u16 n_us) {
uint16_t i,j;
for(i=0;i for(j=0;j<1;j++) {IWDG_KR = 0xaa;} } } void Delayms(u16 n_ms) { u8 k = 20; while(n_ms--) { while(k--) nop(); } } void main(void) { Clk_Init(); //中断内us级延时 uart_init(); rim(); DataFlashRead(APP_Valid_address,temp_Valid_flag,4); if((temp_Valid_flag[0]==0x11) && (temp_Valid_flag[1]==0x22) (temp_Valid_flag[3]==0x44)) { Jump_To_App(); } #ifdef TEST PC_DDR |= 0x80; //PC7输出口 PC_CR1 |= 0x80; //PC7推挽输出 PC_CR2 |= 0x80; //PC7输出速度最大为10MHZ PC_ODR &= ~0x80;//PC7输出低 Buzzer(3); #endif while(1) { uart_receive(); } } (2)Flash函数 /*********************************************** * 函数名 :unlock_PROG * 描述 :不使能FLASH保护 * 创建时间 :2017-05-17 ************************************************/ void unlock_PROG(void) { do{ FLASH_PUKR = 0x56; FLASH_PUKR = 0xAE; }while((FLASH_IAPSR & 0x02)==0); } /*********************************************** * 函数名 :unlock_DATA * 描述 :不使能EEPROM保护 * 创建时间 :2017-05-17 ************************************************/ void unlock_DATA(void) { do{ FLASH_DUKR = 0xAE; memory !!! */ FLASH_DUKR = 0x56; }while((FLASH_IAPSR & 0x08)==0); } /*********************************************** * 函数名 :lock_PROG * 描述 :使能FLASH保护 * 创建时间 :2017-05-17 ************************************************/ void lock_PROG(void) { FLASH_IAPSR &= (~0x02); } /*********************************************** * 函数名 :lock_DATA && (temp_Valid_flag[2]==0x33) && /* Warning: keys are reversed on data * 描述 :使能EEPROM保护 * 创建时间 :2017-05-17 ************************************************/ void lock_DATA(void) { FLASH_IAPSR &= (~0x08); } /*********************************************** * 函数名 :WriteFlashword * 描述 :按字写FLASH/EEPROM * 创建时间 :2017-05-17 ************************************************/ u8 WriteFlashword(u32 DataAddress, u16 DataBuffer) { u32 Address = DataAddress; u16 DataPointer = DataBuffer; unlock_PROG(); unlock_DATA(); *((__far u8*) Address) = *((u8 *)(&DataPointer)); /* Write one byte - from lowest address*/ *((__far u8*)(Address + 1)) = *((u8 *)(&DataPointer) + 1); /* Write one byte*/ while(FLASH_IAPSR & 0x04 == 0); lock_PROG(); lock_DATA(); return 1; } /*********************************************** * 函数名 :WriteBufferFlash * 描述 :写4字节FLASH/EEPROM * 创建时间 :2017-05-17 ************************************************/ u8 WriteBufferFlash(u32 DataAddress, u8 *DataBuffer, u16 DataCount) { u32 Address = (u32)DataAddress; u8 *DataPointer = DataBuffer; unlock_PROG(); unlock_DATA(); while(DataCount >= 4) { FLASH_CR2 |= (uint8_t)0x40; *((__far u8*) Address) = (u8)*DataPointer ; /* Write one byte - from lowest address*/ *((__far u8*)(Address + 1)) = *(DataPointer + 1); /* Write one byte*/ *((__far u8*)(Address + 2)) = *(DataPointer + 2); /* Write one byte*/ *((__far u8*)(Address + 3)) = *(DataPointer + 3); /* Write one byte - from higher address*/ while((FLASH_IAPSR & (0x04 | 0x01)) == 0); Address += 4; DataPointer+= 4; DataCount -= 4; } lock_PROG(); lock_DATA(); return 1; } /*********************************************** * 函数名 :WriteBuffer * 描述 :写FLASH/EEPROM * 创建时间 :2017-05-17 ************************************************/ u8 WriteBuffer(u32 DataAddress, u8 *DataBuffer, u8 DataCount,FLASH_TypeDef MemType) { if(MemType == FLASH_PROG) //for Flash { if((DataAddress >= FLASH_START) && ((DataAddress + DataCount - 1) <= FLASH_END)) return WriteBufferFlash(DataAddress, DataBuffer, DataCount); } else //for EEPROM { if((DataAddress >= EEPROM_START) && ((DataAddress + DataCount - 1) <= EEPROM_END)) return WriteBufferFlash(DataAddress, DataBuffer, DataCount); } return 0; } /*********************************************** * 函数名 :DataFlashRead * 描述 :读FLASH/EEPROM * 创建时间 :2017-05-17 ************************************************/ void DataFlashRead(u32 DataAddress,u8 *DataBuffer,u8 DataCount) { for(u8 i = 0; i < DataCount; i++) { DataBuffer[i] = (*(__far u8*)(DataAddress + i)); //__far 返回32bit } } /*********************************************** * 函数名 :FLASH_EraseBlock * 描述 :读FLASH/EEPROM * 创建时间 :2017-05-17 ************************************************/ __ramfunc void FLASH_EraseBlock(u32 Address) { u8 __far *pwFlash = (__far u8 *)Address; /* Enable erase block mode */ FLASH_CR2 |= 0x20; //*((__far u32*)Address) = (u32)0; *pwFlash = 0; *(pwFlash+1) = 0; *(pwFlash+2) = 0; *(pwFlash+3) = 0; } /*********************************************** * 函数名 :Clean_savespace * 描述 :清除存储空间 * 创建时间 :2017-05-17 ************************************************/ void Clean_savespace(u16 BlockNum, u8 Count) { u32 address;u8 i; unlock_PROG(); unlock_DATA(); for(i=0; i address = (u32)(0x00008000 + (u32)(BlockNum+i) * 128); FLASH_EraseBlock(address); //Delay_ms(6); } lock_PROG(); 远指针 指针指向的地址与数据段的段地址不同 lock_DATA(); } void Jump_To_App(void) { asm(\ SP \ asm(\ A, $FF\ asm(\ XL, A \ asm(\, X \ asm(\ //B800是要跳转到偏移地址 } void Jump_To_RESET(void) { asm(\ SP \ asm(\ A, $FF\ asm(\ XL, A \ asm(\, X \ asm(\ //8000是要跳转到偏移地址 } (3)串口函数 #define Rev_counter 600 //7E CMD LenH LenL......CrcH CrcL E7 typedef struct ud { u8 Receive_data[Rev_counter]; //数据接收 u16 Total_Bytes; //总字节数 u16 Single_Counter; //单包数据计数器 u16 Total_Bytes_Counter; //总接收数据个数计数器 }uart_D; uart_D Uart_data; bool CMD_flag=FALSE; bool RECE_flag=FALSE; u8 Valid_flag[4]={0x11,0x22,0x33,0x44}; //#include \ /*********************************************** * 函数名 :uart_init * 描述 :串口初始化 * 创建时间 :2017-05-17 ************************************************/ void uart_init(void) { CLK_PCKENR1 |= 0x20; //使能串口时钟 //USART1_BRR2 = 0x03; //USART1_BRR1 = 0x68; //波特率9600 USART1_BRR2 = 0x0b; USART1_BRR1 = 0x08; //波特率115200