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的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: linux子系统下载错误,Win10系统
- 下一篇: 《猎头局中局》——摘要