打印
[开发资料]

CW32L052 FLASH存储器

[复制链接]
71|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
maudlu|  楼主 | 2024-4-22 21:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
概述
CW32L052内部集成了64KB嵌入式FLASH供用户使用,可用来存储应用程序和用户数据。
芯片支持对 FLASH 存储器的读、擦除和写操作,支持擦写保护和读保护。
芯片内置 FLASH 编程所需的高压 BOOST 电路,无须额外提供编程电压。
FLASH存储器组织
总容量64KB,分页管理
每页 512 字节
共 128 页
FLASH存储器保护
FLASH 存储器具有擦写保护和读保护功能。
擦写保护
包括锁定页擦写保护和PC 地址页擦写保护,处于保护状态的页面不能被擦写,可避免 FLASH 内容被意外改写。
读保护
以整片 FLASH 为保护对象,不支持单页保护,可避免用户代码被非法读取。
FLASH存储器操作
FLASH 存储器操作包括:读操作、擦除、写(编程)操作。
页擦除
FLASH 的页擦除操作的最小单位为 1 页,即 512 字节。页擦除操作完成后,该页所有地址空间的数据内容均为 0xFF。
如果对未解锁的 FLASH 页面进行页擦除操作,或者对*正在运行的程序[^1]*进行擦除操作,会操作失败,产生错误中断标志。
CW32L052 内部 FLASH 存储器被划分为 128 页,每 8 页对应擦写锁定寄存器的1 个锁定位。擦写锁定寄存器的各位域与 FLASH 锁定页面的对应关系如下表所示:
写操作
基于嵌入式 FLASH 的特性,写操作只能将 FLASH 存储器中位数据由‘1’改写为‘0’,不能由‘0’改写为‘1’, 因此在写数据之前先要对对应地址所在页进行擦除操作。
基于以上陈述,总结出以下三个原则:
不可对数据位内容为‘0’的地址写入
不可对锁定区域内的地址写入
不可对 PC(程序指针)所在的页的地址写入
读操作
CW32L052 对 FLASH 的读操作支持 3 种不同位宽,可采用直接访问绝对地址方式读取,读取的数据位宽必 须和对应地址边界对齐。
核心代码//单片机头文件#include "main.h"//硬件驱动#include "gpio.h"#include "delay.h"//子程序void LCD_Configuration(void);       //段式LCD配置函数void LCD_Display(uint16_t dispdata);     //段式LCD显示函数uint8_t FLASH_Erase(void);         //FLASH页擦除函数uint8_t FLASH_Write(uint8_t *ByteData,uint16_t amount); //FLASH写操作函数int main(void){ int i; int temp8; uint8_t cnt=0; uint8_t WriteBuf[256];    LED_Init();    //初始化程序运行情况指示灯 LCD_Configuration();    //配置LCD液晶显示屏 FLASH_Erase();          //页擦除操作 for(i=0;i<256;i++)      //验证是否擦除成功 {  temp8=*((volatile uint8_t*)(512*127+i));  if(temp8!=0xff)  {   while(1)   {    LED2_ON();       //LED2闪烁    Delay_ms(300);    LED2_OFF();    Delay_ms(300);   }  } } for(i=0;i<256;i++)      //准备写入FLASH存储器的数据 {  WriteBuf=i; } FLASH_Write(WriteBuf,256); //写操作 for(i=0;i<255;i++)           //验证是否写入正确 {  temp8=*((volatile uint8_t*)(512*127+i));  if(temp8!=i)  {   while(1)   {    LED1_ON();     //LED1、LED2同时闪烁指示写入失败    LED2_ON();    Delay_ms(300);    LED1_OFF();    LED2_OFF();    Delay_ms(300);   }  } } LED1_ON();       //指示擦除、读、写均成功 LED2_ON();    while(1)    {  LCD_Display(*((volatile uint8_t*)(512*127+cnt)));  //LCD上依次显示写入的数据  Delay_ms(500);  cnt++;    }}uint8_t FLASH_Erase(void)    //页擦除{ int flag=1; FLASH_UnlockPages(512*127,512*127); flag=FLASH_ErasePages(512*127,512*127); FLASH_LockAllPages(); if(flag!=0) {  while(1)  {   LED1_ON();   Delay_ms(300);   LED1_OFF();   Delay_ms(300);  } } return 0;}uint8_t FLASH_Write(uint8_t *ByteData,uint16_t amount)  //写操作{ int flag=1; FLASH_UnlockPages(512*127,512*127); flag=FLASH_WriteBytes(512*127,ByteData,amount); FLASH_LockAllPages(); if(flag!=0) {  while(1)  {   LED2_ON();   Delay_ms(300);   LED2_OFF();   Delay_ms(300);  } } return 0;}void LCD_Configuration(void)      //段式LCD配置{    __RCC_LCD_CLK_ENABLE(); RCC_LSI_Enable();    LCD_InitTypeDef LCD_InitStruct = {0};    LCD_InitStruct.LCD_Bias = LCD_Bias_1_3;    LCD_InitStruct.LCD_ClockSource = LCD_CLOCK_SOURCE_LSI;    LCD_InitStruct.LCD_Duty = LCD_Duty_1_4;    LCD_InitStruct.LCD_ScanFreq = LCD_SCAN_FREQ_256HZ;    LCD_InitStruct.LCD_VoltageSource = LCD_VoltageSource_Internal;    LCD_Init(&LCD_InitStruct); LCD_COMConfig(LCD_COM0 | LCD_COM1 | LCD_COM2 | LCD_COM3, ENABLE);    LCD_SEG0to23Config(LCD_SEG0|LCD_SEG1|LCD_SEG2|LCD_SEG3|LCD_SEG4|LCD_SEG5|LCD_SEG6|LCD_SEG7, ENABLE); LCD_Cmd(ENABLE);}void LCD_Display(uint16_t dispdata)   //LCD显示{ uint16_t DisBuf[10]={NUM0,NUM1,NUM2,NUM3,NUM4,NUM5,NUM6,NUM7,NUM8,NUM9}; LCD_Write(LCD_RAMRegister_0,0x00000000); LCD_Write(LCD_RAMRegister_1,0x00000000); if(dispdata<10)  LCD_Write(LCD_RAMRegister_0,DisBuf[dispdata]); else if(dispdata<100)  LCD_Write(LCD_RAMRegister_0,DisBuf[dispdata/10]|DisBuf[dispdata%10]<<16); else if(dispdata<1000) {  LCD_Write(LCD_RAMRegister_0,DisBuf[dispdata/100]|DisBuf[dispdata/10%10]<<16);  LCD_Write(LCD_RAMRegister_1,DisBuf[dispdata%10]); } else {  LCD_Write(LCD_RAMRegister_0,0xffffffff);  LCD_Write(LCD_RAMRegister_1,0xffffffff); }}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

1130

帖子

0

粉丝