单片机原理实验1602显示温度时钟
基于51单片机的1602液晶显示温度和时间的C程序

//液晶显示温度#include "AT89X52.H"#define Ddata P0sbit RS=P2^7; //命令数据控制端sbit RW=P2^6; //读写选择端sbit LCDE=P2^5; //液晶使能端sbit DQ=P2^0; //ds18b20与单片机连接口#define uchar unsigned char#define uint unsigned intunsigned char hour=0,min=0,sec=0; //定义初值unsigned int count=0;unsigned char line1[16]={" temp: "}; //16个字符unsigned char line2[16]={" time: 00:00:00"}; //16个字符unsigned char tab[]={'0','1','2','3','4','5','6','7','8','9'}; //数组uchar data disdata[5];uint tvalue; //温度值uchar tflag; //温度正负标志void time();/*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<110;j++);}void delay5ms()//延时5毫秒(不够精确的){unsigned int i;for (i=0;i<1000;i++);}void delay50us(){register int i;for (i=0;i<20;i++);}void delay(){unsigned char m,n;for(m=255;m>0;m--)for(n=255;n>0;n--);}void wr_com(unsigned char comm) //********写控制字符程序E=1 RS=0RW=0 **********//{LCDE=0; //使能端RS=0; //********RS寄存器选择输入端,当RS=0;当进行写模块操作,指向指令寄存器。
LCD1602_显示时间_温度

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define LCDIO P2sbit DQ=P1^3;//ds18b20与单片机连接口sbit rs=P1^0;sbit rd=P1^1;sbit lcden=P1^2;sbit acc0=ACC^0; //移位时的第0位sbit acc7=ACC^7; //移位时用的第7位uchar second,minute,hour,day,month,year,week,count=0; uchar ReadValue,num,time;uint tvalue;//温度值uchar tflag;uchar code table[]={" 2010-11-29 MON"};uchar code table1[]={" 15:45:00 000.0C"};uchar code table2[]= "THUFRISATSUNMONTUEWES";uchar data disdata[5];sbit DATA=P0^1; //时钟数据接口sbit RST=P0^2;sbit SCLK=P0^0;sbit menu=P3^5; //菜单sbit add=P3^6; //加一sbit dec=P3^7; //减一void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); }void delay1(uint z){for(;z>0;z--);}void write_com(uchar com) {rs=0;rd=0;lcden=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchar date) {rs=1;lcden=0;P2=date;delay(5);lcden=1;delay(5);lcden=0;}void init(){uchar num;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);delay(5);write_com(0x80);for(num=0;num<15;num++){write_date(table[num]);delay(5);write_com(0x80+0x40);for(num=0;num<15;num++){write_date(table1[num]);delay(5);}}void Write1302(uchar dat){uchar i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备delay1(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{DATA=dat&0x01; //取出dat的第0位数据写入1302delay(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delay1(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位 }}void WriteSet1302(uchar Cmd,uchar dat){RST=0; //禁止数据传递SCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输delay1(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递}uchar Read1302(void){uchar i,dat;delay(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位 if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delay1(2); //稍微等待SCLK=0; //拉低SCLK,形成脉冲下降沿delay1(2); //稍微等待}return dat; //将读出的数据返回}uchar ReadSet1302(uchar Cmd){uchar dat;RST=0; //拉低RSTSCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输Write1302(Cmd); //写入命令字dat=Read1302(); //读出数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat; //将读出的数据返回}void Init_DS1302(void){WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值 WriteSet1302(0x82,((45/10)<<4|(45%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((15/10)<<4|(15%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((29/10)<<4|(29%10))); //根据写日寄存器命令字,写入日的初始值 WriteSet1302(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值 WriteSet1302(0x8c,((10/10)<<4|(10%10))); //nianWriteSet1302(0x8a,((4/10)<<4|(4%10)));}void DisplaySecond(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0xc7);write_date(0x30+i);write_date(0x30+j);}void DisplayMinute(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0xc4);write_date(0x30+i);write_date(0x30+j);}void DisplayHour(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0xc1);write_date(0x30+i);write_date(0x30+j); }void DisplayDay(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x89);write_date(0x30+i);write_date(0x30+j); }void DisplayMonth(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x86);write_date(0x30+i);write_date(0x30+j); }void DisplayYear(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x83);write_date(0x30+i);write_date(0x30+j); }void DisplayWeek(uchar x) { uchar i;x=x*3;write_com(0x8c);for(i=0;i<3;i++){write_date(table2[x]);x++;}}void read_date(void){ReadValue = ReadSet1302(0x81);second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x83);minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x85);hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x87);day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x89);month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x8d);year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue=ReadSet1302(0x8b); //读星期 week=ReadValue&0x07;DisplaySecond(second);DisplayMinute(minute);DisplayHour(hour);DisplayDay(day);DisplayMonth(month);DisplayYear(year);DisplayWeek(week);}void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num){newval=ReadSet1302(newaddr); //读取当前时间newval=((newval&0x70)>>4)*10+(newval&0x0f); //将bcd码转换成十进制if(flag) //判断是加一还是减一{newval++;switch(s1num){ case 1: if(newval>99) newval=0;DisplayYear(newval);break;case 2: if(newval>12) newval=1;DisplayMonth(newval);break;case 3: if(newval>31) newval=1;DisplayDay(newval);break;case 4: if(newval>6) newval=0;DisplayWeek(newval);break;case 5: if(newval>23) newval=0;DisplayHour(newval);case 6: if(newval>59) newval=0;DisplayMinute(newval);break;case 7: if(newval>59) newval=0;DisplaySecond(newval);break;default:break;}}else{newval--;switch(s1num){ case 1: if(newval==0) newval=99;DisplayYear(newval);break;case 2: if(newval==0) newval=12;DisplayMonth(newval);break;case 3: if(newval==0) newval=31;DisplayDay(newval);break;case 4: if(newval<0) newval=6;DisplayWeek(newval);case 5: if(newval<0) newval=23;DisplayHour(newval);break;case 6: if(newval<0) newval=59;DisplayMinute(newval);break;case 7: if(newval<0) newval=59;DisplaySecond(newval);break;default:break;}}WriteSet1302((newaddr-1),((newval/10)<<4)|(newval%10)); //将新数据写入寄存器}//键盘扫描程序//*******************************************void key_scan(void){ uchar miao,s1num=0;if(menu==0){delay(5);if(menu==0){while(!menu);s1num++;while(1){if(menu==0){delay(5);if(menu==0){while(!menu);s1num++;}}rd=0;miao=ReadSet1302(0x81);second=miao;WriteSet1302(0x80,miao|0x80);write_com(0x0f);//光标闪射if(s1num==1){ year=ReadSet1302(0x8d);write_com(0x80+4); //年光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(year,1,0x8d,1);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(year,0,0x8d,1);}}}if(s1num==2){month=ReadSet1302(0x89);write_com(0x80+7); //月光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(month,1,0x89,2); }}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(month,0,0x89,2); }}}if(s1num==3){ day=ReadSet1302(0x87);write_com(0x80+10);//日光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(day,1,0x87,3);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(day,0,0x87,3); //写入日寄存器 }}}if(s1num==4){ week=ReadSet1302(0x8b);write_com(0x80+14); //星期光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(week,1,0x8b,4);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(week,0,0x8b,4);}}}if(s1num==5){ hour=ReadSet1302(0x85);write_com(0x80+0x40+2); //时光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(hour,1,0x85,5);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(hour,0,0x85,5);}}}if(s1num==6)//调时间分{ minute=ReadSet1302(0x83);write_com(0x80+0x40+5);if(add==0){delay(5);if(add==0){ while(!add);turn_val(minute,1,0x83,6); //写入分寄存器 }}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(minute,0,0x83,6); //写入分寄存器 }}}if(s1num==7)//调时间秒{ second=ReadSet1302(0x81);write_com(0x80+0x40+8);//秒光标if(add==0){delay(3);if(add==0){ while(!add);if(second==0x60)second=0x00;turn_val(second,1,0x81,7);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(second,0,0x81,7);}}}if(s1num==8){ miao=ReadSet1302(0x81);second=miao;WriteSet1302(0x80,second&0x7f);s1num=0;//s1num清零//write_com(0x0c);//光标不闪烁//break;}}}}}void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/ {unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else{tvalue=~tvalue+1;tflag=1;}tvalue=tvalue*(0.425);//温度值扩大10倍,精确到1位小数return(tvalue);}void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=tvalue/1000+0x30;//百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30;//个位数disdata[3]=tvalue%10+0x30;//小数位if(tflag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}write_com(0xc9);write_date(flagdat);//显示符号位write_com(0xca);write_date(disdata[0]);//显示百位write_com(0xcb);write_date(disdata[1]);//显示十位write_com(0xcc);write_date(disdata[2]);//显示个位write_com(0xcd);write_date(0x2e);//显示小数点write_com(0xce);write_date(disdata[3]);//显示小数位write_com(0xcf);write_date('C');}void main(){init();Init_DS1302(); //将1302初始化read_temp();//读取温度ds1820disp();//显示while(1){read_date();key_scan();read_temp();//读取温度ds1820disp();//显示}}完。
51单片机万年历1602显示时间温度按键调时(焊接前备份)

}
if(hmin_fen==6)
{
hmin_fen=0;
//nmin_shi++;
}
ZuiZhong[13]=l_tmpdate[1]%16+0x30;
ZuiZhong[14]=':';
ZuiZhong[15]=l_tmpdate[0]/16+0x30;
ZuiZhong[16]=l_tmpdate[0]%16+0x30;
ZuiZhong[17]=' ';
/* ZuiZhong[18]=Temperature%1000/100+0x30;
ZuiZhong[19]=Temperature%100/10+0x30;
ZuiZhong[20]=Temperature%10+0x30;
ZuiZhong[21]=0xdf;
ZuiZhong[22]='C'; */
write_lcd1602(0x80+0x43,0); // 20
for(i=23;i<=24;i++)
write_lcd1602( ZuiZhong[i], 1 );
if(K1==0)
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P2^6; // 【1602显示引脚定义】
sbit rw=P2^5; //【【【【【7-6-5顺序
51单片机实现电子时钟功能_1602液晶显示

第一章设计要求及系统组成一、基本操作时序:读状态:输入:RS=L,RW=H,E=H 输出:D0~D7=状态字写指令:输入:RS=L,RW=L,D0~D7=指令码,E=高脉冲输出:无读数据:输入:RS=H,RW=H,E= 高脉冲输出:D0~D7数据写数据:输入:RS=H,RW=L。
D0~D7=数据,E=高脉冲输出:无二、、、状态字说明:STA7 D7\ STA6 D6\ STA5 D5 \ STA4 D4 \STA3 D3 \ STA2 D2\\ STA1 D1STA0-6:当前数据地址指针的数值STA7:读写操作使能 1表示禁止,0表示允许对控制器每次进行读写操作之前,都必须进行读写检测,确保STA7为0;但是我们可以进行延时进行实现。
RAM地址映射: LCD 16字*2行00 01 02 03 04 05 06 07 08 08 09 0A 0B 0C 0D 0E 0F (27)40 41 42 4F 50 (67)指令说明:1.初始化设置 1.显示模式设置指令码:00111000<0x38)功能:设置16*2显示,5*7点阵,8位数据接口必须开显示 2.显示开、关及光标设置指令码:00001DCB,功能:D=1 开显示;D=0 关显示;C=1显示光标;B=1 光标闪烁;B=0 光标不显示 000001NS:功能:N=1当读或写一个字符后地址指针加1,且光标加1;N=0相应的减1;S=1当写一个字符,整屏显示左移<N=1)或右移<N=0),以得到光标不移动而屏幕移动的效果。
S=0 当写一个字符,正屏显示不移动。
数据控制:控制器内部设有一个数据地址指针,用户可通过它们来访问内部的全部80字节RAM4.2.1 数据指针设置:指令码:80H+地址码 <0-27H,第二行开始:40H-67H) 4..2.2 读数据,写数据其它设置:01H:显示清屏:1.数据指令清零 2 所有显示清零02H:显示回车:1.数据清零如何进行连接:实际操作中,液晶接到,第一管脚是D,第二管脚是VCC,15和16是背光,D0-D7是数据口,接到单片机的P0口,P0口接了两个锁存器,液晶,D/A,具有高阻状态的都可以随便接,没有影响,,第六管脚是LCDEN相当于 E,使能信号,它接P3^4,R/W接地,表示低电平,因为我们只进行写操作,RS 接2实验板上的P3^5。
用51单片机和1602液晶做的数字钟

用51单片机和1602液晶做的数字钟数字钟是人们日常生活中常见的时间显示设备,它能够精确显示当前的时间,并且兼具简约和实用性。
本文将介绍使用51单片机和1602液晶屏幕制作自己的数字钟的方法。
所需材料在开始制作之前,我们需要准备以下材料: - 51单片机开发板 - 1602液晶屏幕 - 数字时钟芯片RTC(Real-Time Clock) - 面包板和导线 - 电阻和电容 - 编程器和烧录器硬件连接首先,我们需要将51单片机、1602液晶屏幕和RTC芯片连接起来。
根据硬件接口的定义和引脚功能的规定,我们可以进行以下连接: - 将51单片机的VCC 引脚连接到1602液晶屏幕的VCC引脚,用于提供电源。
- 将51单片机的GND引脚连接到1602液晶屏幕的GND引脚,用于地线连接。
- 将51单片机的P0口连接到1602液晶屏幕的数据线D0-D7,用于数据传输。
- 将51单片机的P2口连接到1602液晶屏幕的RS引脚,用于选择数据和命令传输。
- 将51单片机的P3口连接到1602液晶屏幕的EN引脚,用于启用LCD。
此外,还需要将RTC芯片连接到51单片机上,以实现时间的准确显示。
具体的连接方式可以参考RTC芯片的规格说明书。
软件编程完成硬件连接后,我们需要进行软件编程,以便控制51单片机、1602液晶屏幕和RTC芯片的功能。
初始化首先,我们需要对51单片机和1602液晶屏幕进行初始化设置。
这包括设置引脚的功能模式、初始化1602液晶屏幕的显示模式和清空显示区域。
读取时间接下来,我们需要通过RTC芯片来读取当前的时间。
这通常包括读取RTC芯片存储的年、月、日、时、分和秒的数据。
显示时间读取时间后,我们可以将其显示在1602液晶屏幕上。
这可以通过更新特定的LCD显示区域来实现。
我们可以在指定的位置、特定的行和列上显示时间。
更新时间为了实现实时的时间显示,我们需要定期更新显示的时间。
可以使用定时器中断来定期更新时间,并根据需要刷新液晶屏幕上的显示。
1602液晶显示时间与温度程序

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P2^7;sbit lcdrs=P2^5;sbit rw=P2^6;sbit DQ=P3^5;sbit key1=P3^0;sbit key2=P3^1;sbit key3=P3^2;sbit key4=P3^7;uchar count,key1num,key2num,key3num,shi,fen,miao; uchar num;uchar code table[]= {" 00:00:00 "};uchar code table1[]={" 000.0 C "};uchar code table2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; uchar SegBuffer[4]={0};void Delay_15us(uint del){for(del;del>0;del--){_nop_();_nop_();_nop_();_nop_();}_nop_();_nop_();}bit RST_DS18B20(){bit ret=1;DQ=0;Delay_15us(39);DQ=1;Delay_15us(4);ret=DQ;Delay_15us(27);DQ=1;return ret;}void WBIT_DS18B20(bit data_bit){DQ=0;Delay_15us(0);DQ=data_bit;Delay_15us(2);DQ=1;}void WBYTE_DS18B20(uchar data_byte){uchar i;for(i=0;i<8;i++){WBIT_DS18B20((bit)(data_byte & 0x01));data_byte>>=1;}}bit RBIT_DS18B20(){bit data_bit;DQ=0;_nop_();_nop_();_nop_();DQ=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();data_bit=DQ;Delay_15us(3);DQ=1;return data_bit;}uchar RBYTE_DS18B20(){uchar data_byte=0;uchar i,j;for(i=0;i<8;i++){j=RBIT_DS18B20();j=j<<i;data_byte=data_byte|j;}return data_byte;}void START_DS18B20(){DQ=1;_nop_();_nop_();RST_DS18B20();WBYTE_DS18B20(0xcc);WBYTE_DS18B20(0x44);}uint READ_TEM(){uint tem=0;DQ=1;_nop_();_nop_();RST_DS18B20();WBYTE_DS18B20(0xcc);WBYTE_DS18B20(0xbe);tem=RBYTE_DS18B20();tem=(RBYTE_DS18B20()<<8)|tem;return tem;}void Temperature_4(uint data_tem) {uint dat=0;float temp;if(data_tem&0x800){data_tem=~data_tem+1;temp=data_tem*0.0625;temp=temp*10+0.5;dat=temp;SegBuffer[0]=dat%10;SegBuffer[1]=dat/10%10;SegBuffer[2]=dat/100%10;;}else{temp=data_tem*0.0625;temp=temp*10+0.5;dat=temp ;SegBuffer[0]=dat%10;SegBuffer[1]=dat/10%10;SegBuffer[2]=dat/100%10;SegBuffer[3]=dat/1000%10;}}void delay_1ms(uint del){uint i,j;for(i=0;i<del;i++)for(j=0;j<148;j++);}void write_com(uchar com){lcdrs=0;P0=com;delay_1ms(5);lcden=1;delay_1ms(5);lcden=0;}void write_date(uchar date){lcdrs=1;P0=date;delay_1ms(5);lcden=1;delay_1ms(5);lcden=0;}void display(){write_date(0x30+SegBuffer[0]); write_com(0x80+0x40+7);write_date(0x30+SegBuffer[1]); write_com(0x80+0x40+6);write_date(0x30+SegBuffer[2]); write_com(0x80+0x40+5);write_date(0x30+SegBuffer[3]);}void init(){rw=0;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);for(num=0;num<16;num++){write_date(table[num]);delay_1ms(5);}write_com(0x80+0x40);for(num=0;num<16;num++){write_date(table1[num]);delay_1ms(5);}TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;IE=0x82;TR0=1;}void write_sfm(uchar add,uchar date) {uchar shi1,ge;shi1=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi1);}void keyscan(){key4=0;if(key1==0){delay_1ms(1);if(key1==0){key1num++;while(!key1);if(key1num==1){TR0=0;write_com(0x80+11);write_com(0x0f);}if(key1num==2){write_com(0x80+8);}if(key1num==3){write_com(0x80+5);}if(key1num==4){key1num=0;write_com(0x0c);TR0=1;}}}if(key1num!=0){if(key2==0){delay_1ms(1);if(key2==0){while(!key2);if(key1num==1){miao++;if(miao==60)miao=0;write_sfm(10,miao);write_com(0x80+10);}if(key1num==2){fen++;if(fen==60)fen=0;write_sfm(7,fen);write_com(0x80+7);}if(key1num==3){shi++;if(shi==24)shi=0;write_sfm(4,shi);write_com(0x80+4);}}}if(key3==0){delay_1ms(1);if(key3==0){while(!key3);if(key1num==1){miao--;if(miao==-1)miao=59;write_sfm(10,miao);write_com(0x80+10);}if(key1num==2){fen--;if(fen==-1)fen=59;write_sfm(7,fen);write_com(0x80+7);}if(key1num==3){shi--;if(shi==-1)shi=23;write_sfm(4,shi);write_com(0x80+4);}}}}}void main(){uint temp=0;init();while(1){START_DS18B20();temp=READ_TEM();Temperature_4(temp);display();keyscan();}}void T0_time() interrupt 1{TH0=(65536-45872)/256;TL0=(65536-45872)%256;count++;if(count==20){count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}write_sfm(4,shi);}write_sfm(7,fen);}write_sfm(10,miao);}}。
单片机实验报告 ——LCD1602显示时钟

XXXX学院实验报告Experimentation Report of Taiyuan Normal University系部计算机年级大三课程单片机原理与接口技术姓名同组者日期学号项目 LCD1602显示时钟一、实验目的1、了解单片机顺序执行的特点;2、掌握C语言的编写和keilc51的使用;3、熟悉DS1302芯片的工作过程二、实验仪器硬件资源:单片机开发板笔记本电脑 DS1302芯片;软件资源:软件 Keil uVision5;三、实验原理1、流程图2、连接图四、实验结果将LCD屏连接到单片机上,点击编译运行,LCD屏上显示时间:2013-01-01 2 12-00-38。
在DS1302.c文件里修改uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01,0x02, 0x13};为uchar TIME[7] = {0x14, 0x11, 0x19, 0x28, 0x11,0x04, 0x19};点击编译运行按钮,LCD屏幕显示2019-11-28 4 19-11-14。
四、实验代码及分析//主函数void main(){Ds1302Init(); //初始化DS1302LcdInit(); //初始化LCDwhile(1){Ds1302ReadTime(); //DS1302读时间LcdDisplay(); //LCD显示时间}}//初始化DS1302void Ds1302Init(){uchar n;Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能for (n=0; n<7; n++) //写入7个字节的时钟信号:分秒时日月周年{Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);}Ds1302Write(0x8E,0x80); //打开写保护功能}//读取时钟信息void Ds1302ReadTime(){uchar n;for (n=0; n<7; n++) //读取7个字节的时钟信号:分秒时日月周年{TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);}}//---DS1302写入和读取时分秒的地址命令---////---秒分时日月周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。
单片机的LCM1602液晶显示温度与万年历显控制

毕业设计报告(论文)报告(论文)题目:基于单片机的LCM1602液晶控制——温度与万年历显示设计作者所在系部:电子工程系作者所在专业:作者所在班级:作者姓名:作者学号:指导教师姓名:完成时间: 2011年 6 月 9 日院教务处制电子工程系毕业设计(论文)任务书指导教师:教研室主任:系主任:摘要论文的研究工作是以液晶屏显示技术为背景展开的,并且详细介绍了通过MCS-51单片机控制LCM1602液晶的显示情况,以软件形式对系统进行控制,使得系统控制更具灵活与方便。
本文在深入分析LCD显示技术的基础上,重点解析了LCM显示的单片机控制技术,以及LCD显示在各种电子显示中的优势,同时阐述了其在日常显示系统中的应用;并且以Proteus与Keil uVision4软件为基础,编写了MCS-51单片机对LCM1602显示控制的软件,绘制其原理图,并使用Proteus软件与Keil uVision4软件建立联合仿真。
论文主要论述了原理图各个模块的作用,控制软件的各个模块的编程。
关键词液晶显示技术LCM1602 MCS-51单片机Proteus Keil uVision4目录第1章绪论 (1)1.1课题背景及主要技术国内外研究概况 (1)1.2LCM1602显示控制系统简介 (2)1.3课题的建立以及本文完成的主要工作 (3)第2章开发工具软件简介 (4)2.1K EIL U V ISION4软件简介 (4)2.2P ROTEUS软件简介 (4)2.3K EIL U V ISION4与P ROTEUS软件联合仿真 (5)2.4小结 (5)第3章 LCD显示控制技术 (6)3.1LCD显示技术的发展 (6)3.2LCM1602显示控制技术及其体系结构 (7)3.2.1 LCM1602模块简介 (8)3.2.2 LCM1602模块内部结构 (9)3.2.3 LCM1602控制指令 (10)3.3小结 (12)第4章系统硬件概况 (13)4.1系统概况 (13)4.2功能模块 (13)4.2.1 MCS-51单片机最小系统模块 (14)4.2.2 温度采集模块 (14)4.2.3 蜂鸣器报警模块 (15)4.2.4 万年历调节设置模块 (16)4.2.5 LCM1602显示模块 (16)4.2.6 电源模块 (17)3.3小结 (17)第5章软件控制系统概况 (18)5.1程序流程概况 (18)5.2万年历显示控制模块 (18)5.2.1 流程图 (18)5.2.2 源程序代码 (19)5.3温度显示控制模块 (19)5.3.1 程序流程 (19)5.3.2 源程序代码 (19)5.3.3 主程序 (19)5.4小结 (20)第6章课题特点 (21)6.1LCM模块的应用 (21)6.2程序结构化与模块化设计 (21)6.3抗干扰技术 (21)第7章结论 (23)7.1调试联合仿真 (23)7.2仿真结果 (23)7.3小结 (23)致谢 (24)参考文献 (25)附录 (26)基于单片机的LCM1602液晶控制——温度与万年历显示设计第1章绪论1.1 课题背景及主要技术国内外研究概况自20世纪80年代起,显示设备经历着传统工艺的改良、新工艺的发展、成熟的优胜劣汰。
基于单片机的LCD1602电子时钟设计

基于单片机的LCD1602电子时钟设计近年来,随着物联网和智能设备的快速发展,电子时钟作为一种常见的智能设备,广泛应用于家庭、办公室等各种场合。
本文将基于单片机设计一款LCD1602电子时钟,实现时间显示、闹钟设置等功能。
一、硬件设计1.单片机选择在本设计中,选择常用的51系列单片机AT89C51,具有丰富的外设资源和强大的处理能力。
该单片机具有8位数据总线、16位地址总线,并且集成了定时/计数器、中断控制器和串行通信接口等外设。
2.显示模块选择3.时钟模块选择通过接入DS1302时钟模块,可以实现实时时钟的功能。
DS1302模块具有时钟计数器、电压检测电路、串行通信接口等,并且具有低功耗特点。
4.控制板设计根据LCD1602的引脚连接方式,设计一个控制板,用于将单片机、显示模块和时钟模块等连接在一起。
同时,需注意设计供电电路、外设输入输出电平等电路。
二、软件设计1.初始化设置通过单片机的GPIO口配置,将LCD1602和DS1302对应的引脚设置为输出模式,同时初始化LCD显示屏并进行清屏操作。
此外,需设置DS1302时钟模块的时钟、日期、闹钟等参数。
2.时间显示通过读取DS1302时钟模块的计数器,获得当前的小时、分钟和秒数,然后将其格式化为HH:MM:SS的形式,并通过LCD显示出来。
3.时间设置通过单片机的外部中断,当用户按下设置按钮后,进入时间设置模式。
在时间设置模式下,用户可以通过按下不同的按键来调整小时、分钟和秒数。
调整完成后,再次按下设置按钮即可保存设置。
4.闹钟设置通过单片机的定时器中断,设定一个闹钟定时器。
当闹钟定时器触发时,触发相应的中断,然后通过LCD显示闹钟提示。
此外,用户也可以通过按下按钮来设置闹钟时间,并通过单片机的外部中断进行处理。
5.闹钟响铃当闹钟时间到达时,触发相应的中断,通过LCD显示闹钟提示,并通过蜂鸣器发出响铃声。
总结通过本设计,可以实现一款功能齐全的LCD1602电子时钟。
单片机课程毕业设计 数字钟万年历1602显示原理图源程序纯手工电路板

晒晒我自己做的单片机设计手工电路板
数字钟万年历
1.AT89S51芯片作为核心。
2.实现小时、分、秒、年、月、日、星期的显示和实时温度检测。
3.该设计的电子时钟系统由时钟电路、LCD显示电路、按键调整电路和温度检测电路四部分组成。
4.使用时钟芯片DS1302完成时钟日期的功能,以LCD1602为显示器,同时利用温度传感器DS18B20测量周围环境温度.
5.共设计四个按键:
第一个是功能键,切换三个功能,分别是日期、时间和秒表;
第二个是调整键,按一下屏幕不会变化,只有当按调整加减键时,屏幕就会变化。
例如:一上电显示的是年月日,然后想调整,按一下调整键,对应的位置会闪烁,即可按调整加减键,进行修改,年调整好后,再按一下第二个调整键,光标会移动,等到合适的位置即可修改。
第三四个键是加减键;。
利用LCD1602显示的数字温度计毕业设计

(单片机原理及接口技术)利用LCD1602显示的数字温度计一.课程设计的目的1.进一步熟悉和掌握单片机的结构及工作原理。
2.掌握单片机的接口技术及相关外围芯片的外特性,控制方法。
3.通过课程设计,掌握以单片机核心的电路设计的基本方法和技术。
4.通过实际程序设计和调试,逐步掌握模块化程序设计方法和调试技术。
5.通过完成一个包括电路设计和程序开发的完整过程,了解开发一单片机应用系统的全过程,为今后从事相应开发打下基础。
二.课程设计的基本要求1.认真认识设计的意义,掌握设计工作程序,学会使用工具书和技术参考资料,并培养科学的设计思想和良好的设计作风。
2.提高模型建立和设计能力,学会应用相关设计资料进行设计计算的方法。
3.提高独立分析、解决问题的能力,逐步增强实际应用训练。
4.课程设计的说明书要求简洁、通顺,计算正确,图纸表达内容完整、清楚、规范。
5.课程设计说明书封面格式要求见《天津城市建设学院课程设计教学工作规范》附表1。
三.课程设计具体要求a) 要求每位同学独立完成设计任务。
b) 原理图设计1.原理图设计要符合项目的工作原理,连线要正确。
2.图中所使用的元器件要合理选用,电阻、电容等器件的参数要正确标明。
3.原理图要完整,CPU、外围器件、外扩接口、输入/输出装置要一应俱全。
c) 程序调计1.根据要求,将总体功能分解成若干个子功能模块,每个功能模块完成一个特定的功能。
2.根据总体要求及分解的功能模块,确定各功能模块之间的关系,设计出完整的程序流程图。
d) 程序调试1.编写相关程序,并进行仿真。
2.将程序下载到单片机,进行运行调试。
e) 设计说明书1.原理图设计说明简要说明设计目的,原理图中所使用的元器件功能及在图中的作用,各器件的工作过程及顺序。
2.程序设计说明对程序设计总体功能及结构进行说明,对各子模块的功能以及各子模块之间的关系作较详细的描述。
3.画出工作原理图,程序流程图并给出相应的程序清单。
LCD1602显示时间和温度

/*************************************************************/
/* */
/* 延时子程序 */
delay(5);
lcd_wcom(0x38);
delay(5);
lcd_wcom(0x38);
delay(5);
lcd_wcom(0x0c); //显示开,关光标
delay(5);
lcd_wcom(0x06); //移动光标
delay(5);
lcd_wcom(0x01); //清除LCD的显示内容
delay(5);
}
/*************************************************************/
/* */
/* 1602显示字符串 */
/* */
sbit SDA=P3^4; //数据端
sbit RST = P3^5; // DS1302复位端
sbit LCD_RW = P2^5; //1602的读写端
sbit LCD_RS = P2^6; //1602的数据命令端
sbit LCD_EN = P2^7; //1602的使能
/* */
/* LCD初始化设定 */
/* */
/* */
/*******************************************************************/
void lcd_wcom(uchar com)
/*************************************************************/
基于51单片机的用 LCD1602 显示时钟的程序

用LCD1602 显示的时钟2012-04-30 15:04有这样一个题目:求一个为51 单片机编写的LCD 电子时钟的设计,简单就好!希望说一下怎么设计这个时钟,都需要些什么东西,最重要的——把这个设计需要的程序写出来。
设计的任务:以单片机控制的时钟,在LCD 显示器上显示当前的时间。
设计的基本要求:1.使用文字型LCD 显示器显示当前时间。
2.显示格式为“时时:分分:秒秒”。
3.用4个功能键操作来设置当前时间。
各个功能键的功能如下:K1:进入设置现在的时间。
K2:设置小时。
K3:设置分钟。
K4:确认完成设置。
4. 程序执行后工作指示灯LED 闪烁,表示程序开始执行,LCD 显示“00:00:00”,然后开始计时。
题目链接:/question/416705477.html//==================================================提到设计时钟,很多人都想到了时钟芯片DS1302,都说它简单、准确。
其实,这是个误区。
仅仅使用一般的单片机,简单的编程,达到相同DS1302 的准确度,并不是难事。
如果不要求计算平闰年、不要求分清大小月、不要求计算星期几,只是要求一个简单的时钟(及日历),用DS1302,就是自寻烦恼。
大家可以打开题目链接,看看其中的一些答案,就可以看出使用DS1302 是多么的繁琐了,简直就是一场噩梦。
做而论道以前就使用普通的单片机和LCD1602 设计过《时钟与日历》,程序设计的非常合理,时间精度就完全取决于晶振的精度。
设计出来的时钟,几个月都差不上一秒。
针对这个题目,做而论道翻出了以前的设计,删节了一些不需要的功能,设计出了符合题目要求的时钟,用PROTEUS 仿真截图如下:程序用C 语言编写,全部代码如下://---------------------------------------------------#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define KEY_IO P3#define LCD_IO P0sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;sbit SPK = P1^2;sbit LED = P2^4;bit new_s, modify = 0;char t0, sec = 50, min = 59, hour = 23;char code LCD_line1[] = "Designed by ZELD"; char code LCD_line2[] = "Timer: 00:00:00 "; char Timer_buf[] = "23:59:50";//---------------------------------------------------void delay(uint z){uint x, y;for(x = z; x > 0; x--) for(y = 100; y > 0; y--);//---------------------------------------------------void W_LCD_Com(uchar com) //写指令{LCD_RS = 0; LCD_IO = com; // LCD_RS和R/W都为低电平时,写入指令LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_Dat(uchar dat) //写数据{LCD_RS = 1; LCD_IO = dat; // LCD_RS为高、R/W为低时,写入数据LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_STR(uchar *s) //写字符串{while(*s) W_LCD_Dat(*s++);}//---------------------------------------------------void W_BUFF(void) //填写显示缓冲区{Timer_buf[7] = sec % 10 + 48; Timer_buf[6] = sec / 10 + 48;Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;Timer_buf[1] = hour % 10 + 48;Timer_buf[0] = hour / 10 + 48;W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf);}//---------------------------------------------------uchar read_key(void){uchar x1, x2;KEY_IO = 255;x1 = KEY_IO;if (x1 != 255) {delay(100);x2 = KEY_IO;if (x1 != x2) return 255;while(x2 != 255) x2 = KEY_IO;if (x1 == 0x7f) return 0;else if (x1 == 0xbf) return 1;else if (x1 == 0xdf) return 2;else if (x1 == 0xef) return 3;else if (x1 == 0xf7) return 4;}return 255;//---------------------------------------------------void Init(){LCD_RW = 0;W_LCD_Com(0x38); delay(50);W_LCD_Com(0x0c);W_LCD_Com(0x06);W_LCD_Com(0x01);W_LCD_Com(0x80); W_LCD_STR(LCD_line1);W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);TMOD = 0x01; //T0定时方式1TH0 = 0x4c;TR0 = 1; //启动T0PT0 = 1; //高优先级, 以保证定时精度ET0 = 1;EA = 1;}//---------------------------------------------------void main(){uint i, j;uchar Key;Init();while(1) {//-------------------------------if (new_s) { //如果出现了新的一秒, 修改时间new_s = 0; sec++; sec %= 60;if(!sec) { min++; min %= 60;if(!min) { hour++; hour %= 24;}}W_BUFF(); //写显示//-------------------------------if (!sec && !min) { //整点报时for (i = 0; i < 200; i++) {SPK = 0; for (j = 0; j < 100; j++);SPK = 1; for (j = 0; j < 100; j++);} }}//-------------------------------Key = read_key(); //读出按键switch(Key) { //分别处理四个按键case 0: modify = 1; break;case 1: if(modify) {min++; min %= 60; W_BUFF(); break;}case 2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}case 3: modify = 0; break;} }}//---------------------------------------------------void timer0(void) interrupt 1 //T0中断函数, 50ms执行一次{TH0 = 0x4c;t0++; t0 %= 20; //20, 一秒钟if(t0 == 0) {new_s = 1; LED = ~LED;}if(modify) LED = 0;}//===================================================呵呵,全部程序,也不过120 行左右。
1602显示实验报告

一、1602显示二、实验项目:1602显示三、实验地点:四、五、实验时间:2014年7月9日~2014年7月23日六、实验要求:1、在单片机最小系统中加入LCD1602显示屏。
2、能进行数字和字符的显示3、扩展功能一:将实验四中的“单片机时钟”改为1602显示。
4、用Protel99SE绘制实验原理图并完成实验报告。
七、实验具体内容:1、在单片机最小系统中加入LCD1602显示屏。
(1)实验电路图:(2)实验原理:1602显示屏采用标准的16引脚(有背光),其各个引脚接线及作用说明如下:(3)实验中遇到的问题:在电路接线工作完成以后,上电实验时LCD只有背光,无任何显示。
问题原因分析:在接线过程中,我最为关注的是RS、R/W、E三个端口的接线,忽视了D0~D7的接线顺序,从而使D7~D0的方向接反。
因此1602内部的11条指令码都会对应不上,例如清屏指令是0x01,而我则需要写成0x20。
所以按照正常程序指令,在初始化之后,屏幕会一直没有显示。
(4)实验小结:在完成电路图之后觉得本次的接线相对来说比较简单。
心想只要接好RS、R/W、E正负极不反接,就没什么问题。
结果却出乎我的意料,看是简单的D0~D7八个端口的顺序同样起着关键的作用。
因自己的忽视,使我在完成接线之后长时间找不到问题原因之所在。
这次的接线也很好的提醒了我,看似简单的工作,可千万不敢再掉意轻心。
2、能进行数字和字符的显示并将实验四中的“单片机时钟”改为1602显示。
(1) 实验原理:LCD6102的显示方式是先从DDRAM写入要显示地址,在往DDRAM写入要显示的字符码。
控制其操作的有11条LCD1602的内部指令,具体如下:指令1:清显示;指令2:光标复位,光标复位到地址00H;指令3:光标和显示模式设置;I/D:光标移动方向,高电平左移,低电平右移S:屏幕上所有文字是否左移或者右移(高电平有效,低电平无效)指令4:显示开关控制;D:控制整体显示开关,高电平表示开,低电平表示关C:控制光标的开关,高电平表示有光标,低电平表示无光标B:控制光标是否闪烁,高电平闪烁,低电平不闪烁指令5:光标显示移位;S/C:高电平时移动显示文字,低电平时移动显示光标指令6:功能设置命令;DL:高电平时为四位总线,低电平时为八位总线N:低电平时为单行显示,高电平时为双行显示F:低电平时为5x7点阵字符,高电平时为5x10点阵字符指令7:字符发生器存储器地址:指令8:DDRAM地址设置指令9:读忙信号和光标地址BF为忙标志高电平表示忙,此时模块不能接收命令或者数据,低电平表示不忙指令10:写数据指令11:读数据时序控制:读状态:输入RS=0 R/W=1 E=1 输出:D0~D7=状态字写指令:输入RS=0 R/W=1 D0~D7=指令码E=高脉冲输出:无读数据:输入RS=1 R/W=1 E=1 输出:D0~D7=数据写数据:输入RS=1 R/W=0 D0~D7=数据E=高脉冲输出:无(2)程序流程图如下所示:(3)实验中遇到的问题按下4#键时钟显示减1,当显示为00后,继续减1,会出现ASCLL在0之后的码。
51单片机LCD1602液晶显示测温系统

目录第一部分设计任务1.1设计题目及求要求 (3)1.2.1 方案一 (3)1.2.4 方案分析 (3)第二部分设计方案2.1总体设计方案说明 (3)2.2 实物电路图 (4)第三部分电路设计与器件选择3.1 DS18B20工作原理和功能说明 (4)3.2 LCD1602工作原理和功能说明 (16)第四部分 4.1实验程序 (28)第五部分 5.1课程设计总结(心得体会) (34)第六部分 6.1参考文献 (34)1.1设计题目及求要求用电子元器件和单片机通过编写程序做成能实时显示温度的仪器。
1.2.1 方案用通用型1602液晶显示器和DS18B20温度传感器组成温度显示仪,并编写程序用51单片机来控制和连接1602液晶显示器和DS18B20温度传感器。
1.2.2 方案分析1602液晶显示器能显示ASCII码字符,数字、大小写字母、和各种符号。
而且其体积小、功耗低、显示操作简单,显示值清晰,正常温度范围为-20~+60。
DS18B20温度传感器采用单总线协议,与单片机接口仅需用一个I/O接口无需任何外部元件,直接将环境温度转化成数字信号,从而大大简化了传感器于微处理机的接口。
DS18B20温度传感器支持多点组网功能,多个DS18B20可以并联在唯一的三线上,其测试范围在-50~+125.C。
测试结果直接输出数字温度信号,以“一位总线”串行传送给CPU,同时可传送CRC效验码,具有极强的抗干扰纠错能力。
电源板极性接反时,芯片不会因发热而烧毁。
且它具有微型化、低功耗、高新能、抗干扰能力强、一赔微处理器等优点。
考虑到1602液晶显示器和DS18B20温度传感器有诸多优点,顾用二者来完成实验。
2.1总体设计方案说明2.2实物电路图3.1DS18B20的工作原理① DS18B20数字温度传感器概述DS18B20数字温度传感器是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。
因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
单片机原理及应用led1602时钟实训要求

单片机原理及应用led1602时钟实训要求
单片机原理是指通过集成电路技术将微处理器的各个功能模块集成在一块芯片上,从而形成一个完整的微处理器系统。
单片机通常包含CPU、RAM、ROM、IO口、计时/计数器等硬件模块,可以通过编程控制这些硬件模块来实现不同的功能。
应用LED1602时钟的实训要求如下:
1. 硬件设计:设计电路图和PCB布局,将单片机、LED1602液晶屏、时钟模块以及其他必要的元件进行连接。
2. 软件设计:编写单片机的程序,在单片机上控制LED1602液晶屏显示当前的时间,并实现设置时间的功能。
3. 调试测试:烧录程序到单片机上,通过调试和测试确保电路和程序正常工作。
4. 实现功能:实现时钟的基本功能,包括显示当前时间、设置时间、闹钟提醒等。
需要注意的是,在实训过程中要确保安全,正确使用电子元件和工具,防止电路短路、烧坏元件等意外情况的发生。
在实验过程中遵守实验室的安全规定,并由指导教师或专业人员进行指导和监督。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《单片机原理实验》考试报告题目:1602显示温度时钟及星期1602显示温度时钟及星期摘要:本次实验利用STC89C51单片机作为控制器,通过keil编写程序,并且将生成hex文件写入单片机的内存中,实现对单片机的I/O口,液晶显示屏1602和温度传感器DS18B20操作,最终实现在液晶显示器1602上显示时钟,星期以及实时温度的功能。
关键词:STC89C52单片机,液晶显示器1602,DALLAS公司生产的DS18B20数字温度计,时钟,温度,星期1.引言在开始的时候只是想用1602显示成数字温度计,可是在做完温度计之后发现1602屏上还有足够的空间用来显示时钟,所以就在原来的数字温度的程序上进行了扩展,加入了时钟的显示程序以及星期的显示程序。
确定了要显示的内容之后,通过计算字符的个数,对要显示的东西进行了布局,使得其显示看起来比较协调美观。
在做这个实验的时候,数字温度计的程序是最难的部分,我花了两天的时间把参考书上的一个用数码管显示温度的程序读懂,弄清楚DS18B20操作时序和数码管显示温度的基本步骤和原理之后,再结合我已经掌握的1602显示器的知识,尝试这把数码管显示改为1602显示,这个过程就是写这个程序最重要的地方,由于数码管显示原理与数码管显示原理完全不同,要进行比较大的调整,从写完这个程序和到完全调试好这个程序并且进行成功仿真花了大半天的时间。
当我调试完了程序和仿真之后,我在面包板上用相应的元器件搭出了仿真时候的电路,当我把程序写入单片机内,1602显示的实验室温度为30.7。
成功之后,我再把以前写过的数字钟的程序逐渐的移植到这个程序当中,并且重新设置相关的参数,经过半天的调试,最终取得了理想中的结果。
2.原理使用的STC89c51单片机对所有的元器件进行控制。
外接时钟信号的晶振的频率为12MHz,所以其机器周期为1us,在写数字钟的程序是用的是中断计时,因此赋的初值为(65536-50000),即为50ms,中断进行20次后就是一秒,因此也就可以实现比较精准的定时了。
温度传感器DS18B20采用的是单总线协议,与单片机连接只需要一个I/O端口就可以实现双向通信。
它只有三个引脚,一个接高电平,一个接地,还一个就是单总线,在接单总线通常要求外接一个约为5k欧的电阻,仿真实验时我采用的是4.7k欧,搭建实物电路用的是4.3k欧。
该单条信号线既可以传输时钟,又可以传输数据,而且数据传输是双向的,因而这种单总线控制技术具有线路简单硬件开销少,成本低廉,便于总线扩展和维护。
液晶显示屏1602可以显示两行字符,每行最多可以显示16个字符,液晶第3端为对比度调节端,通过一个10k欧的电位器接地来调节液晶显示器的对比度,在仿真时可以不接入,但是在搭建实物电路时必须接上,以免烧坏器件造成损失。
通过先学习以上元器件的工作原理及操作时序,然后在keil上编写出控制这些器件正常工作的程序,并且生成hex文件以供单片机识别和使用。
3.电路4.程序#include<reg51.h>#include<stdio.h>#define uchar unsigned char#define uint unsigned intuchar code T[]={"Temp:"};uchar code *Day[7]={"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; uchar a[6]={0};int num,s,f,m;uint d=0;sbit ds=P2^2;sbit E=P3^4;sbit RS=P3^5;int temp;float f_temp;void delay(){uint x,y;for(x=3;x>0;x--)for(y=110;y>0;y--);}timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;num++;if(num>=20){num=0;m=m+1;} if(m>=60){m=0;f=f+1;}if(f>=60){f=0;s=s+1;}if(s==24){s=0;d++;}if(d==6)d=0;}void reset(void){uint i;ds=0;i=103;while(i>0)i--;ds=1;i=4;while(i>0)i--;}bit tempreadbit(void){uint i;bit dat;ds=0;i++;ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return(dat);}uchar tempread(void){uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1);}return(dat);}void tempwritebyte(uchar dat) {uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb){ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}else{ds=0;i=8;while(i>0)i--;ds=1;i++;i++;}}}void tempchange(void){reset();delay();tempwritebyte(0xcc);tempwritebyte(0x44);}uint get_temp(){uchar a,b;reset();delay();tempwritebyte(0xcc);tempwritebyte(0xbe);a=tempread();b=tempread();temp=b;temp<<=8;temp=temp|a;f_temp=temp*0.0625;temp=f_temp*10+0.5;f_temp=f_temp+0.05; return temp;void write_com(uchar com) {RS=0;P1=com;delay();E=1;delay();E=0;}void write_data(uchar date) {RS=1;P1=date;delay();E=1;delay();E=0;}void display(){uint t,ad;write_com(0x80+0x40);for(t=0;t<5;t++)write_data(T[t]);write_com(0x80+0x45);for(ad=0;ad<6;ad++)write_data(a[ad]);}void dis_temp(uint t){uchar i0,i1,i2,i3;i0=t/100;i1=t%100/10;i2='.';i3=t%100%10;a[0]=i0+'0';a[1]=i1+'0';a[2]=i2;a[3]=i3+'0';a[4]=0xdf;a[5]=0x43;display();}void init_com(void)E=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);TMOD=0x21;PCON=0x00;SCON=0x50;TH0=(65536-50000)/256;TL0=(65536-50000)%256;TH1=0xfd;TL1=0xfd;EA=1;ET0=1;TR0=1;TR1=1;}void comm(char *parr){do{SBUF=*parr++;while(!TI);TI=0;}while(*parr);}void day(uchar *r){while(*r!='\0'){write_data(*r);r++;}}void main(){init_com();while(1){write_com(0x80);write_data(s/10+'0');write_data(s%12+'0');write_data('-');write_data(f/10+'0');write_data(f%10+'0');write_data('-');write_data(m/10+'0');write_data(m%10+'0');write_com(0x89);day(Day[d]);tempchange();dis_temp(get_temp());}}5.结语本次实验涉及的知识基本涵盖了对51单片机操作的主要知识,包括外部晶振,复位电路,对任意I/O口进行操作,定时器工作方式的设置,定时器中断,以及对波特率的设置。
在学习中,通过实验来验证原理可以理解的更加深刻,掌握知识的效率也更高,此次实验主要学到的就是利用C语言编程更加的熟练,以及对DS18B20D的操作,虽然DS18B20D外部结构简单,但是利用程序对其操作的时序还是比较复杂的。
当然,这些都知识电子专业的皮毛,我会在以后的学习里努力去掌握和学习更多更深的知识,不断充实自己。
最后,本次实验最终也取得了理想的效果,算是一次比较成功的实验。
参考文献[1] 郭天祥. 51单片机C语言编程.电子工业出版社 2009年12月.[2] 百度 1602显示字符库。