查看: 1787|回复: 0
收起左侧

第二十四章:CH32V103应用教程——设置FLASH读写保护及解除

[复制链接]

  离线 

  • TA的每日心情
    拍拍
    2022-6-27 11:09
  • 签到天数: 25 天

    [LV.4]

    发表于 2021-4-25 18:55:35 | 显示全部楼层 |阅读模式

    有人预言,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文件
    1. #ifndef __FLASH_H
    2. #define __FLASH_H

    3. #include "ch32v10x_conf.h"

    4. void WriteProtect_Toggle(void);
    5. void ReadProtect_Toggle(void);

    6. #endif
    复制代码

    flash.h文件主要进行函数的声明;
    flash.c文件
    1. #include "flash.h"

    2. //反转写保护的配置,用于演示。若芯片处于写保护状态,则解除;若不是写保护状态,则设置成写保护
    3. void WriteProtect_Toggle(void)
    4. {
    5.     //根据写保护寄存器(FLASH_WPR)值进行判断,闪存写保护状态:1,写保护失效;0,写保护有效。
    6.     if (FLASH_GetWriteProtectionOptionByte() != 0xFFFFFFFF )
    7.     {
    8.         printf("芯片处于写保护状态,即将执行解保护过程...\r\n");

    9.         //解除闪存锁
    10.         FLASH_Unlock();

    11.         //擦除闪存选项字节内容
    12.         FLASH_EraseOptionBytes();

    13.         //对所有页解除写保护
    14.         FLASH_EnableWriteProtection(0x00000000);

    15.         printf("配置完成,芯片将自动复位加载新配置,复位后芯片会解除写保护状态\r\n");

    16.         //启动系统复位,复位芯片,以使选项字节生效
    17.         NVIC_SystemReset();
    18.     }
    19.     else
    20.     {
    21.         printf("芯片处于无写保护状态,即将执行写保护过程...\r\n");

    22.         //解锁
    23.         FLASH_Unlock();

    24.         //擦除闪存选项字节内容,防止因为原有的写保护导致无法写入新的保护配置
    25.         FLASH_EraseOptionBytes();

    26.         //对所有页进行写保护
    27.         FLASH_EnableWriteProtection(0xFFFFFFFF);

    28.         printf("配置完成,芯片将自动复位加载新配置,复位后芯片会处于写保护状态\r\n");

    29.         //启动系统复位,复位芯片,以使选项字节生效
    30.         NVIC_SystemReset();
    31.     }
    32. }

    33. //反转读保护的配置,用于演示。若芯片处于读保护状态,则解除,若不是读保护状态,则设置成读保护
    34. void ReadProtect_Toggle(void)
    35. {
    36.     //判断是否处于读保护状态
    37.     if (FLASH_GetReadOutProtectionStatus () == SET )
    38.     {
    39.         printf("芯片处于读保护状态\r\n");

    40.         //解锁
    41.         FLASH_Unlock();

    42.         printf("即将解除读保护,解除读保护会把 FLASH的所有内容清空\r\n");
    43.         printf("由于解除后程序被清空,所以后面不会有任何提示输出\r\n");
    44.         printf("等待 20秒后即可给芯片下载新的程序...\r\n");

    45.         //解除读保护
    46.         FLASH_ReadOutProtection (DISABLE);

    47.         printf("由于 FLASH 程序被清空,所以本代码不会被执行,串口不会有本语句输出(SRAM 调试模式下例外) \r\n");
    48.     }
    49.     else
    50.     {
    51.         printf("芯片处于无读保护状态,即将执行读保护过程...\r\n");

    52.         //解锁
    53.         FLASH_Unlock();

    54.         //启用读保护
    55.         FLASH_ReadOutProtection (ENABLE);

    56.         printf("芯片已被设置为读保护,上电复位后生效(必须重新给开发板上电,只按复位键无效) \r\n");
    57.         printf("处于保护状态下无法正常下载新程序,必须要先解除保护状态再下载\r\n");
    58.     }
    59. }

    复制代码
    flash.c文件主要进行写保护和读保护以及相应解除配置。
    main.c文件

    1. int main(void)
    2. {
    3.     u16 ADC_val1,ADC_val2;

    4.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    5.     Delay_Init();
    6.         USART_Printf_Init(115200);
    7.         Touch_Key_Init();
    8.         printf("SystemClk:%d\r\n",SystemCoreClock);

    9.         /* 获取写保护寄存器的值进行判断,寄存器位为 0 表示有保护,为 1 表示无保护 */
    10.         /* 若不等于 0xFFFFFFFF,则说明有部分页被写保护了 */
    11.         if (FLASH_GetWriteProtectionOptionByte() !=0xFFFFFFFF )
    12.         {

    13.             printf("\r\n目前芯片处于写保护状态,TKEY1解除保护\r\n");

    14.             printf("写保护寄存器的值:WRPR=0x%x\r\n",FLASH_GetWriteProtectionOptionByte());
    15.         }
    16.         else
    17.         {
    18.             //无写保护
    19.             printf("\r\n目前芯片无写保护,TKEY1设置写保护\r\n");

    20.             printf("写保护寄存器的值:WRPR=0x%x\r\n",FLASH_GetWriteProtectionOptionByte());
    21.         }

    22.         /* 若等于 SET,说明处于读保护状态 */
    23.         if (FLASH_GetReadOutProtectionStatus () == SET )
    24.         {
    25.             printf("\r\n目前芯片处于读保护状态,TKEY2解除保护\r\n");

    26.         }
    27.         else
    28.         {
    29.             printf("\r\n目前芯片无读保护,TKEY2设置读保护\r\n");
    30.         }

    31.         while(1)
    32.     {
    33.             ADC_val1 = Get_Adc_Average(ADC_Channel_1,10);
    34.             ADC_val2 = Get_Adc_Average(ADC_Channel_2,10);

    35.             while(ADC_val1<2000)
    36.             {
    37.                 printf("ADC1=%d\n",ADC_val1);
    38.                 WriteProtect_Toggle();
    39.                 Delay_Ms(1000);
    40.             }
    41.             while(ADC_val2<2000)
    42.             {
    43.                 printf("ADC2=%d\n",ADC_val2);
    44.                 ReadProtect_Toggle();
    45.                 Delay_Ms(1000);
    46.             }
    47.         }
    48. }
    复制代码


    main.c文件主要进行函数初始化以及触摸按键控制,通过触摸按键1和触摸按键2进行写保护和读保护控制。


    4、下载验证


    将编译好的程序下载到开发板并复位,串口打印情况具体如下:

    CH32V CH573单片机芯片-第二十四章:CH32V103应用教程——设置FLASH读写保护及解除risc-v单片机中文社区(1)

    由上图可知,目前芯片不在写保护状态,触摸触摸按键1,设置写保护,串口打印输出如下:
    CH32V CH573单片机芯片-第二十四章:CH32V103应用教程——设置FLASH读写保护及解除risc-v单片机中文社区(2)

    由上图可知,目前芯片处于写保护和读保护状态,触摸触摸按键2,解除读保护状态,串口打印如下:
    CH32V CH573单片机芯片-第二十四章:CH32V103应用教程——设置FLASH读写保护及解除risc-v单片机中文社区(3)

    解除读保护之后,FLASH内容被清空,需重新下载程序。


    设置FLASH读写保护及解除.rar附件下载
    CH32V CH573单片机芯片-第二十四章:CH32V103应用教程——设置FLASH读写保护及解除risc-v单片机中文社区(4) 23、设置FLASH读写保护及解除.rar (492.75 KB, 下载次数: 14)
    链接:https://pan.baidu.com/s/1w_g8o_BzP2ShA90vUiSr0w
    提取码:2jba
    复制这段内容后打开百度网盘手机App,操作更方便哦







    上一篇:第二十三章:CH32V103应用教程——读写内部FLASH
    下一篇:第二十五章:CH32V103应用教程——SD卡测试
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-4-25 08:47 , Processed in 0.592534 second(s), 46 queries .

    快速回复 返回顶部 返回列表