OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3067|回复: 3

F4 原子的模以EEPOM 程序如何读取

[复制链接]

10

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
137
金钱
137
注册时间
2016-8-23
在线时间
22 小时
发表于 2016-11-9 10:35:53 | 显示全部楼层 |阅读模式
//读取指定地址的半字(16位数据)
//faddr:读地址
//返回值:对应数据.
u32 STMFLASH_ReadWord(u32 faddr)
{
        return *(vu32*)faddr;
}  
//获取某个地址所在的flash扇区
//addr:flash地址
//返回值:0~11,即addr所在的扇区
uint16_t STMFLASH_GetFlashSector(u32 addr)
{
        if(addr<ADDR_FLASH_SECTOR_1)return FLASH_Sector_0;
        else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_Sector_1;
        else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_Sector_2;
        else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_Sector_3;
        else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_Sector_4;
        else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_Sector_5;
        else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_Sector_6;
        else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_Sector_7;
        else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_Sector_8;
        else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_Sector_9;
        else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_Sector_10;
        return FLASH_Sector_11;       
}
//从指定地址开始写入指定长度的数据
//特别注意:因为STM32F4的扇区实在太大,没办法本地保存扇区数据,所以本函数
//         写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以
//         写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里
//         没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写.
//该函数对OTP区域也有效!可以用来写OTP区!
//OTP区域地址范围:0X1FFF7800~0X1FFF7A0F
//WriteAddr:起始地址(此地址必须为4的倍数!!)
//pBuffer:数据指针
//NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)       
{
  FLASH_Status status = FLASH_COMPLETE;
        u32 addrx=0;
        u32 endaddr=0;       
  if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;        //非法地址
        FLASH_Unlock();                                                                        //解锁
  FLASH_DataCacheCmd(DISABLE);//FLASH擦除期间,必须禁止数据缓存
               
        addrx=WriteAddr;                                //写入的起始地址
        endaddr=WriteAddr+NumToWrite*4;        //写入的结束地址
        if(addrx<0X1FFF0000)                        //只有主存储区,才需要执行擦除操作!!
        {
                while(addrx<endaddr)                //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
                {
                        if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
                        {   
                                status=FLASH_EraseSector(STMFLASH_GetFlashSector(addrx),VoltageRange_3);//VCC=2.7~3.6V之间!!
                                if(status!=FLASH_COMPLETE)break;        //发生错误了
                        }else addrx+=4;
                }
        }
        if(status==FLASH_COMPLETE)
        {
                while(WriteAddr<endaddr)//写数据
                {
                        if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//写入数据
                        {
                                break;        //写入异常
                        }
                        WriteAddr+=4;
                        pBuffer++;
                }
        }
  FLASH_DataCacheCmd(ENABLE);        //FLASH擦除结束,开启数据缓存
        FLASH_Lock();//上锁
}

//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToRead:字(4位)数
void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)          
{
        u32 i;
        for(i=0;i<NumToRead;i++)
        {
                pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.
                ReadAddr+=4;//偏移4个字节.       
        }
}





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
137
金钱
137
注册时间
2016-8-23
在线时间
22 小时
 楼主| 发表于 2016-11-9 10:37:37 | 显示全部楼层
u8 TEXT_Buffer[60];
#define TEXT_LENTH sizeof(TEXT_Buffer)                          //数组长度       
#define SIZE TEXT_LENTH/4+((TEXT_LENTH%4)?1:0)
#define FLASH_SAVE_ADDR  0X1fff7800          //设置FLASH 保存地址(必须为偶数,且所在扇区,要大于本代码所占用到的扇区.
u8 datatemp[SIZE];  //定义读取接收字符串数组



STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)TEXT_Buffer,SIZE);///对应地址存数据


STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)datatemp,SIZE);////对应地址读数据       
回复 支持 反对

使用道具 举报

10

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
137
金钱
137
注册时间
2016-8-23
在线时间
22 小时
 楼主| 发表于 2016-11-9 10:39:32 | 显示全部楼层
请问一下,  这样存有没有问题,读出来后 这个datatemp  是这个 U32的数组吗。我要如何使用,怎么我用串口发送出来都是0


USART_SendData(USART2, (datatemp[12]%65536)/256);     //向串口2发送modlbus要应答的数据
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待发送结束       

USART_SendData(USART2, (datatemp[12]%65536)%256);     //向串口2发送modlbus要应答的数据
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待发送结束       
回复 支持 反对

使用道具 举报

10

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
137
金钱
137
注册时间
2016-8-23
在线时间
22 小时
 楼主| 发表于 2017-1-3 10:37:36 | 显示全部楼层
已解决
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 06:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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