这两天调试了DHT11,单片机是M0516LBN,对着示波器调了两天没调处来,惭愧,左右找不出问题,无意中将P0_PIN改成P0_PIN的地址,居然成功了,在此分享代码,让后来者不要浪费时间。
#include "delay.h"
void delay_us(uint32_t unCnt)//delay_us(2)-->6US;delay_us(5)-->10US;delay_us(24);-->30US
{
SYST_RVR = unCnt*12; //系统时钟频率 12MHz,计数一次1/12(us),所以乘以12
SYST_CVR = 0;
SYST_CSR |=1UL<<0;
while((SYST_CSR & 1UL<<16)==0);
// uint16_t i=0;
// uint16_t j=0;
// for(i=0;i<unCnt;i++)
// {
// j++;j++;j++;j++;
// }
}
void delay_ms(uint32_t unCnt)
{
SYST_RVR = unCnt*12000; //系统时钟频率 12MHz
SYST_CVR = 0;
SYST_CSR |=1UL<<0;
while((SYST_CSR & 1UL<<16)==0);
// uint16_t i,j;
// for(i=0;i<unCnt;i++)
// {
// for(j=0;j<1169;j++)
// {}
// }
}
void delay_280us(void)
{
uint16_t i;
for(i=0;i<415;i++)
{
}
}
void delay_20ms(void)
{
uint16_t i,j;
for(j=0;j<16800;j++)
{}
}
void delay_10us(void)
{
uint16_t i;
for(i=0;i<14;i++)
{
}
}
void delay_5us(void)
{
uint16_t i;
for(i=0;i<6;i++)
{
}
}
void delay_30us(void)
{
uint16_t i;
for(i=0;i<55;i++)
{
}
}
void delay_40us(void)
{
uint16_t i;
for(i=0;i<65;i++)
{
}
}
void delay_80us(void)
{
uint16_t i;
for(i=0;i<155;i++)
{
}
}
#define DHT_OUT P0_PMD=P0_PMD&0XFFFC|0X0001
#define DHT_IN P0_PMD=P0_PMD&0XFFFC
#define DHT_IO P0_PMD=P0_PMD&0XFFFC|0X0003
#define DHT_OD P0_PMD=P0_PMD&0XFFFC|0X0002
#define DHT_H P0_DOUT|=(1<<0)
#define DHT_L P0_DOUT&=~(1<<0)
#define DHT_DATA P0_PIN&0X01
uint8_t DHTSTA=1;
uint8_t DHT11_ReadDis(void)
{
uint8_t i=0,j=0,dat1,dat2,dat3,dat4,dat5;
DHT_IO;
DHT_L;
delay_20ms();
DHT_H;
delay_us(5);//延时10us
//等待DHT11的低电平响应
while(((*((volatile unsigned long *)0x50004010UL))&0X01));//((*((volatile unsigned long *)0x50004010UL)) --> P0_PIN,换成P0_PIN就不行,读不出数据了
//DHT11响应80us的低电平后会有一个80us的高电平
while(!((*((volatile unsigned long *)0x50004010UL))&0X01));//DHT11会拉高40~80us,等待高电平 -_↓_----
//开始接收数据
for(i=0;i<8;i++)
{
dat1<<=1;
while(((*((volatile unsigned long *)0x50004010UL))&0X01)); //等待低电平
while(!((*((volatile unsigned long *)0x50004010UL))&0X01));//等待高电平
delay_30us();//30us之后还是高电平,那此位为1
if((*((volatile unsigned long *)0x50004010UL))&0X01)
{
dat1|=0x01;
}
}
for(i=0;i<8;i++)
{
dat2<<=1;
while(((*((volatile unsigned long *)0x50004010UL))&0X01));
while(!((*((volatile unsigned long *)0x50004010UL))&0X01));delay_30us();
if((*((volatile unsigned long *)0x50004010UL))&0X01)
{
dat2|=0x01;
}
}
for(i=0;i<8;i++)
{
dat3<<=1;
while(((*((volatile unsigned long *)0x50004010UL))&0X01));
while(!((*((volatile unsigned long *)0x50004010UL))&0X01));delay_30us();
if((*((volatile unsigned long *)0x50004010UL))&0X01)
{
dat3|=0x01;
}
}
for(i=0;i<8;i++)
{
dat4<<=1;
while(((*((volatile unsigned long *)0x50004010UL))&0X01));
while(!((*((volatile unsigned long *)0x50004010UL))&0X01)); delay_30us();
if((*((volatile unsigned long *)0x50004010UL))&0X01)
{
dat4|=0x01;
}
}
for(i=0;i<8;i++)
{
dat5<<=1;
while(((*((volatile unsigned long *)0x50004010UL))&0X01));
while(!((*((volatile unsigned long *)0x50004010UL))&0X01));
delay_30us();
if((*((volatile unsigned long *)0x50004010UL))&0X01)
{
dat5|=0x01;
}
}
//DHT响应完毕,准备接收数据
if(dat5==(dat1+dat2+dat3+dat4))
{
LCD3029_DisHZ16Num(216,223,111,126,&num[dat1%100/10][0],WHITE,BLACK);
LCD3029_DisHZ16Num(224,231,111,126,&num[dat1%10][0],WHITE,BLACK);
LCD3029_DisHZ16Num(216,223,130,145,&num[dat3%100/10][0],WHITE,BLACK);
LCD3029_DisHZ16Num(224,231,130,145,&num[dat3%10][0],WHITE,BLACK);
}
return DHTSTA;
} |