我按照DHT11的典型电路和时序图在PIC18的单片机上实验成功,但是移植到m430f2619上确不行,关键是在发送完启动信号好,dht11没有给一个低电平回应。卡在这里几天了,请做过的大神指点一下。关键地方加粗了,请帮下忙,谢谢。
#include
#define DQ P1IN & BIT0 //数据
#define DQ_HIGH() P1DIR |= BIT0; P1OUT |= BIT0 //设为输出,拉高电平
#define DQ_LOW() P1DIR |= BIT0; P1OUT &= ~BIT0 //设为输出,拉低电平
#define DQ_IN() P1DIR &= ~BIT0 //设为输入,拉高电平
//外接晶振16MHz
#define CPU_F ((double)16000000) //频率
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
//******************************初始化函数************************
void Init_CLK( void ){ int i; BCSCTL3 |= XT2S_2; // XT2频率范围设置 BCSCTL1 &= ~XT2OFF; // 打开XT2振荡器 BCSCTL1 |= DIVA_1; // ACLK/2 do { IFG1 &= ~OFIFG; // 清振荡器失效标志 BCSCTL3 &= ~XT2OF; // 清XT2失效标志 for( i = 0x47FF; i > 0; i-- ); // 等待XT2频率稳定 }while (IFG1 & OFIFG); // 外部时钟源正常起动了吗? BCSCTL2 |= SELM_2 + SELS + DIVS_2 ; // 设置MCLK、SMCLK为XT2}void Init_Port( void ){ P4OUT &= ~( BIT4+BIT3 + BIT6); P4SEL |= BIT6; P4DIR |= BIT4 + BIT6; P7DIR |= 0xFF; P7OUT = 0xFF; P8DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5; P8OUT = 0xFF; P5DIR |= BIT7; P5OUT |= BIT7; P2REN = 0xff; P2IFG = 0; P2IES |= BIT1 + BIT0; //开Key1、Key3 P2IE |= BIT0 + BIT1;}void Init_MCU( void ){ WDTCTL = WDTPW + WDTHOLD; // 关看门狗 Init_CLK(); // 初始化时钟 Init_Port(); // 初始化端口}//******************************初始化函数************************
//***************************dht11*****************************
char receive(void) //接受函数
{
char tem=0,cnt=0,data=0; //临时变量用于存储接受数据
int respond=2;
for(cnt=0;cnt<8;cnt++)
{
respond=2;
while(!DQ && respond++); //等待50us的低电平结束
delay_us(30);
tem=0;
if(DQ) //长于30us定义为1
{
tem=1;
respond=2;
while(DQ && respond++); //结束高电平
}
data<<=1;
data|=tem;
}
return data;
}
int get_TRH()
{
int temp,j;
char respond=1;
unsigned char TH_TEMP,TL_TEMP,RH_TEMP,RL_TEMP,CK_TEMP,TH,TL,RH,RL,CK;
DQ_LOW(); //拉低
delay_ms(20);//18ms 延时一个没错吧,我用LED灯试过亮灭500ms的,目测差别不是很大
DQ_IN(); //拉高
delay_us(40);//40us
//关键在这里DHT11没有给一个低电平的回应,所以下面直接跳过了
if(!DQ)
{
respond=2;
while(!DQ&&respond++);
if(respond==1)
{
return 9911; //超时返回
}
respond=2;
while(DQ&&respond++);
if(respond==1)
{
return 9912; //超时返回
}
RH_TEMP=receive();
RL_TEMP=receive();
TH_TEMP=receive();
TL_TEMP=receive();
CK_TEMP=receive();
DQ_IN(); //接收结束
CK=(TH_TEMP+TL_TEMP+RH_TEMP+RL_TEMP); //数据验证
if(CK==CK_TEMP)
{
TH=TH_TEMP;
TL=TL_TEMP;
RH=RH_TEMP;
RL=RL_TEMP;
}
else
return 9993; //超时返回
temp=(int)(TH); //返回温度值
return temp;
}
return 9999; //没有回应返回
}
//***************************dht11*****************************
int main( void )
{
Init_MCU();
while(1)
{
delay_ms(500);
get_TRH();
}
LPM0;
return 0;
}