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]);//显示写入后的数据
}

实际上,我写了这样的程序进行测试。


实际测试后产生了这样的调试日志:
image.png


一次写入中,复位时FLASH中的值为07dc,写入DF56成功后,再进行了复位,并且随后进行了进行了断电复位。

可以看到,芯片的FLASH可以由1写到0,也可以由0写到1。
我并没有在手册中找到关于FLASH特性的准确描述,这是我参考的手册版本:

image.png


请问,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]);//显示写入后的数据
}

代码似乎无法高亮显示。image.png


您好,关于CH32V203的FLASH,写入一次之后不擦除再次进行写入,读出的是第二次写入的值,不会进行“按位与”。即不擦除写入也是可以正常读出写入的值的。但一般正常进行FLASH操作时,建议在编程写入之前执行一下擦除操作。后续若有问题,可通过邮箱(lzs@wch.cn)和我沟通。



非常感谢。


只有登录才能回复,可以选择微信账号登录