zoukankan      html  css  js  c++  java
  • 8051学习笔记——IIC与EEPROM实验

    main.c

      1 #include <reg51.h>
      2 #include "iic.h"
      3 #define  AT24C02 0xa0  //AT24C02 地址
      4 
      5 sbit    LS138A=P2^2;      //译码器端
      6 sbit    LS138B=P2^3;
      7 sbit    LS138C=P2^4; 
      8 
      9 sbit    K1 = P1^0;     //保存
     10 sbit    K2 = P1^1;     //读取
     11 sbit    K3 = P1^2;     //+数据
     12 sbit    K4 = P1^3;   //-数据
     13 
     14 void delay(unsigned int i);
     15 
     16 //此表为 LED 的字模, 共阴数码管 0-9 
     17 unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; 
     18 
     19 unsigned char Count1;
     20 unsigned long D[17], LedOut[5],LedNumVal;
     21 unsigned int idata USEC;   //表示这个变量类型是unsigned int,地址在idata区,也就是内部RAM地址的128~255内
     22 
     23 void  system_ini() 
     24 {    
     25     TMOD|= 0x11;    //mode 1
     26     TH1 = 0xfe;     //0.5ms
     27     TL1 = 0x0c;
     28     TR1 = 1; 
     29     IE = 0x8A;
     30 }
     31 
     32 void main()
     33 {
     34     unsigned char i;
     35     unsigned char pDat[8];
     36 
     37        system_ini();
     38        while(1)
     39        {
     40          //========================IIC 读取
     41         if(K2 == 0)       //第二个按钮读取数据
     42         { 
     43               IRcvStr(AT24C02,0,&pDat[0], 8); 
     44               for (i=0; i<4; i++)
     45               {
     46                 D[14+i]=pDat[i*2+0]+pDat[i*2+1]*0x100;
     47                 Count1 = D[14];
     48                }         
     49          }
     50 
     51        //========================IIC 保存
     52            if(K1 == 0)    //第一个按钮保存数据
     53            { 
     54             D[14]= Count1;
     55              for (i=0; i<4; i++)
     56              {
     57                    pDat[i*2+0]=D[14+i];
     58                    pDat[i*2+1]=D[14+i]>>8;
     59              }
     60              ISendStr(AT24C02, 0 , &pDat[0], 8); 
     61               D[14] = 0;
     62            }
     63 
     64       /********以下将2402中保存的数据送到LED数码管显示*************/
     65         LedNumVal=Count1;
     66           LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
     67           LedOut[1]=Disp_Tab[LedNumVal%1000/100];
     68           LedOut[2]=Disp_Tab[LedNumVal%100/10]|0x80;
     69           LedOut[3]=Disp_Tab[LedNumVal%10]; 
     70         
     71         for(i=0; i<4; i++) 
     72           {        
     73             P0 =  LedOut[i];
     74            
     75             switch(i)                      
     76              {        
     77                 case 0:LS138A=0; LS138B=0; LS138C=0; break;         
     78                 case 1:LS138A=1; LS138B=0; LS138C=0; break;                 
     79                 case 2:LS138A=0; LS138B=1; LS138C=0; break; 
     80                 case 3:LS138A=1; LS138B=1; LS138C=0; break; 
     81                 case 4:LS138A=0; LS138B=0; LS138C=1; break;
     82              }
     83             delay(100);
     84           }
     85    }
     86 }
     87 
     88 void delay(unsigned int i)
     89 {
     90     char j;
     91     for(i; i > 0; i--)
     92         for(j = 200; j > 0; j--);
     93 }
     94 
     95 void T1zd(void) interrupt 3   //3 为定时器1的中断号  1 定时器0的中断号 0 外部中断1 2 外部中断2  4 串口中断
     96 {
     97     TH1 = 0xfe; //12M    
     98     TL1 = 0x0c;
     99        if(USEC++==200)
    100        {    
    101         USEC = 0;
    102         if(!K3) Count1++;     //改变数据
    103         if(!K4)    Count1--;
    104     }  
    105 }

    iic.h

      1 #include <reg51.h>
      2 #include <intrins.h>
      3 #define _NOP() _nop_()
      4 sbit    SCL = P2^1;
      5 sbit    SDA = P2^0;
      6 bit ack;
      7 
      8 void Start_IIC()
      9 {
     10     SDA = 1;
     11     _NOP();
     12     SCL = 1;
     13     _NOP();_NOP();_NOP();_NOP();_NOP();
     14     SDA = 0;
     15     _NOP();_NOP();_NOP();_NOP();_NOP();
     16     SCL = 0;
     17     _NOP();_NOP();
     18 }
     19 
     20 void Stop_IIC()
     21 {
     22     SDA = 0;
     23     _NOP();
     24     SCL = 1;
     25     _NOP();_NOP();_NOP();_NOP();_NOP();
     26     SDA = 1;
     27     _NOP();_NOP();_NOP();_NOP();_NOP();
     28 }
     29 
     30 void Send_Byte(unsigned char byte)
     31 {
     32     int i;
     33     for(i = 0;i < 8;i++)
     34     {
     35         if((byte << i) & 0x80)    SDA = 1;
     36         else    SDA = 0;
     37         SCL = 1;
     38         _NOP();_NOP();_NOP();_NOP();_NOP();
     39         SCL = 0;
     40     }
     41 
     42     SCL = 1;      //准备接受应答位
     43     _NOP();_NOP();
     44 
     45     if(SDA == 1)    ack = 0;
     46     else    ack = 1;
     47 
     48     SCL = 0;
     49     _NOP();_NOP();
     50 }
     51 
     52 unsigned char Rcv_Byte()
     53 {
     54     unsigned char byte;
     55     int i;
     56     byte = 0;
     57 
     58     for(i = 0;i < 8;i++)
     59     {
     60         SCL = 0;
     61         _NOP();_NOP();_NOP();_NOP();_NOP();
     62         SCL = 1;
     63         _NOP();_NOP();_NOP();_NOP();_NOP();
     64         byte <<= 1;
     65         if(SDA == 1)    byte++;
     66     }
     67     SCL = 0;
     68     _NOP();_NOP();
     69     return byte;
     70 }
     71 
     72 void Ack_IIC(bit a)
     73 {
     74   
     75   if(a==0)    SDA=0;              /*在此发出应答或非应答信号 */
     76   else    SDA=1;
     77   _NOP();_NOP();_NOP();     
     78   SCL=1;
     79   _NOP();_NOP();_NOP();_NOP();_NOP();
     80   SCL=0;                     /*清时钟线,钳住I2C总线以便继续接收*/
     81   _NOP();_NOP();  
     82 }
     83 
     84 //AT2402的功能函数
     85 /*******************************************************************
     86                     向有子地址器件发送多字节数据函数               
     87 函数原型: bit  ISendStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no);  
     88 功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
     89           地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
     90           如果返回1表示操作成功,否则操作有误。
     91 注意:    使用前必须已结束总线。
     92 ********************************************************************/
     93 bit ISendStr(unsigned char  sla,unsigned char  suba,unsigned char  *s,unsigned char  no)
     94 {
     95    unsigned char i;
     96 
     97    Start_IIC();               /*启动总线*/
     98    Send_Byte(sla);             /*发送器件地址*/
     99    if(ack==0)    return(0);
    100    Send_Byte(suba);            /*发送器件字地址,存储单元的地址*/
    101    if(ack==0)    return(0);
    102 
    103    for(i=0;i<no;i++)
    104    {   
    105      Send_Byte(*s);            /*发送数据*/
    106      if(ack==0)return(0);
    107      s++;
    108    } 
    109    Stop_IIC();                /*结束总线*/ 
    110 
    111    return(1);
    112 }
    113 
    114 /*******************************************************************
    115                     向有子地址器件读取多字节数据函数               
    116 函数原型: bit  RecndStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no);  
    117 功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
    118           地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
    119            如果返回1表示操作成功,否则操作有误。
    120 注意:    使用前必须已结束总线。
    121 ********************************************************************/
    122 bit IRcvStr(unsigned char  sla,unsigned char suba,unsigned char  *s,unsigned char  no)
    123 {
    124     unsigned char i;
    125 
    126     Start_IIC();                  /*启动总线*/
    127     Send_Byte(sla);                /*发送器件地址*/
    128     if(ack==0)    return(0);
    129     Send_Byte(suba);               /*发送器件子地址*/
    130     if(ack==0)    return(0);
    131 
    132     Start_IIC();                 /*重新启动总线*/
    133     Send_Byte(sla+1);
    134     if(ack==0)    return(0);
    135     for(i=0;i<no-1;i++)
    136     {   
    137         *s=Rcv_Byte();               /*发送数据*/
    138           Ack_IIC(0);                  /*发送就答位*/  
    139          s++;
    140        } 
    141        *s=Rcv_Byte();
    142        Ack_IIC(1);                   /*发送非应答位*/
    143        Stop_IIC();                   /*结束总线*/ 
    144        return 1;
    145 }
  • 相关阅读:
    UTF-8 GBK UTF8 GB2312 之间的区别和关系
    为什么要需求分析
    数据库建表原则
    使用SQL存储过程有什么好处 用视图有什么好处
    SQL使用视图的优缺点
    百度地图添加多个行政区划
    性能测试日志分析之awk基础用法
    Nginx 安装配置
    linux的top命令参数详解
    Java小程序Linux下运行
  • 原文地址:https://www.cnblogs.com/boyiliushui/p/4781360.html
Copyright © 2011-2022 走看看