找回密码
 立即注册
查看: 357|回复: 4

17-I2C从机中断模式与IO口模拟I2C主机进行自发自收

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2026-01-03 13:57:34

5

主题

3

回帖

72

积分

注册会员

积分
72
发表于 2025-11-4 11:09:39 | 显示全部楼层 |阅读模式
按照下载的这个程序测试,发现采用主机模拟方式的iic,从机无法接收;换成了主机硬件方式的iic可以,那位研究过给个解释,我用了两块开发板进行的验证。
截图202511041109168709.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:725
  • 最近打卡:2026-03-30 12:09:34
已绑定手机

97

主题

7246

回帖

1万

积分

超级版主

积分
13798
发表于 2025-11-4 12:31:04 | 显示全部楼层
可以用逻辑分析仪或示波器对比一下波形有何区别
软件I2C程序:
  1. void        I2C_Delay(void)
  2. {
  3.         u16        dly;
  4.         dly = 8;                //取1对应SCL H为0.5us,L为1.5us,读写仍正常.为了可靠,取8
  5.         while(--dly)        ;
  6. }
  7. void I2C_Start(void)               //start the I2C, SDA High-to-low when SCL is high
  8. {
  9.         P_I2C_SDA = 1;        //SDA = 1;
  10.         I2C_Delay();
  11.         P_I2C_SCL = 1;        //SCL = 1;
  12.         I2C_Delay();
  13.         I2C_Delay();
  14.         I2C_Delay();
  15.         I2C_Delay();
  16.         P_I2C_SDA = 0;        //SDA = 0;
  17.         I2C_Delay();
  18.         I2C_Delay();
  19.         I2C_Delay();
  20.         P_I2C_SCL = 0;        //SCL = 0;
  21.         I2C_Delay();
  22. }
  23. void I2C_Stop(void)                                        //STOP the I2C, SDA Low-to-high when SCL is high
  24. {
  25.         P_I2C_SCL = 0;        //SCL = 0;
  26.         I2C_Delay();
  27.         P_I2C_SDA = 0;        //SDA = 0;
  28.         I2C_Delay();
  29.         P_I2C_SCL = 1;        //SCL = 1;
  30.         I2C_Delay();
  31.         I2C_Delay();
  32.         I2C_Delay();
  33.         P_I2C_SDA = 1;        //SDA = 1;
  34.         I2C_Delay();
  35. }
  36. u8 I2C_Check_ACK(void)         //Check ACK, If status=0: right, if status=1:  error
  37. {
  38.         u8        status;
  39.         P_I2C_SDA = 1;        //SDA = 1;
  40.         I2C_Delay();
  41.         P_I2C_SCL = 1;        //SCL = 1;
  42.         I2C_Delay();
  43.         status = 0;
  44.         if(P_I2C_SDA)
  45.                 status = 1;
  46.         P_I2C_SCL = 0;        //SCL = 0;
  47.         I2C_Delay();
  48.         return        status;
  49. }
复制代码


回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2026-01-03 13:57:34

5

主题

3

回帖

72

积分

注册会员

积分
72
发表于 2025-11-5 13:29:59 | 显示全部楼层
通过软硬件的iic程序比较,软件是有检测从机应答信号的,但是硬件虽然也检测,但是忽略了从机的应答信号,这是主机软硬iic程序的不同点。
主机软件IIC
//========================================================================
// 函数: void SI2C_WriteNbyte(u8 dev_addr, u8 mem_addr, u8 *p, u8 number)
// 描述: I2C写入数据函数.
// 参数: dev_addr: 设备地址, mem_addr: 存储地址, *p写入数据存储位置, number写入数据个数.
// 返回: none.
// 版本: V1.0, 2020-09-15
//========================================================================
void SI2C_WriteNbyte(u8 dev_addr, u8 mem_addr, u8 *p, u8 number)  /*  DeviceAddress,WordAddress,First Data Address,Byte lenth  */
{
        I2C_Start();
        I2C_WriteAbyte(dev_addr);
        I2C_Check_ACK();
        if(!F0)                                           //F0=0,right, F0=1,error
        {
                I2C_WriteAbyte(mem_addr);
                I2C_Check_ACK();
                if(!F0)
                {
                        do
                        {
                                I2C_WriteAbyte(*p); p++;
                                I2C_Check_ACK();
                                if(F0)  break;
                        }
                        while(--number);
                }
        }
        I2C_Stop();
}

主机硬件iic
//========================================================================
// 函数: void I2C_WriteNbyte(u8 dev_addr, u8 mem_addr, u8 *p, u8 number)
// 描述: I2C写入数据函数.
// 参数: dev_addr: 设备地址, mem_addr: 存储地址, *p写入数据存储位置, number写入数据个数.
// 返回: none.
// 版本: V1.0, 2020-09-15
//========================================================================
void I2C_WriteNbyte(u8 dev_addr, u8 mem_addr, u8 *p, u8 number)  /*  DeviceAddress,WordAddress,First Data Address,Byte lenth   */
{
        Start();                                //发送起始命令
        SendData(dev_addr);                     //发送设备地址+写命令
        RecvACK();
        SendData(mem_addr);                     //发送存储地址
        RecvACK();
        do
        {
                SendData(*p++);
                RecvACK();
        }
        while(--number);
        Stop();                                 //发送停止命令
}

差异点在,硬件iic虽然检测从机应答信号,但是是忽略的,软件iic检测从机应答信号,必须有才能下一步。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2026-01-03 13:57:34

5

主题

3

回帖

72

积分

注册会员

积分
72
发表于 2025-11-5 13:37:42 | 显示全部楼层
guo*** 发表于 2025-11-5 13:29
通过软硬件的iic程序比较,软件是有检测从机应答信号的,但是硬件虽然也检测,但是忽略了从机的应答信号, ...

主机软件iic检测应答信号:
void I2C_Check_ACK(void)     //Check ACK, If F0=0, then right, if F0=1, then error
{
        SDA = 1;
        I2C_Delay();
        SCL = 1;
        I2C_Delay();
        F0  = SDA;
        SCL = 0;
        I2C_Delay();
}
其中的F0就是从机应答信号的标识;

以下是硬件iic的ack检测信号程序,只接受不处理
//========================================================================
// 函数: void RecvACK (void)
// 描述: I2C获取ACK函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2020-09-15
//========================================================================
void RecvACK()
{
        I2CMSCR = 0x03;                         //发送读ACK命令
        Wait();
}

我很想知道,从机是怎么发送出应答信号的?
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2026-01-03 13:57:34

5

主题

3

回帖

72

积分

注册会员

积分
72
发表于 2025-11-12 17:38:13 | 显示全部楼层
硬件从机自动发送应答信号,可以初始化设置好,已经验证完毕。
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-4-4 17:41 , Processed in 0.124004 second(s), 65 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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