数码之家

 找回密码
 立即注册
搜索
查看: 3776|回复: 25

软件模拟IIC问题,求大佬帮帮忙!

[复制链接]
发表于 2021-4-7 12:46:22 来自手机浏览器 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我用的是C51单片机,我现在单片机有两个IIC设备,一个在P1.0和P1.1口,另一个在P2.6和P2.7口,我怎么用一个IIC.c分别驱动这两个口的外设啊,两个口同时用sbit定义后,报错,不能用,求大佬指导下小弟,先谢谢了!!!
发表于 2021-4-7 13:08:52 | 显示全部楼层
有一个IIC 不可以吗?IIC总线可以连接多个设备的。
回复 支持 反对

使用道具 举报

发表于 2021-4-7 13:12:23 | 显示全部楼层
i2c可以把所有设备接到相同的接口上, 它们都有各自的地址
回复 支持 反对

使用道具 举报

发表于 2021-4-7 13:39:25 | 显示全部楼层
2个I2C设备(不是相同的设备,相同的设备也可以通过选址实现)可以挂在一条总线上的。不需要2组总线。
I2C设备都有设备地址的,所以一般都用一组总线,先发送地址,等待设备应答,然后再通信。
建议你还是先好好学习一下I2C的实现原理再动手实践。
回复 支持 反对

使用道具 举报

发表于 2021-4-7 13:42:27 | 显示全部楼层
简单做法:再写一个IIC.c驱动另一个IIC
使用面向对象的编程方法:用结构体封装IIC.c的驱动函数,驱动中对于GPIO的操作也换成函数指针的形式。最后针对每一个IIC设备进行接口实例化即可。这样不管有多少个IIC设备,驱动是一样的,只是实例化的硬件接口不同
回复 支持 反对

使用道具 举报

发表于 2021-4-7 13:42:34 | 显示全部楼层
最简单的方法就是飞线联通:lol:
回复 支持 反对

使用道具 举报

发表于 2021-4-7 13:52:25 | 显示全部楼层
你重复定义当然报错了。要定义相对应不同的SCL和SDA。
回复 支持 反对

使用道具 举报

发表于 2021-4-7 16:29:34 | 显示全部楼层
南天音乐 发表于 2021-4-7 13:42
简单做法:再写一个IIC.c驱动另一个IIC
使用面向对象的编程方法:用结构体封装IIC.c的驱动函数,驱动中对于 ...

Keil 支持这样的高级应用吗?我印象中Keil好像只支持标准C,无法用C++的方法。
回复 支持 反对

使用道具 举报

发表于 2021-4-7 20:10:08 | 显示全部楼层
报错,你倒是把错误码上来啊,或者程序
回复 支持 反对

使用道具 举报

发表于 2021-4-7 22:49:59 | 显示全部楼层
本帖最后由 inthsunshine 于 2021-4-7 22:54 编辑
flishmen 发表于 2021-4-7 16:29
Keil 支持这样的高级应用吗?我印象中Keil好像只支持标准C,无法用C++的方法。 ...

这个面向对象毫无关系,只不过把端口/引脚当成函数的参数处理,或者定义成全局变量,函数里直接使用全局变量,原先习惯用宏定义
回复 支持 反对

使用道具 举报

发表于 2021-4-8 09:53:17 | 显示全部楼层
:lol::lol::lol:一个在P1.0和P1.1口,另一个在P2.6和P2.7口
教你一个笨方法:
#define  uchar unsigned char /*宏定义*/
#define  uint  unsigned int
#define  _Nop()  _nop_()        /*定义空指令*/
                                                  /*端口位定义*/

sbit SDA1=P1^0;
sbit SCL1=P1^1;

sbit SDA2=P2^6;
sbit SCL2=P2^7;
bit ack1;          /*应答标志位*/
bit ack2;          /*应答标志位*/
/******以下是两个IIC设备用的分开的IIC模拟代码*******/

  1. <p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">/*******************************************************************
  2.                      起动总线函数              
  3. 函数原型: void  Start_I2c1();
  4. 功能:       启动I2C总线,即发送I2C起始条件.

  5. ********************************************************************/
  6. void Start_I2c1()
  7. {
  8.   SDA1=1;   /*发送起始条件的数据信号*/
  9.   _Nop();
  10.   SCL1=1;
  11.   _Nop();    /*起始条件建立时间大于4.7us,延时*/
  12.   _Nop();
  13.   _Nop();
  14.   _Nop();
  15.   _Nop();   
  16.   SDA1=0;   /*发送起始信号*/
  17.   _Nop();    /* 起始条件锁定时间大于4μs*/
  18.   _Nop();
  19.   _Nop();
  20.   _Nop();
  21.   _Nop();      
  22.   SCL1=0;   /*钳住I2C总线,准备发送或接收数据 */
  23.   _Nop();
  24.   _Nop();
  25. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  26. /*******************************************************************
  27.                       结束总线函数              
  28. 函数原型: void  Stop_I2c()1;
  29. 功能:       结束I2C总线,即发送I2C结束条件.

  30. ********************************************************************/
  31. void Stop_I2c1()
  32. {
  33.   SDA1=0;  /*发送结束条件的数据信号*/
  34.   _Nop();   /*发送结束条件的时钟信号*/
  35.   SCL1=1;  /*结束条件建立时间大于4μs*/
  36.   _Nop();
  37.   _Nop();
  38.   _Nop();
  39.   _Nop();
  40.   _Nop();
  41.   SDA1=1;  /*发送I2C总线结束信号*/
  42.   _Nop();
  43.   _Nop();
  44.   _Nop();
  45.   _Nop();
  46. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  47. /*******************************************************************
  48.                  字节数据传送函数              
  49. 函数原型: void  SendByte(uchar c);
  50. 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  51.      此状态位进行操作.(不应答或非应答都使ack=0 假)   
  52.      发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  53. ********************************************************************/
  54. void  SendByte1(uchar c)
  55. {
  56. uchar BitCnt;

  57. for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
  58.     {
  59.      if((c<<BitCnt)&0x80)SDA1=1;   /*判断发送位*/
  60.        else  SDA1=0;               
  61.      _Nop();
  62.      SCL1=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  63.       _Nop();
  64.       _Nop();               /*保证时钟高电平周期大于4μs*/
  65.       _Nop();
  66.       _Nop();
  67.       _Nop();        
  68.      SCL1=0;
  69.     }
  70.    
  71.     _Nop();
  72.     _Nop();
  73.     SDA1=1;               /*8位发送完后释放数据线,准备接收应答位*/
  74.     _Nop();
  75.     _Nop();  
  76.     SCL1=1;
  77.     _Nop();
  78.     _Nop();
  79.     _Nop();
  80.     if(SDA1==1)ack1=0;   
  81.        else ack1=1;        /*判断是否接收到应答信号*/
  82.     SCL1=0;
  83.     _Nop();
  84.     _Nop();
  85. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  86. /*******************************************************************
  87.                  字节数据传送函数              
  88. 函数原型: uchar  RcvByte1();
  89. 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  90.      发完后请用应答函数。
  91. ********************************************************************/
  92. uchar  RcvByte1()
  93. {
  94.   uchar retc;
  95.   uchar BitCnt;

  96.   retc=0;
  97.   SDA1=1;             /*置数据线为输入方式*/
  98.   for(BitCnt=0;BitCnt<8;BitCnt++)
  99.       {
  100.         _Nop();         
  101.         SCL1=0;       /*置时钟线为低,准备接收数据位*/
  102.         _Nop();
  103.         _Nop();         /*时钟低电平周期大于4.7μs*/
  104.         _Nop();
  105.         _Nop();
  106.         _Nop();
  107.         SCL1=1;       /*置时钟线为高使数据线上数据有效*/
  108.         _Nop();
  109.         _Nop();
  110.         retc=retc<<1;
  111.         if(SDA1==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
  112.         _Nop();
  113.         _Nop();
  114.       }
  115.   SCL1=0;   
  116.   _Nop();
  117.   _Nop();
  118.   return(retc);
  119. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  120. /********************************************************************
  121.                      应答子函数
  122. 原型:  void Ack_I2c1(bit a);

  123. 功能:主控器进行应答信号,(可以是应答或非应答信号)
  124. ********************************************************************/
  125. void Ack_I2c1(bit a)
  126. {

  127.   if(a==0)SDA1=0;     /*在此发出应答或非应答信号 */
  128.         else SDA1=1;
  129.   _Nop();
  130.   _Nop();
  131.   _Nop();     
  132.   SCL1=1;
  133.     _Nop();
  134.     _Nop();              /*时钟低电平周期大于4μs*/
  135.     _Nop();
  136.     _Nop();
  137.     _Nop();
  138. SCL1=0;                /*清时钟线,钳住I2C总线以便继续接收*/
  139.     _Nop();
  140.     _Nop();   
  141. }</p><p>/************************设备2******************************************************************/</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">/*******************************************************************
  142.                      起动总线函数              
  143. 函数原型: void  Start_I2c2();
  144. 功能:       启动I2C总线,即发送I2C起始条件.

  145. ********************************************************************/
  146. void Start_I2c2()
  147. {
  148.   SDA2=1;   /*发送起始条件的数据信号*/
  149.   _Nop();
  150.   SCL2=1;
  151.   _Nop();    /*起始条件建立时间大于4.7us,延时*/
  152.   _Nop();
  153.   _Nop();
  154.   _Nop();
  155.   _Nop();   
  156.   SDA2=0;   /*发送起始信号*/
  157.   _Nop();    /* 起始条件锁定时间大于4μs*/
  158.   _Nop();
  159.   _Nop();
  160.   _Nop();
  161.   _Nop();      
  162.   SCL2=0;   /*钳住I2C总线,准备发送或接收数据 */
  163.   _Nop();
  164.   _Nop();
  165. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  166. /*******************************************************************
  167.                       结束总线函数              
  168. 函数原型: void  Stop_I2c2();
  169. 功能:       结束I2C总线,即发送I2C结束条件.

  170. ********************************************************************/
  171. void Stop_I2c2()
  172. {
  173.   SDA2=0;  /*发送结束条件的数据信号*/
  174.   _Nop();   /*发送结束条件的时钟信号*/
  175.   SCL2=1;  /*结束条件建立时间大于4μs*/
  176.   _Nop();
  177.   _Nop();
  178.   _Nop();
  179.   _Nop();
  180.   _Nop();
  181.   SDA2=1;  /*发送I2C总线结束信号*/
  182.   _Nop();
  183.   _Nop();
  184.   _Nop();
  185.   _Nop();
  186. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  187. /*******************************************************************
  188.                  字节数据传送函数              
  189. 函数原型: void  SendByte2(uchar c);
  190. 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  191.      此状态位进行操作.(不应答或非应答都使ack=0 假)   
  192.      发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  193. ********************************************************************/
  194. void  SendByte2(uchar c)
  195. {
  196. uchar BitCnt;

  197. for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
  198.     {
  199.      if((c<<BitCnt)&0x80)SDA2=1;   /*判断发送位*/
  200.        else  SDA2=0;               
  201.      _Nop();
  202.      SCL2=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  203.       _Nop();
  204.       _Nop();               /*保证时钟高电平周期大于4μs*/
  205.       _Nop();
  206.       _Nop();
  207.       _Nop();        
  208.      SCL2=0;
  209.     }
  210.    
  211.     _Nop();
  212.     _Nop();
  213.     SDA2=1;               /*8位发送完后释放数据线,准备接收应答位*/
  214.     _Nop();
  215.     _Nop();  
  216.     SCL2=1;
  217.     _Nop();
  218.     _Nop();
  219.     _Nop();
  220.     if(SDA2==1)ack2=0;   
  221.        else ack2=1;        /*判断是否接收到应答信号*/
  222.     SCL2=0;
  223.     _Nop();
  224.     _Nop();
  225. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  226. /*******************************************************************
  227.                  字节数据传送函数              
  228. 函数原型: uchar  RcvByte2();
  229. 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  230.      发完后请用应答函数。
  231. ********************************************************************/
  232. uchar  RcvByte()
  233. {
  234.   uchar retc;
  235.   uchar BitCnt;

  236.   retc=0;
  237.   SDA2=1;             /*置数据线为输入方式*/
  238.   for(BitCnt=0;BitCnt<8;BitCnt++)
  239.       {
  240.         _Nop();         
  241.         SCL2=0;       /*置时钟线为低,准备接收数据位*/
  242.         _Nop();
  243.         _Nop();         /*时钟低电平周期大于4.7μs*/
  244.         _Nop();
  245.         _Nop();
  246.         _Nop();
  247.         SCL2=1;       /*置时钟线为高使数据线上数据有效*/
  248.         _Nop();
  249.         _Nop();
  250.         retc=retc<<1;
  251.         if(SDA2==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
  252.         _Nop();
  253.         _Nop();
  254.       }
  255.   SCL2=0;   
  256.   _Nop();
  257.   _Nop();
  258.   return(retc);
  259. }</p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> </p><p style="list-style: none; margin: 0px; padding: 0.5em 0px; color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; font-family: 微软雅黑, 黑体, 宋体; font-size: 18.2px; font-style: normal; font-weight: 400; word-spacing: 0px; white-space: normal; box-sizing: border-box; orphans: 2; widows: 2; background-color: rgb(255, 255, 255); font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
  260. /********************************************************************
  261.                      应答子函数
  262. 原型:  void Ack_I2c2(bit a);

  263. 功能:主控器进行应答信号,(可以是应答或非应答信号)
  264. ********************************************************************/
  265. void Ack_I2c2(bit a)
  266. {

  267.   if(a==0)SDA2=0;     /*在此发出应答或非应答信号 */
  268.         else SDA2=1;
  269.   _Nop();
  270.   _Nop();
  271.   _Nop();     
  272.   SCL2=1;
  273.     _Nop();
  274.     _Nop();              /*时钟低电平周期大于4μs*/
  275.     _Nop();
  276.     _Nop();
  277.     _Nop();
  278. SCL2=0;                /*清时钟线,钳住I2C总线以便继续接收*/
  279.     _Nop();
  280.     _Nop();   
  281. }</p><p>
  282. </p><p> </p>
复制代码
方法虽笨,但是可以帮助你解决当前的问题。单总线挂接多设备的方法,以后再学。先解决有无的问题。

回复 支持 反对

使用道具 举报

发表于 2021-4-8 09:54:03 | 显示全部楼层
本帖最后由 wpppmlah 于 2021-4-8 10:06 编辑

:lol::lol::lol:一个在P1.0和P1.1口,另一个在P2.6和P2.7口
教你一个笨方法:
#define  uchar unsigned char /*宏定义*/
#define  uint  unsigned int
#define  _Nop()  _nop_()        /*定义空指令*/
                                                  /*端口位定义*/

sbit SDA1=P1^0;
sbit SCL1=P1^1;

sbit SDA2=P2^6;
sbit SCL2=P2^7;
bit ack1;          /*应答标志位*/
bit ack2;          /*应答标志位*/
/******以下是两个IIC设备用的分开的IIC模拟代码*******/

  1. <p>/*******************************************************************
  2.                      起动总线函数              
  3. 函数原型: void  Start_I2c1();
  4. 功能:       启动I2C总线,即发送I2C起始条件.

  5. ********************************************************************/
  6. void Start_I2c1()
  7. {
  8.   SDA1=1;   /*发送起始条件的数据信号*/
  9.   _Nop();
  10.   SCL1=1;
  11.   _Nop();    /*起始条件建立时间大于4.7us,延时*/
  12.   _Nop();
  13.   _Nop();
  14.   _Nop();
  15.   _Nop();   
  16.   SDA1=0;   /*发送起始信号*/
  17.   _Nop();    /* 起始条件锁定时间大于4μs*/
  18.   _Nop();
  19.   _Nop();
  20.   _Nop();
  21.   _Nop();      
  22.   SCL1=0;   /*钳住I2C总线,准备发送或接收数据 */
  23.   _Nop();
  24.   _Nop();

  25. /*******************************************************************
  26.                       结束总线函数              
  27. 函数原型: void  Stop_I2c()1;
  28. 功能:       结束I2C总线,即发送I2C结束条件.

  29. ********************************************************************/
  30. void Stop_I2c1()
  31. {
  32.   SDA1=0;  /*发送结束条件的数据信号*/
  33.   _Nop();   /*发送结束条件的时钟信号*/
  34.   SCL1=1;  /*结束条件建立时间大于4μs*/
  35.   _Nop();
  36.   _Nop();
  37.   _Nop();
  38.   _Nop();
  39.   _Nop();
  40.   SDA1=1;  /*发送I2C总线结束信号*/
  41.   _Nop();
  42.   _Nop();
  43.   _Nop();
  44.   _Nop();

  45. /*******************************************************************
  46.                  字节数据传送函数              
  47. 函数原型: void  SendByte(uchar c);
  48. 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  49.      此状态位进行操作.(不应答或非应答都使ack=0 假)   
  50.      发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  51. ********************************************************************/
  52. void  SendByte1(uchar c)
  53. {
  54. uchar BitCnt;

  55. for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
  56.     {
  57.      if((c<<BitCnt)&0x80)SDA1=1;   /*判断发送位*/
  58.        else  SDA1=0;               
  59.      _Nop();
  60.      SCL1=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  61.       _Nop();
  62.       _Nop();               /*保证时钟高电平周期大于4μs*/
  63.       _Nop();
  64.       _Nop();
  65.       _Nop();        
  66.      SCL1=0;
  67.     }
  68.    
  69.     _Nop();
  70.     _Nop();
  71.     SDA1=1;               /*8位发送完后释放数据线,准备接收应答位*/
  72.     _Nop();
  73.     _Nop();  
  74.     SCL1=1;
  75.     _Nop();
  76.     _Nop();
  77.     _Nop();
  78.     if(SDA1==1)ack1=0;   
  79.        else ack1=1;        /*判断是否接收到应答信号*/
  80.     SCL1=0;
  81.     _Nop();
  82.     _Nop();

  83. /*******************************************************************
  84.                  字节数据传送函数              
  85. 函数原型: uchar  RcvByte1();
  86. 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  87.      发完后请用应答函数。
  88. ********************************************************************/
  89. uchar  RcvByte1()
  90. {
  91.   uchar retc;
  92.   uchar BitCnt;

  93.   retc=0;
  94.   SDA1=1;             /*置数据线为输入方式*/
  95.   for(BitCnt=0;BitCnt<8;BitCnt++)
  96.       {
  97.         _Nop();         
  98.         SCL1=0;       /*置时钟线为低,准备接收数据位*/
  99.         _Nop();
  100.         _Nop();         /*时钟低电平周期大于4.7μs*/
  101.         _Nop();
  102.         _Nop();
  103.         _Nop();
  104.         SCL1=1;       /*置时钟线为高使数据线上数据有效*/
  105.         _Nop();
  106.         _Nop();
  107.         retc=retc<<1;
  108.         if(SDA1==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
  109.         _Nop();
  110.         _Nop();
  111.       }
  112.   SCL1=0;   
  113.   _Nop();
  114.   _Nop();
  115.   return(retc);

  116. /********************************************************************
  117.                      应答子函数
  118. 原型:  void Ack_I2c1(bit a);

  119. 功能:主控器进行应答信号,(可以是应答或非应答信号)
  120. ********************************************************************/
  121. void Ack_I2c1(bit a)
  122. {

  123.   if(a==0)SDA1=0;     /*在此发出应答或非应答信号 */
  124.         else SDA1=1;
  125.   _Nop();
  126.   _Nop();
  127.   _Nop();     
  128.   SCL1=1;
  129.     _Nop();
  130.     _Nop();              /*时钟低电平周期大于4μs*/
  131.     _Nop();
  132.     _Nop();
  133.     _Nop();
  134. SCL1=0;                /*清时钟线,钳住I2C总线以便继续接收*/
  135.     _Nop();
  136.     _Nop();   
  137. }</p><p>/************************设备2**********************************************************/</p><p>/*******************************************************************
  138.                      起动总线函数              
  139. 函数原型: void  Start_I2c2();
  140. 功能:       启动I2C总线,即发送I2C起始条件.

  141. ********************************************************************/
  142. void Start_I2c2()
  143. {
  144.   SDA2=1;   /*发送起始条件的数据信号*/
  145.   _Nop();
  146.   SCL2=1;
  147.   _Nop();    /*起始条件建立时间大于4.7us,延时*/
  148.   _Nop();
  149.   _Nop();
  150.   _Nop();
  151.   _Nop();   
  152.   SDA2=0;   /*发送起始信号*/
  153.   _Nop();    /* 起始条件锁定时间大于4μs*/
  154.   _Nop();
  155.   _Nop();
  156.   _Nop();
  157.   _Nop();      
  158.   SCL2=0;   /*钳住I2C总线,准备发送或接收数据 */
  159.   _Nop();
  160.   _Nop();

  161. /*******************************************************************
  162.                       结束总线函数              
  163. 函数原型: void  Stop_I2c2();
  164. 功能:       结束I2C总线,即发送I2C结束条件.

  165. ********************************************************************/
  166. void Stop_I2c2()
  167. {
  168.   SDA2=0;  /*发送结束条件的数据信号*/
  169.   _Nop();   /*发送结束条件的时钟信号*/
  170.   SCL2=1;  /*结束条件建立时间大于4μs*/
  171.   _Nop();
  172.   _Nop();
  173.   _Nop();
  174.   _Nop();
  175.   _Nop();
  176.   SDA2=1;  /*发送I2C总线结束信号*/
  177.   _Nop();
  178.   _Nop();
  179.   _Nop();
  180.   _Nop();

  181. /*******************************************************************
  182.                  字节数据传送函数              
  183. 函数原型: void  SendByte2(uchar c);
  184. 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  185.      此状态位进行操作.(不应答或非应答都使ack=0 假)   
  186.      发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  187. ********************************************************************/
  188. void  SendByte2(uchar c)
  189. {
  190. uchar BitCnt;

  191. for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
  192.     {
  193.      if((c<<BitCnt)&0x80)SDA2=1;   /*判断发送位*/
  194.        else  SDA2=0;               
  195.      _Nop();
  196.      SCL2=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  197.       _Nop();
  198.       _Nop();               /*保证时钟高电平周期大于4μs*/
  199.       _Nop();
  200.       _Nop();
  201.       _Nop();        
  202.      SCL2=0;
  203.     }
  204.    
  205.     _Nop();
  206.     _Nop();
  207.     SDA2=1;               /*8位发送完后释放数据线,准备接收应答位*/
  208.     _Nop();
  209.     _Nop();  
  210.     SCL2=1;
  211.     _Nop();
  212.     _Nop();
  213.     _Nop();
  214.     if(SDA2==1)ack2=0;   
  215.        else ack2=1;        /*判断是否接收到应答信号*/
  216.     SCL2=0;
  217.     _Nop();
  218.     _Nop();
  219. }
  220. /*******************************************************************
  221.                  字节数据传送函数              
  222. 函数原型: uchar  RcvByte2();
  223. 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  224.      发完后请用应答函数。
  225. ********************************************************************/
  226. uchar  RcvByte()
  227. {
  228.   uchar retc;
  229.   uchar BitCnt;

  230.   retc=0;
  231.   SDA2=1;             /*置数据线为输入方式*/
  232.   for(BitCnt=0;BitCnt<8;BitCnt++)
  233.       {
  234.         _Nop();         
  235.         SCL2=0;       /*置时钟线为低,准备接收数据位*/
  236.         _Nop();
  237.         _Nop();         /*时钟低电平周期大于4.7μs*/
  238.         _Nop();
  239.         _Nop();
  240.         _Nop();
  241.         SCL2=1;       /*置时钟线为高使数据线上数据有效*/
  242.         _Nop();
  243.         _Nop();
  244.         retc=retc<<1;
  245.         if(SDA2==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
  246.         _Nop();
  247.         _Nop();
  248.       }
  249.   SCL2=0;   
  250.   _Nop();
  251.   _Nop();
  252.   return(retc);
  253. }
  254. /********************************************************************
  255.                      应答子函数
  256. 原型:  void Ack_I2c2(bit a);

  257. 功能:主控器进行应答信号,(可以是应答或非应答信号)
  258. ********************************************************************/
  259. void Ack_I2c2(bit a)
  260. {

  261.   if(a==0)SDA2=0;     /*在此发出应答或非应答信号 */
  262.         else SDA2=1;
  263.   _Nop();
  264.   _Nop();
  265.   _Nop();     
  266.   SCL2=1;
  267.     _Nop();
  268.     _Nop();              /*时钟低电平周期大于4μs*/
  269.     _Nop();
  270.     _Nop();
  271.     _Nop();
  272. SCL2=0;                /*清时钟线,钳住I2C总线以便继续接收*/
  273.     _Nop();
  274.     _Nop();   
  275. }</p><p>
  276. </p><p> </p></p>
复制代码
方法虽笨,但是可以帮助你解决当前的问题。单总线挂接多设备的方法,以后再学。先解决有无的问题。

回复 支持 反对

使用道具 举报

发表于 2021-4-8 10:32:55 来自手机浏览器 | 显示全部楼层
楼上大佬…居然让我看明白了:praise:
回复 支持 反对

使用道具 举报

发表于 2021-4-8 10:59:22 | 显示全部楼层
建议不添加新的IIC代码,而是将两路合成为一路,根据器件地址分别控制就可以了,这样整体代码也简洁明了。
回复 支持 反对

使用道具 举报

发表于 2021-4-8 12:39:47 来自手机浏览器 | 显示全部楼层
在iic.c里面 建一个 初始化函数 切换设备的时候 调用初始化函数 切换引脚 其他函数就可以共用了
回复 支持 反对

使用道具 举报

发表于 2021-4-9 08:47:56 | 显示全部楼层
inthsunshine 发表于 2021-4-7 22:49
这个面向对象毫无关系,只不过把端口/引脚当成函数的参数处理,或者定义成全局变量,函数里直接使用全局变 ...

你这个还是传统的编程思想,还没领悟到什么是面向对象的方法:titter:
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-11 13:36:58 来自手机浏览器 | 显示全部楼层
flishmen 发表于 2021-4-7 13:08
有一个IIC 不可以吗?IIC总线可以连接多个设备的。

电路板固定了没法子啊!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-11 13:38:02 来自手机浏览器 | 显示全部楼层
o535913 发表于 2021-4-7 13:12
i2c可以把所有设备接到相同的接口上, 它们都有各自的地址

嗯嗯,不过线路板定型了!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-11 13:38:46 来自手机浏览器 | 显示全部楼层
jjbboox 发表于 2021-4-7 13:39
2个I2C设备(不是相同的设备,相同的设备也可以通过选址实现)可以挂在一条总线上的。不需要2组总线。
I2C ...

嗯嗯,线路板是别人的,只能这么想法子!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-11 13:39:46 来自手机浏览器 | 显示全部楼层
南天音乐 发表于 2021-4-7 13:42
简单做法:再写一个IIC.c驱动另一个IIC
使用面向对象的编程方法:用结构体封装IIC.c的驱动函数,驱动中对于 ...

大佬,有具体代码吗?我学习下!
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-6-7 02:11 , Processed in 0.202800 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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