纮康单片机HY17P60基于IIC读取AHT20传感器数据送显

网上关于纮康资料很少,遇到什么问题都百度不了。(代码,波形图,结果后附)

用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                                                                   */
/*----------------------------------------------------------------------------*/

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单片机通过IIC总线接收传感器数据需要以下步骤: 1. 初始化IIC总线,设置IIC总线的时钟频率、传输模式等参数。 2. 设置IIC从设备地址和传感器寄存器地址,通过IIC总线发读取命令。 3. 等待传感器返回数据,通过IIC总线接收传感器数据。 4. 解析接收到的数据,将传感器数据存储在单片机的变量中。 下面是一个基于51单片机IIC接收传感器数据的示例代码: ``` #include <reg51.h> #define SDA P2_0 // IIC数据线 #define SCL P2_1 // IIC时钟线 void IIC_Start() { SDA = 1; SCL = 1; SDA = 0; SCL = 0; } void IIC_Stop() { SDA = 0; SCL = 1; SDA = 1; } unsigned char IIC_SendByte(unsigned char dat) { unsigned char i, ack; for (i = 0; i < 8; i++) { SDA = dat & 0x80; SCL = 1; SCL = 0; dat <<= 1; } SDA = 1; SCL = 1; ack = SDA; SCL = 0; return ack; } unsigned char IIC_ReadByte() { unsigned char i, dat = 0; SDA = 1; for (i = 0; i < 8; i++) { dat <<= 1; SCL = 1; dat |= SDA; SCL = 0; } return dat; } void IIC_Ack() { SDA = 0; SCL = 1; SCL = 0; SDA = 1; } void IIC_NAck() { SDA = 1; SCL = 1; SCL = 0; } void IIC_Init() { SDA = 1; SCL = 1; } void main() { unsigned char addr = 0x50; // 传感器IIC地址 unsigned char reg = 0x00; // 传感器寄存器地址 unsigned char data[2] = {0}; // 存储传感器数据 IIC_Init(); // 初始化IIC总线 IIC_Start(); // 发起始信号 IIC_SendByte(addr << 1); // 发从设备地址 IIC_SendByte(reg); // 发寄存器地址 IIC_Start(); // 发起始信号 IIC_SendByte((addr << 1) | 0x01); // 发从设备地址,读取数据 data[0] = IIC_ReadByte(); // 读取数据 IIC_Ack(); // 发应答信号 data[1] = IIC_ReadByte(); // 读取数据 IIC_NAck(); // 发非应答信号 IIC_Stop(); // 发停止信号 // 将读取传感器数据存储到单片机的变量中 // ... } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值