日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

STM32G030C8T6读写flash

發(fā)布時(shí)間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32G030C8T6读写flash 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

????????最近選型使用STM32G030這款芯片,由于做的功能需要頻繁讀寫flash,最開(kāi)始沒(méi)有注意到芯片的擦寫次數(shù)是1000次,為了確保功能實(shí)現(xiàn),只能是每次寫入flash時(shí)判斷當(dāng)前頁(yè)是否寫滿,寫滿才擦除重新開(kāi)始寫;

? ? ? ? ?每次需要寫入flash的數(shù)據(jù)長(zhǎng)度小于128字節(jié),以128字節(jié)計(jì)算,每一頁(yè)可以寫入16=2048/128 次;?STM32G030C8T6最少可以寫入16000次;如果對(duì)寫入次數(shù)需求高的,可以減少每次寫入數(shù)據(jù)的長(zhǎng)度;

STM32G030C8T6寫入特性參考:stm32g030 內(nèi)部flash存儲(chǔ)一些用戶數(shù)據(jù)的方法 - 簡(jiǎn)書

stm32F103

可編程flash區(qū),以頁(yè)為單位,每頁(yè)1K,共128頁(yè), 擦寫次數(shù)>1萬(wàn)次;

寫入以16位“半字”為最小單位,擦除以頁(yè)為單位;

先解鎖,清標(biāo)志,擦除,寫,上鎖;?

進(jìn)行flash操作時(shí),必須打開(kāi)內(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次!!!? 需考慮壞頁(yè)情況;

寫數(shù)據(jù)時(shí),一般建議關(guān)閉所有中斷!

stm32g030 雙字寫時(shí),不僅要求是雙字形式, 而且要求8字節(jié)對(duì)齊。 否則進(jìn)入硬件錯(cuò)誤!

測(cè)試部分代碼:

//從指定地址開(kāi)始寫入指定長(zhǎng)度的數(shù)據(jù) //ReadAddr:起始地址 //pBuffer:數(shù)據(jù)指針 //NumToWrite:寫入數(shù)據(jù)長(zhǎng)度 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ù)長(zhǎng)度8字節(jié)對(duì)齊判斷if(WriteAddr%FLASH_PAGE_SIZE==0) //寫滿了從一頁(yè)開(kāi)始地址寫需要擦除{ FLASH_EraseInitTypeDef My_Flash={0}; //聲明 FLASH_EraseInitTypeDef 結(jié)構(gòu)體為 My_FlashMy_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //標(biāo)明Flash執(zhí)行頁(yè)面只做擦除操作My_Flash.Page = (WriteAddr - FLASH_BASE) / FLASH_PAGE_SIZE;My_Flash.NbPages = 1; //說(shuō)明要擦除的頁(yè)數(shù),此參數(shù)必須是Min_Data = 1和Max_Data =(最大頁(yè)數(shù)-初始頁(yè)的值)之間的值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) //長(zhǎng)度判斷 {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í)行頁(yè)面只做擦除操作My_Flash.Page = (WriteAddr - FLASH_BASE) / FLASH_PAGE_SIZE;My_Flash.NbPages = 1; //說(shuō)明要擦除的頁(yè)數(shù),此參數(shù)必須是Min_Data = 1和Max_Data =(最大頁(yè)數(shù)-初始頁(yè)的值)之間的值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; }//從指定地址開(kāi)始讀出指定長(zhǎng)度的數(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ù)長(zhǎng)度使用的是64字節(jié)

完整demo下載路徑:STM32G030C8T6讀寫flash-單片機(jī)文檔類資源-CSDN下載

總結(jié)

以上是生活随笔為你收集整理的STM32G030C8T6读写flash的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。