1:数字钟设计
2:基于DS18B20的温度测量模块设计
之前笔者写过一篇用数码管显示日历与温度的实验记录(51单片机的仿真实验——数码管显示日历与温度)。但是数码管在仿真软件上必须用8位和6位将日历与温度分开。若不分开,温度的6位显示在8位数码管上其余的两位会有异常或者不好处理。因此本实验用1602显示屏来代替数码管。
项目工程与仿真实验文件
链接:https://pan.baidu.com/s/1mdz1D9PpkaOwR3cGU9RNpw 提取码:frkg
本实验主要有单片机、七个按键、一个1602显示屏、温度传感器以及一个LED报警灯组成,实现电路如下:
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单片机上给读者一定的帮助,省下找各种解决方案的时间成本。感谢各位观看,如有不足,欢迎在评论内留言与讨论。如果觉得写得好的,可以给我点赞+收藏+关注哦,再次感谢各位!