我这几天在用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));
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
模拟i2c:http://blog.csdn.net/qq_20553613/article/details/78878211
一周热门 更多>