基于51单片机的温度计(外加电子时钟)纯纯纯小白自娱之作,大佬勿进

本文主要是介绍基于51单片机的温度计(外加电子时钟)纯纯纯小白自娱之作,大佬勿进,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于51单片机的温度计(外加电子时钟)

因为学校微机课设的要求,做了一个这么玩意儿,实属小白自娱,大佬勿侃!!
闲话不多说,Let us go!

先上Proteus仿真图

在这里插入图片描述
一上午Proteus速成结果(垃圾的一批。。勿喷)
这里选用的式DS18B20温度传感器+lcd1604显示,左边的电机纯属瞎加,驱动芯片用L298N
!!!该图仅限于仿真,不可用于实际连接!!!

功能

系统实时显示温度值和年月日时分值,当温度高于既定温度,红灯亮,电机运转(相当于一个小风扇);当温度低于既定温度,蓝灯亮;
按键功能:
k1:负责值加一
k2:负责决定需要修改的位(年月日时分秒)
k3:负责总控制标志位
k4:负责值减一

贴一下main.c代码

前情提示,因为速成且任务量着实太小,所以全让我塞一个c文件了,整洁度啊,语法水平啊,全都是最low!!!见谅。。

//      ┏┛ ┻━━━━━┛ ┻┓
//      ┃       ┃
//      ┃   ━   ┃
//      ┃ ┳┛   ┗┳ ┃
//      ┃       ┃
//      ┃   ┻   ┃
//      ┃       ┃
//      ┗━┓   ┏━━━┛
//        ┃   ┃   神兽保佑
//        ┃   ┃   代码无BUG!
//        ┃   ┗━━━━━━━━━┓
//        ┃           ┣┓
//        ┃             ┏┛
//        ┗━┓ ┓ ┏━━━┳ ┓ ┏━┛
//          ┃ ┫ ┫   ┃ ┫ ┫
//          ┗━┻━┛   ┗━┻━┛
#include<reg51.h>
#include"lcd.h"
#include"temp.h"
sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;
sbit ENA=P1^2;
sbit IN2=P1^1;
sbit IN1=P1^0;
sbit led0=P2^0;
sbit led1=P2^1;typedef unsigned long u32;
typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;u16 second=0,min=0,hour=0,date=1,month=1;
u16 year=2000;	  
u8 start_flag=1;           //总控制位
u16 shuzu[6];static u8 choose;  //选择位void LcdDisplay(int);
void UsartConfiguration();
void Delay10ms(void);
void keypros(void);
void LcdDisplay();void Timer0Init()
{TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。TH0=0XFC;	//给定时器赋初值,定时1msTL0=0X18;	ET0=1;//打开定时器0中断允许EA=1;//打开总中断TR0=1;//打开定时器			
}void Int0Configuration()	//外部中断0初始化
{IT0=1;//跳变沿出发方式(下降沿)EX0=1;//打开INT0的中断允许。EA=1;//打开总中断	
}void main()
{Timer0Init();UsartConfiguration();Int0Configuration();//p3.2LcdInit();while(1){if(start_flag==1){if(min==60){hour++;min=0;}if(hour==24){hour=0;date++;}if(year%4==0){if(month==2){if(date>=30){month++;date=1;}}else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){if(date==32){date=1;month++;}}else {if(date==31){date=1;month++;}}}else{if(month==2){if(date>=29){month++;date=1;}}else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){if(date==32){date=1;month++;}}else {if(date==31){date=1;month++;}}}	 //判断是否闰月;if(month==13){month=1;year++;}}//正常时钟功能;else{shuzu[0]=	 year;shuzu[1]=	 month;shuzu[2]=	 date;shuzu[3]=	 hour;shuzu[4]=	 min;shuzu[5]=	 second;if(k1==0)		  //检测按键K1是否按下{	Delay10ms();   //消除抖动 一般大约10msif(k1==0)	 //再次判断按键是否按下{choose++;							  //调要选的位数if(choose==6){choose=0;}	}while(!k1);	 //检测按键是否松开}if(k2==0)		  //检测按键K1是否按下{	Delay10ms();   //消除抖动 一般大约10msif(k2==0)	 //再次判断按键是否按下{shuzu[choose]=shuzu[choose]+1;								  //加数switch(choose){												//防止超出上限值case 0:break;case 1:if(shuzu[choose]==13){shuzu[choose]=0;}break;case 2:if(shuzu[choose]==32){shuzu[choose]=1;}break;case 3:if(shuzu[choose]==13){shuzu[choose]=0;}break;case 4:if(shuzu[choose]==61){shuzu[choose]=0;}break;	case 5:if(shuzu[choose]==61){shuzu[choose]=0;}break;}}while(!k2);	 //检测按键是否松开}if(k4==0)		  //检测按键K1是否按下{	Delay10ms();   //消除抖动 一般大约10msif(k4==0&&shuzu[choose]!=0)	 //再次判断按键是否按下{shuzu[choose]=shuzu[choose]-1;				   //减数且到0后就减不动了;}while(!k4);	 //检测按键是否松开}year=shuzu[0];month=shuzu[1];date=shuzu[2];hour=shuzu[3];min=shuzu[4];second=shuzu[5];}LcdWriteCom(0x80+0X40);LcdWriteData('0'+date/10);LcdWriteData('0'+date%10);LcdWriteData('-');LcdWriteData('0'+hour/10);LcdWriteData('0'+hour%10);LcdWriteData('-');LcdWriteData('0'+min/10);LcdWriteData('0'+min%10);LcdWriteData('-');LcdWriteData('0'+second/10);LcdWriteData('0'+second%10);LcdDisplay(Ds18b20ReadTemp());LcdWriteCom(0x87);	//写地址 80表示初始地址LcdWriteData('C'); LcdWriteCom(0x89);LcdWriteData('0'+year/1000);LcdWriteData('0'+year%1000/1000);LcdWriteData('0'+year%100/10);LcdWriteData('0'+year%10);LcdWriteData('-');LcdWriteData('0'+month/10);LcdWriteData('0'+month%10);}
}
//定时器中断0void Timer0() interrupt 1
{static u16 us;TH0=0XFC;	//给定时器赋初值,定时1msTL0=0X18;us++;if(us==1000){us=0;second++;if(second==60){second=0;min++;}	}	
}//外部中断0
void Int0() interrupt 0		 
{Delay10ms();if(k3==0){start_flag=~start_flag;    //总开始标志,1为校正状态,2为正常运行;	TR0=~TR0;	//控制定时器1;}
}void Delay10ms(void)   //误差 0us
{unsigned char a,b,c;for(c=1;c>0;c--)for(b=38;b>0;b--)for(a=130;a>0;a--);
}void LcdDisplay(int temp) 	 //lcd显示
{unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组float tp;  if(temp< 0)				//当温度值为负数{LcdWriteCom(0x80);		//写地址 80表示初始地址SBUF='-';//将接收到的数据放入到发送寄存器while(!TI);			         //等待发送数据完成TI=0;						 //清除发送完成标志位LcdWriteData('-');  		//显示负//因为读取的温度是实际温度的补码,所以减1,再取反求出原码temp=temp-1;temp=~temp;tp=temp;temp=tp*0.0625*100+0.5;	//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算由?.5,还是在小数点后面。}else{			LcdWriteCom(0x80);		//写地址 80表示初始地址LcdWriteData('+'); 		//显示正SBUF='+';//将接收到的数据放入到发送寄存器while(!TI);			         //等待发送数据完成TI=0;						 //清除发送完成标志位tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量//如果温度是正的那么,那么正数的原码就是补码它本身temp=tp*0.0625*100+0.5;	//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算加上0.5,还是在小数点后面。}datas[0] = temp / 10000;datas[1] = temp % 10000 / 1000;datas[2] = temp % 1000 / 100;datas[3] = temp % 100 / 10;datas[4] = temp % 10;LcdWriteCom(0x81);		  //写地址 80表示初始地址LcdWriteData('0'+datas[0]); //百位 SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器while (!TI);			         //等待发送数据完成TI = 0;LcdWriteCom(0x82);		 //写地址 80表示初始地址LcdWriteData('0'+datas[1]); //十位SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器while (!TI);			         //等待发送数据完成TI = 0;LcdWriteCom(0x83);		//写地址 80表示初始地址LcdWriteData('0'+datas[2]); //个位 SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器while (!TI);			         //等待发送数据完成TI = 0;LcdWriteCom(0x84);		//写地址 80表示初始地址LcdWriteData('.'); 		//显示 ‘.’SBUF = '.';//将接收到的数据放入到发送寄存器while (!TI);			         //等待发送数据完成TI = 0;LcdWriteCom(0x85);		 //写地址 80表示初始地址LcdWriteData('0'+datas[3]); //显示小数点  SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器while (!TI);			         //等待发送数据完成TI = 0;LcdWriteCom(0x86);		 //写地址 80表示初始地址LcdWriteData('0'+datas[4]); //显示小数点 SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器while (!TI);			         //等待发送数据完成TI = 0;if(temp>=4500){led0=0;ENA=1;IN1=0;IN2=1;}				  //警报放在这里,超过45摄氏度,红色led灯亮;外加一个电风扇(直流电机驱动的) ;                  else{            //在显示函数里加判断语句估计除我也没谁了。。。                                            led0=1;ENA=0;}if(temp<=3500){		  //低温警告   对应蓝灯led1=0;	 }else{led1=1;}}void UsartConfiguration()
{SCON|=0X50;			//设置为工作方式1TMOD|=0X20;			//设置计数器工作方式2PCON|=0X80;			//波特率加倍TH1=0XF3;				//计数器初始值设置,注意波特率是4800的TL1=0XF3;TR1=1;					//打开计数器
}

lcd.h和temp.h网上有的是就不发了

仿真效果

*强调文本* _强调文本_显示还算凑活,调值啥的也正常,缺点是温度阈值不可调(懒。。),按键也不太稳,实际意义。。零点几吧。。。。

溜了,下次有缘再见!

bia ! bia !

这篇关于基于51单片机的温度计(外加电子时钟)纯纯纯小白自娱之作,大佬勿进的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/608579

相关文章

Java操作PDF文件实现签订电子合同详细教程

《Java操作PDF文件实现签订电子合同详细教程》:本文主要介绍如何在PDF中加入电子签章与电子签名的过程,包括编写Word文件、生成PDF、为PDF格式做表单、为表单赋值、生成文档以及上传到OB... 目录前言:先看效果:1.编写word文件1.2然后生成PDF格式进行保存1.3我这里是将文件保存到本地后

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

Spring Boot集成PDFBox实现电子签章

概述 随着无纸化办公的普及,电子文档的使用越来越广泛。电子签章作为一种有效的身份验证方式,在很多场景下替代了传统的纸质文件签名。Apache PDFBox 是一个开源的Java库,可以用来渲染、生成、填写PDF文档等操作。本文将介绍如何使用Spring Boot框架结合PDFBox来实现电子签章功能。 准备工作 环境搭建:确保你的开发环境中安装了JDK 8或更高版本,并且配置好了Maven或

【电子通识】半导体工艺——保护晶圆表面的氧化工艺

在文章【电子通识】半导体工艺——晶圆制造中我们讲到晶圆的一些基础术语和晶圆制造主要步骤:制造锭(Ingot)、锭切割(Wafer Slicing)、晶圆表面抛光(Lapping&Polishing)。         那么其实当晶圆暴露在大气中或化学物质中的氧气时就会形成氧化膜。这与铁(Fe)暴露在大气时会氧化生锈是一样的道理。 氧化膜的作用         在半导体晶圆

代码训练营 Day26 | 47.排序II | 51. N-皇后 |

47.排序II 1.跟46题一样只不过加一个树层去重 class Solution(object):def backtracking(self,nums,path,result,used):# recursion stopif len(path) == len(nums):# collect our setresult.append(path[:])return for i in range(

LabVIEW程序员是怎样成长为大佬

成为一名LabVIEW编程领域的“大佬”需要时间、实践、学习和解决复杂问题的经验。尽管LabVIEW作为一种图形化编程语言在初期可能相对容易上手,但要真正成为精通者,需要在多个层面上深入理解。以下是LabVIEW程序员如何逐步成长为“大佬”的路径: 1. 打好基础 LabVIEW的大佬们通常在初期会打下非常坚实的基础,理解LabVIEW编程的核心概念,包括: 数据流编程模型:Lab

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品