网上关于纮康资料很少,遇到什么问题都百度不了。(代码,波形图,结果后附)
用IIC读取AHT20传感器的SDA数据,逻辑分析仪抓取的波形都是对的,也有数据
但传回来的数据一直为0(低电平)
发现SDA的引脚读取不了高电平,测了此引脚对地电压4.5V,是正常的
接着检查IO口的寄存器配置,输入模式,上拉电阻都配置好了,仍然读不到高电平
接着看芯片数据手册,发现IO配置有个叫 数位输入 的功能
把它开启,能读高电平了
接着变量监视器的变量值不对,导致送显不对
然后看读取函数,发现把中间变量赋值为0后,居然不是0
然后对比中间变量和传感器传回的数据类型,发现不一致,然后统一所有的数据类型
还是不对!!!
再仔细检查,原来中间变量(int型)的位数不足以接收传感器的20位数据!!!
代码有需要联系
第一篇博客,内容不是很丰富,有疑问可以留言
逻辑分析仪抓取IIC波形图:
发送测量命令:
读取测量数据:
数据结果
以下是AHT20.C
#define USE_HY17P60_5M
/*----------------------------------------------------------------------------*/
/* Includes */
/*----------------------------------------------------------------------------*/
#include <hy17p60sfr.h>
#include "AHT20.h"
#include "Delay.h"
/*----------------------------------------------------------------------------*/
/* AHT20 */
/*----------------------------------------------------------------------------*/
void SDA_Pin_Output_High(void)
{
GPIO_PT3CLRPU(5);
GPIO_PT3OutputMode(5);
GPIO_PT3SET(5); //SDA 拉高
}
void SDA_Pin_Output_Low(void)
{
GPIO_PT3CLRPU(5);
GPIO_PT3OutputMode(5);
GPIO_PT3CLR(5); //SDA 拉低
}
void SCL_Pin_Output_High(void)
{
GPIO_PT3SET(6); //SCL 拉高
__asm__ ("NOP");
__asm__ ("NOP");
}
void SCL_Pin_Output_Low(void)
{
GPIO_PT3CLR(6); //SCL 拉低
__asm__ ("NOP");
}
void I2C_Start(void) //主机发送START信号
{
SDA_Pin_Output_High(); //SDA 1
SCL_Pin_Output_High(); //SCL 1
SDA_Pin_Output_Low(); //SDA 0
SCL_Pin_Output_Low(); //SCL 0
}
void Stop_I2C(void) //主机发送STOP信号
{
SDA_Pin_Output_Low();
SCL_Pin_Output_High();
SDA_Pin_Output_High();
}
void AHT20_WR_Byte(unsigned char Byte) //往AHT20写一个字节
{
unsigned char Data,N,i;
Data=Byte;
i = 0x80;
for(N=0;N<8;N++)
{
SCL_Pin_Output_Low();
if(i&Data)
{
SDA_Pin_Output_High();
}
else
{
SDA_Pin_Output_Low();
}
SCL_Pin_Output_High();
Data <<= 1;
}
SCL_Pin_Output_Low();
GPIO_PT3SETPU(5);
GPIO_PT3InputMode(5);
}
unsigned char AHT20_RD_Byte(void)//从AHT20读一个字节
{
unsigned char Byte,i,a;
Byte = 0;
SCL_Pin_Output_Low();
GPIO_PT3SETPU(5);
GPIO_PT3InputMode(5); //输入模式
for(i=0;i<8;i++)
{
SCL_Pin_Output_High();
a=0;
if(GPIO_PT3GET(5)) a=1;
Byte = (Byte<<1)|a;
SCL_Pin_Output_Low();
}
GPIO_PT3SETPU(5);
GPIO_PT3InputMode(5);
return Byte;
}
unsigned char Receive_ACK(void)//看AHT20是否回复ACK
{
unsigned short int CNT= 0;
SCL_Pin_Output_Low();
GPIO_PT3SETPU(5);
GPIO_PT3InputMode(5);
SCL_Pin_Output_High();
while((GPIO_PT3GET(5)) && CNT < 100) //SDA是低电平信号时为应答
CNT++;
if(CNT == 100)
{
return 0; //没有回复ACK
}
GPIO_PT3CLR(6);
GPIO_PT3OutputMode(5);
return 1; //回复了ACK
}
void Send_ACK(void)//主机回复ACK
{
SCL_Pin_Output_Low();
SDA_Pin_Output_Low();
SCL_Pin_Output_High();
SCL_Pin_Output_Low();
GPIO_PT3SETPU(5);
GPIO_PT3InputMode(5); //输入模式
}
void Send_NOT_ACK(void) //主机不回复ACK
{
SCL_Pin_Output_Low();
SDA_Pin_Output_High();
SCL_Pin_Output_High();
SCL_Pin_Output_Low();
SDA_Pin_Output_Low();
}
unsigned char AHT20_Read_Status(void)//读取AHT20的状态寄存器
{
unsigned char Byte_first;
I2C_Start();
AHT20_WR_Byte(0x71);
Receive_ACK();
Byte_first = AHT20_RD_Byte();
Send_NOT_ACK();
Stop_I2C();
return Byte_first;
}
void AHT20_SendAC(void) //向AHT20发送AC命令
{
I2C_Start();
AHT20_WR_Byte(0x70);
Receive_ACK();
AHT20_WR_Byte(0xac);//0xAC采集命令
Receive_ACK();
AHT20_WR_Byte(0x33);
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
}
void AHT20_Read_CTdata( long int *ct) //没有CRC校验,直接读取AHT20的温度和湿度数据
{
volatile char Byte_1th = 0;
volatile char Byte_2th = 0;
volatile char Byte_3th = 0;
volatile char Byte_4th = 0;
volatile char Byte_5th = 0;
volatile char Byte_6th = 0;
long int RetuData = 0;
unsigned short int cnt;
AHT20_SendAC();//向AHT20发送AC命令
Delay_ms(80);//延时80ms左右
cnt = 0;
while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表示为空闲状态,若为1,表示忙状态
{
Delay_ms(2);
if(cnt++>=100)
{
break;
}
}
I2C_Start();
AHT20_WR_Byte(0x71);
Receive_ACK();
Byte_1th = AHT20_RD_Byte();//状态字,查询到状态为0x98,表示为忙状态,bit[7]为1;状态为0x1C,或者0x0C,或者0x08表示为空闲状态,bit[7]为0
Send_ACK();
Byte_2th = AHT20_RD_Byte();//湿度
Send_ACK();
Byte_3th = AHT20_RD_Byte();//湿度
Send_ACK();
Byte_4th = AHT20_RD_Byte();//湿度/温度
Send_ACK();
Byte_5th = AHT20_RD_Byte();//温度
Send_ACK();
Byte_6th = AHT20_RD_Byte();//温度
Send_NOT_ACK();
Stop_I2C();
RetuData = (RetuData|Byte_2th)<<8;
RetuData = (RetuData|Byte_3th)<<8;
RetuData = (RetuData|Byte_4th);
RetuData =RetuData >>4;
ct[0] = RetuData;//湿度,Srh
RetuData = 0;
RetuData = (RetuData|Byte_4th)<<8;
RetuData = (RetuData|Byte_5th)<<8;
RetuData = (RetuData|Byte_6th);
RetuData = RetuData&0xfffff;
ct[1] =RetuData; //温度,St
}
void Init_I2C_Sensor_Port(void) //初始化I2C接口,输出为高电平
{
SDA_Pin_Output_High();
SCL_Pin_Output_High();
}
void AHT20_Init(void) //初始化AHT20
{
Init_I2C_Sensor_Port();
I2C_Start();
AHT20_WR_Byte(0x70);
Receive_ACK();
AHT20_WR_Byte(0xa8);//0xA8进入NOR工作模式
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
Delay_ms(10);//延时10ms左右
I2C_Start();
AHT20_WR_Byte(0x70);
Receive_ACK();
AHT20_WR_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE
Receive_ACK();
AHT20_WR_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
Stop_I2C();
Delay_ms(10);//延时10ms左右
}
/*----------------------------------------------------------------------------*/
/* End Of File */
/*----------------------------------------------------------------------------*/