通常情况下,Flash在整页擦除后全部变为1,写入只能从1变为0,想要从0变为1,就必须擦除整页。
也就是说,一处FLASH原本为 1110,如果写入1011,再读取时,应该会读到1010,既多次写入之间的「按位与」。
CH32V203 的FLASH也满足这一特点吗?
通常情况下,Flash在整页擦除后全部变为1,写入只能从1变为0,想要从0变为1,就必须擦除整页。
也就是说,一处FLASH原本为 1110,如果写入1011,再读取时,应该会读到1010,既多次写入之间的「按位与」。
CH32V203 的FLASH也满足这一特点吗?
const?uint16*?flash_store?=?(const?uint16*)(0x08000000?+?16?*?1024?-?256);//这个指针指向FLASH中用于写入测试的地址 int?main(void)?{ ????NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); ????printfInit(115200); ????printf("\n\n\n%s?V%d.%d.%d??-??%s\n",?App_description.app_name,?App_description.high_ver,?App_description.middle_ver,?App_description.low_ver,?__DATA_TIME__); ????printf("SystemClk:%u\n",?Core::Tick_par_second);???? ????printf("Reset?value:%x\n",?flash_store[0]);//每次启动后,读取这一位 ????Random::init(); ????Ammc6Slave::init(); ????while?(1); } void?Ammc6Slave::onRecvAccess(const?byte*?rbuf,?byte?len,?byte*?sbuf){//收到总线数据的响应函数 ????sbuf[0]?=?0x11; ????sbuf[1]?=?0x22; ????sbuf[2]?=?0xa2; ????sbuf[3]?=?0x99; ????sbuf[4]?=?rbuf[0]; ????sbuf[5]?=?rbuf[1]; ????sbuf[6]?=?rbuf[2]; ????sbuf[7]?=?rbuf[3]; ????Ammc6Slave::sendAccess(8); ????Ammc6Slave::loadFinish(); ????uint16?data_to_write?=?rbuf[1];//待写入的数据由总线提供 ????data_to_write?<<=?8; ????data_to_write?|=?rbuf[0]; ????printf("before?%x?write:?%x\n",?data_to_write,?flash_store[0]);//显示写入前的数据 ????Flash::write(flash_store,?data_to_write); ????printf("after?write:?%x\n",flash_store[0]);//显示写入后的数据 }
实际上,我写了这样的程序进行测试。
实际测试后产生了这样的调试日志:
一次写入中,复位时FLASH中的值为07dc,写入DF56成功后,再进行了复位,并且随后进行了进行了断电复位。
可以看到,芯片的FLASH可以由1写到0,也可以由0写到1。
我并没有在手册中找到关于FLASH特性的准确描述,这是我参考的手册版本:
请问,CH32V203 Flash的编程特性是什么样的?编程是否既能让数据从0到1,又能让数据从1到0?
如果用于保存配置信息,是否可以一直使用编程,从不进行擦除?这样做是否安全?
无法删除楼层吗?
这一层删除了
const uint16* flash_store = (const uint16*)(0x08000000 + 16 * 1024 - 256);//这个指针指向FLASH中用于写入测试的地址 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); printfInit(115200); printf("\n\n\n%s V%d.%d.%d - %s\n", App_description.app_name, App_description.high_ver, App_description.middle_ver, App_description.low_ver, __DATA_TIME__); printf("SystemClk:%u\n", Core::Tick_par_second); printf("Reset value:%x\n", flash_store[0]);//每次启动后,读取这一位 Random::init(); Ammc6Slave::init(); while (1); } void Ammc6Slave::onRecvAccess(const byte* rbuf, byte len, byte* sbuf){//收到总线数据的响应函数 sbuf[0] = 0x11; sbuf[1] = 0x22; sbuf[2] = 0xa2; sbuf[3] = 0x99; sbuf[4] = rbuf[0]; sbuf[5] = rbuf[1]; sbuf[6] = rbuf[2]; sbuf[7] = rbuf[3]; Ammc6Slave::sendAccess(8); Ammc6Slave::loadFinish(); uint16 data_to_write = rbuf[1];//待写入的数据由总线提供 data_to_write <<= 8; data_to_write |= rbuf[0]; printf("before %x write: %x\n", data_to_write, flash_store[0]);//显示写入前的数据 Flash::write(flash_store, data_to_write); printf("after write: %x\n",flash_store[0]);//显示写入后的数据 }
代码似乎无法高亮显示。
您好,关于CH32V203的FLASH,写入一次之后不擦除再次进行写入,读出的是第二次写入的值,不会进行“按位与”。即不擦除写入也是可以正常读出写入的值的。但一般正常进行FLASH操作时,建议在编程写入之前执行一下擦除操作。后续若有问题,可通过邮箱(lzs@wch.cn)和我沟通。
非常感谢。