极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11111|回复: 4

IIC通信心得

[复制链接]
发表于 2015-7-4 11:30:35 | 显示全部楼层 |阅读模式
本帖最后由 小智 于 2015-7-4 14:23 编辑
  1. //本程序是在看郭天祥老师视频后编制的,程序在郭老师的基础上做了细微的变动
  2. //并在部分语句后添加了自己的理解,如果有不妥欢迎大家指正出来,谢谢!!!
  3. //程序包含的内容很简单,只是向AT24c02中写入一个字节的数据,然后输出这个数据,并赋给P1口输出
  4. //虽然是51程序,但愿对刚接触IIC通信的朋友有所帮助。
  5. //邮箱:[email protected]
  6. #include <reg52.h>
  7. #define uchar unsigned char
  8. sbit scl=P2^1;//定义时钟线
  9. sbit sda=P2^0;//定义数据线
  10. void delay()//
  11. {;;}
  12. void delay_(uchar x)
  13. {
  14. uchar a,b;
  15. for(a=x;a>0;a--)
  16.    for(b=100;b>0;b--);       
  17. }
  18. void start()//开始,开始的信号为时钟信号高的状态下,数据线一个下降沿    不用应答
  19. {
  20.                 sda=1;
  21.                 delay();
  22.                 scl=1;
  23.                 delay();
  24.                 sda=0;
  25.           delay();               
  26. }
  27. void stop()//终止,终止信号为时钟信号搞得状态下,数据线一个上升沿     不用应答
  28. {
  29.    sda=0;
  30.    delay();
  31.    scl=1;
  32.    delay();
  33.    sda=1;
  34.    delay();       
  35. }
  36. /***********************************************************************************************************************************/
  37. //每次上位机要向下位机读、写数据时都要等待下位机回应(即下位机将数据线sda置低),但是下位机要是一直不回应低上位机就不管了,毕竟有主动权嘛
  38. /***************************************************************************************************************************************/
  39. void respons()//应答        
  40. {
  41.         uchar i;
  42.         scl=1;
  43.         delay();
  44.         while((sda==1)&&(i<250))i++;//如果下位机应答了会将数据线拉低
  45.         scl=0;
  46.         delay();
  47. }
  48. void init()//初始化时将数据线和时钟线都拉高
  49. {
  50.         sda=1;
  51.         delay();
  52.         scl=1;
  53.         delay();
  54. }
  55. void write_byte(uchar date)//写一个字节        需要应答
  56. {
  57.         uchar i,temp;
  58.         temp=date;
  59.         for(i=0;i<8;i++)
  60.         {
  61.           scl=0;         //一个时钟完成一位数据sda的传输,一位数据sda在一个时钟scl内是不允许变化的                 
  62.           delay();                        
  63.                 temp=temp<<1;//左移时,左边溢出的那一位数据会自动保存在PSW的CY位,右边自动补0            
  64.                 sda=CY;//赋给数据线,将要传出到下位机了     
  65.                 delay();      
  66.                 scl=1;
  67.                 delay();
  68.   }
  69.   scl=0;//这个语句是为了满足最后一位数据sda传送时时钟信号scl信号跳变的完整性 低-高-低
  70.   delay();
  71.   sda=1;//置1是为了接收应答信号,应答信号sda的引脚会识别低信号
  72.   delay();
  73. }
  74. /***********************************************************************/
  75. //每个字节共有8位数据,要循环8次才能将一个字节的数据读走。
  76. //数据的写入和读走都要保证数据的稳定,
  77. /***********************************************************************/
  78. uchar read_byte()//读一个字节
  79. {
  80.         uchar i,k;
  81.         scl=0;
  82.         delay();
  83.         sda=1;//数据线释放,这个引脚在读数据线时要释放掉(51中默认为高),它的高低要有下位机决定,这样才能读出下位机的数据
  84.         for(i=0;i<8;i++)
  85.         {
  86.                 scl=1;//高线平时才允许读数据       
  87.                 delay();
  88.                 //j=sda;       
  89.                 k=(k<<1)|sda;//每执行这个语句,都会将刚读取的那位(sda)放在k的低位上
  90.                 scl=0;
  91.                 delay();
  92.         }
  93.          return k;
  94. }
  95. void write_add(uchar address,uchar date_)
  96. {   
  97.           start();//起始信号                                                                         此时主机想向众多从机说话。。。
  98.                 write_byte(0xa0);//写器件地址,高四位是1010,接着三位是000;因为是写,所以最后一位也是0    上位机问众多下位机:你们有谁叫0xa0的吗?我要向你发送点数据!   
  99.                 respons();//发完地址和写请求后等待应答                                                     0xa0回答道:真的啊,那快点发过来
  100.                 write_byte(address);//写该器件存储取地址                                                   主机向从机说道:我要向你的address位发东西了哈!are you ok??
  101.                 respons();//等待回应                                                                       从机回答道:准备好啦!(内心一阵窃喜)
  102.                 write_byte(date_);//写数据喽                                                               主机开始写数据了。。。
  103.           respons();                //                                                                      从机向主机说道:谢谢你,我都收到啦,嘻嘻。。。  
  104.                 stop();           //                                                                       此时主机停止发送数据了。。。。                  
  105. }
  106. /*****************************************************/
  107. //主机要向从机读数据
  108. //对比发送和接收数据两个过程不难发现,貌似接收更难一些,是不是索取比给予都要难一些,单片机通信也是????
  109. /*****************************************************/
  110. uchar read_add(uchar address_)
  111. {
  112.           uchar a;
  113.                 start();         //                     此时主机准备向众多下位机说话。。。   
  114.                 write_byte(0xa0);//器件地址             上位机问众多下位机:你们有谁叫0xa0的吗?
  115.                 respons();       //                     下位机向上位机回答道:我是0xa0,你找我有什么事吗?  
  116.                 write_byte(address_);//储存区地址       上位机向0xa0说道:我打算看看你第address_位数据(以000数据为起点啊)。
  117.                 respons();           //                 下位机0xa0回答道:好的,随时恭候。
  118.                
  119.                 start();             //                 此时上位机在开始准备了。。。            
  120.                 write_byte(0xa1);//写器件地址,要读数据  上位机准备好了,然后对下位机说:你可以接收数据了,你把数据发过来吧!
  121.                 respons();       //                     下位机回答道:好的,已发送,请注意查收
  122.                 a=read_byte();//都会来的值赋给P1引脚    此时主机开始接收了。。。
  123.                 stop();        //                       接收完了一个字节的数据,就停下来通信了                    
  124.                 return a;      //                       接着返回到主程序中对接收到的数据进一步处理  
  125.                
  126. }

  127. void main()
  128. {
  129.           init();//数据线,时钟线拉高
  130.     write_add(23,0x00);//物理地址的第23个地址存入数据0x02
  131.                 delay_(100);//该延迟是为了给写入过程、读出过程留足一定的时间,也就是给硬件喘口气
  132.           P1=read_add(23);//将读出的数据输出到引脚
  133.           while(1);//此程序就让它运行一次
  134. }
  135.    
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

评分

参与人数 1 +30 收起 理由
Ansifa + 30

查看全部评分

回复

使用道具 举报

发表于 2015-7-5 20:43:32 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2015-7-6 08:28:56 | 显示全部楼层
看得不是太懂,51没学过....{:soso_e127:}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-7-8 02:07:17 | 显示全部楼层
wing 发表于 2015-7-6 08:28
看得不是太懂,51没学过....

IIC通信在哪种平台协议都一样的,开始、停止、应答、写一个字节、读一个字节、写数据、读数据,好像就这几个函数,51我用的也不多
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-7-8 02:09:10 | 显示全部楼层
wing 发表于 2015-7-6 08:28
看得不是太懂,51没学过....

除了写数据和读数据放在外边,其他基本都是封装在库里的
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 00:19 , Processed in 0.043099 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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