|
发表于 2009-10-25 15:12:28
|
显示全部楼层
各位大侠,小弟用DHT11传感器的时候出了点问题,自己琢磨了好几天没有结果,请各位大侠来帮忙解决一下。
我用的单片机是ATmega16L。8M晶振。
附上我的程序
#include <iom16v.h>
#include <macros.h>
#include <AVR_PQ1A.h> //包含自定义常量头文件
#define uchar unsigned char
#define uint unsigned int
#define j7 PIND&BIT(7)
#pragma data:code
const uchar table[]="wen du is";
const uchar table1[]="shi du is:";
const uchar shuzu[]="0123456789"; //利用一个温度表解决温度显示乱码
unsigned char wendu_shi,wendu_ge,wendu_xs,
shidu_shi,shidu_ge,shidu_xs; //定义的时候用uchar宏定义就会出错
//===============ms延时程序================//
void delay_ms(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++); //1ms延时
}
}
/*******************************************
函数名称: Delayus
功 能: 延时指定微秒(8M晶振)
参 数: US--延时的微秒数(大约,不是很精确,MS越大越准确)
返回值 : 无
/********************************************/
void delay_us(uint US)
{
uint i;
US=US*5/4; //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
for( i=0;i<US;i++);
}
/*******************************************
//===============us延时函数=================//
void delayus(uchar i) //延时 i=9时,延8.37us ;8M晶振
{
while(i--);
}
*****************************************/
////////////////////// 1602液晶显示程序//////////////////////////////
void write_com(uchar com) //写命令函数
{
PORTD&=~BIT(4);
PORTD&=~BIT(5);
PORTB=com;
PORTD|=BIT(6);
delay_ms(1);
PORTD=0x30;
}
void write_date(uchar date) //写数据函数
{
PORTD|=BIT(4);
PORTD&=~BIT(5);
PORTB=date;
PORTD|=BIT(6);
delay_ms(1);
PORTD=0x30;
}
void chushihua(void) //液晶初始化函数
{
DDRB=0XFF;
DDRD|=BIT(4)|BIT(5)|BIT(6);
PORTD=0x30;
write_com(0X38);
delay_ms(5);
write_com(0X01);
delay_ms(5);
write_com(0X0C);
delay_ms(5);
write_com(0X06);
delay_ms(5);
}
//======================DHT11指令读取===================================//
uchar DHT_COM()
{
uchar i,j,U8comdata,U8temp;
uint U16FLAG;
for(i=0;i<8;i++)
{
DDRD&=~BIT(7);//主机置为输入
// j=PIND&BIT(7);//读取PIND寄存器的值
if(!j7)
{
U16FLAG=65335; //计数65535-65335=200次耗时50US
while((!j7)&&U16FLAG++);//延时等待高电平的到来
//if(j7==0)break;
U16FLAG=65335;
while(j7&&U16FLAG++)
//delay_us(40);//延时30us
U8temp=0;//将0赋值给U8temp
if(j7)//判断高电平是否结束,如果结束,0赋值给U8temp,不执行IF语句
U8temp=1;//如果没结束,1赋值给U8temp // 如果高电平高过预定0高电平值则数据位为 1
}
U16FLAG=2;
while(j7&&U16FLAG++);//延时等待低电平的到来
//超时则跳出for循环
if(U16FLAG==1)
break;
//以上语句判断数据位是0还是1
U8comdata<<=1;
U8comdata|=U8temp;
}
return (U8comdata);
}
//void DHT_Read(void)
//{ }
void main()
{
uchar i;
uint U16FLAG;
uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata,U8temp;
uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
// while(1)
// {
DDRD|=BIT(7);//主机信号置为输出
PORTD|=BIT(7);//输出高电平
delay_us(6);//持续6us;
PORTD&=~BIT(7);//主机输出低电平;
delay_ms(20);//延时18MS以上;
PORTD|=BIT(7);
delay_us(40);
//DDRD&=~(1<<PD7);//主机信号置为输入
DDRD&=~BIT(7);//主机置为输入,读DHT11响应信号
PORTD|=BIT(7);//带上拉的输入
// delay_us(40);//主机拉高延时40us
//j=PIND&BIT(7);//读取寄存器PIND的值;
if(!j7)//判断从机是否发出低电平响应信号
{
U16FLAG=65215; //计数初值65535-65215=320.耗时80US
while((!j7)&&U16FLAG++);//判断从机发出 80us 的低电平响应信号是否结束
//delay_us(40);
U16FLAG=65215;
while(j7&&(U16FLAG++));//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
U8RH_data_H_temp=DHT_COM();
U8RH_data_L_temp=DHT_COM();
U8T_data_H_temp=DHT_COM();
U8T_data_L_temp=DHT_COM();
U8checkdata_temp=DHT_COM();
delay_us(50);//数据传送完毕,延时50us
DDRD|=BIT(7);
PORTD|=BIT(7);//主机置为输出高电平
//数据校验
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
wendu_shi=U8T_data_H/10;
wendu_ge=U8T_data_H%10;
wendu_xs=U8T_data_L/10;
shidu_shi=U8RH_data_H/10;
shidu_ge=U8RH_data_H%10;
shidu_xs=U8RH_data_L/10;
}
}
chushihua();//液晶初始化函数
/*//////////////////////////////////////////////////
液晶显示
***************************************************/
write_com(0X80);//液晶第一行显示
for(i=0;i<9;i++) //显示文字:wendushi
{
write_date(table);
delay_ms(5);
}
write_com(0x80+9); //显示冒号:
write_date(0X3a);
write_com(0x80+10); //显示温度的十数位
write_date(shuzu[wendu_shi]);
write_com(0x80+11); //显示温度的个数位
write_date(shuzu[wendu_ge]);
write_com(0x80+12); //显示小数点
write_date(0x2e);
write_com(0x80+0x00+13); //显示温度的小数位
write_date(shuzu[wendu_xs]);
write_com(0x80+0x00+14); //显示“°”
write_date(0xdf);
write_com(0x80+15); //显示摄氏度符号C
write_date(0x43);
write_com(0X80+0X40); //第二行显示
for(i=0;i<10;i++)
{
write_date(table1); //显示文字:shidushi:
delay_ms(5);
}
write_com(0x80+0x40+10);
write_date(shuzu[shidu_shi]);
write_com(0x80+0x40+11);
write_date(shuzu[shidu_ge]);
write_com(0x80+0x40+12); //显示小数点
write_date(0x2e);
write_com(0x80+0x40+13);
write_date(shuzu[shidu_xs]);
//write_com(0x80+0x40+14);
//write_date(shuzu[shidu_xiaoshu2]);
write_com(0x80+0x40+15); //显示百分号%
write_date(0x25);
} |
|