找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8338|回复: 6
收起左侧

24c08 I2C总线协议操作程序汇编和C语言2个版本详解,终于搞出来了

[复制链接]
ID:83710 发表于 2015-6-23 20:47 | 显示全部楼层 |阅读模式
;24c08操作时序为:起始信号sclk拉高情况下sda由高变低,表示起始
;                 结束信号sclk拉高情况下sda由低变高,表示结束
;                 字节由高位向低位依次发送
;                第一个字节是地址和读写控制,第二个是存储地址,第三个是数据,每个数据结束器件都会发送 ack应答信号;
;  I2C 总线协议
;I2C 总线协议定义如下
;1 只有在总线空闲时才允许启动数据传送
;2 在数据传送过程中当时钟线为高电平时数据线必须保持稳定状态不允许有跳变时钟线
;为高电平时数据线的任何电平变化将被看作总线的起始或停止信号
;起始信号
;时钟线保持高电平期间数据线电平从高到低的跳变作为I2C 总线的起始信号
;停止信号
;时钟线保持高电平期间数据线电平从低到高的跳变作为I2C 总线的停止信号
;
ORG 0000H
SCL EQU P2.6
SDA EQU P2.7
AJMP MAIN
ORG 00030H
MAIN:LCALL INIT   ;主函数,
     LCALL WRITE2408
  LCALL DELAY1
  LCALL READ2408
  MOV P0,A
  AJMP $      

INIT: SETB SCL    ;初始化
    LCALL  DELAY
SETB SDA
LCALL DELAY
RET

START:SETB SDA  ;起始信号
     LCALL DELAY
  SETB SCL
  LCALL DELAY
  CLR SDA
  LCALL DELAY
  RET
STOP:CLR SDA ;   停止信号
     LCALL DELAY
  SETB SCL
  LCALL DELAY
  SETB SDA
  RET
ACK:SETB SCL  ;应答信号
     LCALL DELAY
JB SDA,$
     CLR  SCL
LCALL DELAY
SETB SDA
LCALL DELAY
RET
WRITE:     MOV R4,#08H  ;写
     LOOP:  CLR SCL
     LCALL DELAY
     RLC A
     MOV SDA,C
     LCALL DELAY
     SETB SCL
     LCALL DELAY
     DJNZ R4,LOOP
      
    CLR SCL      ;哎呀吃大亏了,我说怎么就是写一个A0算完了而且还有一个停止信号,娘了个逼我程序里不是这样的啊,奥今天我才看透,原来A0的最低位是0
     LCALL DELAY  ;这里以前是先把SDA释放,再拉低SCL ,相当于一个停止信号啊,所以U820受到后把总线禁止了,也难怪写不出了,哈哈哈又学一招
     SETB SDA   ;原来这么细微的变动都会是你的程序白搭,即使你其他的都是对的;
     LCALL DELAY  ;加油;2010年7月22日午与天津宿舍
     RET    ;EEPROM的成功读取时很有意义的,嘿嘿

READ:MOV R4,#08H     ;读
         SETB SDA
   LCALL DELAY
LOP:   CLR SCL
   LCALL DELAY
   SETB SCL
   LCALL DELAY
   MOV C,SDA
   RLC A
   DJNZ R4,LOP
    CLR SCL
    RET
DELAY:       ;数据稳定
NOP
NOP
NOP
NOP
NOP
RET

WRITE2408:LCALL START
       MOV A,#0A0H
    LCALL WRITE
    LCALL ACK    ;向U820的00H单元写0x88;
    MOV A,#00H
    LCALL WRITE
    LCALL ACK
    MOV A,#88H
    LCALL WRITE
    LCALL ACK
    LCALL STOP
   RET
READ2408:LCALL START
          MOV A,#0A0H
    LCALL WRITE
    LCALL ACK
   MOV A,#00H  ;从U820的00H单元读出数据
       LCALL WRITE
       LCALL ACK
    LCALL START
    MOV A,#0A1H
    LCALL WRITE
    LCALL ACK
    LCALL READ
    LCALL STOP
    RET
DELAY1:        ;延时1S,在应用中这个可以是主程序啊哈哈,真他妈了噶比的爽老子也做出来了;爽啊
    MOV R7,#0A7H
DL1:
    MOV R6,#0ABH
DL0:
    MOV R5,#10H
    DJNZ R5,$
    DJNZ R6,DL0
    DJNZ R7,DL1
    NOP
    RET
  END



  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. sbit sda=P2^7;
  4. sbit scl=P2^6;

  5. void delay1(uchar z)
  6. {
  7. uchar j,k;
  8.     for(k=0;k<z;k++)
  9.                      
  10.        {           
  11.                       for(j=0;j<100;j++) ;  //此处j不得小于27否则读不出数据
  12.         
  13.         }        
  14. }
  15. void delay()
  16. {

  17. ;;
  18. }
  19. void init()
  20. {
  21. sda=1;
  22. delay();
  23. scl=1;
  24. delay();
  25. }
  26. void start()
  27. {
  28. sda=1;
  29.   delay();
  30. scl=1;
  31. delay();
  32. sda=0;
  33. delay();
  34. }
  35. void stop()
  36. {
  37. sda=0;
  38. delay();
  39. scl=1;
  40.   delay();
  41.   sda=1;
  42.    delay();

  43. }
  44. void ack()
  45. {
  46. scl=1;
  47.    delay();
  48.   if(sda==1)
  49.   {  delay1(1000);

  50.   }
  51. scl=0;
  52.   delay();
  53. sda=1;
  54. delay();
  55. }
  56. void write_24c08(uchar add)
  57. {
  58. uchar a,i;
  59.       i=add;
  60.     scl=0;
  61.   delay();
  62. for(a=0;a<8;a++)
  63.   {  
  64.   i=i<<1;
  65.   sda=CY;
  66.    delay();
  67.    scl=1;
  68.     delay();
  69.       scl=0;
  70.   delay();
  71. }
  72. scl=0;
  73. delay();
  74. sda=1;
  75. delay();
  76. }
  77. uchar read_24c08()
  78. {
  79.    uchar a,readdate;
  80.     scl=0;
  81.    delay();
  82.   sda=1;
  83.     delay();
  84. for(a=0;a<8;a++)
  85. {

  86.   scl=1;
  87.    delay();  
  88. readdate=(readdate<<1)|sda;  //这里注意啊,不要换成别的
  89. scl=0;
  90.   delay();

  91. }
  92. return readdate;
  93. }


  94. void main()
  95. {
  96. init();
  97. start();
  98. write_24c08(0xa0);
  99. ack();
  100. write_24c08(0x21);
  101. ack();
  102. write_24c08(0xf0);
  103. ack();
  104. stop();

  105.     delay1(100);
  106.   start();
  107. write_24c08(0xa0);
  108. ack();
  109. write_24c08(0x21);
  110. ack();
  111. start();
  112.   write_24c08(0xa1);
  113. ack();
  114. P0=read_24c08();
  115.   stop();
  116. while(1);
  117. }
复制代码





回复

使用道具 举报

ID:45963 发表于 2015-6-24 07:45 | 显示全部楼层
好,赞一个,最起码不要黑币。衷心感谢
回复

使用道具 举报

ID:216167 发表于 2017-7-14 16:28 | 显示全部楼层
你好,24c08的封装资料有吗
回复

使用道具 举报

ID:315669 发表于 2018-4-24 20:16 | 显示全部楼层
谢谢分享!我最近在研究一个IC,是I2C接口。
回复

使用道具 举报

ID:315669 发表于 2018-4-24 20:17 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

ID:382699 发表于 2020-10-9 15:41 | 显示全部楼层
谢谢楼主,我终于调通了24C08
回复

使用道具 举报

ID:65956 发表于 2020-10-14 08:55 | 显示全部楼层
你这个程序只适用于0-0xFF之内的读和写,如果地址大于0xFF就会从头写了,不信你试试,建议再学习学习修改一下就可实现大容量的EEPROM的读写
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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