最近调AM2320这个温湿度传感器模块,用IIC一直出不来,仔细研究数据手册后终于发现问题了,目前ACK应答正常。
IIC部分直接移植正点原子历程的模拟IIC,改下延迟让速率大概在100K就行。(我将所有涉及的都改成了5us)
上AM2320关键代码
//AM23xx唤醒
void AM23xx_WKUP()
{
IIC_Start();
IIC_Send_Byte(0XB8+0); //发地址
IIC_SCL=1; //注意:此处AM23xx不会产生应答,但还是要给个脉冲。原因见AM23xx数据手册。
delay_us(5); //或者写IIC_Wait_Ack();但不判断应答
IIC_SCL=0;
delay_us(5);
//IIC_Wait_Ack();
delay_ms(1);
IIC_Stop();
}
//写入命令
u8 AM23xx_WriteCMD(u8* CMD)
{
u8 i;
IIC_Start();
IIC_Send_Byte(0XB8+0); //发地址
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
for(i=0;i<3;i++)
{
IIC_Send_Byte(*(CMD+i));
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
}
IIC_Stop();
return 0;
}
//读取数据
u8 AM23xx_ReadData(u8* DataBuf)
{ u8 i;
IIC_Start();
IIC_Send_Byte(0XB8+1); //发地址
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
delay_us(50);
for(i=0;i<7;i++)
{
*(DataBuf+i)=IIC_Read_Byte(1);
}
*(DataBuf+i)=IIC_Read_Byte(0);
IIC_Stop();
return 0;
}
///计算CRC校验码
unsigned int CRC16(unsigned char *ptr, unsigned char len)
{
unsigned int crc=0xffff;
unsigned char i;
while(len--)
{
crc ^=*ptr++;
for(i=0;i<8;i++)
{
if(crc & 0x1)
{
crc>>=1;
crc^=0xa001;
}
else
{
crc>>=1;
}
}
}
return crc;
}
///检测CRC校验码是否正确
unsigned char CheckCRC(unsigned char *ptr,unsigned char len)
{
unsigned int crc;
crc=(unsigned int)CRC16(ptr,len-2);
if(ptr[len-1]==(crc>>8) && ptr[len-2]==(crc & 0x00ff))
{
return 0xff;
}
else
{
return 0;
}
}
///读取温湿度值
u8 AM23xx_ReadT_H(int16_t *TMP ,u16 *HR)
{
u8 AM23xx_DataBuf[8]={0};
AM23xx_WKUP();
if(AM23xx_WriteCMD((u8*)Read_CMD))
{
return 1;
}
delay_ms(2);
if(AM23xx_ReadData(AM23xx_DataBuf))
{
return 1;
}
if(CheckCRC(AM23xx_DataBuf,8))
{
*HR = (AM23xx_DataBuf[2]<<8) | AM23xx_DataBuf[3];
*TMP = (AM23xx_DataBuf[4]<<8) | AM23xx_DataBuf[5];
//printf("HUM:%d TMP:%d
",*HR,*TMP);
return 0;
}
else return 1;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>