找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3554|回复: 16
收起左侧

单片机+Proteus仿真I2C设备, 设备无响应, 如何写代码?

[复制链接]
ID:884307 发表于 2021-2-18 19:11 | 显示全部楼层 |阅读模式
如图, 用自带的I2C debugger看, 发送完数据后的状态都是N(nack), 设备无响应
I2C的启动, 发送, 停止都是正常的, 就是设备不响应, 是我代码的问题还是软件的问题?
Snipaste_2021-02-18_18-36-30.jpg
Snipaste_2021-02-18_18-36-09.jpg

设备是INA219, 电压电流监测模块

文档给的写数据时序图
Snipaste_2021-02-18_19-00-27.jpg
Snipaste_2021-02-18_19-01-23.jpg
文档的典型接法:
Snipaste_2021-02-18_19-05-29.jpg


我知道一上来就贴代码让人很没有读的欲望, 但我真的排查不出问题,恳请各位帮忙!
51模拟I2C总线的部分
  1. void IIC_ack(){
  2.         uchar i;
  3.         SCLK = 0;                //时钟线置低
  4.         SDA = 1;                //拉高SDA
  5.         delay_us();                //延时, 等待SDA被从机拉低
  6.         SCLK = 1;                //拉高时钟线
  7.         while((SDA == 1) && (i < 255)){
  8.                 i++;                //延时, 继续等待
  9.         }
  10.         SCLK = 0;                //拉低时钟线
  11.         delay_us();
  12. }

  13. void IIC_sentByte(uchar _data){
  14.         uchar i, temp;
  15.         temp = _data;
  16.         for(i = 0; i < 8; i++){
  17.                 temp = temp << 1;        //数据向左移, 左移溢出的一位到PSW寄存器的CY中
  18.                 SCLK = 0;                        //时钟线拉低
  19.                 delay_us();
  20.                 SDA = CY;                        //SDA发送CY中的一位数据
  21.                 SCLK = 1;                        
  22.                 delay_us();        
  23.         }
  24.         SCLK = 0;
  25.         delay_us();
  26.         SDA = 1;                                //释放SDA
  27.         delay_us();

  28. }
复制代码

Proteus仿真时读的代码
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include "IIC_Protocol_for8051.h"
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6.         
  7. //当Slave address为1001010 (4AH)时, A1和A0地址线直接采样SDA上的数据
  8. //即 SDA上跑的数据就是A0, A1获取的数据

  9. void INA219_sent2Reg(uchar regAddress, uint _data){
  10.         uchar data_MSB = _data / 256;  //获取数据高八位
  11.         uchar data_LSB = _data - (data_MSB * 256);                //获取数据低八位
  12.         IIC_init();                                                                  //I2C总线启动
  13.         IIC_start();
  14.         IIC_sentByte(0x94);       //发送Slave address(前7位), 和R/#W位(确认传输方向, 第8位)
  15.                      //0x94 = 0x4A(Slave address) * 2 [在0x4A后加一个R/#W位]
  16.                      //0x94 = 10010100    0x4A = 1001010
  17.         IIC_ack();
  18.         IIC_sentByte(regAddress);                                //发送寄存器地址
  19.         IIC_ack();                                                     //并等待从机是否有Ack(响应)
  20.         IIC_sentByte(data_MSB);                                 //发送数据高8位
  21.         IIC_ack();
  22.         IIC_sentByte(data_LSB);                                 //发送低8位
  23.         IIC_ack();
  24.         IIC_stop();                                                  //I2C总线停止
  25. }
  26. void INA219_init(){
  27.         INA219_sent2Reg(0x05, 0x1000);                    //0x1000是要发送的数据, 无特殊含义
  28. }

  29. void main(){
  30.         INA219_init();
  31.         while(1);
  32. }
复制代码

INA219.pdf (1.31 MB, 下载次数: 6)
回复

使用道具 举报

ID:884307 发表于 2021-2-18 19:13 | 显示全部楼层
这个注释...我tab按太多了...大家将就看
回复

使用道具 举报

ID:884307 发表于 2021-2-20 17:50 | 显示全部楼层
glinfei 发表于 2021-2-20 08:54
你写的地址是100101,A0,A1应该接在SDA上啊,怎么图上是悬空呢?

好像确实应该这样...
不过我把A1,A0和SDA连起来之后这个IC还是无响应nack的状态...
回复

使用道具 举报

ID:884307 发表于 2021-2-26 20:33 | 显示全部楼层
angmall 发表于 2021-2-22 14:23
我已经测试过了

是Proteus仿真软件的问题, 这个INA219仿真I2C设备, 电压电流监测模块 , 只能工作的地 ...

非常感谢!
我现在是在自学电子设计, 对于布线和PCB设计之类的知识又一窍不通, 而这些又是必要的
能不能请问一下在哪里能学习这些知识呢?
回复

使用道具 举报

ID:884307 发表于 2021-2-27 21:52 | 显示全部楼层
angmall 发表于 2021-2-22 11:11
你的地址写错了

感谢你的建议!
问一下, 这个

  1. #define INA219_RD_Operation 0x81
  2. #define INA219_WR_Operation 0x80
复制代码

是什么东西, 在文档里没看到0x80这个数字出现, 根据手册第一次发送的应该是slave address, 来指定A0和A1采样的管脚
为什么要发送这个 INA219_RD_Operation 呢? 有什么意义吗?
回复

使用道具 举报

ID:884307 发表于 2021-2-28 10:32 | 显示全部楼层
angmall 发表于 2021-2-27 23:06
8.5.6写入和读取INA219
通过将适当的值写入寄存器指针来访问INA219上的特定寄存器。有关寄存器和相应 ...

好的好的
那这个A0和A1到底是做什么的, 文档说是指定从设备地址, 那这个表格是什么意思?
回复

使用道具 举报

ID:884307 发表于 2021-2-28 11:25 | 显示全部楼层
angmall 发表于 2021-2-28 11:11
I2C 总线是一双线串行总线, 它提供一小型网络系统,为总线上的电路共享公共的总线。
总线上的器件, 每 ...

我不明白的是, 比如当slave address为1000000时, A1和A0都对应到GND上(或者是VSS, SDA, SCL或其他管脚上)对A0和A1的值有什么影响吗?
也就是说, 表格中不同的slave address的值, 是否对A0和A1的值有影响?
回复

使用道具 举报

ID:884307 发表于 2021-3-21 15:26 | 显示全部楼层
angmall 发表于 2021-2-28 20:27
该个是因果关系
因为你需要为每个INA219器件使用不同的地址,因此你需要将A0和A1引脚连接到不同的值。

谢谢, 问题完美解决!
抱歉过了这么久才来回复你.....
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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