OpenEdv-开源电子网

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

关于 24cXX 程序的疑问 寻址

[复制链接]

40

主题

144

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2013-7-26
在线时间
72 小时
发表于 2015-3-9 22:29:43 | 显示全部楼层 |阅读模式
5金钱
论坛源程序在此  http://home.eeworld.com.cn/my/space-uid-93649-blogid-77560.html
疑问?  他的程序的移位语句
#if EEPROM < 32
  ageAddress=(u8)(ReadAddress>>7)&0x0E|ReadAddress_EEPROM;
#else
  ageAddress=WriteAddress_EEPROM;
#endif 

(ReadAddress>>7 为什么不是>>8呢,片内页寻址不是256B,8位的么


摘自原文
       /*****24Cxx Seriel EEPROM*************************/
#define EEPROM 8
/********
01 -> 24C01;   02 -> 24C02;  04 -> 24C04;   08 -> 24C08;
16 -> 24C16;   32 -> 24C32;  64 -> 24C64;   128 -> 24C128;
256-> 24C256;  512 -> 24C512;  
*****/

#if EEPROM==1
   #define PAGE_SIZE           8
   #define EE_SIZE             0x007F
#elif EEPROM==2
   #define PAGE_SIZE           16 
   #define EE_SIZE             0x00FF
#elif EEPROM==4
   #define PAGE_SIZE           16
   #define EE_SIZE             0x01FF
#elif EEPROM==8
   #define PAGE_SIZE           16
   #define EE_SIZE             0x03FF
#elif EEPROM==16
   #define PAGE_SIZE           16
   #define EE_SIZE             0x07FF
#elif EEPROM==32
   #define PAGE_SIZE           32
   #define EE_SIZE             0x0FFF
#elif EEPROM==64
   #define PAGE_SIZE           32
   #define EE_SIZE             0x1FFF
#elif EEPROM==128
   #define PAGE_SIZE           64
   #define EE_SIZE             0x3FFF
#elif EEPROM==256
   #define PAGE_SIZE           64
   #define EE_SIZE             0x7FFF
#elif EEPROM==512
   #define PAGE_SIZE           128
   #define EE_SIZE             0xFFFF
#endif 

      头文件可以写成预编译模式,方便移植后修改,PAGE_SIZE为一页的存储量,EE_SIZE为芯片的存储量,而后一些程序的判断也根据选择的存储芯片来判断。
顶层用于外部程序调用的函数只有两个,读和写两个情况而已
unsigned char EEPROM_Write(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumbyteToWrite);
unsigned char EEPROM_Read(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite);
传递函数有三个:
pBuffer:要存储或读出来的数据所在的变量存储区字符串头指针;
WriteAddress/ReadAddress:要存入EEPROM所在的存储空间的第一个存储空间地址;
NumbyteToWrite:数据写入或读出的字节个数;
这样的应用比较简单 例如在头文件中分配了两类数据的存储空间起始地址DATA1、DATA2
#define DATA1  0x0010
#define DATA2  0x0050
存储数据所在缓存 EE_Buffer[20],应用程序如下写法:
EEPROM_Write(EE_Buffer,DATA1,20);
这样EE_Buffer内的数据便被写入EEPROM中 0x10~0x30 的数据存储空间中了。
合理的分配陪EEPROM 的存储空间对数据管理非常重要。甚至于可以作为一个小型黑匣子一样。

unsigned char EEPROM_Write(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumbyteToWrite)
{
  unsigned char TempBuffer,Temp2Buffer;
  if((WriteAddress+NumbyteToWrite) > EE_SIZE)  //判断是否超出存储空间
    {
      return 0;
    }
  else
    {// 连续写入两次避免因EMC等因素造成的写入失败情况
      IIC_WriteBuffer(pBuffer,WriteAddress,NumbyteToWrite);
      IIC_WriteBuffer(pBuffer,WriteAddress,NumbyteToWrite);
//读取eeprom 的数据与缓存中的数据对比 相同为确认写入成功
      IIC_ReadBuffer(&TempBuffer,WriteAddress+NumbyteToWrite-1,1);
      Temp2Buffer=*(pBuffer+NumbyteToWrite-1);
      if(TempBuffer==Temp2Buffer)
         return 1;
      else
return 0;
    }
}

unsigned char EEPROM_Read(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite) 
{
  if((ReadAddress+NumbyteToWrite) > EE_SIZE) 
    {
      return 0;
    }
  else
    {
      IIC_ReadBuffer(pBuffer,ReadAddress,NumbyteToWrite);
      IIC_ReadBuffer(pBuffer,ReadAddress,NumbyteToWrite);
      return 1;
    }
}

接下来的是是IIC_ReadBuffer、IIC_WriteBuffer,两个函数主要是对存入数据的处理,如页面内写入,超过页面数量的数据处理等,我这里把函数定义为static 函数只能对内部应用,外部只能调用上面的两个函数,累似于API函数一样,这也可以避免不必要的程序调用书写。IIC_ReadBuffer函数相对简单,因为读取没有对页面的限制,可以无限制的读下去。读取缓存的函数只对地址做一下判断即可。写入函数较为复杂,需判断数据起始存储地址 和页等关系
static void IIC_ReadBuffer(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite);
static void IIC_WriteBuffer(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumByteToWrite);

void IIC_ReadBuffer(unsigned char* pBuffer,unsigned int ReadAddress,unsigned char NumbyteToWrite)
{
  u8 PageAddress=0;
  /******pageAddress is over 8bit***********/
/******判断存储地址是否超过8位************/
#if EEPROM < 32
  PageAddress=(u8)(ReadAddress>>7)&0x0E|ReadAddress_EEPROM;
#else
  PageAddress=WriteAddress_EEPROM;
#endif 

 IIC_ReadPage(pBuffer,PageAddress,ReadAddress,NumbyteToWrite); 
}
void IIC_WriteBuffer(unsigned char* pBuffer,unsigned int WriteAddress,unsigned char NumByteToWrite)
{
  u8 NumOfPage=0,NumOfSingle=0; //
  u16 Part=0;//
  u8 PageAddress=0;
  /******pageAddress is over 8bit***********/
  /******判断存储地址是否超过8位************/
#if EEPROM < 32
  PageAddress=(u8)(WriteAddress>>7)&0x0E|WriteAddress_EEPROM;
#else
  PageAddress=WriteAddress_EEPROM;
#endif 
  
  /*********判断起始地址与跨页地址的字节个数********/
  Part=WriteAddress/PAGE_SIZE;
  if(Part!=0)
    {
      Part=PAGE_SIZE*(Part+1)-WriteAddress;      
    }
  else 
    {
      Part=PAGE_SIZE-WriteAddress;
    }
  /******/
  if(Part >= NumByteToWrite)
    {
/***写入的数据个数小于跨页剩余的个数可直接写入 ***/
      IIC_WritePage(pBuffer,PageAddress,WriteAddress,NumByteToWrite);
    }
  else
    {
      NumOfPage = (NumByteToWrite-Part)/PAGE_SIZE;  
      NumOfSingle = (NumByteToWrite-Part)%PAGE_SIZE;   
      pBuffer = IIC_WritePage(pBuffer,PageAddress,WriteAddress,Part);
    /***1.写入的数据个数大于跨页剩余的个数先把剩余的跨页个数填充满 ***/
      NumByteToWrite -= Part;
      WriteAddress += Part;

      while(NumOfPage--)
{     
  pBuffer = IIC_WritePage(pBuffer,PageAddress,WriteAddress,PAGE_SIZE);
/***2.按计算的数据量占页面数,连续写入页面*******/
  WriteAddress += PAGE_SIZE;
}   
      if(NumOfSingle!=0)
{
  IIC_WritePage(pBuffer,PageAddress,WriteAddress,NumOfSingle);
 /***3.补充页面写完后超出的不足一页数据量的数据***/
}
    }
}
剩下的是IIC_WritePage()、IIC_ReadPage()两个函数是芯片的IIC通讯底层函数,根据单片机的IIC通讯模式写入即可。以上的程序可通用到任何24Cxx 系列所应用的程序。

     在实际应用中要注意的便是存储空间的分配,已经空间长度的输入,这样EEPROM的使用便能得心应手。

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

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2015-3-10 08:15:28 | 显示全部楼层
不错,谢谢分享!!!
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

40

主题

144

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2013-7-26
在线时间
72 小时
 楼主| 发表于 2015-3-10 17:32:06 | 显示全部楼层
回复【2楼】八度空间:
---------------------------------
我是提问的。。。。
疑问?  他的程序的移位语句
#if EEPROM < 32
  ageAddress=(u8)(ReadAddress>>7)&0x0E|ReadAddress_EEPROM;
#else
  ageAddress=WriteAddress_EEPROM;
#endif 

(ReadAddress>>7 为什么不是>>8呢,片内页寻址不是256B,8位的么
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2015-3-10 19:04:52 | 显示全部楼层
回复【3楼】16777216:
---------------------------------
读写位是哪个?

其实不用我说你自己运算一下就可以得到答案的
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-25 12:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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