|
本人一个AHT10湿度 测量程序,使用IIC,在89C52测试正常,移植到STC15w408后,测量不出数值,读取的值均为0xFF。但用STC15w408测试SHT30时正常,也是IIC方式。请高人指点。
下面是测量代码:
#include <intrins.h>
#include "stc15.h"
#include "aht10.h"
#include <stdio.h>
sbit SCL = P1^0;
sbit SDA = P1^1;
//声明ACKflag 为字节变量
/*I2C通信初始化*/
void I2C_Start() //起始信号
{
SCL = 1;
SDA = 1;
delay5us();
SDA = 0;
delay5us();
}
void I2C_Stop() //停止信号
{
SCL = 0;
SDA = 0;
SCL = 1;
delay5us();
SDA = 1;
delay5us();
}
/*I2C应答和非应答*/
//I2C主机读从机应答
bit ReadACK()
{
SCL = 0;
SCL = 1;
delay5us();
if(SDA)//非应答
{
SCL = 0;
return (0);
}
else//应答
{
SCL = 0;
return(1);
}
}
//I2C主机发送应答
void sendACK(bit i)
{
SCL = 0;
if(i)
SDA = 1;
else
SDA = 0;
SCL = 1;
delay5us();
SCL = 0;
SDA = 1; //释放数据总线
}
uchar I2cReadByte()
{
uchar j,DAT;
for(j = 0;j<8;j++)
{
DAT <<=1;
SCL = 0;
SCL = 1;
if(SDA)
DAT |= 0X01;
}
return (DAT);
delay5us();
}
void I2CSendByte(uchar DAT) //发送一个字节
{
uchar i;
for(i = 0;i < 8; i++)
{
SCL = 0; //拉低时钟线才能允许数据变化
if(DAT & 0X80)
SDA = 1;
else
SDA = 0;
SCL = 1;
DAT <<= 1;
}
SCL = 0;
SDA = 1;//释放数据总线
}
/*1.延时40ms函数 2.延时5微秒函数*/
void delayms()
{unsigned char i, j, k;
_nop_();
_nop_();
i = 1;
j = 26;
k = 223;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void delay5us()
{ unsigned char i;
_nop_();
i = 11;
while (--i);
}
//*******************************
uchar JH_Read_Status(void) //读取AHT10的状态寄存器
{
uchar Byte_first;
I2C_Start();
I2CSendByte(0x71);
if (!ReadACK()) { //检测应答
return 0;
}
Byte_first = I2cReadByte();
sendACK(1);//此处为回复NOACK,意思为停止读操作
I2C_Stop();
return Byte_first;
}
uchar JH_Read_Cal_Enable(void) //查询cal enable位有没有使能?
{
uchar val = 0; //ret = 0,
val = JH_Read_Status();
if ((val & 0x68) == 0x08) //判断NOR模式和校准输出是否有效
return 1;
else
return 0;
}
void JH_SendAC(void) //向AHT10发送AC命令
{
I2C_Start();
I2CSendByte(0x70);
if (!ReadACK()) { //检测应答
return;
}
I2CSendByte(0xac);
if (!ReadACK()) { //检测应答
return;
}
I2CSendByte(0x33);
if (!ReadACK()) { //检测应答
return;
}
I2CSendByte(0x00);
sendACK(0);
I2C_Stop();
}
void JH_Send_BA(void) //向AHT10发送BA命令
{
I2C_Start();
I2CSendByte(0x70);
if (!ReadACK()) { //检测应答
return;
}
I2CSendByte(0xba);
if (!ReadACK()) { //检测应答
return;
}
I2C_Stop();
}
uchar JH_Init(void) //初始化AHT10
{
JH_Send_BA();
delayms();
I2C_Start();
I2CSendByte(0x70);
if (!ReadACK()) { //检测应答
return 0;
}
I2CSendByte(0xe1); //写系统配置寄存器
if (!ReadACK()) { //检测应答
return 0;
}
I2CSendByte(0x08);
if (!ReadACK()) { //检测应答
return 0;
}
I2CSendByte(0x00);
if (!ReadACK()) { //检测应答
return 0;
}
I2C_Stop();
while (JH_Read_Cal_Enable() == 0)//需要等待状态字status的Bit[3]=1时才去读数据。如果Bit[3]不等于1 ,发软件复位0xBA给AHT10,再重新初始化AHT10,直至Bit[3]=1
{
delayms();
JH_Send_BA(); //复位
//os_delay_us(10000);
delayms();
I2C_Start();
I2CSendByte(0x70);
if (!ReadACK()) { //检测应答
return 0;
}
I2CSendByte(0xe1); //写系统配置寄存器
if (!ReadACK()) { //检测应答
return 0;
}
I2CSendByte(0x08);
if (!ReadACK()) { //检测应答
return 0;
}
I2CSendByte(0x00);
if (!ReadACK()) { //检测应答
return 0;
}
I2C_Stop();
delayms();
}
return 1;
}
void JH_Read_CTdata(unsigned int *Temp,unsigned int *Hum) //读取AHT10的温度和湿度数据
{
volatile uchar Byte_1th = 0;
volatile uchar Byte_2th = 0;
volatile uchar Byte_3th = 0;
volatile uchar Byte_4th = 0;
volatile uchar Byte_5th = 0;
volatile uchar Byte_6th = 0;
u32 RetuData = 0;
int cnt = 0;
delayms();
JH_SendAC();
delayms();
delayms();
while (((JH_Read_Status()&0x80)==0x80)) //等待忙状态结束
{
}
I2C_Start();
I2CSendByte(0x71); //0x70+1 0x70为设备地址 1为方向位
if (!ReadACK()) { //检测应答
return;
}
Byte_1th = I2cReadByte(); //状态字
sendACK(0);
Byte_2th = I2cReadByte(); //湿度字节
sendACK(0);
Byte_3th = I2cReadByte(); //湿度字节
sendACK(0);
Byte_4th = I2cReadByte(); //高4位为湿度 低4位为温度
sendACK(0);
Byte_5th = I2cReadByte(); //温度字节
sendACK(0);
Byte_6th = I2cReadByte(); //温度字节
sendACK(1);//此处为回复NOACK,意思为停止读操作
I2C_Stop();
RetuData = (RetuData | Byte_2th) << 8;
RetuData = (RetuData | Byte_3th) << 8;
RetuData = (RetuData | Byte_4th);
RetuData = RetuData >> 4;
*Hum =(RetuData*1000/1024/1024);
RetuData = 0;
RetuData = (RetuData | Byte_4th) << 8;
RetuData = (RetuData | Byte_5th) << 8;
RetuData = (RetuData | Byte_6th);
RetuData = RetuData & 0xfffff;
*Temp = (RetuData*2000/1024/1024 - 500);
}
|
|