打印
[开发资料]

单片机内部FLASH的字节操作

[复制链接]
68|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
uiint|  楼主 | 2025-3-24 10:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//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; i<NumToRead; i+=4)
    {
            cache.u32data=FLSAH_ReadWord(ReadAddr+i);
                                    pBuffer[i]=cache.buf[0];
                                           pBuffer[i+1]=cache.buf[1];
                                          pBuffer[i+2]=cache.buf[2];
                                          pBuffer[i+3]=cache.buf[3];
    }
}

//==================================================================================
// 向FLASH指定地址 写入大量数据
// WriteAddr:写入首地址
// pBuffer:数据首地址
// NumToWrite:需要写入数据的大小
// 返回: 4=成功  1,2,3,5=失败
// 备注:
//==================================================================================
FLASH_Status  FLASH_Write(unsigned int        WriteAddr,unsigned char *pBuffer,unsigned int NumToWrite)
{

    FLASH_Status status = FLASH_COMPLETE;
          u32tobyte cache;//联合体定义
    unsigned int startaddr,endaddr,pageaddr=0;
          unsigned char buffer[4096];//4K缓冲区 对应FALSH 1页
          unsigned int i;
          unsigned int index,remain;
    startaddr = WriteAddr;
    endaddr = startaddr+NumToWrite;//结束地址
       
    FLASH_Unlock();
    FCU->RO = 0;//去掉所有扇区写保护
    //==================================================================================
    // 判断写入地址是否非法  起始地址或者结束地址不在FALSH范围内则退出
    //==================================================================================
    if(!(IS_FLASH_ADDRESS(startaddr)&& IS_FLASH_ADDRESS(endaddr))) return FLASH_ERROR_PG;
   
           while(startaddr < endaddr)
                 {
                         
                //==================================================================================
    //1.计算起始地址在FALSH哪一页,并获取该页的首地址
                //2.计算起始地址在该页的偏移量
    //3.计算该页还剩余多少字节没写入数据                         
    //==================================================================================
                          pageaddr = FLASH_GetFlashPage(startaddr);//获取起始地址所在页的页首地址
                          index = startaddr-pageaddr;//4K缓冲区内偏移地址
                          remain=4096-index;//缓存区剩余大小
    //==================================================================================
    // 将该页数据读入4K缓冲数组,后面读写都是对该缓冲数组操作
    //==================================================================================                         
                    for(i=0;i<4096;i+=4)//读取一页到缓冲buff
                          {
                                    cache.u32data=FLSAH_ReadWord(pageaddr+i);
                                    buffer[i]=cache.buf[0];
                                           buffer[i+1]=cache.buf[1];
                                          buffer[i+2]=cache.buf[2];
                                          buffer[i+3]=cache.buf[3];
                                }
    //==================================================================================
    // 擦除FALSH对应的页,FLASH只能按页擦除,
                // 这一页数据已经被读到缓冲数组中了 之前的数据也保留下来了                
    //==================================================================================                               
                                status = FLASH_ErasePage(startaddr);
        if(status != FLASH_COMPLETE) return status;//擦除1页 4K字节                                       
    //==================================================================================
    //1.判断要写入的数据是否大于该页剩余容量(即计算写入的数据长度是否跨多页)
                //2.将需要写入的数据转存到缓冲数据               
    //==================================================================================                               
                                if(NumToWrite > remain)//需要写入的数据量大于缓冲buf剩余字节数
                                {
                                        for(i=index;i<4096;i++)//将需要写入FALSH的数据写入缓冲buff
                                        {
                                                         buffer[i]=*(pBuffer++);                               
                                        }
                                        NumToWrite-=remain;//需要写入的数据长度-本次已经写入的数据长度       
          startaddr+=remain;//地址向后偏移本次写入的字节数                                       
                          }
                                else
                                {
                                  for(i=index;i<NumToWrite+index;i++)//将需要写入FALSH的数据写入缓冲buff
                                        {
                                                         buffer[i]=*(pBuffer++);                               
                                        }
          startaddr+=NumToWrite;//地址向后偏移本次写入的字节数                                                               
                                }       
    //==================================================================================
    // 将缓冲数组(4K)写入FLASH 对应的页
                // 此处必须从页首写入,因为缓冲数组正好4K,对应FALSH 1页       
    //==================================================================================                               
                                for(i=0;i<4096;i+=4)//将缓冲buffer写入 FALSH
                          {
                                    cache.buf[0]=buffer[i];
                                           cache.buf[1]=buffer[i+1];
                                          cache.buf[2]=buffer[i+2];
                                          cache.buf[3]=buffer[i+3];
                                       
                                          if((status=FLASH_ProgramWord(pageaddr+i,cache.u32data))!= FLASH_COMPLETE)
                                                {
                                                                FLASH_Lock();
                                                                return status;//写入失败 FLASH上锁
                                                }                                                                    
                                }                       
                 }
    FLASH_Lock();
}


使用特权

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

本版积分规则

40

主题

4318

帖子

1

粉丝