芯源半导体CW32
直播中

李秀兰

8年用户 1538经验值
私信 关注
[经验]

单片机内部FLASH字节操作


[list=1]
[*]#include
[*]#include
[*]#include //C语言标准库
[*]#include "flash.h"
[*]
[*]#define USER_FLASH_START_ADDR   0x01070000   //FLASH最后两个扇区  供用户使用
[*]
[*]
[*]u32tou8 u32data;//定义一个联合体
[*]
[*]//==================================================================================
[*]// 获取某个地址所在的页首地址
[*]// addr:FLASH地址
[*]// 返回:该地址所在的页 共128页(0~127)
[*]//==================================================================================
[*]unsigned int FLASH_GetFlashPage(unsigned int addr)
[*]{
[*]          if (IS_FLASH_ADDRESS(addr))
[*]                {
[*]                   return  (addr (~0xFFF));//清0低12位就是该页的起始地址
[*]          }
[*]}
[*]//==================================================================================
[*]// 从FLASH中读取 一个字(32位)
[*]// addr:读取地址
[*]// 返回: 读到的字数据
[*]//备注: 地址为4字节对齐
[*]//==================================================================================
[*]unsigned int FLSAH_ReadWord(unsigned int addr)
[*]{
[*]    return (*(unsigned int *)addr);
[*]}
[*]
[*]
[*]//==================================================================================
[*]//从FLASH指定地址 读取数据
[*]//备注: 读取数据类型为32位  读取地址为4字节对齐
[*]//==================================================================================
[*]void  FLASH_Read(unsigned int        ReadAddr,unsigned char *pBuffer,unsigned int NumToRead)
[*]{
[*]    unsigned int i;
[*]          u32tobyte cache;
[*]    for(i=0; iRO = 0;//去掉所有扇区写保护
[*][i]    //==================================================================================
[*][i]    // 判断写入地址是否非法  起始地址或者结束地址不在FALSH范围内则退出
[*][i]    //==================================================================================
[*][i]    if(!(IS_FLASH_ADDRESS(startaddr)   IS_FLASH_ADDRESS(endaddr))) return FLASH_ERROR_PG;
[*]
[*][i]           while(startaddr < endaddr)
[*][i]                 {
[*]
[*][i]                //==================================================================================
[*][i]    //1.计算起始地址在FALSH哪一页,并获取该页的首地址
[*][i]                //2.计算起始地址在该页的偏移量
[*][i]    //3.计算该页还剩余多少字节没写入数据
[*][i]    //==================================================================================
[*][i]                          pageaddr = FLASH_GetFlashPage(startaddr);//获取起始地址所在页的页首地址
[*][i]                          index = startaddr-pageaddr;//4K缓冲区内偏移地址
[*][i]                          remain=4096-index;//缓存区剩余大小
[*][i]    //==================================================================================
[*][i]    // 将该页数据读入4K缓冲数组,后面读写都是对该缓冲数组操作
[*][i]    //==================================================================================
[*][i]                    for(i=0;i<4096;i+=4)//读取一页到缓冲buff
[*][i]                          {
[*][i]                                    cache.u32data=FLSAH_ReadWord(pageaddr+i);
[*][i]                                    buffer[i]=cache.buf[0];
[*][i][i]                                           buffer[i+1]=cache.buf[1];
[*][i][i]                                          buffer[i+2]=cache.buf[2];
[*][i][i]                                          buffer[i+3]=cache.buf[3];
[*][i][i]                                }
[*][i][i]    //==================================================================================
[*][i][i]    // 擦除FALSH对应的页,FLASH只能按页擦除,
[*][i][i]                // 这一页数据已经被读到缓冲数组中了 之前的数据也保留下来了
[*][i][i]    //==================================================================================
[*][i][i]                                status = FLASH_ErasePage(startaddr);
[*][i][i]        if(status != FLASH_COMPLETE) return status;//擦除1页 4K字节
[*][i][i]    //==================================================================================
[*][i][i]    //1.判断要写入的数据是否大于该页剩余容量(即计算写入的数据长度是否跨多页)
[*][i][i]                //2.将需要写入的数据转存到缓冲数据
[*][i][i]    //==================================================================================
[*][i][i]                                if(NumToWrite > remain)//需要写入的数据量大于缓冲buf剩余字节数
[*][i][i]                                {
[*][i][i]                                        for(i=index;i<4096;i++)//将需要写入FALSH的数据写入缓冲buff
[*][i][i]                                        {
[*][i][i]                                                         buffer[i]=*(pBuffer++);
[*][i][i][i]                                        }
[*][i][i][i]                                        NumToWrite-=remain;//需要写入的数据长度-本次已经写入的数据长度
[*][i][i][i]          startaddr+=remain;//地址向后偏移本次写入的字节数
[*][i][i][i]                          }
[*][i][i][i]                                else
[*][i][i][i]                                {
[*][i][i][i]                                  for(i=index;i

更多回帖

发帖
×
20
完善资料,
赚取积分