#include "flash.h" uint16_t STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字节 /** * @brief Unlock the FLASH control register access * @retval LL Status */ LL_StatusTypeDef LL_Flash_Unlock(void) { if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) { /* Authorize the FLASH Registers access */ WRITE_REG(FLASH->KEYR, FLASH_KEY1); WRITE_REG(FLASH->KEYR, FLASH_KEY2); /* Verify Flash is unlocked */ if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) { return LL_ERROR; } } else return LL_ERROR; return LL_OK; } /** * @brief Locks the FLASH control register access * @retval LL Status */ LL_StatusTypeDef LL_FLASH_Lock(void) { /* Set the LOCK Bit to lock the FLASH Registers access */ SET_BIT(FLASH->CR, FLASH_CR_LOCK); return LL_OK; } /** * @brief Get the FLASH Status * @retval LL Status */ LL_StatusTypeDef LL_FLASH_GetStatus(void) { uint32_t res; res=FLASH->SR; if(res&(1<<0))return LL_BUSY; //忙 else if(res&(1<<2))return LL_ERROR; //编程错误 else if(res&(1<<4))return LL_PROTECT; //写保护错误 return LL_OK; //操作完成 } LL_StatusTypeDef LL_FLASH_Wait(void) { LL_StatusTypeDef res; uint16_t time = 50000; res = LL_FLASH_GetStatus(); while(res == LL_BUSY) { res = LL_FLASH_GetStatus(); if(time==0) { res = LL_TIMEOUT; break; } time--; } return res; } LL_StatusTypeDef LL_FLASH_ErasePage(uint32_t PageAddress) { LL_StatusTypeDef res; res = LL_FLASH_Wait(); if(res == LL_OK) { SET_BIT(FLASH->CR, FLASH_CR_PER); //页擦除 WRITE_REG(FLASH->AR, PageAddress); //设置页地址 SET_BIT(FLASH->CR, FLASH_CR_STRT); //开始擦除 res = LL_FLASH_Wait(); //等待操作结束 if(res != LL_BUSY) FLASH->CR &= ~FLASH_CR_PER; //清除PER位 } return res; } LL_StatusTypeDef LL_FLASH_ProgramHalfWord(uint32_t Address,uint16_t Data) { LL_StatusTypeDef res; res=LL_FLASH_Wait(); if(res == LL_OK) { SET_BIT(FLASH->CR, FLASH_CR_PG); //编程使能 *(__IO uint16_t*)Address = Data; //写入数据 res=LL_FLASH_Wait(); //等待操作 if(res != LL_BUSY) //操作成功 FLASH->CR &= ~FLASH_CR_PG; //清除PG位 } return res; } #if STM32_FLASH_WREN //如果使能了写 //不检查的写入 //WriteAddr:起始地址 //pBuffer:数据指针 //NumToWrite:半字(16位)数 void STMFLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite) { uint16_t i; for(i=0;i=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址 LL_Flash_Unlock(); //解锁 offaddr=WriteAddr-STM32_FLASH_BASE; //实际偏移地址. secpos=offaddr/STM_SECTOR_SIZE; //扇区地址 0~127 for STM32F103RBT6 secoff=(offaddr%STM_SECTOR_SIZE)/2; //在扇区内的偏移(2个字节为基本单位.) secremain=STM_SECTOR_SIZE/2-secoff; //扇区剩余空间大小 if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围 while(1) { STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容 for(i=0;i(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完 else secremain=NumToWrite;//下一个扇区可以写完了 } } LL_FLASH_Lock();//上锁 } #endif //读取指定地址的半字(16位数据) //faddr:读地址 //返回值:对应数据. uint16_t LL_FLASH_ReadHalfWord(uint32_t faddr) { return *(__IO uint16_t*)faddr; } uint32_t LL_FLASH_ReadWord(uint32_t faddr) { uint32_t i = 0; i = LL_FLASH_ReadHalfWord(faddr+2); i = i<<16; i |= LL_FLASH_ReadHalfWord(faddr); return i; } void LL_FLASH_WriteHalfWord(uint32_t WriteAddr,uint16_t data) { STMFLASH_Write(WriteAddr,&data,1); } void LL_FLASH_WriteWord(uint32_t WriteAddr,uint32_t data) { uint16_t buffer[2] = {data,data>>16}; STMFLASH_Write(WriteAddr,buffer,2); }