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

阅读: 评论:0

基于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 !

本文发布于:2024-01-29 02:09:28,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170646537311971.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:大佬   温度计   之作   单片机   时钟
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23