久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2024|回復: 11
打印 上一主題 下一主題
收起左側

請問I2C從機單片機接收程序怎么寫?

[復制鏈接]
跳轉到指定樓層
樓主
如題
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:123289 發表于 2022-9-1 17:41 | 只看該作者
仔細再讀I2C通訊原理,芯片手冊。
回復

使用道具 舉報

板凳
ID:624769 發表于 2022-9-1 22:00 | 只看該作者
從機通常是被動觸發型, 大多情況下,你從機是不可能啥是都不干,就用一個 while(SDA); 一直等主機發起始信號過來吧? 通常總要用到系統中斷來等待被觸發吧???
你連個單片機型號都沒有,鬼知道應該用哪個中斷方式來判定主機發送起始信號?
回復

使用道具 舉報

地板
ID:1043477 發表于 2022-9-2 10:40 | 只看該作者
188610329 發表于 2022-9-1 22:00
從機通常是被動觸發型, 大多情況下,你從機是不可能啥是都不干,就用一個 while(SDA); 一直等主機發起始信 ...

這個單片機是已51為基礎開發的型號,名字叫RX8F103 系列是通用型 1T 8051 Core MCU。在同樣的系統時鐘下,指令代碼完全兼容傳統 8051;
回復

使用道具 舉報

5#
ID:1043477 發表于 2022-9-2 10:46 | 只看該作者
yzwzfyz 發表于 2022-9-1 17:41
仔細再讀I2C通訊原理,芯片手冊。

感覺都看麻了
回復

使用道具 舉報

6#
ID:1043477 發表于 2022-9-2 10:47 | 只看該作者
188610329 發表于 2022-9-1 22:00
從機通常是被動觸發型, 大多情況下,你從機是不可能啥是都不干,就用一個 while(SDA); 一直等主機發起始信 ...

我現在寫的程序就是用whlie(),來判斷是否開始
回復

使用道具 舉報

7#
ID:1043608 發表于 2022-9-2 11:58 | 只看該作者
仔細再讀I2C通訊原理,芯片手冊,根據單片機型號來編寫程序
回復

使用道具 舉報

8#
ID:155507 發表于 2022-9-2 12:38 | 只看該作者

RX8F103系列





給你個思路吧 從機想要接收 就需要知道主機的時鐘線 把時鐘線接到外部中斷 進入中斷后讀取數據線 最后把數組組成一個字節
時鐘線時跳變的,最好有個片選CS,將CS腳接到中斷可能更好

網上找來的,可能會有所幫助吧


  1. /****************************************************************/
  2. bit iic_start_decide()    //IIC 開始判斷
  3. {
  4.         while(SCL==0);                   //開始不滿足條件
  5.         while((SCL==1)&&(SDA==1));       //開始條件
  6.         if((SCL==1)&&(SDA==0))           //開始
  7.         {
  8.                 while(SCL==1);               //等待到時鐘開始低跳變
  9.                 return 1;
  10.         }
  11.         else
  12.         return 0;
  13. }

  14. /****************************************************************/
  15. bit iic_stop_decide()            //IIC 結束判斷
  16. {
  17.         while(SCL==0);               //結束不滿足條件
  18.         if((SCL==1)&&(0==SDA))       //結束
  19.         {
  20.                 while(SDA==0);           //等待到數據開始高跳變
  21.                 return 1;
  22.         }
  23.         else
  24.         {
  25.                 return 0;
  26.         }
  27. }
  28. /****************************************************************/
  29. uchar iic_receive()
  30. {
  31.         uchar i;
  32.         uchar rdata='0';

  33.         SDA=1;
  34.         for(i=0;i<8;i++)
  35.         {
  36.                 rdata<<=1;
  37.                 while(SCL==0);        //當時鐘為低時,數據無效,等待
  38.                 if(SDA==1)
  39.                 rdata++;
  40.                 while(SCL==1);        //防止在一個高電平時讀8次
  41.         }
  42.         return (rdata);
  43. }
  44. /****************************************************************/
  45. bit iic_ack_decide()
  46. {
  47.         bit ack_flag;         //局部變量
  48.         SDA=0;                ////8位發送完畢,釋放數據線SDA,準備接收應答位
  49.         while(SCL==0);        //等待SCL變高電平
  50.         //ack_flag=0;
  51.         while(SCL==1);        //等待SCL變高電平
  52.         SDA=1;
  53.         ack_flag=1;
  54.         return(ack_flag);
  55. }

復制代碼




回復

使用道具 舉報

9#
ID:401564 發表于 2022-9-2 16:16 | 只看該作者
感覺這沒什么意義呀,還不如果用Modbus
如果你只是你自己用的,兩個單片機之間的通訊,直接用串口就行了
回復

使用道具 舉報

10#
ID:624769 發表于 2022-9-2 19:31 | 只看該作者
從8樓貼出的資料看, 你這片單片機是支持 硬件 I2C 從機模式的, 因此,不建議你用 軟件來實現, 建議參看該單片機手冊 I2C 從機這個篇章,用硬件來實現, 除了 幾個寄存器需要設置一下,其他都和 串口一主多從的從機側的發送/接收 差不多的流程。也是被觸發后,查驗地址,和自己是否吻合,吻合的話 分析指令,主機是讀,還是寫,寫的話簡單,收取所有主機發出的數據,然后統一處理,是讀的話,把需要給主機的數據準備好,扔一個字節到 I2Cbuf, 等主機讀走后,中斷再次觸發,再扔下一個字節到 I2Cbuf,周而復始。
回復

使用道具 舉報

11#
ID:155507 發表于 2022-9-3 08:31 | 只看該作者
給你個STC8G作為參考。


  1. //STC8G---I2C硬件模式
  2. //從機中斷模式
  3. #include "reg51.h"
  4. #include "intrins.h"

  5. sfr     P_SW2   =   0xba;

  6. #define I2CCFG      (*(unsigned char volatile xdata *)0xfe80)
  7. #define I2CMSCR     (*(unsigned char volatile xdata *)0xfe81)
  8. #define I2CMSST     (*(unsigned char volatile xdata *)0xfe82)
  9. #define I2CSLCR     (*(unsigned char volatile xdata *)0xfe83)
  10. #define I2CSLST     (*(unsigned char volatile xdata *)0xfe84)
  11. #define I2CSLADR    (*(unsigned char volatile xdata *)0xfe85)
  12. #define I2CTXD      (*(unsigned char volatile xdata *)0xfe86)
  13. #define I2CRXD      (*(unsigned char volatile xdata *)0xfe87)

  14. sfr     P1M1    =   0x91;
  15. sfr     P1M0    =   0x92;
  16. sfr     P0M1    =   0x93;
  17. sfr     P0M0    =   0x94;
  18. sfr     P2M1    =   0x95;
  19. sfr     P2M0    =   0x96;
  20. sfr     P3M1    =   0xb1;
  21. sfr     P3M0    =   0xb2;
  22. sfr     P4M1    =   0xb3;
  23. sfr     P4M0    =   0xb4;
  24. sfr     P5M1    =   0xc9;
  25. sfr     P5M0    =   0xca;

  26. sbit    SDA     =   P1^4;
  27. sbit    SCL     =   P1^5;

  28. bit isda;                                       //設備地址標志
  29. bit isma;                                       //存儲地址標志
  30. unsigned char addr;
  31. unsigned char pdata buffer[256];

  32. void I2C_Isr() interrupt 24
  33. {
  34.     _push_(P_SW2);
  35.     P_SW2 |= 0x80;

  36.     if (I2CSLST & 0x40)
  37.     {
  38.         I2CSLST &= ~0x40;                       //處理START事件
  39.     }
  40.     else if (I2CSLST & 0x20)
  41.     {
  42.         I2CSLST &= ~0x20;                       //處理RECV事件
  43.         if (isda)
  44.         {
  45.             isda = 0;                           //處理RECV事件(RECV DEVICE ADDR)
  46.         }
  47.         else if (isma)
  48.         {
  49.             isma = 0;                           //處理RECV事件(RECV MEMORY ADDR)
  50.             addr = I2CRXD;
  51.             I2CTXD = buffer[addr];
  52.         }
  53.         else
  54.         {
  55.             buffer[addr++] = I2CRXD;            //處理RECV事件(RECV DATA)
  56.         }
  57.     }
  58.     else if (I2CSLST & 0x10)
  59.     {
  60.         I2CSLST &= ~0x10;                       //處理SEND事件
  61.         if (I2CSLST & 0x02)
  62.         {
  63.             I2CTXD = 0xff;                      //接收到NAK則停止讀取數據
  64.         }
  65.         else
  66.         {
  67.             I2CTXD = buffer[++addr];            //接收到ACK則繼續讀取數據
  68.         }
  69.     }
  70.     else if (I2CSLST & 0x08)
  71.     {
  72.         I2CSLST &= ~0x08;                       //處理STOP事件
  73.         isda = 1;
  74.         isma = 1;
  75.     }

  76.     _pop_(P_SW2);
  77. }

  78. void main()
  79. {
  80.     P0M0 = 0x00;
  81.     P0M1 = 0x00;
  82.     P1M0 = 0x00;
  83.     P1M1 = 0x00;
  84.     P2M0 = 0x00;
  85.     P2M1 = 0x00;
  86.     P3M0 = 0x00;
  87.     P3M1 = 0x00;
  88.     P4M0 = 0x00;
  89.     P4M1 = 0x00;
  90.     P5M0 = 0x00;
  91.     P5M1 = 0x00;

  92.     P_SW2 = 0x80;

  93.     I2CCFG = 0x81;                              //使能I2C從機模式
  94.     I2CSLADR = 0x5a;                            //設置從機設備地址寄存器I2CSLADR=0101_1010B
  95.                                                 //即I2CSLADR[7:1]=010_1101B,MA=0B。
  96.                                                 //由于MA為0,主機發送的的設備地址必須與
  97.                                                 //I2CSLADR[7:1]相同才能訪問此I2C從機設備。
  98.                                                 //主機若需要寫數據則要發送5AH(0101_1010B)
  99.                                                 //主機若需要讀數據則要發送5BH(0101_1011B)
  100.     I2CSLST = 0x00;
  101.     I2CSLCR = 0x78;                             //使能從機模式中斷
  102.     EA = 1;

  103.     isda = 1;                                   //用戶變量初始化
  104.     isma = 1;
  105.     addr = 0;
  106.     I2CTXD = buffer[addr];

  107.     while (1);
  108. }


  109. //從機模式 查詢方式
  110. #include "reg51.h"
  111. #include "intrins.h"

  112. sfr     P_SW2   =   0xba;

  113. #define I2CCFG      (*(unsigned char volatile xdata *)0xfe80)
  114. #define I2CMSCR     (*(unsigned char volatile xdata *)0xfe81)
  115. #define I2CMSST     (*(unsigned char volatile xdata *)0xfe82)
  116. #define I2CSLCR     (*(unsigned char volatile xdata *)0xfe83)
  117. #define I2CSLST     (*(unsigned char volatile xdata *)0xfe84)
  118. #define I2CSLADR    (*(unsigned char volatile xdata *)0xfe85)
  119. #define I2CTXD      (*(unsigned char volatile xdata *)0xfe86)
  120. #define I2CRXD      (*(unsigned char volatile xdata *)0xfe87)

  121. sfr     P1M1    =   0x91;
  122. sfr     P1M0    =   0x92;
  123. sfr     P0M1    =   0x93;
  124. sfr     P0M0    =   0x94;
  125. sfr     P2M1    =   0x95;
  126. sfr     P2M0    =   0x96;
  127. sfr     P3M1    =   0xb1;
  128. sfr     P3M0    =   0xb2;
  129. sfr     P4M1    =   0xb3;
  130. sfr     P4M0    =   0xb4;
  131. sfr     P5M1    =   0xc9;
  132. sfr     P5M0    =   0xca;

  133. sbit    SDA     =   P1^4;
  134. sbit    SCL     =   P1^5;

  135. bit isda;                                       //設備地址標志
  136. bit isma;                                       //存儲地址標志
  137. unsigned char addr;
  138. unsigned char pdata buffer[256];

  139. void main()
  140. {
  141.     P0M0 = 0x00;
  142.     P0M1 = 0x00;
  143.     P1M0 = 0x00;
  144.     P1M1 = 0x00;
  145.     P2M0 = 0x00;
  146.     P2M1 = 0x00;
  147.     P3M0 = 0x00;
  148.     P3M1 = 0x00;
  149.     P4M0 = 0x00;
  150.     P4M1 = 0x00;
  151.     P5M0 = 0x00;
  152.     P5M1 = 0x00;

  153.     P_SW2 = 0x80;

  154.     I2CCFG = 0x81;                              //使能I2C從機模式
  155.     I2CSLADR = 0x5a;                            //設置從機設備地址寄存器I2CSLADR=0101_1010B
  156.                                                 //即I2CSLADR[7:1]=010_1101B,MA=0B。
  157.                                                 //由于MA為0,主機發送的的設備地址必須與
  158.                                                 //I2CSLADR[7:1]相同才能訪問此I2C從機設備。
  159.                                                 //主機若需要寫數據則要發送5AH(0101_1010B)
  160.                                                 //主機若需要讀數據則要發送5BH(0101_1011B)
  161.     I2CSLST = 0x00;
  162.     I2CSLCR = 0x00;                             //禁止從機模式中斷

  163.     isda = 1;                                   //用戶變量初始化
  164.     isma = 1;
  165.     addr = 0;
  166.     I2CTXD = buffer[addr];

  167.     while (1)
  168.     {
  169.         if (I2CSLST & 0x40)
  170.         {
  171.             I2CSLST &= ~0x40;                   //處理START事件
  172.         }
  173.         else if (I2CSLST & 0x20)
  174.         {
  175.             I2CSLST &= ~0x20;                   //處理RECV事件
  176.             if (isda)
  177.             {
  178.                 isda = 0;                       //處理RECV事件(RECV DEVICE ADDR)
  179.             }
  180.             else if (isma)
  181.             {
  182.                 isma = 0;                       //處理RECV事件(RECV MEMORY ADDR)
  183.                 addr = I2CRXD;
  184.                 I2CTXD = buffer[addr];
  185.             }
  186.             else
  187.             {
  188.                 buffer[addr++] = I2CRXD;        //處理RECV事件(RECV DATA)
  189.             }
  190.         }
  191.         else if (I2CSLST & 0x10)
  192.         {
  193.             I2CSLST &= ~0x10;                   //處理SEND事件
  194.             if (I2CSLST & 0x02)
  195.             {
  196.                 I2CTXD = 0xff;                  //接收到NAK則停止讀取數據
  197.             }
  198.             else
  199.             {
  200.                 I2CTXD = buffer[++addr];        //接收到ACK則繼續讀取數據
  201.             }
  202.         }
  203.         else if (I2CSLST & 0x08)
  204.         {
  205.             I2CSLST &= ~0x08;                   //處理STOP事件
  206.             isda = 1;
  207.             isma = 1;
  208.         }
  209.     }
  210. }

  211. //測試I2C從機模式代碼的主機代碼
  212. #include "reg51.h"
  213. #include "intrins.h"

  214. sfr     P_SW2   =   0xba;

  215. #define I2CCFG      (*(unsigned char volatile xdata *)0xfe80)
  216. #define I2CMSCR     (*(unsigned char volatile xdata *)0xfe81)
  217. #define I2CMSST     (*(unsigned char volatile xdata *)0xfe82)
  218. #define I2CSLCR     (*(unsigned char volatile xdata *)0xfe83)
  219. #define I2CSLST     (*(unsigned char volatile xdata *)0xfe84)
  220. #define I2CSLADR    (*(unsigned char volatile xdata *)0xfe85)
  221. #define I2CTXD      (*(unsigned char volatile xdata *)0xfe86)
  222. #define I2CRXD      (*(unsigned char volatile xdata *)0xfe87)

  223. sfr     P1M1    =   0x91;
  224. sfr     P1M0    =   0x92;
  225. sfr     P0M1    =   0x93;
  226. sfr     P0M0    =   0x94;
  227. sfr     P2M1    =   0x95;
  228. sfr     P2M0    =   0x96;
  229. sfr     P3M1    =   0xb1;
  230. sfr     P3M0    =   0xb2;
  231. sfr     P4M1    =   0xb3;
  232. sfr     P4M0    =   0xb4;
  233. sfr     P5M1    =   0xc9;
  234. sfr     P5M0    =   0xca;

  235. sbit    SDA     =   P1^4;
  236. sbit    SCL     =   P1^5;

  237. void Wait()
  238. {
  239.     while (!(I2CMSST & 0x40));
  240.     I2CMSST &= ~0x40;
  241. }

  242. void Start()
  243. {
  244.     I2CMSCR = 0x01;                             //發送START命令
  245.     Wait();
  246. }

  247. void SendData(char dat)
  248. {
  249.     I2CTXD = dat;                               //寫數據到數據緩沖區
  250.     I2CMSCR = 0x02;                             //發送SEND命令
  251.     Wait();
  252. }

  253. void RecvACK()
  254. {
  255.     I2CMSCR = 0x03;                             //發送讀ACK命令
  256.     Wait();
  257. }

  258. char RecvData()
  259. {
  260.     I2CMSCR = 0x04;                             //發送RECV命令
  261.     Wait();
  262.     return I2CRXD;
  263. }

  264. void SendACK()
  265. {
  266.     I2CMSST = 0x00;                             //設置ACK信號
  267.     I2CMSCR = 0x05;                             //發送ACK命令
  268.     Wait();
  269. }

  270. void SendNAK()
  271. {
  272.     I2CMSST = 0x01;                             //設置NAK信號
  273.     I2CMSCR = 0x05;                             //發送ACK命令
  274.     Wait();
  275. }

  276. void Stop()
  277. {
  278.     I2CMSCR = 0x06;                             //發送STOP命令
  279.     Wait();
  280. }

  281. void Delay()
  282. {
  283.     int i;

  284.     for (i=0; i<3000; i++)
  285.     {
  286.         _nop_();
  287.         _nop_();
  288.         _nop_();
  289.         _nop_();
  290.     }
  291. }

  292. void main()
  293. {
  294.     P0M0 = 0x00;
  295.     P0M1 = 0x00;
  296.     P1M0 = 0x00;
  297.     P1M1 = 0x00;
  298.     P2M0 = 0x00;
  299.     P2M1 = 0x00;
  300.     P3M0 = 0x00;
  301.     P3M1 = 0x00;
  302.     P4M0 = 0x00;
  303.     P4M1 = 0x00;
  304.     P5M0 = 0x00;
  305.     P5M1 = 0x00;

  306.     P_SW2 = 0x80;

  307.     I2CCFG = 0xe0;                              //使能I2C主機模式
  308.     I2CMSST = 0x00;

  309.     Start();                                    //發送起始命令
  310.     SendData(0x5a);                             //發送設備地址(010_1101B)+寫命令(0B)
  311.     RecvACK();
  312.     SendData(0x00);                             //發送存儲地址
  313.     RecvACK();
  314.     SendData(0x12);                             //寫測試數據1
  315.     RecvACK();
  316.     SendData(0x78);                             //寫測試數據2
  317.     RecvACK();
  318.     Stop();                                     //發送停止命令

  319.     Start();                                    //發送起始命令
  320.     SendData(0x5a);                             //發送設備地址(010_1101B)+寫命令(0B)
  321.     RecvACK();
  322.     SendData(0x00);                             //發送存儲地址高字節
  323.     RecvACK();
  324.     Start();                                    //發送起始命令
  325.     SendData(0x5b);                             //發送設備地址(010_1101B)+讀命令(1B)
  326.     RecvACK();
  327.     P0 = RecvData();                            //讀取數據1
  328.     SendACK();
  329.     P2 = RecvData();                            //讀取數據2
  330.     SendNAK();
  331.     Stop();                                     //發送停止命令

  332.     P_SW2 = 0x00;

  333.     while (1);
  334. }


復制代碼



回復

使用道具 舉報

12#
ID:961114 發表于 2022-9-3 11:16 | 只看該作者
本帖最后由 STC莊偉 于 2022-9-5 13:29 編輯


STC-ISP軟件V6.90I版

http://www.stcmcudata.com/STC8F-DATASHEET/STC32G.pdf
回復

使用道具 舉報

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

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产日韩一区 | 欧美日韩久久久久 | 精品一区二区在线观看 | 黄色国产视频 | 日韩欧美在线观看视频网站 | 国产精品久久一区 | 久久精品一级 | 91小视频在线 | 午夜精品 | 一级黄色片毛片 | 黄色高清视频 | 91看片网 | 亚洲1区| 亚洲成人免费在线 | 日韩成人免费视频 | 国产精品 欧美精品 | 日韩欧美成人一区二区三区 | 国产成人精品一区二区三区 | 最新国产精品视频 | 91国内精品久久 | 又爽又黄axxx片免费观看 | 一区二区精品 | 国产亚洲精品久久久久动 | 日本在线黄色 | 成人中文字幕在线观看 | av网站在线播放 | 国产91亚洲精品一区二区三区 | 北条麻妃视频在线观看 | 欧美日产国产成人免费图片 | www.黄网 | 综合成人在线 | 久久专区 | 精品国产一区二区三区久久影院 | 日韩欧美二区 | 国产97碰免费视频 | 久久精品手机视频 | 天天看片天天干 | 黄色在线免费播放 | 久久国产成人精品国产成人亚洲 | 中文字幕在线播放第一页 | 91麻豆精品国产91久久久更新资源速度超快 |