欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

STM32G030C8T6读写flash

发布时间:2023/12/20 编程问答 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 STM32G030C8T6读写flash 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

        最近选型使用STM32G030这款芯片,由于做的功能需要频繁读写flash,最开始没有注意到芯片的擦写次数是1000次,为了确保功能实现,只能是每次写入flash时判断当前页是否写满,写满才擦除重新开始写;

         每次需要写入flash的数据长度小于128字节,以128字节计算,每一页可以写入16=2048/128 次; STM32G030C8T6最少可以写入16000次;如果对写入次数需求高的,可以减少每次写入数据的长度;

STM32G030C8T6写入特性参考:stm32g030 内部flash存储一些用户数据的方法 - 简书

stm32F103

可编程flash区,以页为单位,每页1K,共128页, 擦写次数>1万次;

写入以16位“半字”为最小单位,擦除以页为单位;

先解锁,清标志,擦除,写,上锁; 

进行flash操作时,必须打开内部HSI;

stm32G030

                                          用时   \/

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

擦写次数  仅>= 1K次!!!  需考虑坏页情况;

写数据时,一般建议关闭所有中断!

stm32g030 双字写时,不仅要求是双字形式, 而且要求8字节对齐。 否则进入硬件错误!

测试部分代码:

//从指定地址开始写入指定长度的数据 //ReadAddr:起始地址 //pBuffer:数据指针 //NumToWrite:写入数据长度 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); //数据长度8字节对齐判断if(WriteAddr%FLASH_PAGE_SIZE==0) //写满了从一页开始地址写需要擦除{ FLASH_EraseInitTypeDef My_Flash={0}; //声明 FLASH_EraseInitTypeDef 结构体为 My_FlashMy_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作My_Flash.Page = (WriteAddr - FLASH_BASE) / FLASH_PAGE_SIZE;My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址HAL_FLASHEx_Erase(&My_Flash, &PageError); //调用擦除函数擦除 } for(i=0;i<len/8;i++)//复制 //8字节数据对齐组包{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);//擦除这个扇区 FLASH_EraseInitTypeDef My_Flash={0}; //声明 FLASH_EraseInitTypeDef 结构体为 My_FlashMy_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作My_Flash.Page = (WriteAddr - FLASH_BASE) / FLASH_PAGE_SIZE;My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址HAL_FLASHEx_Erase(&My_Flash, &PageError); //调用擦除函数擦除 } HAL_FLASH_Lock();//上锁 }u8 STMFLASH_ReadByte(u32 faddr) {return *(__IO uint8_t*) (faddr);// return *(u8*) faddr; }//从指定地址开始读出指定长度的数据 //ReadAddr:起始地址 //pBuffer:数据指针 //NumToWrite:半字(16位)数 void STMFLASH_Read_Byte(u32 ReadAddr,u8 *pBuffer,u16 NumToRead) {u16 i;for(i=0;i<NumToRead;i++){pBuffer[i]=STMFLASH_ReadByte(ReadAddr);//读1个字节.ReadAddr+=1;//偏移1个字节. } } #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] );}}} }

运行效果:测试代码单次写入数据长度使用的是64字节

完整demo下载路径:STM32G030C8T6读写flash-单片机文档类资源-CSDN下载

总结

以上是生活随笔为你收集整理的STM32G030C8T6读写flash的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。