电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
课程设计系列之数字式温度计
分 享
扫描二维码分享
课程设计系列之数字式温度计
51单片机
课程设计
温度计
入门电子设计
关注
发布时间: 2021-03-25
丨
阅读: 1392
## 简介 大家好,又到了要做课程设计的时候了,课程设计虽然难度并不大,但对于初学单片机的朋友们来说还是有点麻烦的,本系列文章主要是为不不熟悉单片机的朋友提供一些思路,从硬件连接到程序设计,一步步实现一个简单的课程设计,希望对大家有所帮助。 本篇文章的内容是通过51单片机实现一个数字式温度计,作为温度计首先要实现温度的读取,然后读取的温度可以通过显示器进行显示,显示的时候可以进行华氏度和摄氏度的切换,我们还可以添加一个当温度过高时的声音提示。温度计的功能基本就是这些,接下来我们要进行硬件的连接了。 ## 硬件设计 硬件设计主要是元器件的选型的电路的连接,在设计的时候可以先通过仿真软件进行仿真,软硬件设计好后再进行实物的焊接,在这里用到的仿真软件是Protuse,软件的安装和基本的使用方法大家可以搜索一下,在这里就不详细介绍了,新建好文件后我们添加要使用的电子元件,下面是我们要用到的元件: - AT89C52单片机 - 按键 - LCD1602 - DS18B20 - 蜂鸣器 - 电阻 选择好相应的元件后就可以开始连接电路了,首先来看51单片机的电路连接,在仿真中是不用在外面再连接电路的电源和晶振电路的,所以只用引出数据控制的引脚即可,引脚处添加上拉电阻可以提高IO口的驱动能力, ![](https://cf01.ickimg.com/bbsimages/202103/c873c157ee562e2cd2508dd81ebe02b9.png) 然后是DS18B20的电路,连接VCC和GND,中间的引脚是传输数据的, ![](https://cf01.ickimg.com/bbsimages/202103/b91a10be352e29804740391855fc270f.png) LCD1602的连接在这里算是比较复杂的了,我们可以先搜索一下LCD1602各个引脚的作用: - VSS:接地 - VDD:接电源 - V0:对比度调整端,使用时可接电位器接地进行对比度调节 - RS:寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器 - RW:读写信号线,高电平读,低电平写 - E:使能端,下降沿写操作,高电平读操作 - DB0:数据总线最低位 - DB1:数据总线1位 - DB2:数据总线2位 - DB3:数据总线3位 - DB4:数据总线4位 - DB5:数据总线5位 - DB6:数据总线6位 - DB7:数据总线7位 - A:背光电源正极 - K:背光电源负极 了解好各个引脚的作用就可以按照功能进行连接了,仿真中VEE脚用于调节显示屏的亮度,在这里直接接地就好,在焊接实物的时候可以添加一个电位器进行调节, ![](https://cf01.ickimg.com/bbsimages/202103/00ec75dd034359383aad97e5335e99d3.png) 在连接蜂鸣器的时候选择好驱动电路,驱动电路不同最后程序也会有一点不同, ![](https://cf01.ickimg.com/bbsimages/202103/340605897e96a0944de45c9f2ba33d96.png) 最后再添加几个按键用于设置就好了,现在温度计的电路部分就连接好了。 ![](https://cf01.ickimg.com/bbsimages/202103/8347f24ce358f730f2ac58d032418554.png) ## 软件设计 在设计好硬件电路后就可以开始编写程序了,编程使用的软件是Keil,软件的基本操作同样不再详细介绍了,选择好我们使用的芯片创建好项目我们就开始具体的程序编写。 温度计首先是要实现温度的读取,下面是DS18B20的驱动程序, ```cpp void dsInit() { unsigned int i; ds = 0; i = 100; while(i>0) i--; ds = 1; i = 4; while(i>0) i--; } ``` ```cpp void dsWait() { unsigned int i; while(ds); while(~ds); i = 4; while(i > 0) i--; } ``` ```cpp bit readBit() { unsigned int i; bit b; ds = 0; i++; ds = 1; i++; i++; b = ds; i = 8; while(i>0) i--; return b; } ``` ```cpp unsigned char readByte() { unsigned int i; unsigned char j, dat; dat = 0; for(i=0; i<8; i++) { j = readBit(); dat = (j << 7) | (dat >> 1); } return dat; } ``` ```cpp void writeByte(unsigned char dat) { unsigned int i; unsigned char j; bit b; for(j = 0; j < 8; j++) { b = dat & 0x01; dat >>= 1; if(b) { ds = 0; i++; i++; ds = 1; i = 8; while(i>0) i--; } else { ds = 0; i = 8; while(i>0) i--; ds = 1; i++; i++; } } } ``` ```cpp void sendChangeCmd() { dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0x44); } void sendReadCmd() { dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0xbe); } int getTmpValue() { unsigned int tmpvalue; float t; unsigned char low, high; sendReadCmd(); low = readByte(); high = readByte(); tmpvalue = high; tmpvalue <<= 8; tmpvalue |= low; value = tmpvalue; t = value * 0.0625; value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5 return value; } ``` 接下来的工作就是将获取到的温度显示在LCD显示屏上,根据前面连接LCD电路时的引脚功能图可以了解各个引脚的作用,这是编写显示程序的基础,下面是关于LCD驱动的程序, ```c void writeComm(uchar comm) { RS = 0; P0 = comm; LCDEN = 1; delayUs(); LCDEN = 0; delayMs(1); } void writeData(uchar dat) { RS = 1; P0 = dat; LCDEN = 1; delayUs(); LCDEN = 0; delayMs(1); } void init() { dula = wela = 0; writeComm(0x38); writeComm(0x0c); writeComm(0x06); writeComm(0x01); } void writeString(uchar * str, uchar length) { uchar i; for(i = 0; i < length; i++) { writeData(str[i]); } } ``` 现在要把获取到的温度进行显示, ```c void display(int v) { unsigned char count; unsigned char datas[] = {0, 0, 0, 0, 0}; unsigned int tmp = abs(v); datas[0] = tmp / 10000; datas[1] = tmp % 10000 / 1000; datas[2] = tmp % 1000 / 100; datas[3] = tmp % 100 / 10; datas[4] = tmp % 10; writeComm(0xc0+3); if(v < 0) { writeString("- ", 2); } else { writeString("+ ", 2); } if(datas[0] != 0) { writeData('0'+datas[0]); } for(count = 1; count != 5; count++) { writeData('0'+datas[count]); if(count == 2) { writeData('.'); } } } void displayvalue() { if(key == 0) { delayMs(1000); writeComm(0xc0); getTmpValue(); display(Celsius); sendChangeCmd(); } if(key == 1) { delayMs(1000); writeComm(0xc0); getTmpValue(); display(Fahrenheit); sendChangeCmd(); } if(key == 2) { delayMs(1000); writeComm(0xc0); display(temperature); sendChangeCmd(); if(y == 0) { temperature_g = temperature; } if(y == 1) { temperature_d = temperature; } } } ``` 显示程序写好以后我们可以将hex文件下载到仿真电路的芯片中看一下运行的效果, ![](https://cf01.ickimg.com/bbsimages/202103/8060309b2d5cd9b90dd9688d940a2e42.png) 可以看到现在LCD上已经成功的显示出了读取到的温度,到这一步一个温度计的基本功能已经完成了,接下来就来实现华氏度摄氏度的转换和高温报警了。 华氏度摄氏度的切换可以通过简单的数学计算完成, ```c Fahrenheit = Celsius*1.8 + 3200; ``` 算出相应的温度后进行切换就用到按键了,当按下按键后显示华氏度,再次按下按键后显示摄氏度,按键的程序比较简单, ```c int keyboard() { if(key1 == 0) { delayMs(5); if(key1 == 0) { x++; if(x == 2) { x = 0; } if(x == 0) { uchar table[] = "Fahrenheit:"; sendChangeCmd(); init(); writeComm(0x80); writeString(table,11); key = 1; } if(x == 1) { uchar table[] = "Celsius:"; sendChangeCmd(); init(); writeComm(0x80); writeString(table,8); key = 0; } } } if(key2 == 0) { delayMs(5); if(key2 == 0) { y++; if(y == 2) { y = 0; } if(y == 0) { uchar table[] = "temperature_g:"; sendChangeCmd(); init(); writeComm(0x80); writeString(table,14); key = 2; temperature = temperature_g; } if(y == 1) { uchar table[] = "temperature_d:"; sendChangeCmd(); init(); writeComm(0x80); writeString(table,14); key = 2; temperature = temperature_d; } } } if(key3 == 0) { delayMs(5); if(key3 == 0) { temperature = temperature + 100; key = 2; } } if(key4 == 0) { delayMs(5); if(key4 == 0) { temperature = temperature - 100; key = 2; } } return key; } ``` 编写好程序后再次下载到仿真中看一下效果,当我们按下按键后显示屏上显示的内容也切换成了相应的内容, ![](https://cf01.ickimg.com/bbsimages/202103/94ec54691f7f264e0109e0f57c19a7ee.png) ![](https://cf01.ickimg.com/bbsimages/202103/c05618fb701ac2d688b4b72b1c45f6ba.png) 到这一步温度的切换就成功实现了,现在到最后的温度报警,我们还需要几个按键用来实现温度的设置, ```c void main() { uchar table[] = "Celsius:"; sendChangeCmd(); init(); beep = 1; writeComm(0x80); writeString(table,8); while(1) { Celsius = value; Fahrenheit = Celsius*1.8 + 3200; keyboard(); displayvalue(); if(value >= temperature_g||value <= temperature_d) { beep = 0; } else beep = 1; } } ``` 最后可以把程序下载到仿真里面看一下设置温度的效果, ![](https://cf01.ickimg.com/bbsimages/202103/09488266a1ab13695b85de0cc3464dac.png) 这样我们设计的数字式温度计的全部功能就都实现了,在文章中用到的像是LCD显示屏的电路连接和驱动程序都可以单独拿出来用的别的设计上面,原理都是相同的,也不需要没做一个设计就单独设计一套程序,也就节省了时间,之后的课程设计系列教程还会介绍其他的小设计,希望正在做课程设计的朋友看完文章后有所帮助。
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
入门电子设计
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交