找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9424|回復(fù): 6
收起左側(cè)

24c08 I2C總線協(xié)議操作程序匯編和C語言2個版本詳解,終于搞出來了

[復(fù)制鏈接]
ID:83710 發(fā)表于 2015-6-23 20:47 | 顯示全部樓層 |閱讀模式
;24c08操作時序?yàn)椋浩鹗夹盘杝clk拉高情況下sda由高變低,表示起始
;                 結(jié)束信號sclk拉高情況下sda由低變高,表示結(jié)束
;                 字節(jié)由高位向低位依次發(fā)送
;                第一個字節(jié)是地址和讀寫控制,第二個是存儲地址,第三個是數(shù)據(jù),每個數(shù)據(jù)結(jié)束器件都會發(fā)送 ack應(yīng)答信號;
;  I2C 總線協(xié)議
;I2C 總線協(xié)議定義如下
;1 只有在總線空閑時才允許啟動數(shù)據(jù)傳送
;2 在數(shù)據(jù)傳送過程中當(dāng)時鐘線為高電平時數(shù)據(jù)線必須保持穩(wěn)定狀態(tài)不允許有跳變時鐘線
;為高電平時數(shù)據(jù)線的任何電平變化將被看作總線的起始或停止信號
;起始信號
;時鐘線保持高電平期間數(shù)據(jù)線電平從高到低的跳變作為I2C 總線的起始信號
;停止信號
;時鐘線保持高電平期間數(shù)據(jù)線電平從低到高的跳變作為I2C 總線的停止信號
;
ORG 0000H
SCL EQU P2.6
SDA EQU P2.7
AJMP MAIN
ORG 00030H
MAIN:LCALL INIT   ;主函數(shù),
     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  ;應(yīng)答信號
     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 ,相當(dāng)于一個停止信號啊,所以U820受到后把總線禁止了,也難怪寫不出了,哈哈哈又學(xué)一招
     SETB SDA   ;原來這么細(xì)微的變動都會是你的程序白搭,即使你其他的都是對的;
     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:       ;數(shù)據(jù)穩(wěn)定
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單元讀出數(shù)據(jù)
       LCALL WRITE
       LCALL ACK
    LCALL START
    MOV A,#0A1H
    LCALL WRITE
    LCALL ACK
    LCALL READ
    LCALL STOP
    RET
DELAY1:        ;延時1S,在應(yīng)用中這個可以是主程序啊哈哈,真他媽了噶比的爽老子也做出來了;爽啊
    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否則讀不出數(shù)據(jù)
  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. }
復(fù)制代碼





相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:45963 發(fā)表于 2015-6-24 07:45 | 顯示全部樓層
好,贊一個,最起碼不要黑幣。衷心感謝
回復(fù)

使用道具 舉報(bào)

ID:216167 發(fā)表于 2017-7-14 16:28 | 顯示全部樓層
你好,24c08的封裝資料有嗎
回復(fù)

使用道具 舉報(bào)

ID:315669 發(fā)表于 2018-4-24 20:16 | 顯示全部樓層
謝謝分享!我最近在研究一個IC,是I2C接口。
回復(fù)

使用道具 舉報(bào)

ID:315669 發(fā)表于 2018-4-24 20:17 | 顯示全部樓層
謝謝分享!
回復(fù)

使用道具 舉報(bào)

ID:382699 發(fā)表于 2020-10-9 15:41 | 顯示全部樓層
謝謝樓主,我終于調(diào)通了24C08
回復(fù)

使用道具 舉報(bào)

ID:65956 發(fā)表于 2020-10-14 08:55 | 顯示全部樓層
你這個程序只適用于0-0xFF之內(nèi)的讀和寫,如果地址大于0xFF就會從頭寫了,不信你試試,建議再學(xué)習(xí)學(xué)習(xí)修改一下就可實(shí)現(xiàn)大容量的EEPROM的讀寫
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表