DHT11无法读出数据,请教各位
uchar RH_data_h, TM_data_h, RH_data_l, TM_data_l, cleck_data, temp;uchar data; //数据缓冲数组
uchar RH_data = {0, 0, '\0'}, TM_data = {0, 0, '\0'};
uchar RH_data_R = {0,0,'\0'}, TM_data_T = {0,0,'\0'};
uchar asc_D = {0,0, '\0'};
uchar T0_NUM;
// 内部晶振是使用1M的
// 数据口是PA0
// 延时函数在最后说明
/*************************************************************
函数名称:receive_data
功能:接受数据
************************************************************/
void receive_data()
{
uchar i,j,m;
DDRA = 0x00 ;//DATA_IN;
for(i = 0; i < 5; i++) //五字节的数据
{
data = 0X00;
for(j = 0; j < 8; j++)
{
while(!MOSIN); //等待低电平的到来,当低电平到来后便开始计时
for(m = 0; m < 50; m++); //延时50us后看还是不是高电平,如果是高那么这位就为1,否则为0
if(MOSIN) //上面延时了50us,此时引脚数据寄存器还是高电平的话,表明接受到的是1
{ //否则为0,
data |= BIT(7 - j); //由此可知,先读取的高位,此命令只是写入1的位,data = 0X00,所以没写的还是0
while(MOSIN); //如果是低电平则表示下一位的开始
}
}
}
}
/***********************************************
函数名称:ask_reply_do
功能:主机发出信号,DHT11回复信号,并且处理接收到的数据
**************************************************/
void ask_reply_do()
{
//主机拉低18ms
uchar i;
DDRA =0xff; //DATA_OUT;
PORTA = 0x00; //PORT_CLR;
delay_ms(20);
PORTA = 0xff; //PORT_SE //总线由上拉电阻拉高 主机延时20us
for(i = 0; i < 23; i++); //此操作为微秒级的延时
DDRA = 0x00 ;//DATA_IN;
//主机设为输入 判断从机响应信号
for(i = 0; i < 10;i++);
if(!MOSIN ) // 判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
{
//判断从机是否发出 80us 的低电平响应信号是否结束
while(!MOSIN); //等待从机把电平拉高
while(MOSIN); //从机是否发出了高电平,是的话就跳出继续,下面就是接受数据了
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
//数据接收状态
receive_data();
DDRA = 0xff; //DATA_OUT; //保证DHT11没工作时数据脚为高电平
PORTA = 0xff; //PORT_SET;
//数据校验
temp = (data + data + data + data);
if(data == temp)
{
RH_data = data; //只要整数部分
RH_data = data;
TM_data = data;
TM_data = data;
cleck_data = data;
}
}
}
/*------将读到的数据进行拆分显示到液晶上,x为要显示的数据,y为在液晶上要显示的位置----------*/
void show_TM_RH(uchar page, uchar line, uchar data)
{
uchar i, j, m;
j = data / 10;
m = data % 10;
LCD_set_addr(page, line);
LCD12864_sendbyte(1, j + 0x30);
LCD12864_sendbyte(1, m + 0x30);
}
//延时函数部分
void delay_1us(void) //1us延时函数
{
asm("nop");
}
void delay_us(unsigned int n) //N us延时函数
{
unsigned int i = 0;
for (i = 0; i < n; i++)
delay_1us();
}
void delay_1ms(void) //1ms延时函数
{
unsigned int i;
for (i = 0;i < 141; i++); //晶振为1M时,为8M时为1140
}
void delay_ms(unsigned int n) //N ms延时函数
{
unsigned int i = 0;
for (i = 0; i < n; i++)
delay_1ms();
} 延时。先用示波器调好两个延时再试。 奥松官网有STC的代码 不用调试直接可用 问题已经解决啦。。。还是延时的问题,给大家提供比较精确的延时void delay_30ms (unsigned int n) //延时30msn=4992
{
unsigned int i;
i = n;
while (i--);
}
void delay_50us (unsigned int n) //延时50usn = 0
{
unsigned int i;
i = n;
while (i--);
}
void delay_30us (unsigned int n) //延时30us n=2
{
while (n--);
} 较长时间延时还是用定时器好,不但精确,在多个任务需要运行的时候会有效提高单片机效率,在不同单片机之间移植程序也方便些。
页:
[1]