OpenEdv-开源电子网

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

AM2320温湿度传感器无应答信号~

[复制链接]

1

主题

5

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2013-9-8
在线时间
9 小时
发表于 2016-8-6 23:20:21 | 显示全部楼层 |阅读模式
10金钱
我这几天在用AM2320温湿度传感 器,但数据一直读不回来!发现ACK信号时有时无,都几天了,I2C程序在其他器件上使用都正常,看手册上用在2320上也只需注意几个延时就好了啊~!且也是按照手册上的I2C MODBUS格式要求,可死活出不来,麻烦提供一下帮助哈!!!!下在是.C文件~大神帮帮我。。。。


#include "AM2320.h"
#include "sys.h"
#include "delay.h"
u8 AM2320_Ack_temp;
unsigned char IIC_TX_Buffer[]={0x03,0x00,0x04}; //读温湿度命令: 读指令,寄存器起始地址,寄存器个数(MODBUS格式无CRC)
unsigned char IIC_RX_Buffer[8] = {0x00};//读回的温湿度

void AM2320_I2C_SDA_IN(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;               
        GPIO_InitStructure.GPIO_Pin=AM2320_I2C_SDA;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_Init(AM2320_GPIO_I2C,&GPIO_InitStructure);       
}
void AM2320_I2C_SDA_OUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;       
        GPIO_InitStructure.GPIO_Pin=AM2320_I2C_SDA;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_Init(AM2320_GPIO_I2C,&GPIO_InitStructure);
}

//函数名;AM2320_I2C_Init
//输入:无
//输出:无
//描述:初始化SDA和SCL
void AM2320_I2C_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;               
        GPIO_InitStructure.GPIO_Pin=AM2320_I2C_SCL|AM2320_I2C_SDA;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_Init(AM2320_GPIO_I2C,&GPIO_InitStructure);
    AM2320_SCL_H;
    AM2320_SDA_H;
}
/*******************************************************************************
函数名:AM2320_I2C_Start
功能:  产生I2C开始信号(SDA在SCL高电平时产生一个下降沿信号)
参数:  无
返回值:无
*******************************************************************************/
void AM2320_I2C_Start(void) //产生起始信号              
{
    AM2320_I2C_SDA_OUT();
        AM2320_SDA_H;
    AM2320_SCL_H;
    delay_us(4);
    AM2320_SDA_L;
    delay_us(4);
    AM2320_SCL_L;
        delay_us(4);
}
/*******************************************************************************
函数名:AM2320_I2C_Stop
功能:  产生I2C停止信号(SDA在SCL高电平时产生一个上升沿信号)
参数:  无
返回值:无
*******************************************************************************/
void AM2320_I2C_Stop(void)//产生停止信号              
{
    AM2320_I2C_SDA_OUT();
        AM2320_SCL_L;
        AM2320_SDA_L;
    delay_us(4);
        AM2320_SCL_H;
        delay_us(4);
    AM2320_SDA_H;
        delay_us(4);
}                                            

//主机产生应答信号ACK
void AM2320_I2C_Ack(void)
{
   AM2320_SCL_L;
   AM2320_I2C_SDA_OUT();
   AM2320_SDA_L;
   delay_us(4);
   AM2320_SCL_H;
   delay_us(4);
   AM2320_SCL_L;
   delay_us(4);
}

//主机不产生应答信号NACK
void AM2320_I2C_NAck(void)
{
   AM2320_SCL_L;;
   AM2320_I2C_SDA_OUT();
   AM2320_SDA_H;
   delay_us(5);
   AM2320_SCL_H;
   delay_us(5);
   AM2320_SCL_L;
   delay_us(5);
}
/*******************************************************************************
函数名:AM2320_EN
功能: 唤醒传感器
参数: 无
返回值:无
********************************************************************************/
void AM2320_EN(void)
{
  AM2320_I2C_Start();
  AM2320_I2C_Send_Byte(0xb8);
  AM2320_I2C_Wait_Ack(); //唤醒
// Test_Ack();
  delay_us(200);
  delay_us(200);
  delay_us(200);
  delay_us(200);
  delay_us(30);
// Test_Ack();
  AM2320_I2C_Stop();
}
/*******************************************************************************
函数名:AM2320_I2C_Wait_Ack
功能:  等待从机应答信号,并检查应答位是否正确
参数:  
返回值:1 无应答  0接收应答成功
*******************************************************************************/
u8 AM2320_I2C_Wait_Ack(void)
{
        u8 tempTime=0;
        AM2320_I2C_SDA_IN();
        AM2320_SDA_H;
        delay_us(4);
        AM2320_SCL_H;
        delay_us(4);
        while(GPIO_ReadInputDataBit(AM2320_GPIO_I2C,AM2320_I2C_SDA))
        {
                tempTime++;
                if(tempTime>250)
                {
                        AM2320_I2C_Stop();
                        return 1;
                }         
        }

        AM2320_SCL_L;
        return 0;
}
/*******************************************************************************
函数名:AM2320_I2C_Send_Byte
功能:  向I2C总线写入数据,并检查应答位是否正确
参数:  Data 发送的字节
返回值:
*******************************************************************************/
void AM2320_I2C_Send_Byte(u8 Data)        //I2C 写一个字节
{
        u8 i=0;
        AM2320_I2C_SDA_OUT();
        AM2320_SCL_L;//拉低时钟开始数据传输
        for(i=0;i<8;i++)
        {
                if((Data&0x80)>0) //0x80  1000 0000
                 AM2320_SDA_H;
                else
                 AM2320_SDA_L;               
                Data<<=1;
                delay_us(4);
                AM2320_SCL_H;
                delay_us(4);
                AM2320_SCL_L;;
               
        }
}
/*******************************************************************************
函数名:AM2320_I2C_Read_Byte
功能: 从I2C总线读一个字节的数据
参数: receive 要读出的数据存放的地址
返回值:1成功  0失败
*******************************************************************************/
u8 AM2320_I2C_Read_Byte(void)//I2C 读取一个字节
{
   u8 i=0,receive=0;
   AM2320_I2C_SDA_IN();
   for(i=0;i<8;i++)
   {
                   AM2320_SCL_L;
                delay_us(2);
                AM2320_SCL_H;
                receive<<=1;
                if(GPIO_ReadInputDataBit(AM2320_GPIO_I2C,AM2320_I2C_SDA))
                {
                   receive++;
                   delay_us(1);
                }                                       
   }
//           if(ack==0)
//                   AM2320_I2C_NAck();
//        else
//                AM2320_I2C_Ack();
        return receive;
}
/*******************************************************************************
函数名:AM2320_Writedata
功能: 向I2C总线写一个或多个字节的数据
参数: Addr写入的起始地址,*buf 要写入的数据存放的地址,len要写入的数据长度
返回值:1失败     0成功
*******************************************************************************/
u8 AM2320_Writedata(u8 *buf,u8 n) //写数据
{
        u8 i;
        AM2320_I2C_Start();
        AM2320_I2C_Send_Byte(0xB8);
        AM2320_Ack_temp=AM2320_I2C_Wait_Ack();        //等待应答信号
    if (!AM2320_Ack_temp)
        {
                   for(i=0;i<n;i++)//写入n字节数据
                   {
               AM2320_I2C_Send_Byte(buf);
                  //AM2320_I2C_Ack();
                  AM2320_Ack_temp=AM2320_I2C_Wait_Ack();        //等待应答信号
                  if (AM2320_Ack_temp)
                  {
                    return;
                  }
                   }
        }
        AM2320_I2C_Stop();
        return         AM2320_Ack_temp;
}
/*******************************************************************************
函数名:AM2320_Readdata
功能: 向I2C总线读一个或多个字节的数据
参数: *p要读出的数据存放的地址,n要读出数据的长度
返回值:1失败     0成功
*******************************************************************************/
u8 AM2320_Readdata(u8 *p,u8 n) //读取数据
{
    u8 i;
        AM2320_I2C_Start();
        AM2320_I2C_Send_Byte(0xb9);
        AM2320_Ack_temp=AM2320_I2C_Wait_Ack();        //等待应答信号
    if (!AM2320_Ack_temp)
        {
          delay_us(35);
          for(i=0;i<n-1;i++)  //读取字节数据
       {
                 p=AM2320_I2C_Read_Byte(); //读取数据
                 AM2320_I2C_Ack();
       }
           p = AM2320_I2C_Read_Byte();
           AM2320_I2C_NAck();
     }
        AM2320_I2C_Stop();
        return AM2320_Ack_temp;         
}
/*******************************************************************************
函数名:AM2320_READ
功能: 读取温湿度寄存器数据
参数: IIC_RX_Buffer要读出的数据存放的地址
返回值:

*******************************************************************************/
void AM2320_READ(void)
{
          memset(IIC_RX_Buffer,0,sizeof(IIC_RX_Buffer));
    AM2320_EN();
    printf("Q1:%d\r\n",AM2320_Writedata(IIC_TX_Buffer,3));
     Delayms(2);
        printf("Q2:%d\r\n",AM2320_Readdata(IIC_RX_Buffer,8));

}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2013-9-8
在线时间
9 小时
 楼主| 发表于 2016-8-7 11:03:34 | 显示全部楼层
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11559
金钱
11559
注册时间
2014-4-1
在线时间
1318 小时
发表于 2016-8-7 11:49:18 | 显示全部楼层

谁都一眼看不出来问题,所以没法回复。

对照时序图,看看是哪一步的ACK没有回应,然后往前面查。
肯定是前面过程有问题。

回复

使用道具 举报

56

主题

343

帖子

0

精华

高级会员

Rank: 4

积分
977
金钱
977
注册时间
2016-3-8
在线时间
267 小时
发表于 2018-1-19 14:42:38 | 显示全部楼层
我也出现这问题,用模拟IIC。后来干脆就不要应答就好了。
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-19 15:47:09 | 显示全部楼层
pdwdzz 发表于 2018-1-19 14:42
我也出现这问题,用模拟IIC。后来干脆就不要应答就好了。

模拟i2c:http://blog.csdn.net/qq_20553613/article/details/78878211
回复

使用道具 举报

4

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2019-1-22
在线时间
24 小时
发表于 2019-5-5 16:37:03 | 显示全部楼层
pdwdzz 发表于 2018-1-19 14:42
我也出现这问题,用模拟IIC。后来干脆就不要应答就好了。

不要应答不行,不要应答最后返回值都是11111111111
回复

使用道具 举报

13

主题

272

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5390
金钱
5390
注册时间
2017-8-14
在线时间
249 小时
发表于 2020-1-9 11:25:37 | 显示全部楼层
21CANWeb_STM32F10x开发板AM2320源程序见附件
21CANWeb_STM32F10x开发板AM2320源程序200109.zip (155.05 KB, 下载次数: 9)
详细资料扣扣群204408503自行下载
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-26 16:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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