拓冰建站拓冰建站
首页 / 资讯中心 / 正文

STC8A8K64S4A12驱动DHT11温湿度传感器并串口显示实战解析

简介基于STC8A8K64S4A12-LQFP44单片机的DHT11温湿度传感器串口助手显示实验是一份面向单片机学习者和嵌入式开发者的完整软件例程。资源围绕DHT11驱动、串口1初始化及数据帧格式化输出展开主函数清晰展示了温度湿度数组清零、传感器数据读取与上传流程适合用于快速验证最小系统硬件或作为传感器驱动移植模板。压缩包共13个文件包含DHT11.C/H驱动源码、uart.c串口配置、main.c主程序、Keil工程文件uvproj/uvopt以及编译生成的hex与m51文件整体仅226KB结构精炼便于直接打开工程查看或烧录到开发板测试。资源已吸引685人学习使用者可通过例程掌握单总线时序读取、准双向口与推挽输出配置、串口中断收发等关键知识点从而缩短温湿度采集类项目的开发周期。1. 串口助手里显示温湿度代码能过编译只是第一步把“基于STC8A8K64S4A12-LQFP44单片机DHT11温湿度传感器串口助手显示实验软件例程源码.rar”这个标题拆开看真正值钱的不是DHT11驱动而是从IO口配置、单总线时序、串口初始化到上位机显示这一整条链路的串法。很多人拿到类似的例程下载到板子上发现串口助手里全是乱码或者一直显示ERR问题往往不在DHT11本身而在主频配置、引脚模式或者读取节奏上。这篇文章不做源码逐行注释而是讲清楚这类例程背后必须想明白的硬件规划、时序判据和调试方法。适合正在用STC8A系列做传感器实验、或者想把网上零散代码整理成自己能改的工程的人。2. 先定硬件STC8A8K64S4A12的引脚、上拉与时钟2.1 LQFP44封装下这颗芯片的资源边界STC8A8K64S4A12是典型的增强型80511T指令周期主频比传统51快得多片上有64KB Flash、8KB SRAMADC、PWM、多个串口和定时器都集成好了。LQFP44封装的好处是引脚数量充足P0到P3基本全部引出串口1的P3.0/P3.1、DHT11想接的P2口都不需要跟其他功能抢线实验时用杜邦线直接飞线非常方便。要特别注意一点STC8A系列是1T内核同样一段延时循环放在传统STC89C52上能用放到这颗芯片上实际时间会差一个数量级。所以例程里的延时函数、波特率重装值都必须按照这颗芯片的主频重新算这一点是很多从老51转过来的人最容易翻车的环节。2.2 DHT11接哪个引脚上拉电阻怎么配DHT11是单总线器件数据线空闲时必须被拉高通信时主机和DHT11轮流拉低总线。STC8A的IO口可以通过PxM0、PxM1两个寄存器配置成准双向、推挽、高阻输入和开漏四种模式。对于DHT11的数据脚我一般会选用准双向模式这种模式下IO内部有弱上拉既能输出低电平作为起始信号也能直接读取外部电平省去了模式切换的麻烦。外部再并一个4.7kΩ上拉电阻到VCC是为了提高总线抗干扰能力特别是杜邦线超过20厘米时没有这个电阻很容易出现偶发校验错误。DHT11的供电范围是3.3V到5.5V实验板如果用5V系统就整体供5V如果用3.3V单片机就统一供3.3VDHT11的模拟输出精度不会因供电电压有本质变化。信号单片机引脚IO模式说明DATAP2.0准双向DHT11数据线外部接4.7kΩ上拉到VCCVCC3.3V或5V-DHT11供电引脚GNDGND-与单片机共地TXDP3.1准双向串口1发送接USB-TTL的RXDRXDP3.0高阻输入串口1接收接USB-TTL的TXD2.3 波特率为什么总用定时器1的0xFFFD串口助手里显示温湿度前提是串口波特率算准。STC8A8K64S4A12的串口1波特率可以由定时器1或定时器2产生常见例程用定时器1配置成16位自动重装模式。以11.0592MHz主频、9600bps为例12T分频下重装值计算公式为65536 - 11059200 / (12 × 32 × 9600) 65536 - 3 65533也就是TH10xFFTL10xFD。这个组合在11.0592MHz下波特率误差为0所以绝大多数实验例程都采用这个主频和这个重装值。初始化代码通常长这样void UART1_Init(void) { SCON 0x50; // 串口1模式18位UART使能接收REN AUXR 0xBF; // T1x120定时器1按12T分频 AUXR 0xEF; // S1BRT0串口1波特率发生器选择定时器1 TMOD (TMOD 0x0F) | 0x00; // 定时器1模式016位自动重装 TH1 0xFF; TL1 0xFD; // 11.0592MHz 9600bps TR1 1; // 启动定时器1 ES 1; // 使能串口1中断 EA 1; // 打开总中断 }代码里SCON0x50是串口1模式1的标准配置8位数据、可变波特率、允许接收。AUXR的两个位是STC8A特有的第6位控制定时器1的分频第4位选择串口1的波特率发生器。如果这两步漏了后面串口助手收到的数据大概率是乱码。主频来源也值得确认STC8A8K64S4A12支持内部IRC和外部晶振下载程序时可以通过STC-ISP软件把IRC频率设置成11.0592MHz这样整板不需要外接晶振。但要记住下载器里选的频率必须和代码里延时所依据的主频一致否则DHT11时序和串口波特率会同时出问题。3. DHT11单总线时序是例程的核心应答、0/1与校验3.1 一次完整握手主机拉低18ms后释放DHT11的通信由主机发起流程固定主机先把总线拉低至少18ms然后释放总线并等待20到40us再读DHT11的响应。DHT11收到起始信号后会先拉低总线80us左右再拉高80us左右这个低-高组合就是“我准备好了”的应答信号。应答结束后DHT11开始连续输出40bit数据高位先出。uint8_t DHT11_Start(void) { uint8_t cnt 0; DHT_PIN 0; // 主机拉低总线 Delay_ms(18); // 起始信号持续18ms DHT_PIN 1; // 释放总线准双向模式下写1即释放 Delay_us(30); // 等待DHT11应答 if (DHT_PIN) return 1; // 总线为高说明DHT11没有拉低应答 while (!DHT_PIN cnt 100); // 等待应答低电平结束 cnt 0; while (DHT_PIN cnt 100); // 等待应答高电平结束 if (!DHT_PIN) return 1; // 应为高电平却仍为低信号异常 return 0; // 握手成功 }这段代码的关键在于主机释放总线后必须立刻检测电平变化不能加一个长延时再读。DHT11的应答低电平只有80us左右在1T主频下稍不留神就过去了。第二个while循环里用cnt做超时保护防止总线卡死在某个电平上导致程序死等。3.2 位判定高电平宽度超过40us就是1DHT11输出的每一位都由一段约50us的低电平起始然后是一段高电平。数据0的高电平持续时间约23到27us数据1的高电平约68到74us。所以判0还是判1看的不是低电平而是低电平之后那段高电平有多宽。uint8_t DHT11_ReadBit(void) { uint8_t cnt 0; while (!DHT_PIN cnt 200); // 等待位起始低电平结束 cnt 0; while (DHT_PIN cnt 200); // 统计高电平持续时间 return (cnt 40) ? 1 : 0; // 超过40次循环判为1 }这个函数的cnt不是精确的微秒数而是循环次数。在11.0592MHz下约等于每次循环1us所以阈值40对应40us左右正好落在数据0和数据1的高电平宽度中间。main函数里的程序主循环延时也要注意不能低于1秒。while (1) { if (rx_cmd 0xA1) // 串口助手发0xA1触发一次读取 { if (DHT11_Start() 0) { hum_i DHT11_ReadByte(); hum_d DHT11_ReadByte(); tem_i DHT11_ReadByte(); tem_d DHT11_ReadByte(); checksum DHT11_ReadByte(); if ((uint8_t)(hum_i hum_d tem_i tem_d) checksum) { UART1_SendString(T:); UART1_SendU8(tem_i); UART1_SendByte(.); UART1_SendU8(tem_d); UART1_SendString( RH:); UART1_SendU8(hum_i); UART1_SendByte(.); UART1_SendU8(hum_d); UART1_SendString(\r\n); } else { UART1_SendString(CRC ERR\r\n); } } else { UART1_SendString(DHT11 NO RESPONSE\r\n); } rx_cmd 0; // 命令执行完清空 } // 主循环里不额外做长延时等串口命令触发 }这个主循环和前面那种“上电后无限循环读”的做法不太一样每次读取由串口命令触发更适合观察DHT11在不同环境下的实时响应。发送字符串时注意小数字段如果为0会显示成T:25.0 RH:60.0这种格式在串口助手里最容易对齐查看。4.5 这些代码里的常见误用很多人在写DHT11例程时会把读取函数放在一个大循环里不加节流直接反复读。DHT11手册和实际表现都要求两次读取间隔不低于1秒高频读取时器件会不应答或者返回固定值。另外位读取的阈值40是跟主频强相关的如果换成24MHz主频还不改参数数据0很容易被误判成数据1。最后准双向模式下写0是强拉低写1是释放总线不能像推挽输出那样理解成“输出高电平”理清这一点才能看懂DHT11驱动里的电平操作。5. 串口助手调试技巧与逻辑分析仪快速验证5.1 串口命令触发读取的小协议实验例程里除了上电自动发数据更灵活的做法是让串口助手发命令触发读取。常见约定是0xA1单次读取、0xA2开始自动周期上报、0xA3停止上报这样在调试时不用反复按复位键。void UART1_ISR(void) interrupt 4 { if (RI) { RI 0; rx_cmd SBUF; // 只缓存最新一条命令 } }这个中断函数只处理接收不处理发送发送路径由查询方式完成。要注意的是如果上位机连续发多条命令MCU来不及处理后面的命令会覆盖前面的所以实际使用中每次发完命令等结果返回再发下一条。5.2 优先用逻辑分析仪看DHT11波形遇到DHT11返回ERR或者数据跳变不要先怀疑代码把逻辑分析仪接在P2.0上采样率设8MHz以上抓一次握手和40bit数据。看波形时重点确认三件事起始低电平是否接近18ms应答信号是否存在每位的高电平宽度是否落在对应区间。波形不对问题在硬件波形对但数据错问题在读取逻辑。5.3 串口助手常见表现对照串口助手现象可能原因排查方向全部是0x00或0xFF波特率不匹配或USB-TTL接线反了检查TXD/RXD是否交叉确认波特率9600一直输出NO RESPONSE上拉电阻缺失或DHT11供电不足检查DATA线上拉、VCC电压数据偶尔CRC ERR读取间隔太短或杜邦线过长主循环延时加到2秒缩短杜邦线温度和湿度固定不变DHT11损坏或总线被其他外设占用换一颗DHT11确认P2.0没有复用最后一个调试技巧在DHT11_Start返回失败时用串口输出失败码而不是简单的字符串比如把握手失败的阶段用数字带出来配合逻辑分析仪的波形就能快速定位是起始信号没发出去还是应答没读回来。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门