基于51单片机1602温度显示时钟

基于51单片机LCD1602温度显示时钟

要在1602上显示时间和温度先要了解1602是如何显示的。详情可以参考我之前的文章基于51单片机1602显示 ;时间显示可以用时钟芯片DS1302,但是此次我没使用,接着使用定时中断写可以参考之前我的文章基于51单片机定时,数码管显示时间,温度检测由于使用51单片机使用DS18B20方便一点因为DS18B20传递的直接是数字量单片机可以直接识别,如果使用热敏电阻还要进行模数转换而且温度测量精度也不高。

整体设计思路

按照系统设计的需求,初步确定系统由电源模块、时钟模块、显示模块、键盘接口模块、温度测量模块和闹钟模块共六个模块组成,其中电源模块采用5V电源对单片机供电,温度模块采用DS18B20温度传感器对当前环境温度进行采集,利用按键对当前时间节点进行校正,采用定时器T0对电子时钟的时间进行计数操作,采用1602显示器对当前时间和当前环境温度进行显示,利用蜂鸣器对所设定时间节点进行发声操作,系统设计框图如图所示。

时间显示模块
此次时间显示相对与数码管显示那次 我修改了一下加入了按键可以修改时间到当前时间而不是从0开始。
先对1602的第一行进行输入显示时间初始数组写入,然后将中断开启,每1秒记1次并判断一下秒时分,将其与时间初始数组地址联系一块,这样时间就随中断计时的改变一直改变。改变时间也是对初始时间数组改变,时间调节函数对按键进行扫描,看有无按键按下,对应按键按下,中断停止通过其余按键扫描,对初始数组标志位地址改变实现加减。通过闹钟函数对计入数字次数进行扫描,看是否到达预定次数,即可模拟实现闹钟的功能。
1602初始化我就不写了(看前面文章)直接开始关键点时间数组导入,和改变时间显示。
定时器中断记时还是老操作了:

void init_t0(){//中断初始化
	TMOD=0X01; 
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	EA=1; 
	ET0=1;
	TR0=1;
}

void timer0()interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
time++;
}
void tem(){
if(time==20){
		time=0;
		miao++;
		if(miao==60){
			miao=0;
			fen++;
			if(fen==60){
				fen=0;
				shi++;
				if(shi==24){
					shi=0;
				}
				write_sfm(0,shi);//调用分离十位个位函数分离后送到1602对应位置显示
			}
			write_sfm(3,fen);
		} 
		write_sfm(6,miao);
	}
	//可以内部设置闹钟直接判断
	if(miao==10&&fen == 00&&shi == 00){
		bz=0;
		delay_ms(1000);
		bz=1;
		}
			
}

时间显示重点
时间规格写好了,怎么才能将shi,fen,miao,这几个变量写入1602,之前的数码管是将数码管显示数字编码写成一个数组,计时器写好后对10取整取余 分离十位个位判段数组下标然后传递给数码管显示。对余1602也可以采取类似的办法,将十位个位分离后送到对应1602显示位置,显示位置与下面送入1602时间初始数组有关

void write_sfm(uchar add,uchar date)
{
	uchar s,g;
	s=date/10;
	g=date%10;
	write_com(0x80+add);//这里写命令写数据参考前面1602显示文章
	write_date(0x30+s);
	write_date(0x30+g);
}

uchar code time_0[]="00:00:00";
	for(i=0;i<8;i++){
		write_date(time_0[i]); 
		delay_ms(1);  
	}	

改变时间我是这样写的:判断按键1按下然后中断停止,而后直接寻址,然后判断按键2按下加一按键3按下减一,按键1再按下可以再寻址,时分秒按完就恢复。

void key_g(){
	if(k0==0){//判断按键1按下了吗
		delay_ms(10);
		if(k0==0){
			while(!k0);
			num++;
			if(num==1){//最开始光标在秒那
				TR0=0; 
				write_com(0x0f);
				write_com(0x80+7);
			}
			if(num==2){//再按一次光表在分那
				write_com(0x80+4);
			}
			if(num==3){
				write_com(0x80+1);
			}
			if(num==4){
				num=0;
				TR0=1;
				write_com(0x0c);
			}
		}
	}
	if(k1==0) //改变光标所在位置的数字+1
		{
			delay_ms(10);
			if(k1==0)
				{
					while(!k1);
					if(num==1){ 
						miao++;
						if(miao==60)miao=0;
						write_sfm(6,miao);
						write_com(0x80+7);
						}
					if(num==2){
						fen++;
						if(fen==60)fen=0;
						write_sfm(3,fen);
						write_com(0x80+4);
					}
					if(num==3){
						shi++;
						if(shi==24)shi=0;
						write_sfm(0,shi);
						write_com(0x80+1);
					}
				}
		}
		if(k2==0) //改变光标所在位置的数字-1
			{
				delay_ms(10);
				if(k2==0){
					while(!k2);
					if(num==1){
						miao--;
						if(miao==-1)
							miao=59;
						write_sfm(6,miao);
						write_com(0x80+7);
					}
					if(num==2){
						fen--;
						if(fen==-1)fen=59;
						write_sfm(3,fen);
						write_com(0x80+4);
					}
					if(num==3){ 
						shi--;
						if(shi==-1)shi=23;
						write_sfm(0,shi);
						write_com(0x80+1);
					}
				}
			}
}

直接在主函数里调用这些函数(注意顺序,初始化都要在前面)
温度显示函数调用详情参考基于51单片机DS18B20测温

void main(){
	uint i;
	write_init();//1602初始化
	init_t0();//开启定时器初始化
	for(i=0;i<8;i++){
		write_date(time_0[i]); 
		delay_ms(1);  
	}	
	while(1){					
		tem();
		key_g();
		LcdDisplay(Ds18b20ReadTemp());
		if(Ds18b20ReadTemp()==20.0){
		bz=0;
		delay_ms(1000);
		bz=1;
		}
		if(Ds18b20ReadTemp()==-015.0){
		bz=0;
		delay_ms(10000);
		bz=1;
		}	
	}
}

仿真效果如图:
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值