//--³ÌÐòÔËÐÐ״̬ȷ¶¨ //----0x55 Main //----0xff Spare void IAP_ProState(void) { #ifdef MAINAPP if(STMFLASH_ReadWord(IAP_UPD_OK_ADDR) != 0x55) { STMFLASH_WriteWord(IAP_UPD_OK_ADDR, 0x55); } #endif #ifdef SPAREAPP if(STMFLASH_ReadWord(IAP_UPD_OK_ADDR) == 0x55) { STMFLASH_WriteWord(IAP_UPD_OK_ADDR, 0xff); } #endif }
void System_Init(void) { INTX_DISABLE(); //close all interruption HF_BSP_Init(); enter_bootloader_flag=STMFLASH_ReadWord(FLASH_APP1_ADDR - 4); if(enter_bootloader_flag !=256 ) //jump to app code { enter_bootloader_flag=256; STMFLASH_Write(FLASH_APP1_ADDR - 4 , &enter_bootloader_flag , 1); HF_Set_Beep_State(1); delay_ms(500); delay_ms(500); HF_Set_Beep_State(0); enter_bootloader_flag=0; STMFLASH_Write(FLASH_APP1_ADDR - 4 , &enter_bootloader_flag , 1); Load_Flash_APP(FLASH_APP1_ADDR); } enter_bootloader_flag = 0; STMFLASH_Write(FLASH_APP1_ADDR - 4 , &enter_bootloader_flag , 1); HF_Set_Beep_State(1); delay_ms(500); delay_ms(500); delay_ms(500); delay_ms(500); HF_Set_Beep_State(0); INTX_ENABLE(); //enable all interruption }
/** * @Function void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead); * @description 从指定地址开始读出指定长度的数据 * @Input u32 ReadAddr:起始地址 * u32 pBuffer:数据指针 * u32 NumToRead:字(4位)数 * @Return void */ void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead) { u32 i; for(i=0;i<NumToRead;i++) { pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节. ReadAddr+=4;//偏移4个字节. } }
/** * @Function void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite); * @description 从指定地址开始写入指定长度的数据 *特别注意:因为STM32F4的扇区实在太大,没办法本地保存扇区数据,所以本函数 * 写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以 * 写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里 * 没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写. *该函数对OTP区域也有效!可以用来写OTP区! *OTP区域地址范围:0X1FFF7800~0X1FFF7A0F * @Input u32 WriteAddr:起始地址(此地址必须为4的倍数!!) * u32 *pBuffer:数据指针 * u32 NumToWrite:字(32位)数(就是要写入的32位数据的个数.) * @Return void */ void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite) { FLASH_Status status = FLASH_COMPLETE; u32 addrx=0; u32 endaddr=0; if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return; //非法地址 FLASH_Unlock(); //解锁 FLASH_DataCacheCmd(DISABLE); //FLASH擦除期间,必须禁止数据缓存 addrx=WriteAddr; //写入的起始地址 endaddr=WriteAddr+NumToWrite*4; //写入的结束地址 if(addrx<0X1FFF0000) //只有主存储区,才需要执行擦除操作!! { while(addrx<endaddr) //扫清一切障碍.(对非FFFFFFFF的地方,先擦除) { if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF) //有非0XFFFFFFFF的地方,要擦除这个扇区 { status=FLASH_EraseSector(STMFLASH_GetFlashSector(addrx),VoltageRange_3);//VCC=2.7~3.6V之间!! if(status!=FLASH_COMPLETE)break; //发生错误了 }else addrx+=4; } } if(status==FLASH_COMPLETE) { while(WriteAddr<endaddr) //写数据 { if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//写入数据 { break; //写入异常 } WriteAddr+=4; pBuffer++; } } FLASH_DataCacheCmd(ENABLE); //FLASH擦除结束,开启数据缓存 FLASH_Lock(); //上锁 }