找回密码
 立即注册
楼主: zhuls

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

[复制链接]
  • 打卡等级:偶尔看看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左右,一样会随机出现
回复 支持 反对

使用道具 举报 送花

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

1

主题

5

回帖

139

积分

注册会员

积分
139
发表于 2025-5-18 19:16:19 | 显示全部楼层
Debu*** 发表于 2025-5-18 18:00
实验箱例程“AI8051U-DEMO-CODE-V1.2”的“84-USB录放音声卡-TLV320AIC23B-内部36.864M-外接32768Hz晶振 ...

谢谢!我的代码分拆后,各驱各的没有题。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:208
  • 最近打卡:2025-06-16 08:41:37
已绑定手机

67

主题

1913

回帖

4297

积分

荣誉版主

无情的代码机器

积分
4297
发表于 2025-5-18 19:58:17 | 显示全部楼层
这个需求扔给Ai,代码已经写的大差不差了,是这个意思不:

  1. #ifndef I2C_MANAGER_H
  2. #define I2C_MANAGER_H
  3. #include <stdint.h>
  4. #include <stdbool.h>
  5. // I2C引脚操作函数指针类型定义
  6. typedef void (*I2CPinSetFunc)(bool state);
  7. typedef bool (*I2CPinGetFunc)(void);
  8. typedef void (*I2CDelayFunc)(uint32_t us);
  9. // I2C设备配置结构体
  10. typedef struct {
  11.     I2CPinSetFunc sda_set;     // SDA引脚设置函数
  12.     I2CPinGetFunc sda_get;     // SDA引脚读取函数
  13.     I2CPinSetFunc scl_set;     // SCL引脚设置函数
  14.     I2CDelayFunc delay_us;     // 延时函数
  15.     uint32_t delay_base;       // 基础延时参数
  16. } I2CDeviceConfig;
  17. // I2C设备句柄
  18. typedef struct {
  19.     I2CDeviceConfig* config;   // 设备配置
  20.     uint8_t device_addr;       // 设备地址
  21. } I2CDeviceHandle;
  22. // 初始化I2C设备配置
  23. void I2C_InitDeviceConfig(I2CDeviceConfig* config,
  24.                          I2CPinSetFunc sda_set, I2CPinGetFunc sda_get,
  25.                          I2CPinSetFunc scl_set, I2CDelayFunc delay_us,
  26.                          uint32_t delay_base);
  27. // 初始化I2C设备句柄
  28. void I2C_InitDeviceHandle(I2CDeviceHandle* handle,
  29.                          I2CDeviceConfig* config, uint8_t device_addr);
  30. // I2C起始信号
  31. void I2C_Start(I2CDeviceHandle* handle);
  32. // I2C停止信号
  33. void I2C_Stop(I2CDeviceHandle* handle);
  34. // 发送一个字节
  35. bool I2C_WriteByte(I2CDeviceHandle* handle, uint8_t data);
  36. // 读取一个字节
  37. uint8_t I2C_ReadByte(I2CDeviceHandle* handle, bool ack);
  38. // 延时函数
  39. void I2C_Delay(I2CDeviceHandle* handle, uint32_t factor);
  40. #endif // I2C_MANAGER_H   
复制代码
  1. #include "i2c_manager.h"
  2. #include "STC8H.h"  // 根据实际芯片型号调整头文件
  3. // 初始化I2C设备配置
  4. void I2C_InitDeviceConfig(I2CDeviceConfig* config,
  5.                          I2CPinSetFunc sda_set, I2CPinGetFunc sda_get,
  6.                          I2CPinSetFunc scl_set, I2CDelayFunc delay_us,
  7.                          uint32_t delay_base) {
  8.     config->sda_set = sda_set;
  9.     config->sda_get = sda_get;
  10.     config->scl_set = scl_set;
  11.     config->delay_us = delay_us;
  12.     config->delay_base = delay_base;
  13. }
  14. // 初始化I2C设备句柄
  15. void I2C_InitDeviceHandle(I2CDeviceHandle* handle,
  16.                          I2CDeviceConfig* config, uint8_t device_addr) {
  17.     handle->config = config;
  18.     handle->device_addr = device_addr;
  19. }
  20. // I2C延时函数
  21. void I2C_Delay(I2CDeviceHandle* handle, uint32_t factor) {
  22.     handle->config->delay_us(handle->config->delay_base * factor);
  23. }
  24. // I2C起始信号
  25. void I2C_Start(I2CDeviceHandle* handle) {
  26.     handle->config->sda_set(1);
  27.     handle->config->scl_set(1);
  28.     I2C_Delay(handle, 4);
  29.     handle->config->sda_set(0);
  30.     I2C_Delay(handle, 4);
  31.     handle->config->scl_set(0);
  32. }
  33. // I2C停止信号
  34. void I2C_Stop(I2CDeviceHandle* handle) {
  35.     handle->config->sda_set(0);
  36.     handle->config->scl_set(1);
  37.     I2C_Delay(handle, 4);
  38.     handle->config->sda_set(1);
  39.     I2C_Delay(handle, 4);
  40. }
  41. // 发送一个字节
  42. bool I2C_WriteByte(I2CDeviceHandle* handle, uint8_t data) {
  43.     uint8_t i;
  44.     bool ack;
  45.    
  46.     for (i = 0; i < 8; i++) {
  47.         handle->config->sda_set((data & 0x80) != 0);
  48.         data <<= 1;
  49.         I2C_Delay(handle, 2);
  50.         handle->config->scl_set(1);
  51.         I2C_Delay(handle, 4);
  52.         handle->config->scl_set(0);
  53.         I2C_Delay(handle, 2);
  54.     }
  55.    
  56.     // 接收ACK
  57.     handle->config->sda_set(1);
  58.     I2C_Delay(handle, 2);
  59.     handle->config->scl_set(1);
  60.     I2C_Delay(handle, 2);
  61.     ack = handle->config->sda_get();
  62.     handle->config->scl_set(0);
  63.     I2C_Delay(handle, 2);
  64.    
  65.     return !ack; // 返回ACK状态,0表示成功
  66. }
  67. // 读取一个字节
  68. uint8_t I2C_ReadByte(I2CDeviceHandle* handle, bool ack) {
  69.     uint8_t i, data = 0;
  70.    
  71.     handle->config->sda_set(1);
  72.    
  73.     for (i = 0; i < 8; i++) {
  74.         data <<= 1;
  75.         I2C_Delay(handle, 2);
  76.         handle->config->scl_set(1);
  77.         I2C_Delay(handle, 2);
  78.         if (handle->config->sda_get()) {
  79.             data |= 0x01;
  80.         }
  81.         handle->config->scl_set(0);
  82.     }
  83.    
  84.     // 发送ACK/NACK
  85.     handle->config->sda_set(!ack);
  86.     I2C_Delay(handle, 2);
  87.     handle->config->scl_set(1);
  88.     I2C_Delay(handle, 4);
  89.     handle->config->scl_set(0);
  90.     I2C_Delay(handle, 2);
  91.    
  92.     return data;
  93. }   
复制代码
  1. #include "i2c_manager.h"
  2. #include "STC8H.h"  // 根据实际芯片型号调整头文件
  3. // 引脚操作函数实现
  4. // 24c08 (P37:SDA, P36:SCL)
  5. static void I2C_24C08_SDA_Set(bool state) { P37 = state; }
  6. static bool I2C_24C08_SDA_Get(void) { return P37; }
  7. static void I2C_24C08_SCL_Set(bool state) { P36 = state; }
  8. // RX8025T (P15:SDA, P14:SCL)
  9. static void I2C_RX8025T_SDA_Set(bool state) { P15 = state; }
  10. static bool I2C_RX8025T_SDA_Get(void) { return P15; }
  11. static void I2C_RX8025T_SCL_Set(bool state) { P14 = state; }
  12. // SC7A20 (P22:SDA, P21:SCL)
  13. static void I2C_SC7A20_SDA_Set(bool state) { P22 = state; }
  14. static bool I2C_SC7A20_SDA_Get(void) { return P22; }
  15. static void I2C_SC7A20_SCL_Set(bool state) { P21 = state; }
  16. // 延时函数
  17. static void I2C_Delay_Us(uint32_t us) {
  18.     // 根据实际系统时钟实现延时
  19.     // 这里简化处理,实际应用中需要根据系统时钟频率进行精确延时
  20.     while(us--);
  21. }
  22. // 设备配置和句柄
  23. static I2CDeviceConfig i2c_24c08_config;
  24. static I2CDeviceConfig i2c_rx8025t_config;
  25. static I2CDeviceConfig i2c_sc7a20_config;
  26. static I2CDeviceHandle i2c_24c08_handle;
  27. static I2CDeviceHandle i2c_rx8025t_handle;
  28. static I2CDeviceHandle i2c_sc7a20_handle;
  29. // 引脚初始化
  30. void Init_GPIO(void) {
  31.     // 配置为开漏输出
  32.     P3M1 |= 0xC0;  // P36,P37开漏
  33.     P3M0 &= 0x3F;
  34.    
  35.     P1M1 |= 0x30;  // P14,P15开漏
  36.     P1M0 &= 0xCF;
  37.    
  38.     P2M1 |= 0x06;  // P21,P22开漏
  39.     P2M0 &= 0xF9;
  40. }
  41. // I2C设备初始化
  42. void Init_I2C_Devices(void) {
  43.     // 初始化24c08配置
  44.     I2C_InitDeviceConfig(&i2c_24c08_config,
  45.                        I2C_24C08_SDA_Set, I2C_24C08_SDA_Get,
  46.                        I2C_24C08_SCL_Set, I2C_Delay_Us, 5);
  47.                        
  48.     // 初始化RX8025T配置
  49.     I2C_InitDeviceConfig(&i2c_rx8025t_config,
  50.                        I2C_RX8025T_SDA_Set, I2C_RX8025T_SDA_Get,
  51.                        I2C_RX8025T_SCL_Set, I2C_Delay_Us, 10);
  52.                        
  53.     // 初始化SC7A20配置
  54.     I2C_InitDeviceConfig(&i2c_sc7a20_config,
  55.                        I2C_SC7A20_SDA_Set, I2C_SC7A20_SDA_Get,
  56.                        I2C_SC7A20_SCL_Set, I2C_Delay_Us, 8);
  57.    
  58.     // 初始化设备句柄
  59.     I2C_InitDeviceHandle(&i2c_24c08_handle, &i2c_24c08_config, 0xA0);
  60.     I2C_InitDeviceHandle(&i2c_rx8025t_handle, &i2c_rx8025t_config, 0xDE);
  61.     I2C_InitDeviceHandle(&i2c_sc7a20_handle, &i2c_sc7a20_config, 0x30);
  62. }
  63. // 24c08读写示例
  64. void EEPROM_WriteByte(uint8_t addr, uint8_t data) {
  65.     I2C_Start(&i2c_24c08_handle);
  66.     I2C_WriteByte(&i2c_24c08_handle, i2c_24c08_handle.device_addr);
  67.     I2C_WriteByte(&i2c_24c08_handle, addr);
  68.     I2C_WriteByte(&i2c_24c08_handle, data);
  69.     I2C_Stop(&i2c_24c08_handle);
  70. }
  71. uint8_t EEPROM_ReadByte(uint8_t addr) {
  72.     uint8_t data;
  73.    
  74.     I2C_Start(&i2c_24c08_handle);
  75.     I2C_WriteByte(&i2c_24c08_handle, i2c_24c08_handle.device_addr);
  76.     I2C_WriteByte(&i2c_24c08_handle, addr);
  77.    
  78.     I2C_Start(&i2c_24c08_handle);
  79.     I2C_WriteByte(&i2c_24c08_handle, i2c_24c08_handle.device_addr | 0x01);
  80.     data = I2C_ReadByte(&i2c_24c08_handle, false);
  81.     I2C_Stop(&i2c_24c08_handle);
  82.    
  83.     return data;
  84. }
  85. // 主函数
  86. void main(void) {
  87.     Init_GPIO();
  88.     Init_I2C_Devices();
  89.    
  90.     // 示例:向24c08写入数据并读取
  91.     EEPROM_WriteByte(0x00, 0x55);
  92.    
  93.     while(1) {
  94.         // 主循环
  95.     }
  96. }   
复制代码


三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

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

14

主题

1312

回帖

3298

积分

论坛元老

积分
3298
发表于 2025-5-19 08:42:43 | 显示全部楼层
zhu*** 发表于 2025-5-18 19:11
说的是,奈何菜鸟功力不足,能想到的问题都查了个遍,什么上下拉电阻、改延时、加滤波、、,(手边就一个 ...

电路图和代码发上来,让大家一起帮忙找茬
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:462
  • 最近打卡:2025-06-16 10:02:39

33

主题

2447

回帖

5168

积分

论坛元老

积分
5168
发表于 2025-5-19 10:44:33 | 显示全部楼层
一个思路是把用到的引脚传入软件IIC的函数里面,,但是由于51单片机的GPIO的寄存器不能直接通过指针访问,,所以你还得写几个驱动GPIO的函数,而且用这个函数驱动的话,非常影响性能,,如果追求通讯速率的话,可以用宏定义替换这些GPIO驱动函数。但是这样的话,如果需要修改引脚的话只能重新烧程序。。不过只对一块主板的话也不是不行。。
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:67
  • 最近打卡:2025-06-16 08:30:05
已绑定手机

17

主题

472

回帖

1341

积分

金牌会员

积分
1341
发表于 2025-5-19 11:17:18 | 显示全部楼层
本身可以挂一起,减小上拉电阻
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:253
  • 最近打卡:2025-06-16 07:49:12

0

主题

1

回帖

1101

积分

金牌会员

积分
1101
发表于 2025-5-28 11:04:20 | 显示全部楼层
zhu*** 发表于 2025-5-18 19:14
是的,上拉改过1K8的,,总线串电阻、并100P电容都试过,速率一度改为250K左右,一样会随机出现 ...

要不要换个思路?不用管随机出现错误的原因,而是想办法识别对错,然后建立重发机制。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-16 13:15 , Processed in 0.137511 second(s), 98 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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