|
#include <avr/io.h>
#include <util/delay.h>
//口定義
#define PORT_DHT PORTC
//口方向定義
#define DDR_DHT DDRC
//讀取口定義
#define PIN_DHT PINC
//數(shù)據(jù)位定義
#define BIT_DHT PC4
#define RS PA0 //數(shù)據(jù)/命令控制端 0命令,1 數(shù)據(jù)
#define RW PA1 //讀/寫(xiě)選擇控制端 0寫(xiě),1讀
#define E PA2 //使能端 下降沿讀,高電平寫(xiě)
#define L_DHT PORT_DHT&=~(1<<BIT_DHT) //數(shù)據(jù)線(xiàn)強(qiáng)制拉低
#define H_DHT PORT_DHT|=(1<<BIT_DHT) //數(shù)據(jù)線(xiàn)強(qiáng)制拉高
#define O_DHT DDR_DHT|=(1<<BIT_DHT) //Mega16控制總線(xiàn),PD4為輸出
#define P_DHT DDR_DHT&=~(1<<BIT_DHT) //釋放總線(xiàn),PD4為輸入
#define I_DHT PIN_DHT&(1<<BIT_DHT) //數(shù)據(jù)線(xiàn)的狀態(tài)
void LCDPort_Init(void); //液晶端口初始化
void LCD_Init(void); //LCD 初始化
void Write_Com(unsigned char LCD_Com); //LCD 寫(xiě)指令
void Write_Data_Byte(unsigned char LCD_Data); //LCD 寫(xiě)字節(jié)數(shù)據(jù)
void Write_Place_xy(unsigned char x,unsigned char y); //指定當(dāng)前寫(xiě)字符的位置
void Write_Data_String(unsigned char x,unsigned char y,unsigned char *data);//在指定的(x,y)位置上寫(xiě)入字符串?dāng)?shù)據(jù)
void Write_Data_Char(unsigned char x,unsigned char y,unsigned char data);//在指定的(x,y)位置上寫(xiě)入字符數(shù)據(jù)
void Check_Busy(void); //讀寫(xiě)檢測(cè)函數(shù),每次對(duì)液晶操讀作前都要進(jìn)行寫(xiě)檢測(cè)
void Delayus(unsigned int lus); //us延時(shí)函數(shù)
void Delayms(unsigned int lms); //ms延時(shí)函數(shù)
/*******************************************************/
unsigned Reset()
{
O_DHT;
H_DHT;
_delay_us(2);
L_DHT;
_delay_us(19);
P_DHT;
_delay_us(20);
if(I_DHT)
return 0;
else
return 1;
}
int main(void)
{
_delay_ms(1000);
unsigned char tdata[5];
unsigned long u16Flag; // 超時(shí)計(jì)數(shù)
unsigned char iiii;
unsigned long u32I; // 接收數(shù)據(jù)臨時(shí)變量
unsigned long ReceiveValue = 0; // 接收數(shù)據(jù)包變量
unsigned long ReceiveValue1 = 0; // 接收校驗(yàn)和變量
unsigned int ReceiveHighByte; // 分解數(shù)據(jù)包 濕度
unsigned int ReceiveLowByte; // 分解數(shù)據(jù)包溫度
LCDPort_Init();
LCD_Init();
Write_Data_String(0,0,"ddddddd");
while(1)
if(Reset())
{ P_DHT;
while((!(I_DHT)) && ((u16Flag++)<50000));
ReceiveValue = 0;
ReceiveValue1 = 0;
u16Flag = 0;
while((I_DHT) && ((u16Flag++)<50000));
for(u32I=0x80000000; u32I>0; u32I>>=1)
{
u16Flag = 0;
while((!(I_DHT))&& ((u16Flag++)<3000));
u16Flag = 0;
_delay_us(28);
if(I_DHT)
{
ReceiveValue |= u32I;
}
while((I_DHT)&&((u16Flag++)<300));
}
for(u32I=0x80;u32I>0;u32I>>=1)
{
u16Flag = 0;
while((!(I_DHT))&&((u16Flag++)<3000));
u16Flag = 0;
_delay_us(28);
if(I_DHT)
{
ReceiveValue1 |= u32I;
}
while((I_DHT)&&((u16Flag++)<300));
}
while(!(I_DHT));
O_DHT;
H_DHT;
ReceiveLowByte =(unsigned int )( ReceiveValue&0x0000FFFF);
ReceiveHighByte = ReceiveValue>>16;
/****************************display******************************/
tdata[0]=*((unsigned char*)(&ReceiveHighByte) + 1)/10;
tdata[1]=*((unsigned char*)(&ReceiveHighByte) + 1)%10;
tdata[2]=*((unsigned char*)(&ReceiveLowByte) + 1)/10;
tdata[3]=*((unsigned char*)(&ReceiveLowByte) + 1)%10;
Write_Com(0xc0);
Write_Data_Byte( tdata[0]+0x30 );//顯示濕度十位
Write_Com(0xc1);
Write_Data_Byte( tdata[1]+0x30 );//顯示濕度個(gè)位
Write_Com(0xc2);
// Write_Data_Byte("%");
Write_Com(0xc4);
Write_Data_Byte( tdata[2]+0x30 );//顯示溫度十位
Write_Com(0xc5);
Write_Data_Byte( tdata[3]+0x30 );//顯示溫度個(gè)位
Write_Com(0xc6);
Write_Data_Byte(0xdf);//顯示"。"
Write_Com(0xc7);
Write_Data_Byte('C');
}
else
{
}
}
void LCDPort_Init()
{
//LCD 數(shù)據(jù)端口設(shè)置
PORTD = 0X00; //
DDRD = 0XFF; //配置端口PD全部為輸出口,LCD 數(shù)據(jù)端口
//LCD 控制端口設(shè)置
PORTA &= ~((1 << RS) | (1 << RW) | (1 << E)); //
DDRA |= (1 << RS) | (1 << RW) | (1 << E);
}
//LCD 初始化
void LCD_Init()
{
Write_Com(0X01); //清屏
Delayms(5);
Write_Com(0X38); //顯示模式設(shè)置 16x2顯示,5x7點(diǎn)陣,8 位數(shù)據(jù)接口
Delayms(5);
//Write_Com(0X0f); //顯示開(kāi)關(guān)控制,開(kāi)顯示,光標(biāo)顯示,光標(biāo)閃爍
Write_Com(0X0c); //顯示開(kāi)關(guān)控制,開(kāi)顯示,光標(biāo)不顯示,光標(biāo)不閃爍
Delayms(5);
Write_Com(0X06); //光標(biāo)設(shè)置,讀或?qū)懸粋(gè)字符后,地址指針加一,光標(biāo)加一,整屏不移動(dòng)
Delayms(5);
}
//LCD 寫(xiě)指令
void Write_Com(unsigned char LCD_Com)
{
Check_Busy();
PORTA &= ~(1 << RS); //RS=0,寫(xiě)命令
PORTA &= ~(1 << RW); //RW=0,寫(xiě)指令
PORTA |= (1 << E); //E=1,寫(xiě)操作
Delayms(1);
PORTD = LCD_Com; //指令送數(shù)據(jù)端口
PORTA &= ~(1 << E); //E=0,停止寫(xiě)操作
Delayms(1);
}
//LCD 寫(xiě)字節(jié)數(shù)據(jù)
void Write_Data_Byte(unsigned char LCD_Data)
{
Check_Busy();
PORTA |= (1 << RS); //RS=1,寫(xiě)數(shù)據(jù)
PORTA &= ~(1 << RW); //RW=0,寫(xiě)指令
PORTA |= (1 << E); //E=1,寫(xiě)操作
Delayms(1);
PORTD = LCD_Data; // 數(shù)據(jù)送數(shù)據(jù)端口
PORTA &= ~(1 << E); //E=0,停止寫(xiě)操作
Delayms(1);
}
//指定當(dāng)前寫(xiě)字符的位置
void Write_Place_xy(unsigned char x,unsigned char y)
{
unsigned char address;
if(y == 0) //行位置
{
address = 0x80 + x; //列位置,
}
else
{
address = 0x80 + 0x40 + x; //
}
Write_Com(address); //寫(xiě)地址
}
//在指定的(x,y)位置上寫(xiě)入字符串?dāng)?shù)據(jù)
void Write_Data_String(unsigned char x,unsigned char y,unsigned char *data)
{
Write_Place_xy(x,y); //寫(xiě)地址
while(*data)
{
Write_Data_Byte(*data); //寫(xiě)字符串
data++; //指針地址加1
}
}
//在指定的(x,y)位置上寫(xiě)入字符數(shù)據(jù) x列位置,y行位置
void Write_Data_Char(unsigned char x,unsigned char y,unsigned char data)
{
Write_Place_xy(x,y); //
Write_Data_Byte(data); //
}
//讀寫(xiě)檢測(cè)函數(shù),每次對(duì)液晶操作前都要進(jìn)行讀寫(xiě)檢測(cè)
void Check_Busy()
{
DDRD = 0X00; //PB口置為輸入口,準(zhǔn)備讀取數(shù)據(jù)
PORTA &= ~(1 << RS); //RS=0,讀命令
PORTA |= (1 << RW); //RW=1,讀指令
PORTA |= (1 << E); //E=1,使能
while(0X80 & PIND); //監(jiān)測(cè)忙信號(hào),直到忙信號(hào)為0,才能進(jìn)行讀寫(xiě)操作
PORTA &= ~(1 << E); //E=0
DDRD = 0XFF; //PB口置為輸出口,準(zhǔn)備向端口發(fā)送數(shù)據(jù)
}
//us級(jí)別的延時(shí)函數(shù)
void Delayus(unsigned int lus)
{
while(lus--)
{
_delay_loop_2(4); //_delay_loop_2(1)是延時(shí)4 個(gè)時(shí)鐘周期,參數(shù)為4 則延時(shí)16
//個(gè)時(shí)鐘周期,本實(shí)驗(yàn)用16M晶體,則16 個(gè)時(shí)鐘周期為16/16=1us
}
}
//ms級(jí)別的延時(shí)函數(shù)
void Delayms(unsigned int lms)
{
while(lms--)
{
Delayus(1000); //延時(shí)1ms
}
}
|
-
|