找回密码
 立即注册
查看: 243|回复: 15

求组,GPIO的分组(不知合不合适这样叫?)

[复制链接]
  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2025-06-16 00:00:12
已绑定手机

1

主题

5

回帖

139

积分

注册会员

积分
139
发表于 2025-5-18 14:56:56 | 显示全部楼层 |阅读模式
有个项目,主控STC8H,要用到3个IIC设备,分别是24c08、RX8025t、SC7A20h。
其中:
24c08的SDA=P37,SCL=P36;
RX8025T的SDA=P15,SCL=P14;
SC7A20的SDA=P22,SCL=P21;
在不想复用SDA和SCL的情景下,如何通过结构体来切换不同设备的IIC接口,并配置不同的延时参数,从而共享标准IIC的代码?
目的要让代码简洁可靠,而不要为每一个I2C设备都准备一套代码?
如果后期还有类似的设备,比如BMP180,DTH11,==,也要方便扩展?

请大神们伸手拉菜鸟一把。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9128

积分

超级版主

DebugLab

积分
9128
发表于 2025-5-18 15:12:41 | 显示全部楼层
使用硬件I2C

如多个I2C设备不想接一起,可以接到不同的IO,分时复用,I2C脚位切换寄存器如下:
截图202505181510513709.jpg

I2C底层驱动程序可以复用:
  1. void I2C_Start(void)
  2. {
  3.         I2C_Busy=1;
  4.         I2CMSCR=0x81;
  5.         while(I2C_Busy);
  6. }
  7. void I2C_SendData(unsigned char dat)
  8. {
  9.         I2CTXD=dat;
  10.         I2C_Busy=1;
  11.         I2CMSCR=0x82;
  12.         while(I2C_Busy);
  13. }
  14. void I2C_RecvACK(void)
  15. {
  16.         I2C_Busy=1;
  17.         I2CMSCR=0x83;
  18.         while(I2C_Busy);
  19. }
  20. //unsigned char I2C_RecvData(void)
  21. //{
  22. //        I2C_Busy=1;
  23. //        I2CMSCR=0x84;
  24. //        while(I2C_Busy);
  25. //        return I2CRXD;
  26. //}
  27. //void I2C_SendACK(void)
  28. //{
  29. //        I2CMSST=0x00;
  30. //        I2C_Busy=1;
  31. //        I2CMSCR=0x85;
  32. //        while(I2C_Busy);
  33. //}
  34. //void I2C_SendNAK(void)
  35. //{
  36. //        I2CMSST=0x01;
  37. //        I2C_Busy=1;
  38. //        I2CMSCR=0x85;
  39. //        while(I2C_Busy);
  40. //}
  41. void I2C_Stop(void)
  42. {
  43.         I2C_Busy=1;
  44.         I2CMSCR=0x86;
  45.         while(I2C_Busy);
  46. }
复制代码


DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2025-06-16 00:00:12
已绑定手机

1

主题

5

回帖

139

积分

注册会员

积分
139
发表于 2025-5-18 16:43:26 | 显示全部楼层
Debu*** 发表于 2025-5-18 15:12
使用硬件I2C

如多个I2C设备不想接一起,可以接到不同的IO,分时复用,I2C脚位切换寄存器如下:

硬件切换是个方法,可惜因为IO被 限死,布局原因,调不到一块了。
最好是能能软件模拟IIC,IO可以任意调整。

点评

实验箱例程“AI8051U-DEMO-CODE-V1.2”的“84-USB录放音声卡-TLV320AIC23B-内部36.864M-外接32768Hz晶振”中有软件模拟I2C:  详情 回复 发表于 2025-5-18 18:00
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:99
  • 最近打卡:2025-06-16 09:28:47

733

主题

1万

回帖

1万

积分

管理员

积分
16649
发表于 2025-5-18 17:34:51 | 显示全部楼层
I2C 总线可以挂多个不同的从器件啊/从器件地址不同
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2025-06-16 00:00:12
已绑定手机

1

主题

5

回帖

139

积分

注册会员

积分
139
发表于 2025-5-18 17:43:35 | 显示全部楼层
神*** 发表于 2025-5-18 17:34
I2C 总线可以挂多个不同的从器件啊/从器件地址不同

理论上是这样的,也试过把所有的I2C设备挂在同一BUS上,但一些突发数据在传输过程中,总会出现无法预知的错误

点评

从机较多要减小上拉电阻,如4.7K改2.2K,时钟频率不要超过400K  详情 回复 发表于 2025-5-18 17:46
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9128

积分

超级版主

DebugLab

积分
9128
发表于 2025-5-18 17:46:35 | 显示全部楼层
zhu*** 发表于 2025-5-18 17:43
理论上是这样的,也试过把所有的I2C设备挂在同一BUS上,但一些突发数据在传输过程中,总会出现无法预知的 ...

从机较多要减小上拉电阻,如4.7K改2.2K,时钟频率不要超过400K
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-16 07:06:57
已绑定手机

79

主题

5131

回帖

9128

积分

超级版主

DebugLab

积分
9128
发表于 2025-5-18 18:00:17 | 显示全部楼层
zhu*** 发表于 2025-5-18 16:43
硬件切换是个方法,可惜因为IO被 限死,布局原因,调不到一块了。
最好是能能软件模拟IIC,IO可以任意调 ...

实验箱例程“AI8051U-DEMO-CODE-V1.2”的“84-USB录放音声卡-TLV320AIC23B-内部36.864M-外接32768Hz晶振”中有软件模拟I2C:
  1. sbit        P_AIC23_SCL = P5^1;                //2024-7-21
  2. sbit        P_AIC23_SDA = P5^0;
  3. /****************************/
  4. void        AIC23_Delay(void)
  5. {
  6.         u16        dly;
  7.         dly = 10;                //取1对应SCL H为0.5us,L为1.5us,读写仍正常.为了可靠,取8
  8.         while(--dly)        ;
  9. }
  10. /****************************/
  11. void AIC23_Start(void)               //start the I2C, SDA High-to-low when SCL is high
  12. {
  13.         P_AIC23_SDA = 1;        //SDA = 1;
  14.         AIC23_Delay();
  15.         P_AIC23_SCL = 1;        //SCL = 1;
  16.         AIC23_Delay();
  17.         AIC23_Delay();
  18.         AIC23_Delay();
  19.         AIC23_Delay();
  20.         P_AIC23_SDA = 0;        //SDA = 0;
  21.         AIC23_Delay();
  22.         AIC23_Delay();
  23.         AIC23_Delay();
  24.         P_AIC23_SCL = 0;        //SCL = 0;
  25.         AIC23_Delay();
  26. }
  27. void AIC23_Stop(void)                                        //STOP the I2C, SDA Low-to-high when SCL is high
  28. {
  29.         P_AIC23_SCL = 0;        //SCL = 0;
  30.         AIC23_Delay();
  31.         P_AIC23_SDA = 0;        //SDA = 0;
  32.         AIC23_Delay();
  33.         P_AIC23_SCL = 1;        //SCL = 1;
  34.         AIC23_Delay();
  35.         AIC23_Delay();
  36.         AIC23_Delay();
  37.         P_AIC23_SDA = 1;        //SDA = 1;
  38.         AIC23_Delay();
  39. }
  40. u8 AIC23_Check_ACK(void)         //Check ACK, If status=0: right, if status=1:  error
  41. {
  42.         u8        status;
  43.         P_AIC23_SDA = 1;        //SDA = 1;
  44.         AIC23_Delay();
  45.         P_AIC23_SCL = 1;        //SCL = 1;
  46.         AIC23_Delay();
  47.         status = 0;
  48.         if(P_AIC23_SDA)        status = 1;
  49.         P_AIC23_SCL = 0;        //SCL = 0;
  50.         AIC23_Delay();
  51.         return        status;
  52. }
  53. /****************************/
  54. void AIC23_WriteAbyte(u8 dat)                //write a byte to I2C
  55. {
  56.         u8 i;
  57.         for(i=0; i<8; i++)
  58.         {
  59.                 if(dat & 0x80)        P_AIC23_SDA = 1;        //SDA = 1;
  60.                 else                        P_AIC23_SDA = 0;        //SDA = 0;
  61.                 AIC23_Delay();
  62.                 P_AIC23_SCL = 1;        //SCL = 1;
  63.                 dat <<= 1;
  64.                 AIC23_Delay();
  65.                 P_AIC23_SCL = 0;        //SCL = 0;
  66.                 AIC23_Delay();
  67.         }
  68. }
  69. /****************************/
  70. u8        AIC23_RegWrite(u8 RegAddr, u8 dat)        //返回0: 正确, >0: 错误
  71. {
  72.         u8        status;
  73.         status = 1;
  74.         AIC23_Start();
  75.         AIC23_WriteAbyte(AIC23_WR);                //device address + WR
  76.         if(AIC23_Check_ACK() == 0)
  77.         {
  78.                 AIC23_WriteAbyte(RegAddr);        //register address
  79.                 if(AIC23_Check_ACK() == 0)
  80.                 {
  81.                         AIC23_WriteAbyte(dat);        //data
  82.                         if(AIC23_Check_ACK() == 0)        //data
  83.                                         status = 0;
  84.                 }
  85.         }
  86.         AIC23_Stop();
  87.         return        status;
  88. }
复制代码
TLV320AIC23.c (4.68 KB, 下载次数: 4)

DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:498
  • 最近打卡:2025-06-16 09:44:50
已绑定手机

14

主题

1312

回帖

3298

积分

论坛元老

积分
3298
发表于 2025-5-18 18:05:53 | 显示全部楼层
zhu*** 发表于 2025-5-18 17:43
理论上是这样的,也试过把所有的I2C设备挂在同一BUS上,但一些突发数据在传输过程中,总会出现无法预知的 ...

建议检查、排查“无法预知的错误”,遇到问题就躲避不是学习的一个端正态度。

并且,玩儿单片机的乐趣就在排障,代码一写就OK说实话就真没意思了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2025-06-16 00:00:12
已绑定手机

1

主题

5

回帖

139

积分

注册会员

积分
139
发表于 2025-5-18 19:11:52 | 显示全部楼层
21cns*** 发表于 2025-5-18 18:05
建议检查、排查“无法预知的错误”,遇到问题就躲避不是学习的一个端正态度。

并且,玩儿单片机的乐趣就 ...

说的是,奈何菜鸟功力不足,能想到的问题都查了个遍,什么上下拉电阻、改延时、加滤波、、,(手边就一个28元的玩具级的逻辑分析仪)还是抓不住这个随机的错误,为止卡了快1个月了。。
才想到要拆分总线,拆了之后可以是可以,但总觉得代码不够意思,一组IIc一套代码,啰嗦极了。。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2025-06-16 00:00:12
已绑定手机

1

主题

5

回帖

139

积分

注册会员

积分
139
发表于 2025-5-18 19:14:41 | 显示全部楼层
Debu*** 发表于 2025-5-18 17:46
从机较多要减小上拉电阻,如4.7K改2.2K,时钟频率不要超过400K

是的,上拉改过1K8的,,总线串电阻、并100P电容都试过,速率一度改为250K左右,一样会随机出现
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-16 22:12 , Processed in 0.216936 second(s), 108 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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