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

2019-07-21 01:55发布

我这几天在用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 ",AM2320_Writedata(IIC_TX_Buffer,3));
     Delayms(2);
        printf("Q2:%d ",AM2320_Readdata(IIC_RX_Buffer,8));

}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。