免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1272 | 回复: 0

简单的I2C总线传输例子 [复制链接]

论坛徽章:
0
发表于 2011-12-23 01:27 |显示全部楼层

说明:进行I2C传输,时候在读和写时1个字节需要start write/read stop

start在保持SCL为高,变化SDA为低
stop相反。
在write时,先置SCL为0,然后变化sda然后置SCL为1,另外一端感知到电压变化即存了1bit,连续传8位。
在read时,先设置为读操作,然后将SCL置为0,读取1个bit,然后将SCL置1,对方发送第2bit,如此连续8位。


  1. #include <REG52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. sbit scl=P1^5; //24c08 SCL
  6. sbit sda=P3^6; //24c08 SDA

  7. uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  8. uchar sec; //定义计数值,每过1秒,sec加1
  9. uint write;        //写标志位
  10. void flash(void)
  11. {
  12.     _nop_();
  13.     _nop_();
  14. }//延迟2us

  15. void x24c02_init(void)
  16. {
  17.     scl = 1;
  18.     flash();
  19.     sda = 1;
  20.     flash();
  21. }

  22. void start(void)
  23. {
  24.     scl = 1;
  25.     flash();
  26.     sda = 1;
  27.     flash();
  28.     sda = 0;
  29.     flash();
  30.     scl = 0;
  31.     flash();
  32. }

  33. void stop()
  34. {
  35.     scl = 0;
  36.     flash();
  37.     sda = 0;
  38.     flash();
  39.     scl = 1;
  40.     flash();
  41.     sda = 1;
  42.     flash();
  43. }

  44. void writex(uchar j)
  45. {
  46.     uchar i,temp;
  47.     temp = j;
  48.     for(i=0; i<8; i++)
  49.     {
  50.         scl = 0;
  51.         flash();
  52.         sda = (bit)(temp & 0x80);
  53.         flash();
  54.         scl = 1;
  55.         flash();
  56.         temp = temp << 1;
  57.     }
  58.     scl = 0;
  59.     flash();
  60. }

  61. uchar readx(void)
  62. {
  63.     uchar i, j, k = 0;
  64.     for(i=0; i<8; i++)
  65.     {
  66.         scl = 0;
  67.         flash();        
  68.         if(sda == 1)
  69.         {
  70.             j = 1;
  71.         }
  72.         else j = 0;
  73.         k = (k << 1) | j;
  74.         scl = 1;
  75.         flash();
  76.     }
  77.     return(k);
  78. }

  79. void ack(void)
  80. {
  81.     uchar i = 0;
  82.     scl = 1;
  83.     flash();
  84.     while((sda == 1) && (i < 255))//保持scl高电平,等待如果高电平一直等,知道sda低电平或超时
  85.     {
  86.         i++;
  87.     }
  88.     scl = 0;
  89.     flash();
  90. }

  91. uchar x24c02_read(uchar address)//先写从设备地址,然后写读写byte地址
  92. {
  93.     uchar i;
  94.     start();
  95.     writex(0xa0);
  96.     ack();
  97.     writex(address);
  98.     ack();
  99.     start();
  100.     writex(0xa1);
  101.     ack();
  102.     i = readx();
  103.     stop();
  104.     return(i);
  105. }

  106. void x24c02_write(uchar address, uchar info)
  107. {
  108.     start();
  109.     writex(0xa0);
  110.     ack();
  111.     writex(address);
  112.     ack();
  113.     writex(info);
  114.     ack();
  115.     stop();
  116. }
  117. void Delay_1ms(uint i)
  118. {
  119.     uchar x, j;
  120.     for(j=0; j<i; j++)
  121.     for(x=0; x<=148; x++)
  122.     ;    
  123. }

  124. void LED() //LED显示函数
  125. {
  126.     P2 = 6;
  127.     P0 = table[sec / 10];
  128.     Delay_1ms(5);
  129.     P2 = 7;
  130.     P0 = table[sec % 10];
  131.     Delay_1ms(5);
  132. }
  133. void time0(void) interrupt 1 using 3 //定时中断服务函数
  134. {
  135.     static uchar Count = 0;
  136.     TH0 = 0x4c; //对TH0 TL0赋值
  137.     TL0 = 0x00; //重装计数初值
  138.     Count++;
  139.     if(Count == 20) //计满20次(1秒)时
  140.     {
  141.         Count = 0; //重新再计
  142.         sec++;
  143.         write = 1; //1秒写一次24C08
  144.         if(sec == 100) //定时100秒,在从零开始计时
  145.         {
  146.             sec = 0;
  147.         }
  148.     }
  149. }

  150. void Time0_Init(void)
  151. {
  152.     TMOD = 0x01;             //定时器工作在方式1
  153.     ET0 = 1;
  154.     EA = 1;
  155.     TH0 = 0x4c;     //对TH0 TL0赋值
  156.     TL0 = 0x00;     //使定时器0.05秒中断一次
  157.     TR0 = 1;                 //开始计时
  158. }

  159. void Main(void)
  160. {
  161.     x24c02_init();     //初始化24C02
  162.     sec = x24c02_read(2);    //读出保存的数据赋于sec    
  163.     Time0_Init();
  164.     while(1)
  165.     {
  166.          LED();
  167.         if(write == 1)              //判断计时器是否计时一秒
  168.         {
  169.             write =0; //清零
  170.             x24c02_write(2,sec); //在24c08的地址2中写入数据sec
  171.         }
  172.     }
  173. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP