离线
TA的每日心情 | 拍拍 2022-6-27 11:09 |
---|
签到天数: 25 天 [LV.4]
|
有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 sky 于 2021-9-10 17:07 编辑
本章教程将使用CH32V103内部FLASH进行FLASH读写保护及解除设置。
1、用户选择字简介及相关函数介绍
用户选择字固化在FLASH中,在系统复位后会被重新装载到相应寄存器,用户可以任意的进行擦除和编程。用户选择字信息块总共有8个字节(4个字节为写保护,1个字节为读保护,1个字节为配置选项,2 个字节存储用户数据),每个位都有其反码位用于装载过程中的校验。
① 用户选择字解锁
通过写入序列到FLASH_OBKEYR寄存器可解锁用户选择字操作。解锁后,FLASH_CTLR寄存器的OBWRE位将置1,表示可以进行用户选择字的擦除和编程。通过将FLASH_CTLR寄存器的“OBWRE”位,软件清0来再次锁定。
解锁序列:1)向 FLASH_OBKEYR 寄存器写入 KEY1 = 0x45670123;
2)向 FLASH_OBKEYR 寄存器写入 KEY2 = 0xCDEF89AB。
注:用户选择字操作需要解除“LOCK”和“OBWRE”两层锁定
② 用户选择字编程
只支持标准编程方式,一次写入半字(2 字节)。实际过程中,对用户选择字进行编程时,FPEC只使用半字中的低字节,并自动计算出高字节(高字节为低字节的反码),然后开始编程操作,这将保证用户选择字中的字节和它的反码始终是正确的。
1)检查 FLASH_CTLR 寄存器 LOCK 位,如果为 1,需要执行“解除闪存锁”操作。
2)检查 FLASH_STATR 寄存器的 BSY 位,以确认没有其他正在进行的编程操作。
3)检查 FLASH_CTLR 寄存器 OBWRE 位,如果为 0,需要执行“用户选择字解锁”操作。
4)设置 FLASH_CTLR 寄存器的 OBPG 位为‘1’,开启用户选择字编程。
5)写入要编程的半字(2 字节)到指定地址。
6)等待 BYS 位变为‘0’或 FLASH_STATR 寄存器的 EOP 位为‘1’表示编程结束,将 EOP 位清 0。
7)读编程地址数据校验。
8)继续编程可以重复 5-7 步骤,结束编程将 OBPG 位清 0。
注:当修改选择字中的“读保护”变成“非保护”状态时,会自动执行一次整片擦除主存储区操作。如果修改“读保护”之外的选型,则不会出现整片擦除的操作。
③ 用户选择字擦除
直接擦除整个 128 字节用户选择字区域。
1)检查FLASH_CTLR寄存器LOCK位,如果为1,需要执行“解除闪存锁”操作。
2)检查FLASH_STATR寄存器的BSY位,以确认没有正在进行的编程操作。
3)检查FLASH_CTLR寄存器OBWRE位,如果为0,需要执行“用户选择字解锁”操作。
4)设置FLASH_CTLR寄存器的OBER 位为‘1’,开启用户选择字擦除。
5)等待BYS位变为‘0’或FLASH_STATR寄存器的EOP位为‘1’表示擦除结束,将 EOP 位清 0。
6)读擦除地址数据校验。
7)结束将 OBER 位清 0。
④ 解除读保护
闪存是否读保护,由用户选择字决定。读取FLASH_OBR寄存器,当RDPRT 位为‘1’表示当前闪存处于读保护状态,闪存操作上受到读保护状态的一系列安全防护。解除读保护过程如下:
1)擦除整个用户选择字区域,此时读保护字段RDPR将变成0xFF,此时读保护仍然有效。
2)用户选择字编程,写入正确的RDPR代码0xA5以解除闪存的读保护。(此步骤首先将导致系统自动对闪存执行整片擦除操作)
3)进行上电复位以重新加载选择字节(包括新的RDPR码),此时读保护被解除。
⑤ 解除写保护
闪存是否写保护,由用户选择字决定。读取FLASH_WPR寄存器,每个比特位代表4K字节闪存空间,当比特位为‘1’表示非写保护状态,为‘0’表示写保护。解除写保护过程如下:
1)擦除整个用户选择字区域。
2)写入正确的RDPR码 0xA5,允许读访问;
3)进行系统复位,重新加载选择字节(包括新的WRPR[3:0]字节),写保护被解除。
关于CH32V103用户选择字具体信息,可参考CH32V103应用手册。关于CH32V103内部FLASH标准库函数,前面已经介绍,在此不再赘述。
2、硬件设计
本章教程为设置内部FLASH读写保护及解除,使用CH32V103内部资源,无需进行硬件连接。
3、软件设计
本章教程主要进行FLASH读写保护以及解除设置,主要通过触摸按键控制。
当按下触摸按键1,则执行写保护状态反转:若目前芯片处于写保护状态,按下触摸按键1则解除写保护;若目前不在写保护状态,按下触摸按键1则设置写保护。
当按下触摸按键2,则执行读保护状态反转:若目前芯片处于读保护状态,按下触摸按键2则解除读保护;若目前不在读保护状态,按下触摸按键2则设置读保护。
关于触摸按键程序在前面章节已经介绍,本章主要进行读写保护及解除程序介绍,具体程序如下:
flash.h文件
- #ifndef __FLASH_H
- #define __FLASH_H
- #include "ch32v10x_conf.h"
- void WriteProtect_Toggle(void);
- void ReadProtect_Toggle(void);
- #endif
复制代码
flash.h文件主要进行函数的声明;
flash.c文件- #include "flash.h"
- //反转写保护的配置,用于演示。若芯片处于写保护状态,则解除;若不是写保护状态,则设置成写保护
- void WriteProtect_Toggle(void)
- {
- //根据写保护寄存器(FLASH_WPR)值进行判断,闪存写保护状态:1,写保护失效;0,写保护有效。
- if (FLASH_GetWriteProtectionOptionByte() != 0xFFFFFFFF )
- {
- printf("芯片处于写保护状态,即将执行解保护过程...\r\n");
- //解除闪存锁
- FLASH_Unlock();
- //擦除闪存选项字节内容
- FLASH_EraseOptionBytes();
- //对所有页解除写保护
- FLASH_EnableWriteProtection(0x00000000);
- printf("配置完成,芯片将自动复位加载新配置,复位后芯片会解除写保护状态\r\n");
- //启动系统复位,复位芯片,以使选项字节生效
- NVIC_SystemReset();
- }
- else
- {
- printf("芯片处于无写保护状态,即将执行写保护过程...\r\n");
- //解锁
- FLASH_Unlock();
- //擦除闪存选项字节内容,防止因为原有的写保护导致无法写入新的保护配置
- FLASH_EraseOptionBytes();
- //对所有页进行写保护
- FLASH_EnableWriteProtection(0xFFFFFFFF);
- printf("配置完成,芯片将自动复位加载新配置,复位后芯片会处于写保护状态\r\n");
- //启动系统复位,复位芯片,以使选项字节生效
- NVIC_SystemReset();
- }
- }
- //反转读保护的配置,用于演示。若芯片处于读保护状态,则解除,若不是读保护状态,则设置成读保护
- void ReadProtect_Toggle(void)
- {
- //判断是否处于读保护状态
- if (FLASH_GetReadOutProtectionStatus () == SET )
- {
- printf("芯片处于读保护状态\r\n");
- //解锁
- FLASH_Unlock();
- printf("即将解除读保护,解除读保护会把 FLASH的所有内容清空\r\n");
- printf("由于解除后程序被清空,所以后面不会有任何提示输出\r\n");
- printf("等待 20秒后即可给芯片下载新的程序...\r\n");
- //解除读保护
- FLASH_ReadOutProtection (DISABLE);
- printf("由于 FLASH 程序被清空,所以本代码不会被执行,串口不会有本语句输出(SRAM 调试模式下例外) \r\n");
- }
- else
- {
- printf("芯片处于无读保护状态,即将执行读保护过程...\r\n");
- //解锁
- FLASH_Unlock();
- //启用读保护
- FLASH_ReadOutProtection (ENABLE);
- printf("芯片已被设置为读保护,上电复位后生效(必须重新给开发板上电,只按复位键无效) \r\n");
- printf("处于保护状态下无法正常下载新程序,必须要先解除保护状态再下载\r\n");
- }
- }
复制代码 flash.c文件主要进行写保护和读保护以及相应解除配置。
main.c文件
- int main(void)
- {
- u16 ADC_val1,ADC_val2;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- Delay_Init();
- USART_Printf_Init(115200);
- Touch_Key_Init();
- printf("SystemClk:%d\r\n",SystemCoreClock);
- /* 获取写保护寄存器的值进行判断,寄存器位为 0 表示有保护,为 1 表示无保护 */
- /* 若不等于 0xFFFFFFFF,则说明有部分页被写保护了 */
- if (FLASH_GetWriteProtectionOptionByte() !=0xFFFFFFFF )
- {
- printf("\r\n目前芯片处于写保护状态,TKEY1解除保护\r\n");
- printf("写保护寄存器的值:WRPR=0x%x\r\n",FLASH_GetWriteProtectionOptionByte());
- }
- else
- {
- //无写保护
- printf("\r\n目前芯片无写保护,TKEY1设置写保护\r\n");
- printf("写保护寄存器的值:WRPR=0x%x\r\n",FLASH_GetWriteProtectionOptionByte());
- }
- /* 若等于 SET,说明处于读保护状态 */
- if (FLASH_GetReadOutProtectionStatus () == SET )
- {
- printf("\r\n目前芯片处于读保护状态,TKEY2解除保护\r\n");
- }
- else
- {
- printf("\r\n目前芯片无读保护,TKEY2设置读保护\r\n");
- }
- while(1)
- {
- ADC_val1 = Get_Adc_Average(ADC_Channel_1,10);
- ADC_val2 = Get_Adc_Average(ADC_Channel_2,10);
- while(ADC_val1<2000)
- {
- printf("ADC1=%d\n",ADC_val1);
- WriteProtect_Toggle();
- Delay_Ms(1000);
- }
- while(ADC_val2<2000)
- {
- printf("ADC2=%d\n",ADC_val2);
- ReadProtect_Toggle();
- Delay_Ms(1000);
- }
- }
- }
复制代码
main.c文件主要进行函数初始化以及触摸按键控制,通过触摸按键1和触摸按键2进行写保护和读保护控制。
4、下载验证
将编译好的程序下载到开发板并复位,串口打印情况具体如下:
由上图可知,目前芯片不在写保护状态,触摸触摸按键1,设置写保护,串口打印输出如下:
由上图可知,目前芯片处于写保护和读保护状态,触摸触摸按键2,解除读保护状态,串口打印如下:
解除读保护之后,FLASH内容被清空,需重新下载程序。
设置FLASH读写保护及解除.rar附件下载
23、设置FLASH读写保护及解除.rar
(492.75 KB, 下载次数: 14)
链接:https://pan.baidu.com/s/1w_g8o_BzP2ShA90vUiSr0w
提取码:2jba
复制这段内容后打开百度网盘手机App,操作更方便哦
完
|
上一篇: 第二十三章:CH32V103应用教程——读写内部FLASH下一篇: 第二十五章:CH32V103应用教程——SD卡测试
|