51单片机的仿真实验——1602显示屏显示万年历与温度

实验内容:

1:数字钟设计
2:基于DS18B20的温度测量模块设计


问题描述:

之前笔者写过一篇用数码管显示日历与温度的实验记录(51单片机的仿真实验——数码管显示日历与温度)。但是数码管在仿真软件上必须用8位和6位将日历与温度分开。若不分开,温度的6位显示在8位数码管上其余的两位会有异常或者不好处理。因此本实验用1602显示屏来代替数码管。


实验产出:

项目工程与仿真实验文件
链接:https://pan.baidu.com/s/1mdz1D9PpkaOwR3cGU9RNpw 提取码:frkg


仿真视图:

本实验主要有单片机、七个按键、一个1602显示屏、温度传感器以及一个LED报警灯组成,实现电路如下:
51单片机的仿真实验——1602显示屏显示万年历与温度_第1张图片


项目代码:

a.1602代码源:

#include
#include<1602.h>
void delay(uint z)
{
    uint x;
	for(x=z;x>0;x--);
}
void write_com(uchar com)
{
     P0=com;
	 lcdrs=0;
	 lcden=0;
	 delay(1);
	 lcden=1;
	 delay(1);
	 lcden=0;
}
void write_date(uchar date)
{
    P0=date;
	lcdrs=1;
	lcden=0;
	delay(1);
	lcden=1;
	delay(1);
	lcden=0;
}
void Init()
{
   write_com(0x38);
   delay(1);
   write_com(0x0f);
   delay(1);
   write_com(0x06);
   delay(1);
   write_com(0x01);
   delay(1);
}

b.主函数代码(数据读取主要原理与数码管类似 具体内容可以参见(51单片机的仿真实验——数码管显示日历与温度)):

#include
#include<1602.h>
#define uchar unsigned char
#define uint unsigned int
uchar table1[]=" Temperture: ";
uchar table2[14];
uchar table3[14];
uchar table4[14];
uchar table5[]="540 ZYB   ";
uchar table6[]="   DATA/WD:";
sbit P2_6 = P2^6 ;
sbit P2_7 =	P2^7 ;
unsigned char tab[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x39};

//uchar code led_7seg[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
uint hour=23,minute=59,second=580,month=12,day=31;
uint n=0,i=0;
uint count=0,year=2000,a,b;
/*sbit P2_0=P2^0;
sbit P2_1=P2^1;
sbit P2_2=P2^2;
sbit P2_3=P2^3;
sbit P2_4=P2^4;
sbit P2_5=P2^5;
sbit P2_6=P2^6;
sbit P2_7=P2^7;		 */
uint flag=0;

void init_timer0(void)
{
	TMOD=0x01;
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	ET0=1;
	TR0=1;
	EA=1;
}


void Init_DS18B20(void)
{
	unsigned char x=0;
	P2_6 = 1; 
	delay(8); 
	P2_6 = 0; 
	delay(80); 
	P2_6 = 1; 
	delay(14);
	x=P2_6;
	delay(20);
}	  	

/*void qinglin()
{
	for(i=0;i<100;i++);
		
} 	*/

tochar(int i)
{
	char a;
	if(i==0) a='0';
	if(i==1) a='1';
	if(i==2) a='2';
	if(i==3) a='3';
	if(i==4) a='4';
	if(i==5) a='5';
	if(i==6) a='6';
	if(i==7) a='7';
	if(i==8) a='8';
	if(i==9) a='9';
	return a;	 
}

void display(void)
{
		  table3[0]=tochar(year/1000);
		  table4[4]=tochar(hour/10); 
//		  P2_0=1;
//		  qinglin();
		  table3[1]=tochar(year/100%10);
		  table4[5]=tochar(hour%10);
//		  P2_1=1;
//		  qinglin();
		  table3[2]=tochar(year/10%10);
		  table4[6]=':';
//		  P2_2=1;
//		  qinglin();
		  table3[3]=tochar(year%10);
		  table4[7]=tochar(minute/10);
//		  P2_3=1;
//		  qinglin();
		  table3[4]='-';
		  table3[5]=tochar(month/10);
		  table4[8]=tochar(minute%10);
//		  P2_4=1;
//		  qinglin();
		  table3[6]=tochar(month%10);
		  table4[9]=':';
//		  P2_5=1;
//		  qinglin();
		  table3[7]='-';
		  table3[8]=tochar(day/10);
		  table4[10]=tochar(second/165);
//		  P2_6=1;
//		  qinglin();
		  table3[9]=tochar(day%10);
		  table4[11]=tochar(second*10/165%10);
//		  P2_7=1;
//    	  qinglin();
}

void runnian(void)
{
	if((year%4==0)&&(year%100!=0)||(year%400==0))
	{
		if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
		{b=32;}
		if((month==4)||(month==6)||(month==9)||(month==11))
		{b=31;}
		if(month==2)
		{b=30;}
	}
	else{
		if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
		{b=32;}
		if((month==4)||(month==6)||(month==9)||(month==11))
		{b=31;}
		if(month==2)
		{b=29;}
	}
}
void dl_10ms(void)
{
	int i;
	for(i=1000;i>0;i--);
}

uchar kbscan(void)
{
	uchar sccode,recode;
	P1=0xF0;
	if((P1&0xF0)!=0xF0)
	{
		dl_10ms();
		if((P1&0xF0)!=0xF0)
		{
			sccode=0xFE;
			while((sccode&0x10)!=0)
			{
				P1=sccode;
				if((P1&0xF0)!=0xF0)
				{
					recode=(P1&0xF0)|0x0F;
					return((~sccode)+(~recode));
				}
				else
				{
					sccode=(sccode<<1)|0x01;
				}
			}
		}
	}
	return 0;
}			 
						     
ReadOneChar(void)
{
	unsigned char i=0;
	unsigned char dat = 0;
	for (i=8;i>0;i--)
	{
		P2_6 = 0; 		     
		dat>>=1;
		P2_6 = 1; 			   
		if(P2_6)
			dat|=0x80;
		delay(4);
	}
	return(dat);
}

void WriteOneChar(unsigned char dat)
{
	unsigned char i=0;
	for (i=8; i>0; i--)
	{
		P2_6 = 0;
		P2_6 = dat&0x01;
		delay(5);
		P2_6 = 1;
		dat>>=1;
	}
	delay(4);
}	  

ReadTemperature(void)
{
	unsigned char a=0;
	unsigned char b=0;
	unsigned int t=0;
	Init_DS18B20();
	WriteOneChar(0xCC);		  														     
	WriteOneChar(0x44); 
	Init_DS18B20();
	WriteOneChar(0xCC);
	WriteOneChar(0xBE); 
	a=ReadOneChar(); 
	b=ReadOneChar();   
	t=b<<8; 
	t=t|a;
	return(t);
}



void display_tempmain(unsigned int i) 
{
	//tochar(int i);
	float temp ;
	unsigned char xiaoshu;
	unsigned int zhengshu;
	if((0xf000&i)==0xf000)
	{
  		i=~i+1;	
  		P0=0x00;
  		P0=tab[10];
 		P3=0xfe;
  		delay(1000);
	}
 	temp = (0x000f & i) * 10.0 * 0.0625;
 	xiaoshu = temp;
 	zhengshu= i>>4;
	if(zhengshu>=28) P2_7=1;
	else P2_7=0;
	table2[0]=' ';
	table2[1]=' ';
	table2[2]=' ';
	table2[3]=tochar(zhengshu/100);
	table2[4]=tochar(zhengshu%100/10);
	table2[5]=tochar(zhengshu%100%10);
	table2[6]='.';
	table2[7]=tochar(xiaoshu);
	table2[8]='C';
	table2[9]=' ';
	table2[10]=' ';
	table2[11]=' ';
	table2[12]=' ';
	table2[13]=' ';
}


void display_Init_Temp()
{
     uchar i;
	 write_com(0x80);
	 write_com(0x0C);
	 for(i=0;i<14;i++)
	 {
	     write_date(table1[i]);
		 delay(5);
	 }
	 write_com(0x80+0x40);
 //    write_com(0x0C);
	 for(i=0;i<12;i++)
	 {
	     write_date(table2[i]);
		 delay(5);
      }
}

void display_Init_Time()
{	  
 	 uchar i;
	 display();
	 write_com(0x80);
	 write_com(0x0C);
	 for(i=0;i<14;i++)
	 {
	     write_date(table3[i]);
		 delay(5);
	 }
	 write_com(0x80+0x40);
 //    write_com(0x0C);
	 for(i=0;i<12;i++)
	 {
	     write_date(table4[i]);
		 delay(5);
      }
}

void display_Init_zuozhe()
{	  
 	 uchar i;
	 display();
	 write_com(0x80);
	 write_com(0x0C);
	 for(i=0;i<14;i++)
	 {
	     write_date(table5[i]);
		 delay(5);
	 }
	 write_com(0x80+0x40);
 //    write_com(0x0C);
	 for(i=0;i<12;i++)
	 {
	     write_date(table6[i]);
		 delay(5);
      }			  
}	 
void main()
{
     uchar key;
	 unsigned int temp;		 
	 Init();
	 init_timer0();
     //qinglin();
	 
	 while(1)
	 {
	 	temp=ReadTemperature();
	 	display_tempmain(temp);
	//	display();
	//	display_Init_Time();
		if(flag==0)
		{
		    display_Init_Temp();
		}
		else if(flag==1)
		{
		//	display();
			display_Init_Time();
		}  
		else if(flag==2)
		{
		//	display();
			display_Init_zuozhe();
		}  
	 	 key=kbscan();
		switch(key)
		{
			case 0x11:
			{	
				flag=1;
				if(hour<23)hour++;
				else 
				{
				    
					hour=0;
					day++;
				} 
				while(key==0x11)
				{
					key=kbscan();
				}
			}
				break;
			case 0x21:
			{
				flag=1;
				if(minute<59) minute++;
				else 
				{	
					minute=0;
					hour++;
				}
				while(key==0x21)
				{
					key=kbscan();
				}
			}
				break;
			case 0x41:
			{
				flag=1;
				runnian();
				if(day<(b-1)) day++;
				else 
				{
					day=1;
					month++;
					if(month==13) 
						month=1;
				}
				while(key==0x41)
				{
					key=kbscan();
				}
			}
				break;
			case 0x81:
			{
				flag=1;
				if(month<=11) month++;
				else 
				{
					month=1;
					year++;
				}
				while(key==0x81)
				{
					key=kbscan();
				}
			}
			break;
			case 0x12:
			{	
				flag=1;
				year++;
				while(key==0x12)
				{
					key=kbscan();
				}
			}
			break;
			case 0x22:
			{	
				flag=1;
				year--;
				while(key==0x22)
				{
					key=kbscan();
				}
			}
			break;
		/*	case 0x42:
			{	
				flag=0;
				while(key==0x42)
				{
					key=kbscan();
				}
			}
			break;
			case 0x82:
			{	
				flag=1;
				while(key==0x82)
				{
					key=kbscan();
				}
			}
			break; */
			case 0x42:
			{	
				if(flag==0)
					flag=1;
					else if(flag==1)
						flag=2;
						else if(flag==2) 
							flag=0;
				while(key==0x42)
				{
					key=kbscan();
				}
			}
			break;
/*			case 0x82:
			{	
				if(flag==0||flag==1)
				flag=2;
				else flag=0;
				while(key==0x82)
				{
					key=kbscan();
				}
			}
			break;	  */
		default:break;
		}
	 }
}

void timer0_int(void) interrupt 1 
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	second++; 
	dl_10ms();
/*	for(n=0;n<20;n++){
		switch(n & 0x07)
		{
		case 0:{P0=0xFF; P2=0x00; P3=0xFF;
				P0=led_7seg[hour%10];
				P3=led_7seg[year/100%10];P2=0x02;}break;
		case 1:{P0=0xFF; P2=0x00; P3=0xFF;
				P0=led_7seg[hour/10];
				P3=led_7seg[year/1000];P2=0x01;}break;
		case 2:{P0=0xFF; P2=0x00; P3=0xFF;
				P0=led_7seg[10];
				P3=led_7seg[year/100%10];P2=0x04;}break;
		case 3:{P0=0xFF; P2=0x00; P3=0xFF;
				P0=led_7seg[minute%10];
				P3=led_7seg[month/10];P2=0x10;}break;
		case 4:{P0=0xFF; P2=0x00; P3=0xFF;
				P0=led_7seg[minute/10];
				P3=led_7seg[year%10];P2=0x08;}break;
		case 5:{P0=0xFF; P2=0x00; P3=0xFF;
				P0=led_7seg[10];
				P3=led_7seg[month%10];P2=0x20;}break;
		case 6:{P0=0xFF; P2=0x00; P3=0xFF;
				P0=led_7seg[second%10];
				P3=led_7seg[day%10];P2=0x80;}break;
		case 7:{P0=0xFF; P2=0x00;
				P0=led_7seg[second/10];
				P3=led_7seg[day/10];P2=0x40;}break;
		default:break;
		}	
	}	 */
/*	if(count==10)
	{
		count=0;
		second++;				 */
		if(second==990)
		{
			second=0;
			minute++;
			if(minute==60)
			{
				minute=0;
				hour++;
				if(hour==24)
				{
					hour=0;
					day++;
					runnian();
					if(day==b)
					{
						day=1;
						month++;
						if(month==13)
						{
							month=1;
							year++;
						}
					}
				}
			}
		//}
	}
}


实验结论:

本项目在数码管实验的基础上增加了作者标签函数(display_Init_zuozhe())以及温度过高时指示灯的报警(if(zhengshu>=28) P2_7=1)。整体来说其实1602显示屏的显示还相对于数码管更加简单一点。但是1602显示屏在原理图上还需要多接一些元器件,并且不能接错,否则显示数据会异常。


总结:

希望本博客能在51单片机上给读者一定的帮助,省下找各种解决方案的时间成本。感谢各位观看,如有不足,欢迎在评论内留言与讨论。如果觉得写得好的,可以给我点赞+收藏+关注哦,再次感谢各位!
在这里插入图片描述

你可能感兴趣的:(51单片机,单片机,c++,c语言)