STM32G030C8T6读写flash
????????最近選型使用STM32G030這款芯片,由于做的功能需要頻繁讀寫flash,最開始沒有注意到芯片的擦寫次數(shù)是1000次,為了確保功能實(shí)現(xiàn),只能是每次寫入flash時(shí)判斷當(dāng)前頁是否寫滿,寫滿才擦除重新開始寫;
? ? ? ? ?每次需要寫入flash的數(shù)據(jù)長度小于128字節(jié),以128字節(jié)計(jì)算,每一頁可以寫入16=2048/128 次;?STM32G030C8T6最少可以寫入16000次;如果對(duì)寫入次數(shù)需求高的,可以減少每次寫入數(shù)據(jù)的長度;
STM32G030C8T6寫入特性參考:stm32g030 內(nèi)部flash存儲(chǔ)一些用戶數(shù)據(jù)的方法 - 簡書
stm32F103
可編程flash區(qū),以頁為單位,每頁1K,共128頁, 擦寫次數(shù)>1萬次;
寫入以16位“半字”為最小單位,擦除以頁為單位;
先解鎖,清標(biāo)志,擦除,寫,上鎖;?
進(jìn)行flash操作時(shí),必須打開內(nèi)部HSI;
stm32G030
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 用時(shí)? ?\/
64-bit? ? ? ? program? ? ? ? ?85~125us;
32 Double word program? ? ? ? X ms
page(2k)? ? ? program? ? ? ? ? ? ? X ms
bank(64k)? ? ? program? ? ? ? ? ? X s
page(2k)? ? ? erase? ? ? ? ? ? ? ? ?40ms
Mass? ? ? ? ? erase? ? ? ? ? ? ? ? ? ?X ms
擦寫次數(shù)? 僅>= 1K次!!!? 需考慮壞頁情況;
寫數(shù)據(jù)時(shí),一般建議關(guān)閉所有中斷!
stm32g030 雙字寫時(shí),不僅要求是雙字形式, 而且要求8字節(jié)對(duì)齊。 否則進(jìn)入硬件錯(cuò)誤!
測(cè)試部分代碼:
//從指定地址開始寫入指定長度的數(shù)據(jù) //ReadAddr:起始地址 //pBuffer:數(shù)據(jù)指針 //NumToWrite:寫入數(shù)據(jù)長度 void STMFLASH_Write_64(u32 WriteAddr,u8*pBuffer,u16 NumToWrite) {u16 i;u64 data_write;u16 len =NumToWrite; u8 len_flag=0; if(NumToWrite>FLASH_PAGE_SIZE)return;if( (WriteAddr<FLASH_BASE) ||(WriteAddr>=(FLASH_BASE+FLASH_PAGE_SIZE*FLASH_PAGE_NB)))return;//非法地址HAL_FLASH_Unlock(); //解鎖 len_flag=len%8;len=len+get_rem_data(len_flag); //數(shù)據(jù)長度8字節(jié)對(duì)齊判斷if(WriteAddr%FLASH_PAGE_SIZE==0) //寫滿了從一頁開始地址寫需要擦除{ FLASH_EraseInitTypeDef My_Flash={0}; //聲明 FLASH_EraseInitTypeDef 結(jié)構(gòu)體為 My_FlashMy_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //標(biāo)明Flash執(zhí)行頁面只做擦除操作My_Flash.Page = (WriteAddr - FLASH_BASE) / FLASH_PAGE_SIZE;My_Flash.NbPages = 1; //說明要擦除的頁數(shù),此參數(shù)必須是Min_Data = 1和Max_Data =(最大頁數(shù)-初始頁的值)之間的值uint32_t PageError = 0; //設(shè)置PageError,如果出現(xiàn)錯(cuò)誤這個(gè)變量會(huì)被設(shè)置為出錯(cuò)的FLASH地址HAL_FLASHEx_Erase(&My_Flash, &PageError); //調(diào)用擦除函數(shù)擦除 } for(i=0;i<len/8;i++)//復(fù)制 //8字節(jié)數(shù)據(jù)對(duì)齊組包{u32 data_1=0;u64 data_2=0;data_1=(pBuffer[8*i+0])|(pBuffer[8*i+1]<<8)|(pBuffer[8*i+2]<<16)|(pBuffer[8*i+3]<<24); //data_2=(pBuffer[8*i+4])|(pBuffer[8*i+5]<<8)|(pBuffer[8*i+6]<<16)|(pBuffer[8*i+7]<<24); data_write= data_1| (data_2<<32); if( HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,WriteAddr,data_write) == HAL_OK)WriteAddr+=8;//地址增加2. } HAL_FLASH_Lock(); //上鎖 } u8 get_rem_data(u8 data) //長度判斷 {u8 re_data=0;switch (data){case 0: re_data=0; break;case 1: re_data=7; break;case 2: re_data=6; break;case 3: re_data=5; break;case 4: re_data=4; break;case 5: re_data=3; break;case 6: re_data=2; break;case 7: re_data=1; break;}return re_data; }void stm32_FLASH_ErasePage(u32 WriteAddr) //擦除 {if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+FLASH_PAGE_SIZE*FLASH_PAGE_NB)))return;//非法地址HAL_FLASH_Unlock(); //解鎖if(WriteAddr%FLASH_PAGE_SIZE==0) { // FLASH_PageErase(WriteAddr);//擦除這個(gè)扇區(qū) FLASH_EraseInitTypeDef My_Flash={0}; //聲明 FLASH_EraseInitTypeDef 結(jié)構(gòu)體為 My_FlashMy_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //標(biāo)明Flash執(zhí)行頁面只做擦除操作My_Flash.Page = (WriteAddr - FLASH_BASE) / FLASH_PAGE_SIZE;My_Flash.NbPages = 1; //說明要擦除的頁數(shù),此參數(shù)必須是Min_Data = 1和Max_Data =(最大頁數(shù)-初始頁的值)之間的值uint32_t PageError = 0; //設(shè)置PageError,如果出現(xiàn)錯(cuò)誤這個(gè)變量會(huì)被設(shè)置為出錯(cuò)的FLASH地址HAL_FLASHEx_Erase(&My_Flash, &PageError); //調(diào)用擦除函數(shù)擦除 } HAL_FLASH_Lock();//上鎖 }u8 STMFLASH_ReadByte(u32 faddr) {return *(__IO uint8_t*) (faddr);// return *(u8*) faddr; }//從指定地址開始讀出指定長度的數(shù)據(jù) //ReadAddr:起始地址 //pBuffer:數(shù)據(jù)指針 //NumToWrite:半字(16位)數(shù) void STMFLASH_Read_Byte(u32 ReadAddr,u8 *pBuffer,u16 NumToRead) {u16 i;for(i=0;i<NumToRead;i++){pBuffer[i]=STMFLASH_ReadByte(ReadAddr);//讀1個(gè)字節(jié).ReadAddr+=1;//偏移1個(gè)字節(jié). } } #define FLASH_SAVE_ADDR_MAX_31 0X0800f800 u8 data_flash[64]; static u16 count_delay=0; u8 flag_v_a=0; int main(void) {HAL_Init();SystemClock_Config(); // led_gpio_config(); // d_out_gpio_config(); // d_in_gpio_config(); // rs485_en_gpio_config(); UART1_init(115200);UART2_init(115200); printf("******************sys begain **************\r\n");data_flash[0]=0x55;fauil_delay_work=30;IWDG_Init(4,625*6); // 頻率:32K/64/1 Tout= ((prer分頻)* rlr /32) 7while (1){ printf("\r\n\r\nwrite falsh data \r\n");for(u8 i=0;i<sizeof(data_flash);i++){if(i==0) data_flash[0]=0x55;else data_flash[i]=i+data_coun; printf("%02x ",data_flash[i] );}data_coun++;HAL_Delay(1000);stm32_save_flash(FLASH_SAVE_ADDR_MAX_31,data_flash,sizeof(data_flash));IWDG_Feed();HAL_Delay(1000);if(stm32_read_flash(FLASH_SAVE_ADDR_MAX_31,data_flash,sizeof(data_flash))) {printf("\r\n\r\nread falsh data \r\n");for(u8 i=0;i<sizeof(data_flash);i++){printf("%02x ",data_flash[i] );}}} }運(yùn)行效果:測(cè)試代碼單次寫入數(shù)據(jù)長度使用的是64字節(jié)
完整demo下載路徑:STM32G030C8T6讀寫flash-單片機(jī)文檔類資源-CSDN下載
總結(jié)
以上是生活随笔為你收集整理的STM32G030C8T6读写flash的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux子系统下载错误,Win10系统
- 下一篇: matlab meas 函数_力科示波器