• 51单片机连接24C02-C语言测试代码


    忙了一天多终于透彻了,自己写的不好使,用别人的逐步分析改成自己的,我写得非常简洁易懂。

    我总结3点需要注意的地方

    1.关闭非IIC通信器件,比如我的开发板SDA和SCL连接了DS1302,造成干扰会没有结果。

    2.IIC通信的应答,发送端在SCL为0时将SDA置1,等待接收端拉低SDA;接收端在拉低SDA持续一个周期后,应将SDA置1释放总线。

    主机作为发送端等待应答

    SDA=1;
    SCL=1;
    while(SDA);
    SCL=0;
    

    主机作为接收端,进行应答或不应答

    SDA=0;    //不应答则为1    
    SCL=1;
    SCL=0;
    SDA=1;
    

    3.24C02在写入周期完成后还有有内部写入时间Twr,所以可以查手册加入适当时间的延时函数,或者使用查询应答的方式进行延时等待。

    总之,关键是注意参考数据手册及IIC总线规范,尤其是芯片特别说明以及时序的控制,再结合代码就能弄懂了。

    下面是我写的代码,用上了所有的功能,包括 Current Read 对应的函数 readnext() 。多字节写入时不用考虑分页问题,函数自动解决,直接给数组即可。使用数码管显示结果。

      1 #include<reg52.h>
      2 
      3 sbit RST=P2^4;    //用来关闭ds1302
      4 
      5 
      6 sbit SDA=P2^0;                         
      7 sbit SCL=P2^1;
      8 //内部使用的函数
      9 bit start(unsigned char dev);
     10 void stop(void);
     11 bit write_byte(unsigned char dat);
     12 unsigned char read_byte(bit ack);
     13 void waitack(void);
     14 //外部使用
     15 void writes(unsigned char address,unsigned char dat[],unsigned char num);
     16 void reads(unsigned char address,unsigned char dat[],unsigned char num);
     17 unsigned char read(unsigned char address);
     18 void write(unsigned char address,unsigned char dat);
     19 unsigned char readnext(void);
     20 
     21 /*数码管部分*/
     22 sbit du=P2^6;
     23 sbit we=P2^7;
     24 void display(void);
     25 void delayms(unsigned time);
     26 unsigned char code table[]={
     27 0x3f,0x06,0x5b,0x4f,
     28 0x66,0x6d,0x7d,0x07,
     29 0x7f,0x6f,0x77,0x7c,
     30 0x39,0x5e,0x79,0x71};
     31 unsigned char num[6]={0};
     32 
     33 
     34 void main(void)
     35 {
     36     //测试用数据
     37     unsigned char a[9]={2,3,5,7,13,15,11,4,8};
     38     unsigned char b[13]={0};
     39 
     40     RST=0;    //关闭ds1302消除影响
     41 
     42     write(11,6);
     43     write(12,1);
     44     writes(2,a,9);
     45     b[9]=readnext();    //b[9]=6
     46     b[10]=readnext();    //b[10]=1
     47     reads(2,b,9);        //b[0-8]=a[0-8]
     48     b[11]=readnext();    //b[11]=6
     49     b[12]=read(12);        //b[12]=1
     50     
     51     num[5]=b[3];
     52     num[4]=b[6];
     53     num[3]=b[9];
     54     num[2]=b[10];
     55     num[1]=b[11];
     56     num[0]=b[12];
     57     
     58     while(1)
     59     {
     60         display();
     61     } 
     62 }
     63 
     64 //传入设备地址,返回设备是否应答
     65 bit start(unsigned char dev)
     66 {    
     67     SDA=1;
     68     SCL=1;
     69     SDA=0;
     70     SCL=0;
     71     return write_byte(dev);
     72 }
     73 
     74 void stop(void)
     75 {
     76     SDA=0;
     77     SCL=1;
     78     SDA=1;
     79 }
     80 
     81 //传入要写入的字节,返回设备是否应答
     82 bit write_byte(unsigned char dat)
     83 {
     84     unsigned char i=8;
     85     bit ack;
     86     while(i--)
     87     {
     88         dat<<=1;
     89         SDA=CY;
     90         SCL=1;
     91         SCL=0;
     92     }
     93     SDA=1;        //接收设备应答
     94     SCL=1;
     95     ack=~SDA;
     96     SCL=0;
     97     return ack;
     98 }
     99 
    100 //在写入后等待24c02完成内部写入
    101 //恢复响应的时间为手册中的twr
    102 void waitack(void)    
    103 {                        
    104     while(!start(0xa0));                
    105     stop();
    106 }
    107 
    108 //传入是否应答设备,返回读取的字节
    109 unsigned char read_byte(bit ack)
    110 {
    111     unsigned char i=8,ret;
    112     
    113     while(i--)
    114     {
    115         ret<<=1;
    116         SCL=1;
    117         ret|=SDA;
    118         SCL=0;
    119     }
    120     SDA=~ack;    //应答或不应答设备
    121     SCL=1;
    122     SCL=0;
    123     SDA=1;    //应答时要注意的时序
    124     return ret;
    125 }
    126 
    127 //传入写入地址,数组,写入字节数
    128 //函数自动进行分页写入
    129 void writes(unsigned char address,unsigned char dat[],unsigned char num)
    130 {
    131     unsigned char i;
    132     
    133     for(i=0;i<num;)    
    134     {
    135         start(0xa0);
    136         write_byte(address);
    137         do
    138             write_byte(dat[i++]);
    139         while(++address&0x07 && i<num);        //分页条件判断
    140         stop();
    141         waitack();    //延时等待以完成内部写入
    142     }    
    143 }
    144 
    145 //传入读取地址,接收用的数组,读取字节数
    146 void reads(unsigned char address,unsigned char dat[],unsigned char num)
    147 {
    148     unsigned char i;    
    149 
    150     start(0xa0);
    151     write_byte(address);
    152 
    153     start(0xa1);
    154 
    155     for(i=0;i<num-1;i++)
    156         dat[i]=read_byte(1);
    157 
    158     dat[i]=read_byte(0);
    159     stop();
    160 }
    161 
    162 void write(unsigned char address,unsigned char dat)
    163 {
    164     writes(address,&dat,1);
    165 }
    166 
    167 unsigned char read(unsigned char address)
    168 {
    169     unsigned char ret;
    170     reads(address,&ret,1);
    171     return ret;
    172 }
    173 
    174 //对应手册中的Current Read
    175 unsigned char readnext(void)
    176 {
    177     unsigned char ret;
    178     start(0xa1);
    179     ret=read_byte(0);
    180     stop();
    181     return ret;
    182 }
    183 
    184 void delayms(unsigned time)
    185 {
    186     unsigned i,j;
    187 
    188     for(i=time;i>0;i--)
    189         for(j=110;j>0;j--)
    190         ;
    191 }
    192 
    193 void display(void)
    194 {
    195     unsigned char i;
    196     
    197     for(i=0;i<6;i++)
    198     {
    199         P0=0;
    200         du=1;
    201         du=0;
    202 
    203         P0=~(0x20>>i);
    204         we=1;
    205         we=0;
    206 
    207         P0=table[num[i]];
    208         du=1;
    209         du=0;
    210 
    211         delayms(1);
    212     }
    213 }
    24C02.c
  • 相关阅读:
    模仿企业在宣传中的动画效果页面
    模仿头条导航的左右滚动效果
    Ubuntu 1210怎么获得root权限登录
    Linux嵌入式 -- 内核简介(x86)
    linux ioctl()函数
    BUTTON标签和INPUT标签的区别【转】
    如何删除列表中的空格
    python第一模块数据类型
    python第一模块基础语法
    最短路 dijkstra+优先队列+邻接表
  • 原文地址:https://www.cnblogs.com/zackcoder/p/3530438.html
Copyright © 2020-2023  润新知