标题: 怎么用51单片机写一个I2C从机的代码 [打印本页]

作者: gordor    时间: 2021-2-2 15:01
标题: 怎么用51单片机写一个I2C从机的代码
网上的I2C都是主机多然而从机的代码很少而且用软件模拟的更少希望有人发一些有用的资料学习一下

作者: zsyzdx    时间: 2021-2-3 09:43
大部分单片机都是主机吧,什么情况下单片机会作为从机使用呢?
作者: 77599585    时间: 2021-2-3 12:03
给你个思路吧 从机想要接收 就需要知道主机的时钟线 把时钟线接到外部中断 进入中断后读取数据线 最后把数组组成一个字节
作者: 黄youhui    时间: 2021-2-3 13:26
77599585 发表于 2021-2-3 12:03
给你个思路吧 从机想要接收 就需要知道主机的时钟线 把时钟线接到外部中断 进入中断后读取数据线 最后把数 ...

时钟线时跳变的,最好有个片选CS,将CS脚接到中断可能更好

作者: angmall    时间: 2021-2-3 17:38
网上找来的,可能会有所帮助吧

  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. }


复制代码

  1. ;/*------------------------------------------------------------------*/
  2. ;/* --- STC MCU International Limited -------------------------------*/
  3. ;/* --- STC 1T Series MCU Simulate I2C Slave Demo -------------------*/
  4. ;/* --- Mobile: (86)13922805190 -------------------------------------*/
  5. ;/* --- Fax: 86-755-82944243 ----------------------------------------*/
  6. ;/* --- Tel: 86-755-82948412 ----------------------------------------*/
  7. ;/* --- Web: www.STCMCU.com -----------------------------------------*/
  8. ;/* If you want to use the program or the program referenced in the  */
  9. ;/* article, please specify in which data and procedures from STC    */
  10. ;/*------------------------------------------------------------------*/

  11. SCL BIT P1.0
  12. SDA BIT P1.1

  13. ;----------------------------

  14.         ORG 0

  15. RESET:
  16.     SETB SCL
  17.     SETB SDA
  18.    
  19.     CALL I2C_WAITSTART  ;等待起始信号
  20.     CALL I2C_RXBYTE     ;接收地址数据
  21.     CLR C
  22.     CALL I2C_TXACK      ;回应ACK
  23.     SETB C              ;读/写 IDATA[80H - FFH]
  24.     RRC A               ;读/写位->C
  25.     MOV R0,A            ;地址送入R0
  26.     JC READDATA         ;C=1(读) C=0(写)
  27. WRITEDATA:
  28.     CALL I2C_RXBYTE     ;接收数据
  29.     MOV @R0,A           ;写入IDATA
  30.     INC R0              ;地址+1
  31.     CLR C
  32.     CALL I2C_TXACK      ;回应ACK
  33.     CALL I2C_WAITSTOP   ;等待停止信号
  34.     JMP RESET
  35.    
  36. READDATA:
  37.     MOV A,@R0
  38.     INC R0
  39.     CALL I2C_TXBYTE     ;发送IDATA数据
  40.     CALL I2C_RXACK      ;接收ACK
  41.     CALL I2C_WAITSTOP   ;等待停止信号
  42.     JMP RESET

  43. ;----------------------------
  44. ;等待起始信号
  45. ;----------------------------
  46. I2C_WAITSTART:
  47.     JNB SCL,$       ;等待时钟->高
  48.     JB SDA,$        ;等待数据线下降沿
  49.     JB SCL,$        ;等待时钟->低
  50.     RET

  51. ;----------------------------
  52. ;等待结束信号
  53. ;----------------------------
  54. I2C_WAITSTOP:
  55.     JNB SCL,$       ;等待时钟->高
  56.     JNB SDA,$       ;等待数据线上升沿
  57.     RET

  58. ;----------------------------
  59. ;发送ACK/NAK信号
  60. ;----------------------------
  61. I2C_TXACK:
  62.     MOV SDA,C       ;送ACK数据
  63.     JNB SCL,$       ;等待时钟->高
  64.     JB SCL,$        ;等待时钟->低
  65.     SETB SDA        ;发送完成
  66.     RET

  67. ;----------------------------
  68. ;接收ACK/NAK信号
  69. ;----------------------------
  70. I2C_RXACK:
  71.     SETB SDA        ;准备读数据
  72.     JNB SCL,$       ;等待时钟->高
  73.     MOV C,SDA       ;读取ACK信号
  74.     JB SCL,$        ;等待时钟->低
  75.     RET

  76. ;----------------------------
  77. ;接收一字节数据
  78. ;----------------------------
  79. I2C_RXBYTE:
  80.     MOV R7,#8       ;8位计数
  81. RXNEXT:
  82.     JNB SCL,$       ;等待时钟->高
  83.     MOV C,SDA       ;读取数据口
  84.     RLC A           ;保存数据
  85.     JB SCL,$        ;等待时钟->低
  86.     DJNZ R7,RXNEXT  ;收下一位
  87.     RET

  88. ;----------------------------
  89. ;发送一字节数据
  90. ;----------------------------
  91. I2C_TXBYTE:
  92.     MOV R7,#8       ;8位计数
  93. TXNEXT:
  94.     RLC A           ;移出数据位
  95.     MOV SDA,C       ;数据送数据口
  96.     JNB SCL,$       ;等待时钟->高
  97.     JB SCL,$        ;等待时钟->低
  98.     DJNZ R7,TXNEXT  ;送下一位
  99.     RET

  100. ;----------------------------

  101.         END
复制代码


作者: gordor    时间: 2021-2-9 21:07
zsyzdx 发表于 2021-2-3 09:43
大部分单片机都是主机吧,什么情况下单片机会作为从机使用呢?

我现在的项目就是一个主单片机控制一个从的51单片机领导要求用I2C通信我要做的就是那个从的单片机




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1