1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32C8T6+DHT11在OLED上显示 温度,湿度
平台 STM32T103C8T6 传感器:DHT11 1.DTH11的工作原理 2.程序 程序这块我自己直接用了正点原子的战舰历程里面的DHT11的历程, 这个是DHT11.c #include "dht11.h" #include "delay.h" //复位DHT11 void DHT11_Rst(void) { DHT11_IO_OUT(); //SET OUTPUT DHT11_DQ_OUT=0; //拉低DQ delay_ms(20); //拉低至少18ms DHT11_DQ_OUT=1; //DQ=1 delay_us(30); //主机拉高20~40us } //等待DHT11的回应 //返回1:未检测到DHT11的存在 //返回0:存在 u8 DHT11_Check(void) { u8 retry=0; DHT11_IO_IN();//SET INPUT while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; else retry=0; while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; return 0; } //从DHT11读取一个位 //返回值:1/0 u8 DHT11_Read_Bit(void) { u8 retry=0; while(DHT11_DQ_IN&&retry<100)//等待变为低电平 { retry++; delay_us(1); } retry=0; while(!DHT11_DQ_IN&&retry<100)//等待变高电平 { retry++; delay_us(1); } delay_us(40);//等待40us if(DHT11_DQ_IN)return 1; else return 0; } //从DHT11读取一个字节 //返回值:读到的数据 u8 DHT11_Read_Byte(void) { u8 i,dat; dat=0; for (i=0;i<8;i++) { dat<<=1; dat|=DHT11_Read_Bit(); } return dat; } //从DHT11读取一次数据 //temp:温度值(范围:0~50°) //humi:湿度值(范围:20%~90%) //返回值:0,正常;1,读取失败 u8 DHT11_Read_Data(u8 *temp,u8 *humi) { u8 buf[5]; u8 i; DHT11_Rst(); if(DHT11_Check()==0) { for(i=0;i<5;i++)//读取40位数据 { buf=DHT11_Read_Byte(); } if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) { *humi=buf[0]; *temp=buf[2]; } }else return 1; return 0; } //初始化DHT11的IO口 DQ 同时检测DHT11的存在 //返回1:不存在 //返回0:存在 u8 DHT11_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PG端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PG11端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO口 GPIO_SetBits(GPIOA,GPIO_Pin_1); //PG11 输出高 DHT11_Rst(); //复位DHT11 return DHT11_Check();//等待DHT11的回应 } //这里我改了IO口,改成了PA1,大家也可以给改成其他IO 这个是DHT11.h #ifndef __DHT11_H #define __DHT11_H #include "sys.h" // //IO方向设置 #define DHT11_IO_IN() {GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=8<<4;}//上拉下拉输入 #define DHT11_IO_OUT() {GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=3<<4;}//输出,50MHz IO操作函数 #define DHT11_DQ_OUT PAout(1) //数据端口 PA0 #define DHT11_DQ_IN PAin(1) //数据端口 PA0 u8 DHT11_Init(void);//初始化DHT11 u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度 u8 DHT11_Read_Byte(void);//读出一个字节 u8 DHT11_Read_Bit(void);//读出一个位 u8 DHT11_Check(void);//检测是否存在DHT11 void DHT11_Rst(void);//复位DHT11 #endif //这里也要改一下 那DHT11部分的程序就到这里了,接下来就是主程序的修改了 Main.c 照样的添加头文件,初始化添加函数 #include "dht11.h" DHT11_Init(); //两个U8类型的定义,因为DHT11的精度是分辨率是1℃和1%RH u8 temperature=10; u8 humidity=20; u8 tem_BUF[20];//后面OLED用到 u8 hum_BUF[20]; DHT11_Read_Data(&temperature,&humidity); //读取温湿度值 //可以先printf一下到串口看看有没有读到,如果读到了就进行下一步,如果没有读到就考虑一下传感器是不是接错线了,或者考虑换一下IO //我买的是如下图的, printf("温度:%d ℃ 湿度:%d %RH rn",temperature,humidity); 我的资料在这里 3. 显示部分 显示部分我用了一块IIC的四线OLED,问就是省事 用的是中景园家的OLED,驱动他们提供的资料会有,我就不贴出来了, 然后先制作显示中文的字库, 打开专用的字库制作软件,PCtoLCD2002 然后把生成的字模复制到oledfont.h这个文件下的char Hzk[]这个里面 为啥是这个呢?因为 / //显示汉字 void OLED_ShowCHinese(u8 x,u8 y,u8 no) { u8 t,adder=0; OLED_Set_Pos(x,y); for(t=0;t<16;t++) { OLED_WR_Byte(Hzk[2*no][t],OLED_DATA); adder+=1; } OLED_Set_Pos(x,y+1); for(t=0;t<16;t++) { OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA); adder+=1; } } //里面有个 Hzk 这个,当然你也可以把它改成其他的都可以的 然后在主函数里面调用显示 DHT11_Read_Data(&temperature,&humidity); //读取温湿度值 sprintf(tem_BUF,"%d ",temperature); sprintf(hum_BUF,"%d ",humidity); OLED_ShowCHinese(0,4,0);//温 OLED_ShowCHinese(16,4,1);//度 OLED_ShowCHinese(62,4,4);//℃ OLED_ShowString(36,4,tem_BUF,16); OLED_ShowCHinese(0,6,2);//湿 OLED_ShowCHinese(16,6,3);//度 OLED_ShowString(36,6,hum_BUF,16); OLED_ShowString(62,6,"%RH",16);. delay_ms(700); 4.效果 如果有兄弟觉得显示中文麻烦 英文显示可以这样 DHT11_Read_Data(&temperature,&humidity); //读取温湿度值 sprintf(tem_BUF,"Tem:%d C ",temperature); sprintf(hum_BUF,"Hum:%d RH",humidity); OLED_ShowString(36,4,tem_BUF,16); OLED_ShowString(36,6,hum_BUF,16); 动图效果因为刷新时1s一次,所以手机拍出来会看得到很严重的刷新感觉, 英文显示效果 下一期把这些加入到机智云,通过机智云的app可以实时查看传感器的状态 需要用到一个8266模块,连接wifi |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1180浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 20:38 , Processed in 1.014841 second(s), Total 48, Slave 39 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号