尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

STC单片机驱动DS18B20温度传感器+ST7735 TFT屏显示完整指南

发布时间:2026/9/14 14:16:22

资讯中心
01
ARTICLE

STC单片机驱动DS18B20温度传感器+ST7735 TFT屏显示完整指南

STC单片机驱动DS18B20温度传感器+ST7735 TFT屏显示完整指南
简介面向STC单片机开发者和嵌入式初学者此压缩包完整展示了如何将STC单片机与ST7735驱动1.8寸TFT屏及DS18B20数字温度传感器结合搭建实时环境温度显示系统。资源围绕底层驱动、通信协议和界面显示展开包含C语言源码、头文件、工程配置文件及演示视频覆盖从单总线读取温度到TFT屏幕绘制的全过程适合学习1-Wire通信、SPI/LCD驱动和单片机外设协同开发的读者参考。包内共111个文件以c/h源码、obj/lst中间文件、uvproj/uvopt工程配置为主另有hex烧录文件、map/m51链接映射及mp4演示录屏整体约38.96MB结构清晰既能直接查看源码逻辑也可导入Keil工程重新编译。目前已有631人学习文件内还包含PCA、定时器、按键等模块可帮助读者理解系统初始化与任务调度是入门STC图形化温度监测项目的实用参考。1. STC单片机驱动DS18B20和ST7735 TFT屏这一组合难点在哪一个环境温度显示器最省事的方案是STM32加现成库但放到STC单片机上难点就变了DS18B20靠一条IO口做单总线通信时序窗口窄到微秒级STC89C52这类12T单片机连硬件SPI都没有ST7735这块1.8寸屏的刷新还要靠IO口去模拟。同样一个温度值在串口打印容易让它稳定显示到TFT彩屏上中间隔着两条链路一条是DS18B20的读写时序另一条是ST7735的信号时序。这篇内容把这两条链路的连接、驱动写法、显示格式和排错顺序完整理一遍适合用51内核做仪表显示或者想把串口数据搬到TFT液晶屏上的开发者。2. STC单片机与ST7735 TFT屏的硬件连接和SPI基础2.1 STC89C52RC和STC15系列驱动ST7735的差别在哪先做选型。STC89C52RC是12T内核没有硬件SPISTC15系列是1T内核部分型号带硬件SPI但很多从51转过来的项目仍然用软件模拟SPI。晶振建议选11.0592MHz而不是12MHz一方面串口波特率误差小另一方面STC89C52在11.0592MHz下一个机器周期约1.085us计算DS18B20时序延时更容易。如果是STC15系列1T内核同样的DelayUs函数实际延时只有STC89C52的约1/12不改延时函数直接跑DS18B20十有八九读不回温度。STC单片机复位电路在这里也起作用单片机复位时所有IO口恢复成准双向高电平如果屏幕的RST引脚和单片机复位脚直接并联复位期间屏幕也会跟着复位。等单片机跑起来去初始化屏幕时时序已经错乱了。我一般用单独的IO口控制屏幕RST这样上电顺序完全由程序掌控。2.2 引脚分配DS18B20的一条IO和ST7735的五条信号线下面是一套常用连接使用STC89C52RC时P1口接屏幕、P2.0接温度传感器。模块信号STC89C52RC引脚说明DS18B20DQP2.0外部接4.7kΩ上拉到VCCST7735SCLKP1.0串行时钟ST7735MOSIP1.1主机输出数据ST7735CSP1.2片选低有效ST7735DCP1.3数据/命令选择ST7735RSTP1.4复位低有效ST7735BLKP1.5背光控制ST7735的核心电压是3.3V而STC89C52的IO口是5V电平。现在市面上多数1.8寸TFT模块自带稳压和电平转换可以直接5V供电但裸屏或精简模块没有这时候SCLK和MOSI必须串1kΩ电阻限流再做电平匹配强行直连会缩短屏幕寿命。DS18B20可以5V供电DQ引脚也是5V电平和STC匹配没问题。2.3 软件SPI的最小实现ST7735的SPI只需要单向通信SCK空闲低电平MOSI在SCK上升沿被采样MSB先出。没有硬件SPI时发送一个字节就是循环8次先拉低SCK再置位MOSI最后拉高SCK。sbit LCD_SCL P1^0; sbit LCD_SDA P1^1; sbit LCD_CS P1^2; sbit LCD_DC P1^3; sbit LCD_RST P1^4; sbit LCD_BLK P1^5; void DelayUs(unsigned int us) { while(us--) { _nop_(); _nop_(); } } void Lcd_WriteByte(unsigned char dat) { unsigned char i; for(i 0; i 8; i) { LCD_SCL 0; if(dat 0x80) LCD_SDA 1; else LCD_SDA 0; LCD_SCL 1; dat 1; } }Lcd_WriteByte每次先把SCL拉低给MOSI留出建立时间再拉高形成上升沿ST7735就在这个上升沿采样数据。注意先拉低再拉高而不是先置数据再翻转因为SCK空闲低电平是ST7735的默认极性。初始化完成后如果屏幕完全没有反应先用万用表量SCK在空闲时是不是低电平这是最快排查点。2.4 命令与数据的区别ST7735的DC引脚Lcd_WriteByte只负责往总线送数据至于这个字节是命令还是参数由DC引脚决定。DC为低时主机发送的是命令为高时发送的是数据。初始化序列里大量出现“一个命令后面跟几个参数”的格式就是靠DC引脚切换的。void Lcd_WrCmd(unsigned char cmd) { LCD_CS 0; LCD_DC 0; Lcd_WriteByte(cmd); LCD_CS 1; } void Lcd_WrData(unsigned char dat) { LCD_CS 0; LCD_DC 1; Lcd_WriteByte(dat); LCD_CS 1; }CS在整个字节传输期间拉到低电平确保同一时刻只有这块屏幕在接收数据。如果板子上并联了多块SPI设备CS选错会导致其他设备也收到命令屏幕出现随机乱画。这个底层函数后面所有显示操作都会复用值得单独建一个lcd_driver.c放起来。3. DS18B20时序与STC单片机的精确读写3.1 单总线时序复位脉冲与存在脉冲DS18B20是单总线设备所有通信都由主机发起。第一步是复位时序主机拉低总线480至960us然后释放并等待15至60us此时DS18B20会拉低总线60至240us产生一个存在脉冲表示设备在线。时序阶段最小值典型值最大值主机拉低480us500us960us释放后等待15us60us60us存在脉冲低电平60us—240ussbit DQ P2^0; unsigned char DS18B20_Reset(void) { unsigned char flag; DQ 0; DelayUs(500); DQ 1; DelayUs(60); flag DQ; DelayUs(400); return flag; }flag在存在脉冲期间读到0说明传感器在线读到1说明总线上没有设备或线路没接对。这里有个STC特有的细节STC89C52的IO口是准双向结构拉高后可以靠内部弱上拉读输入不用切换方向但STC15系列如果配置成开漏输出释放总线后必须把IO口切回高阻输入否则读到的永远是低电平存在脉冲判断会失效。3.2 STC单片机上的写时隙与读时隙复位成功后每次读写都是一个独立的时隙。写1主机拉低总线15us内释放靠外部上拉拉高写0主机拉低总线并保持60至120us再释放。读时隙主机拉低1us后释放在15us内采样总线电平。这三个操作的区别只在电平持续时间上。void DS18B20_WriteBit(unsigned char bitval) { DQ 0; if(bitval) DQ 1; DelayUs(20); DQ 1; } unsigned char DS18B20_ReadBit(void) { unsigned char bitval; DQ 0; _nop_(); DQ 1; bitval DQ; DelayUs(20); return bitval; }读时序里最容易出错的是采样点DQ 1之后必须立刻读不能加长延时。_nop_()在11.0592MHz下大约1usDS18B20在主机释放总线后开始驱动总线采样窗口一般在15us内。如果在这里换成DelayUs(10)再去读大概率读到1因为传感器已经释放总线了。字节读写就是把位操作循环8次void DS18B20_WriteByte(unsigned char dat) { unsigned char i; for(i 0; i 8; i) { DS18B20_WriteBit(dat 0x01); dat 1; } } unsigned char DS18B20_ReadByte(void) { unsigned char i, dat 0; for(i 0; i 8; i) { dat 1; if(DS18B20_ReadBit()) dat | 0x80; } return dat; }LSB先出这是单总线的固定格式。读写字节之前先算好时间一个时隙约60us一个字节8个时隙关中断时间不到1ms不会影响主循环。3.3 完整的温度转换命令序列DS18B20的每一次温度转换都需要两条命令链。第一条链是启动转换复位、跳过ROM、发0x44。第二条链是读取结果复位、跳过ROM、发0xBE再连续读9字节暂存器。unsigned char DS18B20_StartConvert(void) { if(DS18B20_Reset()) return 1; DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 启动温度转换 return 0; }0xCC是跳过ROM命令。总线上只有一个传感器时可以不读64位序列号直接操作。如果总线上挂了多个DS18B20就必须先用0x33读ROM拿到每个设备的序列号再用0x55匹配ROM否则所有传感器会同时应答数据互相冲突。转换期间总线可以释放单片机去做屏幕刷新。12位分辨率下转换时间典型值750ms上限约750ms。转换完成后通过读暂存器把温度取回来int DS18B20_GetRawTemperature(void) { int raw; DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); raw DS18B20_ReadByte() | (DS18B20_ReadByte() 8); return raw; }严格的做法是把剩余7字节读完用CRC8校验多项式是X8X5X41。工程上如果只需要显示温度可以只读前两字节后直接复位总线省掉CRC计算时间。传感器刚上电时暂存器里是0x0550也就是85°C如果读出这个值先别怀疑传感器坏了。3.4 把温度寄存器换算成定点数不用浮点DS18B20的12位温度数据中LSB对应0.0625°C数据以16位有符号数存储。换算成“温度乘以100”的定点数可以完全避开浮点运算因为STC89C52没有浮点单元软件浮点慢且占用大量代码空间。int DS18B20_GetTemperatureX100(void) { int raw; unsigned int temp; int result; raw DS18B20_GetRawTemperature(); if(raw 0x8000) { raw ~raw 1; // 负数取补码 temp (unsigned int)raw * 625 / 100; result -(int)temp; } else { temp (unsigned int)raw * 625 / 100; result (int)temp; } return result; // 单位0.01摄氏度 }raw * 625 / 100等价于raw * 0.0625 * 100先乘以625再除以100整个过程都是整数运算。返回的result比如2531就代表25.31°C。负数先取补码再计算最后把负号补回去。显示时用result / 100拿整数部分用result % 100拿小数部分。提示如果读出的温度始终是85°C大概率不是传感器坏了而是复位时序没把传感器唤醒读到的只是暂存器上电默认值。先去查复位脉冲宽度再用示波器看DQ引脚上有没有存在脉冲。4. ST7735初始化、坐标设置与温度数值显示4.1 屏幕初始化ST7735S的最小命令序列ST7735S这类TFT液晶屏上电后要先经过延时、唤醒、设置方向、设置颜色格式最后才能显示。下面是一组能跑通的最小序列void Lcd_Init(void) { LCD_RST 0; DelayMs(120); LCD_RST 1; DelayMs(120); Lcd_WrCmd(0x01); // 软件复位 DelayMs(150); Lcd_WrCmd(0x11); // 退出睡眠 DelayMs(120); Lcd_WrCmd(0x36); // MADCTL显示方向 Lcd_WrData(0xC8); Lcd_WrCmd(0x3A); // COLMOD颜色格式 Lcd_WrData(0x05); // RGB565 Lcd_WrCmd(0x29); // 开启显示 DelayMs(20); }命令参数作用0x01无软件复位清空内部寄存器0x11无退出睡眠模式必须等待120ms0x360xC8设置扫描方向与RGB顺序0x3A0x05像素格式为RGB565每像素2字节0x29无打开显示输出0x36的参数0xC8是我常用的横屏方向。bit7控制行扫描方向bit6控制列扫描方向bit5控制行列交换。如果画面出现镜像只翻转bit6或bit7不要整个字节乱试。0x3A设成0x05是16位色也就是RGB565屏幕内部每个像素点占两个字节。SLPOUT到DISPON之间的延时非常重要用STC单片机控制RST引脚而不是直接并联复位电路就是为了让屏幕在单片机IO口稳定后再走初始化流程。如果你用的是IPS TFT LCD面板SLPOUT后的延时建议提到150msIPS面板对初始化时序比普通TFT更挑剔。4.2 设置绘图窗口为什么1.8寸屏会偏2个像素ST7735内部的GRAM尺寸比1.8寸面板的可见区域大一圈常见的误差是X方向偏移2个像素、Y方向偏移1个像素。不处理这个偏移画出来的内容整体错位。设置窗口用0x2A列地址命令和0x2B行地址命令之后用0x2C开始写显存数据。void Lcd_SetWindow(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) { Lcd_WrCmd(0x2A); Lcd_WrData(x1 2); Lcd_WrData(y1 1); Lcd_WrData(x2 2); Lcd_WrData(y2 1); Lcd_WrCmd(0x2B); Lcd_WrData(x1); Lcd_WrData(y1); Lcd_WrData(x2); Lcd_WrData(y2); Lcd_WrCmd(0x2C); }0x2A和0x2B的参数都是先发高字节再发低字节但在128x160这种小分辨率下直接用8位宽度传参即可。偏移量加在列地址上x1 2、x2 2。如果屏幕四边出现彩条或边缘错位就把2和1互换测试不同批次的面板偏移不完全一样。4.3 颜色填充函数窗口设置完成后往0x2C连续写像素数据屏幕就会按行列顺序填充颜色。颜色数据是RGB565格式两个字节的发送顺序和初始化里的BGR位有关void Lcd_FillColor(unsigned int color, unsigned int count) { while(count--) { Lcd_WrData(color 8); Lcd_WrData(color 0xFF); } }color 8先发高字节color 0xFF后发低字节。如果发现红色和蓝色对调问题出在0x36的BGR位把0xC8改成0x08红色和蓝色分量就会互换回来。这个测试用纯红色0xF800填充全屏最直观。4.4 显示温度数值字模拆分与局部刷新显示温度需要把整数、小数、符号分别查字模再定位到屏幕的固定区域。我这里用8x16的ASCII字模每个字符占8列16行像素取模软件按字节纵向取模即可。void Lcd_ShowTemp(unsigned char x, unsigned char y, int temp) { unsigned char buf[7]; unsigned char i, len 0; int t; if(temp 0) { buf[len] -; t -temp; } else { t temp; } buf[len] t / 100 0; // 整数部分 buf[len] .; buf[len] (t / 10) % 10 0; // 十分位 buf[len] t % 10 0; // 百分位 buf[len] C; for(i 0; i len; i) { Lcd_ShowChar(x, y, buf[i]); x 8; } }这里用了一个buf数组拼字符串先处理负号再处理整数、小数点、小数位。后面刷新只需要对这块区域重画不用每次清全屏。如果每次读温度都Lcd_FillColor全屏清一次屏幕会持续闪烁因为750ms的转换周期和显示刷新周期在视觉上直接打架肉眼能看出明显闪动。局部刷新的做法是在Lcd_ShowTemp之前先调用Lcd_SetWindow固定温度显示区域然后整个函数只往这块区域填充即可。主循环结构一般是启动转换等待期间刷新屏幕读取温度并显示如此循环。5. 联调校准STC单片机读不到温度与显示乱码的快速定位5.1 三个典型症状的排查顺序现象优先检查的方向常见根因屏幕白屏或花屏RST引脚上电时序SLPOUT后延时不足或初始化数据发错温度固定显示85°C复位脉冲宽度和上拉电阻DS18B20没被正常唤醒数字闪烁或数值乱跳读写期间是否被中断打断定时器或串口中断抢占单总线时序白屏时用示波器抓SCK和MOSI看初始化命令是否在正确时间发出。ST7735没有MISO回读路径一旦数据线接错屏幕不会给你任何错误提示。温度85°C的场景先量P2.0上拉到VCC的电阻再检查DS18B20_Reset的返回值返回1表示总线上根本没有设备。5.2 中断与临界区DS18B20的时隙窗口最窄在15us左右如果在读时隙期间发生串口中断或定时器中断回来之后采样点已经错过。最直接的保护是在读温度前关闭总中断EA 0; temp DS18B20_GetTemperatureX100(); EA 1;一次完整读取关中断时间在1ms以内对串口接收缓冲来说完全可以接受。但要注意关中断期间不要去调DelayMs这类长延时函数否则整个主循环都会被卡住。STC15系列如果开了看门狗关中断超过喂狗周期会直接复位需要把喂狗语句放在关中断之前。5.3 用示波器抓单总线波形把探头挂在DQ引脚触发方式选下降沿。正常波形应该是一段约500us的低电平复位脉冲释放后出现一个短促的低电平存在脉冲之后是一串整齐的60us左右读写时隙。如果你看到一个写时隙里出现两个下降沿多半是延时偏短传感器把前一个时隙误判成了复位脉冲。如果没有示波器可以用LED做粗测初始化后让DQ输出高电平如果传感器在线LED会保持高亮而不是闪烁这个判断比读寄存器还快。5.4 温度校准DS18B20出厂有校准但线缆电阻、传感器自热都会带来零点几度的偏差。程序里预留一个偏移宏校准后统一叠加#define TEMP_OFFSET_X100 20 result TEMP_OFFSET_X100;TEMP_OFFSET_X100的单位是0.01°C20代表0.20°C。校准方法是把传感器和水银温度计放在同一环境静置10分钟后读差值然后填入宏。注意传感器要远离电源芯片和屏幕背光这两个热源会让显示值比环境温度高出不少偏移量只能补偿固定误差补偿不了布局造成的持续自热。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。