stm32 读写Flash
????在有些场合掉电保存是很有用的,但一般都是用EEPROM,要新增硬件电路,比较麻烦。stm32有一个Flash控制器,用户可以在线读写Flash,这样一定情况下可以用读写Flash做掉电保存,挺方便的。擦写不多于10万次。 ? ? 我用的是stm32F10x3ZET6的Flash(512K)结构如下: ???? 存储区的地址:0x0800 0000--0x0807 FFFF 这一段存储区使用存储程序的,用户也可以读写这一块区域。当然你得保证你读写的区域不是你的程序存储的区域。为此你要对你的编程器进行设置,如何你是用的j-link,用keil直接下载的,你可以进行一下设置,进入 “魔术棒”---utilities--seting 程序编程区域设为0x0800 0000--0x0007 0000 。 这样这之后的区域就0x0007 0001--0x0807 FFFF你就可以任意读写了。 程序: ????1、一定要开启HSI时钟。 ????2、先擦除后写入。擦除时只能按页擦除。 ????3、读写必须是半字(16 bit)。 下面为读写配置函数。 flash.c #include?"flash.h" void?Flash_Init(void) { RCC_HSICmd(ENABLE);//开启内部高速时钟 } uint8_t?Flash_Write(uint32_t?STARTADDR,?uint16_t?data[],?uint16_t?len)//擦除一页从这一页的开始写一组数据,成功返回0,不成功返回1 { FLASH_Status?flashStatus?=?FLASH_COMPLETE; uint16_t?i=0; FLASH_Unlock();???? //解锁 FLASH_ClearFlag(FLASH_FLAG_BSY?|?FLASH_FLAG_EOP?|?FLASH_FLAG_PGERR?|??FLASH_FLAG_WRPRTERR); //清除flag?? flashStatus?=?FLASH_ErasePage(STARTADDR); //擦除以STARTADDR开始的那一页 if(flashStatus?!=?FLASH_COMPLETE)//是否擦除成功,不成功返回1 return?1; for(i=0;?i<len;?i++) FLASH_ProgramHalfWord(STARTADDR+2*i,?data[i]);?????//写入数组??? FLASH_Lock();//锁定flash return?0; } void?Flash_Read(uint32_t?startaddr,?uint16_t?len)? { uint16_t?i=0; for(i=0;?i<len;?i++) data[i]?=?*(vu16*)(startaddr+i*2);//为什么这个指针是指向flash,而不是内存呢?因为 //在arm中ram,sdram,flash都映射到同一套地址中,在startaddr所在的这一片地址就是对应着flash } 测试程序,写进去再读出来,发到串口。 #include?"stm32f10x.h" #include?"stm32f10x_it.h" #include?"led.h" #include?"usart.h" #include?"stdio.h" #include?"timer.h" #include?"dma.h" #include?"adc.h" #include?"flash.h" void?init() { Usart1_Init(115200); Flash_Init(); } #define?STARTADDR?0x0807f800 int?main() { uint8_t?flag?=?0; uint8_t?i=0; uint16_t?data[5]={1,?2,?3,?4,?5}; uint16_t?num[5]={0}; init(); //printf("hello"); Flash_Write(STARTADDR,?data,?5); Flash_Read(STARTADDR,?num,?5); for(i=0;?i<5;?i++) { printf("%d",?num[i]); } while(1); } 认为重要的就这些了,其他的问题可以百度到。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |