• [51单片机] EEPROM 24c02 [读取存储多字节]


    先将数据存进去,然后再读出来显示在数码管上。

    除了代码里定义的连线外还要把p0连接到8位数码管的8针上。

      1 /*-----------------------------------------------
      2 名称:IIC协议 EEPROM24c02
      3 内容:此程序用于检测EEPROM性能,测试方法如下:写入24c02一些数据,然后在内存中清除这些数据,
      4 掉电后主内存将失去这些信息,然后从24c02中调入这些数据。看是否与写入的相同。
      5 函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 一定的修改....(本例是1us机器
      6 周期,即晶振频率要小于12MHZ)
      7 ------------------------------------------------*/  
      8 #include <reg52.h>          //头文件的包含
      9 #include <intrins.h>
     10 
     11 #define  _Nop()  _nop_()        //定义空指令
     12 
     13 // 常,变量定义区
     14 unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
     15 0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F
     16 unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
     17 
     18 sbit LATCH1=P2^2;
     19 sbit LATCH2=P2^3;
     20 
     21 sbit SDA=P2^1;            //模拟I2C数据传送位
     22 sbit SCL=P2^0;            //模拟I2C时钟控制位
     23 
     24 bit ack;                  //应答标志位
     25 
     26 void DelayUs2x(unsigned char t);//函数声明 
     27 void DelayMs(unsigned char t);
     28 /*------------------------------------------------
     29 uS延时函数,含有输入参数 unsigned char t,无返回值
     30 unsigned char 是定义无符号字符变量,其值的范围是
     31 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
     32 长度如下 T=tx2+5 uS 
     33 ------------------------------------------------*/
     34 void DelayUs2x(unsigned char t)
     35 {   
     36     while(--t);
     37 }
     38 /*------------------------------------------------
     39 mS延时函数,含有输入参数 unsigned char t,无返回值
     40 unsigned char 是定义无符号字符变量,其值的范围是
     41 0~255 这里使用晶振12M,精确延时请使用汇编
     42 ------------------------------------------------*/
     43 void DelayMs(unsigned char t)
     44 {
     45     
     46     while(t--)
     47     {
     48         //大致延时1mS
     49         DelayUs2x(245);
     50         DelayUs2x(245);
     51     }
     52 }
     53 /*------------------------------------------------
     54 启动总线
     55 ------------------------------------------------*/
     56 void Start_I2c()
     57 {
     58     SDA=1;   //发送起始条件的数据信号
     59     _Nop();
     60     SCL=1;
     61     _Nop();    //起始条件建立时间大于4.7us,延时
     62     _Nop();
     63     _Nop();
     64     _Nop();
     65     _Nop();    
     66     SDA=0;     //发送起始信号
     67     _Nop();    //起始条件锁定时间大于4μ
     68     _Nop();
     69     _Nop();
     70     _Nop();
     71     _Nop();       
     72     SCL=0;    //钳住I2C总线,准备发送或接收数据
     73     _Nop();
     74     _Nop();
     75 }
     76 /*------------------------------------------------
     77 结束总线
     78 ------------------------------------------------*/
     79 void Stop_I2c()
     80 {
     81     SDA=0;    //发送结束条件的数据信号
     82     _Nop();   //发送结束条件的时钟信号
     83     SCL=1;    //结束条件建立时间大于4μ
     84     _Nop();
     85     _Nop();
     86     _Nop();
     87     _Nop();
     88     _Nop();
     89     SDA=1;    //发送I2C总线结束信号
     90     _Nop();
     91     _Nop();
     92     _Nop();
     93     _Nop();
     94 }
     95 /*----------------------------------------------------------------
     96 字节数据传送函数               
     97 函数原型: void  SendByte(unsigned char c);
     98 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
     99 此状态位进行操作.(不应答或非应答都使ack=0 假)     
    100 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
    101 ------------------------------------------------------------------*/
    102 void  SendByte(unsigned char c)
    103 {
    104     unsigned char BitCnt;
    105     
    106     for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位
    107     {
    108         if((c<<BitCnt)&0x80)SDA=1;   //判断发送位
    109         else  SDA=0;                
    110         _Nop();
    111         SCL=1;               //置时钟线为高,通知被控器开始接收数据位
    112         _Nop(); 
    113         _Nop();             //保证时钟高电平周期大于4μ
    114         _Nop();
    115         _Nop();
    116         _Nop();         
    117         SCL=0; 
    118     }
    119     _Nop();
    120     _Nop();
    121     SDA=1;               //8位发送完后释放数据线,准备接收应答位
    122     _Nop();
    123     _Nop();   
    124     SCL=1;
    125     _Nop();
    126     _Nop();
    127     _Nop();
    128     if(SDA==1)ack=0;     
    129     else ack=1;        //判断是否接收到应答信号
    130     SCL=0;
    131     _Nop();
    132     _Nop();
    133 }
    134 /*----------------------------------------------------------------
    135 字节数据传送函数               
    136 函数原型: unsigned char  RcvByte();
    137 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
    138 发完后请用应答函数。  
    139 ------------------------------------------------------------------*/    
    140 unsigned char  RcvByte()
    141 {
    142     unsigned char retc;
    143     unsigned char BitCnt;
    144     
    145     retc=0; 
    146     SDA=1;             //置数据线为输入方式
    147     for(BitCnt=0;BitCnt<8;BitCnt++)
    148     {
    149         _Nop();           
    150         SCL=0;       //置时钟线为低,准备接收数据位
    151         _Nop();
    152         _Nop();      //时钟低电平周期大于4.7us
    153         _Nop();
    154         _Nop();
    155         _Nop();
    156         SCL=1;       //置时钟线为高使数据线上数据有效
    157         _Nop();
    158         _Nop();
    159         retc=retc<<1;
    160         if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
    161         _Nop();
    162         _Nop(); 
    163     }
    164     SCL=0;    
    165     _Nop();
    166     _Nop();
    167     return(retc);
    168 }
    169 /*----------------------------------------------------------------
    170 应答子函数
    171 原型:  void Ack_I2c(void);
    172 ----------------------------------------------------------------*/
    173 void Ack_I2c(void)
    174 {
    175     SDA=0;     
    176     _Nop();
    177     _Nop();
    178     _Nop();      
    179     SCL=1;
    180     _Nop();
    181     _Nop();              //时钟低电平周期大于4μ
    182     _Nop();
    183     _Nop();
    184     _Nop();  
    185     SCL=0;               //清时钟线,钳住I2C总线以便继续接收
    186     _Nop();
    187     _Nop();    
    188 }
    189 /*----------------------------------------------------------------
    190 非应答子函数
    191 原型:  void NoAck_I2c(void);
    192 ----------------------------------------------------------------*/
    193 void NoAck_I2c(void)
    194 {
    195     SDA=1;
    196     _Nop();
    197     _Nop();
    198     _Nop();      
    199     SCL=1;
    200     _Nop();
    201     _Nop();              //时钟低电平周期大于4μ
    202     _Nop();
    203     _Nop();
    204     _Nop();  
    205     SCL=0;                //清时钟线,钳住I2C总线以便继续接收
    206     _Nop();
    207     _Nop();    
    208 }
    209 /*----------------------------------------------------------------
    210 向无子地址器件发送字节数据函数               
    211 函数原型: bit  ISendByte(unsigned char sla,ucahr c);  
    212 功能:     从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
    213 如果返回1表示操作成功,否则操作有误。
    214 注意:    使用前必须已结束总线。
    215 ----------------------------------------------------------------*/
    216 /*bit ISendByte(unsigned char sla,unsigned char c)
    217 {
    218     Start_I2c();               //启动总线
    219     SendByte(sla);             //发送器件地址
    220     if(ack==0)return(0);
    221     SendByte(c);               //发送数据
    222     if(ack==0)return(0);
    223     Stop_I2c();                 //结束总线
    224     return(1);
    225 }
    226 */
    227 
    228 /*----------------------------------------------------------------
    229 向有子地址器件发送多字节数据函数               
    230 函数原型: bit  ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);  
    231 功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
    232 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
    233 如果返回1表示操作成功,否则操作有误。
    234 注意:    使用前必须已结束总线。
    235 ----------------------------------------------------------------*/
    236 bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
    237 {
    238     unsigned char i;
    239     
    240     Start_I2c();               //启动总线
    241     SendByte(sla);             //发送器件地址
    242     if(ack==0)return(0);
    243     SendByte(suba);            //发送器件子地址
    244     if(ack==0)return(0);
    245     
    246     for(i=0;i<no;i++)
    247     {   
    248         SendByte(*s);            //发送数据
    249         DelayMs(1);
    250         if(ack==0)return(0);
    251         s++;
    252     } 
    253     Stop_I2c();                  //结束总线
    254     return(1);
    255 }
    256 
    257 /*----------------------------------------------------------------
    258 向无子地址器件读字节数据函数               
    259 函数原型: bit  IRcvByte(unsigned char sla,ucahr *c);  
    260 功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地
    261 址sla,返回值在c.
    262 如果返回1表示操作成功,否则操作有误。
    263 注意:    使用前必须已结束总线。
    264 ----------------------------------------------------------------*/
    265 /*bit IRcvByte(unsigned char sla,unsigned char *c)
    266 {
    267     Start_I2c();                //启动总线
    268     SendByte(sla+1);            //发送器件地址
    269     if(ack==0)return(0);
    270     *c=RcvByte();               //读取数据
    271     NoAck_I2c();              //发送非就答位
    272     Stop_I2c();               //结束总线
    273     return(1);
    274 }
    275 
    276 */
    277 /*----------------------------------------------------------------
    278 向有子地址器件读取多字节数据函数               
    279 函数原型: bit  ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);  
    280 功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
    281 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
    282 如果返回1表示操作成功,否则操作有误。
    283 注意:    使用前必须已结束总线。
    284 ----------------------------------------------------------------*/
    285 bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
    286 {
    287     unsigned char i;
    288     
    289     Start_I2c();               //启动总线
    290     SendByte(sla);             //发送器件地址
    291     if(ack==0)return(0);
    292     SendByte(suba);            //发送器件子地址
    293     if(ack==0)return(0);
    294     
    295     Start_I2c();
    296     SendByte(sla+1);
    297     if(ack==0)return(0);
    298     
    299     for(i=0;i<no-1;i++)
    300     {   
    301         *s=RcvByte();              //发送数据
    302         Ack_I2c();                //发送就答位 
    303         s++;
    304     } 
    305     *s=RcvByte();
    306     NoAck_I2c();                 //发送非应位
    307     Stop_I2c();                    //结束总线
    308     return(1);
    309 }
    310 /*------------------------------------------------
    311 主函数
    312 ------------------------------------------------*/
    313 void main()
    314 {
    315     unsigned char dofly[4]={1,2,3,4};          // 显示码值 1234
    316     unsigned char i;
    317     
    318     ISendStr(0xae,4,dofly,4);                   //写入24c02
    319     DelayMs(200);
    320     dofly[0]=0;                                  //清除当前数据
    321     dofly[1]=0;
    322     dofly[2]=0;
    323     dofly[3]=0;
    324     IRcvStr(0xae,4,dofly,4);                  //调用存储数据
    325     
    326     while(1)
    327     { 
    328        P0=dofly_DuanMa[dofly[i]];//显示存储数据
    329        LATCH1=1;                  //锁存
    330        LATCH1=0;
    331        
    332        P0=dofly_WeiMa[i];  //取位码
    333        LATCH2=1;          // 锁存
    334        LATCH2=0;
    335        DelayMs(200);      //延时用于演示显示数据
    336        DelayMs(200);
    337        i++;
    338        if(i==4)
    339            i=0;
    340     }
    341 }
  • 相关阅读:
    Python中的类(上)
    Django REST Framework API Guide 07
    Django REST Framework API Guide 06
    Django REST Framework API Guide 05
    Django REST Framework API Guide 04
    Django REST Framework API Guide 03
    Django REST Framework API Guide 02
    Django REST Framework API Guide 01
    Django 详解 信号Signal
    Django 详解 中间件Middleware
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/3704051.html
Copyright © 2020-2023  润新知