OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2737|回复: 3

STM32L052C8T6通过I2C模拟读16位数

[复制链接]

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-5-29
在线时间
15 小时
发表于 2020-7-27 16:22:47 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 13886419675 于 2020-7-27 16:27 编辑

最近项目用到一款接近光传感器VCNL4040,在连续读16位数据的时候,发现低八位读出来是正确的,但是高八位读出来的都是0xFF。我看Datasheet上面每次读完数据之后都是主机主动应答,程序也是这么写的,但最后的结果还是不对。不知道论坛里面大佬们知道是什么问题吗???救救孩子吧
这是Datasheet读写流程。
  1. void VCNL4040_WrData(uchar cmd,uchar data_L,uchar data_H)
  2. {                   
  3.                 IIC_Start();
  4.        
  5.                 IIC_Send_Byte(Write_SlaveAddress);//写模式
  6.                 IIC_Wait_Ack();       

  7.                 IIC_Send_Byte(cmd);//发送命令代码
  8.                 IIC_Wait_Ack();       
  9.        
  10.                 IIC_Send_Byte(data_L);//发送数据低八位
  11.                 IIC_Wait_Ack();       

  12.                 IIC_Send_Byte(data_H);//发送数据高八位
  13.                 IIC_Wait_Ack();       
  14.        
  15.                 IIC_Stop();//产生一个停止条件               
  16. }


  17. //函数名称:VCNL4040_RdData(uchar cmd)
  18. //功能描述: 从VCNL4040指定命令代码中读出16位数据
  19. //参数说明:Cmd为指定命令代码
  20. //-----------------------------------------------------------------------------------------
  21. u16 VCNL4040_RdData(uchar cmd)
  22. {                                  
  23.                 u16  data=0,data_H=0;                           
  24.                 u16 data_L=0;
  25.        
  26.                 IIC_Start();//产生一个开始条件
  27.        
  28.                 IIC_Send_Byte(Write_SlaveAddress);//写操作
  29.                 IIC_Wait_Ack();         
  30.                
  31.                 IIC_Send_Byte(cmd);//发送命令代码
  32.                 IIC_Wait_Ack();       
  33.        
  34.                 IIC_Start();
  35.                 IIC_Send_Byte(Read_SlaveAddress);//读操作
  36.                 IIC_Wait_Ack();       
  37.        
  38.                 data_L=IIC_Read_Byte(0);//读出16位数据中的低八位       
  39.                 IIC_Ack();       
  40.                 data_H=IIC_Read_Byte(0);//读出16位数据中的高八位
  41.                 IIC_Ack();       
  42.        
  43.                 IIC_Stop();//产生一个停止条件
  44.        
  45.                 data = data_L+data_H*256;//16bit数据
  46.        
  47.                 return data;
  48. }
复制代码

上面是我写的读写函数
  1. //产生ACK应答
  2. void IIC_Ack(void)
  3. {
  4.                 IIC_SCL_LOW;
  5.                 IIC_SDA_Init(0);
  6.                 IIC_SDA_LOW;
  7.                 delay_us(2);
  8.                 IIC_SCL_HIGH;
  9.                 delay_us(2);
  10.                 IIC_SCL_LOW;
  11. }
复制代码
这是IIC的ACK应答函数。确实没看出问题到底出在哪里啊

TIM截图20200727162653.png

最佳答案

查看完整内容[请看2#楼]

问题解决了,原来正点原子里面的读函数是包含响应函数与不响应函数的 将VCNL4040_RdData()中多余的响应函数注释掉之后,修改为 亲测可以正确读取设备ID,还是看代码不仔细的锅啊
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-5-29
在线时间
15 小时
 楼主| 发表于 2020-7-27 16:22:48 | 显示全部楼层
问题解决了,原来正点原子里面的读函数是包含响应函数与不响应函数的
  1. uchar IIC_Read_Byte(uchar ack)
  2. {
  3.                 uchar i,receive=0;

  4.                 IIC_SDA_Init(1);//SDA设置为输入

  5.                 for(i=0;i<8;i++ )
  6.                 {
  7.                         IIC_SCL_LOW;
  8.                         delay_us(2);
  9.                         IIC_SCL_HIGH;
  10.                         receive<<=1;
  11.                        
  12.                         if(IIC_SDA_READ)receive++;   
  13.                         delay_us(1);
  14.                 }                                         
  15.                 if (!ack)
  16.                 IIC_NAck();//发送nACK
  17.                 else
  18.                 IIC_Ack(); //发送ACK   
  19.                
  20.                 return receive;
  21. }
复制代码


将VCNL4040_RdData()中多余的响应函数注释掉之后,修改为
  1. u16 VCNL4040_RdData(uchar cmd)
  2. {                                  
  3.                 u16  data=0,data_H=0;                           
  4.                 u16 data_L=0;
  5.        
  6.                 IIC_Start();//产生一个开始条件
  7.        
  8.                 IIC_Send_Byte(Write_SlaveAddress);//写操作
  9.                 IIC_Wait_Ack();//主机等待应答
  10.                
  11.                 IIC_Send_Byte(cmd);//发送命令代码
  12.                 IIC_Wait_Ack();       
  13.        
  14.                 IIC_Start();
  15.                 IIC_Send_Byte(Read_SlaveAddress);//读操作
  16.                 IIC_Wait_Ack();               
  17.        
  18.                 data_L=IIC_Read_Byte(1);//读出16位数据中的低八位,应答
  19. //                IIC_Ack();//主机应答
  20.                 data_H=IIC_Read_Byte(0);//读出16位数据中的高八位,不应答
  21. //            IIC_Ack();               

  22.                 IIC_Stop();//产生一个停止条件
  23.        
  24.                 data = data_L+data_H*256;//16bit数据
  25.        
  26.                 return data;
  27. }
复制代码

亲测可以正确读取设备ID,还是看代码不仔细的锅啊
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-5-29
在线时间
15 小时
 楼主| 发表于 2020-7-27 16:23:39 | 显示全部楼层
本帖最后由 13886419675 于 2020-7-27 16:30 编辑

有没有大佬
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2020-7-28 02:48:13 | 显示全部楼层
帮顶
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-30 09:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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