zoukankan      html  css  js  c++  java
  • IIC总线程序(芯片AT24C02 EEPROM)

      1 #include<reg52.h>
      2 #define uint unsigned int 
      3 #define uchar unsigned char
      4  
      5 sbit SCL =P2^1;
      6 sbit SDA =P2^0;
      7 
      8 sbit K1 =P3^0;
      9 sbit K2 =P3^1;
     10 sbit K3 =P3^0;
     11 sbit K4 =P3^1;
     12 
     13 sbit LSA =P2^2;
     14 sbit LSB =P2^3;
     15 sbit LSC =P2^4;
     16 uchar num;
     17 uchar code smgduan[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
     18 
     19 /*******************************************************************************
     20 * 函数名         : Delay10us()
     21 * 函数功能           : 延时10us
     22 * 输入           : 无
     23 * 输出              : 无
     24 *******************************************************************************/
     25 void Delay10us()//通过计算来确定延时为10uM
     26 {
     27     unsigned char a,b;
     28     for(b=1;b>0;b--)
     29         for(a=2;a>0;a--);
     30 
     31 }
     32 /*******************************************************************************
     33 * 函数名         : I2cStart()
     34 * 函数功能         : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿
     35 * 输入           : 无
     36 * 输出              : 无
     37 * 备注           : 起始之后SDA和SCL都为0
     38 *******************************************************************************/
     39 
     40 void I2cStart()
     41 {
     42     SDA=1;
     43     Delay10us();
     44     SCL=1;
     45     Delay10us();//建立时间是SDA保持时间>4.7us
     46     SDA=0;
     47     Delay10us();//保持时间是>4us
     48     SCL=0;            
     49     Delay10us();        
     50 }
     51 /*******************************************************************************
     52 * 函数名         : I2cStop()
     53 * 函数功能         : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿
     54 * 输入           : 无
     55 * 输出              : 无
     56 * 备注           : 结束之后保持SDA和SCL都为1;表示总线空闲
     57 *******************************************************************************/
     58 
     59 void I2cStop()
     60 {
     61     SDA=0;
     62     Delay10us();
     63     SCL=1;
     64     Delay10us();//建立时间大于4.7us
     65     SDA=1;
     66     Delay10us();        
     67 }
     68 //针对IIC的写字节
     69 uchar IICsendByte(uchar dat)
     70 {
     71     uchar a=0,b;
     72     SDA =dat;
     73     for(a=0;a<8;a++)
     74     {
     75         SDA =dat>>7; //将最高位取出,然后其他的为都通过右移掉
     76         dat =dat<<1; // 因为dat的值一直没有变化,故而,将其左移一位,最高位移掉,次高位变成最高位
     77         SDA =1;
     78         delay(1);
     79         SCL=0;
     80         delay(1);
     81     }  //此时8位数据已经全部传送完成 接下来进行应答
     82     SDA=1; //SDA和SCL为1是为了下面应答做铺垫    
     83     delay(1);
     84     SCL=1;
     85 //    delay(1);
     86     while(SDA) //当应答成功的话,SDA=0;跳出循环
     87     {
     88         b++;
     89         if(b>200)
     90             SCL=0;
     91             dealy(1);
     92             return 0; //表示发送(通讯)失败
     93     }
     94     SCL =0;
     95     delay(1); 
     96     return 1;  //发送成功的时候,返回1
     97 }
     98 //针对IIC的读字节
     99 uchar IICReadByte()
    100 {
    101     uchar a,dat =0;
    102     SD1=1; //首先先让其拉高,让其处于空闲状态,不至于让下面的SDA的数据为低 
    103     delay(1);
    104     for(a=0;a<8;a++)
    105     {
    106         SCL =1; //为了读数据,故而首先让SCL为高,就是为了让数据稳定后再读
    107         dealy(1);
    108         dat<<=1;  //  0  00  10  110   要将其放在dat|=SDA前面,否则当把8位数据全部放到dat中后, 再移一位的话,就会使得最高位移走,数据出错                         将其左移一位,等二次循环过来时,这是就会原来保存在dat中的数据就会继续左移一次     
    109         dat|=SDA; //     01     11     111     也就是只需要让其移动7次,不将最高位移走 让dat与SDA进行“按位或”将SDA的值赋给dat 
    110         delay(1);
    111         SCL=0; //让SCL为低,就是为了让数据改变
    112         delay(1);
    113     }
    114     return dat;
    115 }
    116 //芯片AT24C02通讯的读写 
    117 void AT24C02writeByte(uchar add,uchar dat)
    118 {
    119     IICstart();
    120     IICsendByte(0xa0);//这是器件地址,8位  高四位是固定的 最后一位表示0为写、1为读、其余的三位A1、A2、A3,我们接了地
    121     IICsendByte(add);
    122     IICsendByte(dat);//应答与否我们都在IIC的字节函数中谢了
    123     IICStop();
    124 }
    125 uchar AT24C02read(uchar add)//由于是要读取信号,故而需要知道读取的地址即可
    126 {
    127     uchar value;
    128     IICstart();
    129     IICsendByte(0xa0);//这是器件地址,8位  高四位是固定的 最后一位表示0为写、1为读、其余的三位A1、A2、A3,我们接了地
    130     IICsendByte(add);
    131     IICstart(); //由于前面要写入它的地址,之后要读里面的数据,所以读写的方向会发生变化,所以必须要重新写入起始信号和器件地址
    132     IICsendByte(0xa1);
    133     value =IICReadByte();//直接读取地址中的数据,并且将读回来的值保存到value中去
    134     IICstop();
    135     return value; 
    136 }
    137 //独立按键的函数
    138 void keypros()
    139 {
    140     if (K1==0)
    141         {
    142             delay(10);
    143             if(K1==0)
    144                 {
    145                     AT24C02writeByte(1,num); //按键1实现将num的值,写入到 1 的地址中去,因为AT24C02这个芯片有255个内存
    146                 }
    147                 while(!K1);//判断按键是否释放  如果忘记写这个语句,这个函数的功能就会不停地进行
    148         }
    149     if (K2==0)
    150         {
    151             delay(10);
    152             if(K2==0)
    153                 {
    154                     num =AT24C02read(1); //将存储到 1这个内存中的数据读取出来,再赋给变量num这个值
    155                 }
    156                 while(!K2);
    157         }
    158         
    159     if (K3==0)
    160         {
    161             delay(10);
    162             if(K3==0)
    163                 {
    164                     num++;  //对num的值进行加1运行
    165                     if(num>255) //因为num的变量为uchar,故而只能存储255个字符
    166                      num =0;  
    167                 }
    168                 while(!K3);
    169         }
    170     if (K4==0)
    171         {
    172             delay(10);
    173             if(K4==0)
    174                 {
    175                     num =0; //对num精心清零运算
    176                 }
    177                 while(!K4);
    178         }
    179 }
    180 /*******************************************************************************
    181 * 函数名         :DigDisplay()
    182 * 函数功能         :数码管显示函数
    183 * 输入           : 无
    184 * 输出              : 无
    185 *******************************************************************************/
    186 void DigDisplay()
    187 {
    188     u8 i;
    189     for(i=0;i<4;i++)
    190     {
    191         switch(i)     //位选,选择点亮的数码管,
    192         {
    193             case(0):
    194                 LSA=0;LSB=0;LSC=0; break;//显示第0位
    195             case(1):
    196                 LSA=1;LSB=0;LSC=0; break;//显示第1位
    197             case(2):
    198                 LSA=0;LSB=1;LSC=0; break;//显示第2位
    199             case(3):
    200                 LSA=1;LSB=1;LSC=0; break;//显示第3位    
    201         }
    202         P0=disp[3-i];//发送数据
    203         delay(100); //间隔一段时间扫描    
    204         P0=0x00;//消隐
    205     }        
    206 }
    207 /*******************************************************************************
    208 * 函数名         :datapros()
    209 * 函数功能         :数据处理函数
    210 * 输入           : 无
    211 * 输出              : 无
    212 *******************************************************************************/
    213 void datapros()
    214 {
    215     disp[0]=smgduan[num/1000];//千位
    216     disp[1]=smgduan[num%1000/100];//百位
    217     disp[2]=smgduan[num%1000%100/10];//个位
    218     disp[3]=smgduan[num%1000%100%10];        
    219 }
    220 void main()
    221 {    
    222     while(1)
    223     {
    224         Keypros();     //按键处理函数
    225         datapros();     //数据处理函数
    226         DigDisplay();//数码管显示函数        
    227     }        
    228 }
    View Code
  • 相关阅读:
    MonoRail学习Component
    Eclipse中用户库的使用
    ASP.Net2.0中自定义控件在page中的注册
    WF学习Console Workflow Application
    Which Style of Workflow When?[转]
    使用UserControl时,在Page中定义方式
    参数类型异常
    GridView使用一些记录
    在使用Mybatis进行测试时出现报错:Caused by: java.lang.ClassNotFoundException: Cannot find class: Student
    递归反向输出字符串
  • 原文地址:https://www.cnblogs.com/wises/p/9539462.html
Copyright © 2011-2022 走看看