基于单片机的带温度显示的数字钟设计(c51语言编程)
C51单片机毕业设计电子钟

概述单片机具有体积小、功能强可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。
C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语言的功能。
此外,C语言程序具有完善的模块程序结构,从而为软件开发中采用模块化程序设计方法提供了有力的保障。
因此,使用C语言进行程序设计已成为软件开发的一个主流。
C语言来编写目标系统软件,会大大缩短开发周期,且明显地增加软件的可靠性,便于改进和扩展,从而研制出规模更大、性能更完备的系统。
因此,用C语言进行8051单片机程序设计是单片机开发与应用的必然趋势。
本课程的目的是学习运用C语言开发单片机应用系统软件。
为将来从事单片机应用系统的开发打下坚实的基础。
一、题目电子钟二、课程设计目的(1)巩固、加深和扩大单片机应用的知识面,提高综合及灵活运用所学知识解决工业控制的能力;(2)培养针对课题需要,选择和查阅有关手册、图表及文献资料的自学能力,提高组成系统、编程、调试的动手能力;(3)过对课题设计方案的分析、选择、比较、熟悉单片机用系统开发、研制的过程,软硬件设计的方法、内容及步骤。
三、课程设计系统环境(1)ADEK5196ET;(2)AEDK机电实验平台;(3)Keil c51软件调试环境;四、课程设计要求(1)掌握ADEK5196实验开发系统中的实验模块原理;(2)综合运用实验模块,用C51开发设计具有一定功能的单片机控制系统,进行软、硬件设计及调试;(3)写出完整的设计任务书:课题的名称、系统的功能、硬件原理图、软件框图、程序清单、参考资料;五、系统功能说明利用8279键盘显示接口电路。
使用8279可实现对键盘/显示器的自动扫描,以减轻CPU负担,其具有显示稳定、程序简单、不会出现误动作等特点。
电子钟的格式为:XX XX XX,由左向右分别为:时、分、秒。
基于单片机的多功能电子钟的实现

基于单片机的多功能电子钟的实现一.实验设计要求:1、以DS1302实时时钟芯片和液晶显示屏LCD1602为基础设计一款数字钟。
2、用DS18B20采集温度并实时显示。
3、能够进行时间和日期的调整,并具有闹钟和重要日期提醒功能。
4、具有温度报警功能二.实验仪器、仪表目录1、DS1302实时时钟芯片1片2、LCD1602液晶显示屏1个,3、AT89C52芯片1片5、DS18B20芯片一片6、晶振、电容、电阻、开关各若干等7、proteus仿真软件8、Keil C51、PC机三.实验步骤1、打开Keil软件,新建一个工程digital_clock,选择芯片AT89C52。
2、将编写的程序保存成“.C”的形式。
3、分别编写DS1302.h、DS18B20.h、LCD1602.h和digital.c文件并编译,直到编译通过。
4、打开proteus软件,画出实验电路图。
5、在AT89C52中,载入KEIL程序生成的HEX文档并运行。
6、对功能部分进行调试,观察运行结果,直到达到预期效果。
四.设计原理、运行结果及分析(一)设计方案原理与设计特点分析电子钟总的设计模块:11.1电路原理图:1.2 DS1302分析:首先DS1302是DALLAS 公司推出的涓流充电时钟芯片。
内含有一个实时时钟/日历和31字节静态RAM 通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作。
DS1302芯片广脚介绍:X1、X2为32.768KHz 晶振管脚。
GND 为地。
RST 复位脚。
I/O 数据输入/输出引脚。
SCLK 串行时钟。
Vcc1,Vcc2电源供电管脚。
与单片机连接的信号线为:DS1302_IO 接P1^0; 实时时钟数据线引脚 DS1302_SCLK 接P1^1; 实时时钟时钟线引脚 DS1302_RST 接P1^2; 实时时钟复位线引脚特别注意DS1302芯片在读取或写入数据时,都是一位一位传送的,并且每咬先送高电平,再1.3否一位,具体某地址进行一字节数据的写入或读取时,都要调用实时时钟写入一字节(内部函数) Write_DS1302和实时时钟读取一字节(内部函数) Read_DS1302两个函数。
51单片机数字钟设计

51单片机数字钟设计是一种常用的电子设计,它使用51单片机作为控制核心,通过数码管显示时间。
以下是一个简单的51单片机数字钟设计步骤:
1. 硬件设计
首先,需要选择一个合适的51单片机型号,如AT89C51、AT89S52等。
然后,需要选择数码管显示模块,可以选择多个数码管显示小时、分钟和秒。
同时,还需要选择适当的电源模块为数码管和单片机提供电源。
2. 软件设计
在软件设计方面,需要编写程序来控制数码管的显示,并实现时间的计数和更新。
可以使用定时器中断来实现时间的计数和更新。
同时,还需要编写程序来读取按键输入,以便用户可以调整时间。
3. 调试
在完成硬件和软件设计后,需要进行调试。
首先,需要检查硬件连接是否正确,然后通过调试程序来检查数码管的显示是否正确,以及时间计数和更新是否正常。
以上是一个简单的51单片机数字钟设计步骤,实际的设计可能需要根据具体需求进行修改和调整。
基于单片机的数字时钟之C51单片机

基于单片机的数字时钟之C51单片机基于单片机的数字时钟C51单片机王假设愚学号2020008003072020/7/18概述AT89C51是美国ATMEL公司生产的低功耗,高性能CMOS8位单片机,片内含4K的可编程的Flash只读程序储备器,器件采纳ATMEL公司的高密度、非易失性储备技术生产,兼容标准8051指令系统及引脚。
它集Flash程序储备器既可在线编程〔ISP〕也可用传统方法进行编程及通用8位微处理器于单片机芯片中,ATMEL公司的功能强大,低价位AT89S51单片机可为您提供许多高性价比的应用场合,可灵活应用于各种操纵领域。
功能特性概述AT89S51提供以下标准功能:4K字节闪速储备器,128字节内部RAM,32个I/O口线,看门狗〔WDT〕,两个数据指针,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。
同时,AT89S51可降至0HZ的静态逻辑操作,并支持两种软件可选的节电工作模式。
闲暇方式停止CPU的工作,但承诺RAM,定时/计数器,串行通信口及中断系统连续工作。
掉电方式储存RAM中到内容,但振荡器停止工作并禁止其它所有工作部件直到下一个硬件复位。
AT89S51硬件电路原理复位及振荡电路复位电路由按键复位和上电复位两部分组成,如图2所示。
AT89S系列单片及为高电平复位,通常在复位引脚RST上连接一个电容到VCC,再连接一个电阻到GND,由此形成一个RC 充放电回路保证单片机在上电时RST脚上有足够时刻的高电平进行复位,随后回来到低电平进入正常工作状态,那个电阻和电容的典型值为8.2K和10uF。
按键复位确实是在复位电容上并联一个开关,当开关按下时电容被放电、RST也被拉到高电平,而且由于电容的充电,会保持一段时刻的高电平来使单片机复位。
MCS51 LITE使用22.1184MHz的晶体振荡器作为振荡源,由于单片机内部带有振荡电路,因此外部只要连接一个晶振和两个电容即可,电容容量一样在15pF至50pF之间。
基于单片机的时钟、温度显示

#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit rs=P1^0;//寄存器选择sbit rw=P1^1;//读写信号线sbit lcden=P1^2;//led使能端sbit scl=P1^3;//时钟线sbit rst=P1^5;//复位线sbit io=P1^4;//数据口sbit key_set_time=P3^4;//设置时间键sbit key_add=P3^5;//加键sbit key_minus=P3^6;//减键sbit key_set_alarm=P3^7;//设置闹钟键sbit bee=P1^6;//蜂鸣器接口sbit dq=P1^7;//ds18b20测温uchar getTimebuf[7];//存放时间数据uchar time[]={" : : "};//时间格式字符串uchar date[]={"20 --"};//日期格式字符串uchar weeklist[]={"SunMonTueWedThuFriSat"};//星期字符列表uchar week[]={" "};//星期格式字符串int count;//设定秒分时日月星期年的时候count的值分别为1235647 int alarm;//是否进入闹钟设置界面123分别代表开关分小时的设置int isOpen;//闹钟是否开启默认不开启int fen,shi;//闹钟的分钟小时int isRing;//闹钟是否在响uchar isInit_1302;//是否初始化时钟完毕int num;int temperature;//温度int temp_flag;//温度正负标志void delay(uint x){int y;while(x--){for(y=100;y>0;y--);}}void write_1602com(uchar com){//1602写指令rs=0;lcden=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void write_1602data(uchar dat){//1602写数据rs=1;lcden=0;P2=dat;delay(5);lcden=1;delay(5);lcden=0;}void init_1602(){//初始化1602液晶rw=0;lcden=0;write_1602com(0x38);//设置显示模式write_1602com(0x0c);//显示开关及光标是否显示和闪动write_1602com(0x06);//光标移动方向write_1602com(0x01);//清屏}void write_ds1302_byte(uchar temp){//ds1302写一个字节数据uchar i;for(i=0;i<8;i++){io=temp&0x01;//将数据放到IO口上scl=0;//scl为低时准备数据scl=1;//上升沿写入temp>>=1;}}void write_ds1302(uchar add,uchar dat){//向地址add写入数据datrst=0;scl=0;rst=1;write_ds1302_byte(add);write_ds1302_byte(dat);scl=1;rst=0;}uchar read_ds1302(uchar add){//ds1302读数据uchar i,dat;rst=0;scl=0;rst=1;write_ds1302_byte(add);//首先写入要读的数据处的地址for(i=0;i<8;i++){if(io==1){dat|=0x80;}scl=1;scl=0;//下降沿读取数据dat>>=1;}scl=1;rst=0;return dat;}void read_time(uchar curr_time[]){uchar i;uchar ucAddr = 0x81;for (i=0;i<7;i++){curr_time[i] = read_ds1302(ucAddr);//格式为: 秒分时日月星期年ucAddr += 2;}}void set_time(uchar *pSecDa){//设定时间uchar i;uchar ucAddr = 0x80;write_ds1302(0x8e,0x00);for(i =7;i>0;i--){write_ds1302(ucAddr,*pSecDa); //秒分时日月星期年pSecDa++;ucAddr+=2;}write_ds1302(0x8e,0x80);}void init_ds1302(){//ds1302初始化isInit_1302=read_ds1302(0x81);//读出时钟状态if(isInit_1302&0x80){//说明没有初始化write_ds1302(0x8e,0x00);//关闭写保护以后一直开着write_ds1302(0x90,0xa5); //辅助电源充电命令一个二极管一个2K电阻write_ds1302(0x80,0x00);//秒CH置0 开启时钟write_ds1302(0x82,0x59);//分write_ds1302(0x84,0x10);//时write_ds1302(0x86,0x07);//日write_ds1302(0x88,0x05);//月write_ds1302(0x8a,0x04);//星期write_ds1302(0x8c,0x14);//年write_ds1302(0x8e,0x80);}}char int_to_char(int temp){//把0到9对应的数字转为字符char x='0';switch(temp){case 0:x='0';break;case 1:x='1';break;case 2:x='2';break;case 3:x='3';break;case 4:x='4';break;case 5:x='5';break;case 6:x='6';break;case 7:x='7';break;case 8:x='8';break;case 9:x='9';break;}return x;}int ds18b20_read_temp();void display(){uchar bai,shi,ge,point,fuhao;read_time(getTimebuf);//时时读取时间time[6]=(getTimebuf[0])/16+48;//格式化时间秒time[7]=(getTimebuf[0])%16+48;time[3]=(getTimebuf[1])/16+48;//格式化时间分time[4]=(getTimebuf[1])%16+48;time[0]=(getTimebuf[2])/16+48;//格式化时间小时time[1]=(getTimebuf[2])%16+48;date[8]=getTimebuf[3]/16+48;//格式化日期日date[9]=getTimebuf[3]%16+48;date[5]=getTimebuf[4]/16+48;//格式化日期月date[6]=getTimebuf[4]%16+48;date[2]=getTimebuf[6]/16+48;//格式化日期年date[3]=getTimebuf[6]%16+48;week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期week[1]=weeklist[(getTimebuf[5]%10)*3+1];week[2]=weeklist[(getTimebuf[5]%10)*3+2];write_1602com(0x80+1);for(num=0;num<10;num++){write_1602data(date[num]);}write_1602data(' ');for(num=0;num<3;num++){write_1602data(week[num]);}write_1602com(0x80+0x40);for(num=0;num<8;num++){write_1602data(time[num]);}//显示温度值write_1602com(0x80+0x40+8);//设置数据指针temperature=ds18b20_read_temp();bai=temperature/1000+0x30;shi=temperature%1000/100+0x30;ge=temperature%100/10+0x30;point=temperature%100%10+0x30;if(temp_flag==1){//说明为正数不显示符号位两种fuhao=0x20;//显示空白if(bai==0x30){bai=0x20;//如果百位为0 不显示if(shi==0x30){shi=0x20;//如果百位为0 十位也为0 都不显示}}write_1602data(fuhao);write_1602data(bai);write_1602data(shi);}else{fuhao=0x2d;//显示负号两种write_1602data(0x20);//因为负数最低到55,所以不显示百位if(shi==0x30){write_1602data(0x20);write_1602data(fuhao);}else{write_1602data(fuhao);write_1602data(shi);}}write_1602data(ge);write_1602data('.');write_1602data(point);write_1602data(0xdf);write_1602data('C');}void display_alarm(uchar add,int dat){//把设定的时分显示出来int x,y;x=dat/10;y=dat%10;write_1602com(add);write_1602data(int_to_char(x));write_1602com(add+1);//防止写后地址自动向后加一光标闪烁看不到write_1602data(int_to_char(y));write_1602com(add+1);}void init_alarm(){//闹钟设置界面只有首次进入才执行uchar code x[]="SET ALARM";uchar i;if(alarm==0){write_1602com(0x01);//清屏write_1602com(0x80+3);//设置数据指针for(i=0;i<9;i++){write_1602data(x[i]);}display_alarm(0x80+0x40+5,shi);//载入闹钟的时分write_1602com(0x80+0x40+7);write_1602data(':');display_alarm(0x80+0x40+8,fen);if(isOpen){//初始化的时候如果已经设定闹钟则显示ONwrite_1602com(0x80+0x40+13);write_1602data(' ');write_1602data('O');write_1602data('N');}else{write_1602com(0x80+0x40+13);write_1602data('O');write_1602data('F');write_1602data('F');}}}void key_scan(){int i;uchar code tips1[]="SET SUCCESS";//闹钟设置成功的提示uchar code tips2[]="CANCEL SUCCESS";//取消闹钟的提示if(key_set_time==0){//检测是否按下delay(10);//消抖if(key_set_time==0){//再次检测是否按下while(!key_set_time);//检测是否松开delay(10);//延时消抖while(!key_set_time);//再次检测是否松开if(alarm==0){//当没有显示闹钟界面时才显示时间设定count++;write_ds1302(0x80,0x80);//让时钟停止if(count==8){//继续走时,说明时间已经设定好了write_1602com(0x0c);//让光标消失write_ds1302(0x80,0);//让时钟继续set_time(getTimebuf);//写入新的时间count=0;return;}switch(count){case 1:write_1602com(0x80+0x40+7);//在秒的位置break;case 2:write_1602com(0x80+0x40+4);//在分的位置break;case 3:write_1602com(0x80+0x40+1);//在时的位置break;case 4:write_1602com(0x80+14);//在星期的位置break;case 5:write_1602com(0x80+10);//在日的位置break;case 6:write_1602com(0x80+7);//在月的位置break;case 7:write_1602com(0x80+4);//在年的位置break;}write_1602com(0x0f);//让光标闪烁}}}if(key_add==0){//检测是否按下delay(10);//消抖if(key_add==0){//再次检测是否按下while(!key_add);//检测是否松开delay(10);//延时消抖while(!key_add);//再次检测是否松开if(count!=0){switch(count){case 1://在秒的位置getTimebuf[0]++;if(getTimebuf[0]==0x5a){getTimebuf[0]=0;}if(getTimebuf[0]==0x4a){getTimebuf[0]=0x50;}if(getTimebuf[0]==0x3a){getTimebuf[0]=0x40;}if(getTimebuf[0]==0x2a){getTimebuf[0]=0x30;}if(getTimebuf[0]==0x1a){getTimebuf[0]=0x20;}getTimebuf[0]=0x10;}time[6]=(getTimebuf[0])/16+48;//格式化时间秒time[7]=(getTimebuf[0])%16+48;write_1602com(0x80+0x40+6);//在秒的位置write_1602data(time[6]);write_1602com(0x80+0x40+7);//在秒的位置write_1602data(time[7]);write_1602com(0x80+0x40+7);//让光标在秒的位置闪烁break;case 2://在分的位置getTimebuf[1]++;if(getTimebuf[1]==0x5a){getTimebuf[1]=0;}if(getTimebuf[1]==0x4a){getTimebuf[1]=0x50;}if(getTimebuf[1]==0x3a){getTimebuf[1]=0x40;}if(getTimebuf[1]==0x2a){getTimebuf[1]=0x30;}if(getTimebuf[1]==0x1a){getTimebuf[1]=0x20;}if(getTimebuf[1]==0x0a){getTimebuf[1]=0x10;}time[3]=(getTimebuf[1])/16+48;//格式化时间分time[4]=(getTimebuf[1])%16+48;write_1602com(0x80+0x40+3);//在分的位置write_1602data(time[3]);write_1602com(0x80+0x40+4);//在分的位置write_1602data(time[4]);write_1602com(0x80+0x40+4);//让光标在分的位置闪烁break;case 3://在时的位置getTimebuf[2]++;if(getTimebuf[2]==0x24){}if(getTimebuf[2]==0x1a){getTimebuf[2]=0x20;}if(getTimebuf[2]==0x0a){getTimebuf[2]=0x10;}time[0]=(getTimebuf[2])/16+48;//格式化时间小时time[1]=(getTimebuf[2])%16+48;write_1602com(0x80+0x40+0);//在小时的位置write_1602data(time[0]);write_1602com(0x80+0x40+1);write_1602data(time[1]);write_1602com(0x80+0x40+1);break;case 4://在星期的位置getTimebuf[5]++;if(getTimebuf[5]==0x08){getTimebuf[5]=0x01;}if((getTimebuf[5]%10)*3==21){//轮完了重新开始week[0]=weeklist[0];week[1]=weeklist[1];week[2]=weeklist[2];}else{week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期week[1]=weeklist[(getTimebuf[5]%10)*3+1];week[2]=weeklist[(getTimebuf[5]%10)*3+2];}write_1602com(0x80+12);write_1602data(week[0]);write_1602com(0x80+13);write_1602data(week[1]);write_1602com(0x80+14);write_1602data(week[2]);write_1602com(0x80+14);break;case 5://在日的位置getTimebuf[3]++;if(getTimebuf[3]==0x32){getTimebuf[3]=0x01;}if(getTimebuf[3]==0x2a){getTimebuf[3]=0x30;}if(getTimebuf[3]==0x1a){getTimebuf[3]=0x20;}if(getTimebuf[3]==0x0a){getTimebuf[3]=0x10;}date[8]=(getTimebuf[3])/16+48;date[9]=(getTimebuf[3])%16+48;write_1602com(0x80+9);write_1602data(date[8]);write_1602com(0x80+10);write_1602data(date[9]);write_1602com(0x80+10);break;case 6://在月的位置getTimebuf[4]++;if(getTimebuf[4]==0x13){getTimebuf[4]=0x01;}if(getTimebuf[4]==0x0a){getTimebuf[4]=0x10;}date[5]=(getTimebuf[4])/16+48;date[6]=(getTimebuf[4])%16+48;write_1602com(0x80+6);write_1602data(date[5]);write_1602com(0x80+7);write_1602data(date[6]);write_1602com(0x80+7);break;case 7://在年的位置getTimebuf[6]++;if(getTimebuf[6]==0x9a){getTimebuf[6]=0x00;}if(getTimebuf[6]==0x8a){getTimebuf[6]=0x90;}if(getTimebuf[6]==0x7a){getTimebuf[6]=0x80;}if(getTimebuf[6]==0x6a){getTimebuf[6]=0x70;}if(getTimebuf[6]==0x5a){getTimebuf[6]=0x60;}if(getTimebuf[6]==0x4a){getTimebuf[6]=0x50;}if(getTimebuf[6]==0x3a){getTimebuf[6]=0x40;}if(getTimebuf[6]==0x2a){getTimebuf[6]=0x30;}if(getTimebuf[6]==0x1a){getTimebuf[6]=0x20;}if(getTimebuf[6]==0x0a){getTimebuf[6]=0x10;}date[2]=(getTimebuf[6])/16+48;date[3]=(getTimebuf[6])%16+48;write_1602com(0x80+3);write_1602data(date[2]);write_1602com(0x80+4);write_1602data(date[3]);write_1602com(0x80+4);break;}}if(alarm!=0){switch(alarm){case 1://调节闹钟的开与关if(isOpen==0){isOpen=1;write_1602com(0x80+0x40+13);write_1602data(' ');write_1602data('O');write_1602data('N');}else{isOpen=0;write_1602com(0x80+0x40+13);write_1602data('O');write_1602data('F');write_1602data('F');}//防止写后地址自动向后加一光标闪烁看不到write_1602com(0x80+0x40+15);break;case 2://调节闹钟的分fen++;if(fen==60){fen=0;}display_alarm(0x80+0x40+8,fen);break;case 3://调节闹钟的小时shi++;if(shi==24){shi=0;}display_alarm(0x80+0x40+5,shi);break;}}}}if(key_minus==0){//检测是否按下delay(10);//消抖if(key_minus==0){//再次检测是否按下while(!key_minus);//检测是否松开delay(10);//延时消抖while(!key_minus);//再次检测是否松开if(count!=0){switch(count){case 1://在秒的位置getTimebuf[0]--;if(getTimebuf[0]==0xff){getTimebuf[0]=0x59;}if(getTimebuf[0]==0x4f){getTimebuf[0]=0x49;}if(getTimebuf[0]==0x3f){getTimebuf[0]=0x39;}if(getTimebuf[0]==0x2f){getTimebuf[0]=0x29;}if(getTimebuf[0]==0x1f){getTimebuf[0]=0x19;}if(getTimebuf[0]==0x0f){getTimebuf[0]=0x09;}time[6]=(getTimebuf[0])/16+48;//格式化时间秒time[7]=(getTimebuf[0])%16+48;write_1602com(0x80+0x40+6);//在秒的位置write_1602data(time[6]);write_1602com(0x80+0x40+7);//在秒的位置write_1602data(time[7]);write_1602com(0x80+0x40+7);//让光标在秒的位置闪烁break;case 2://在分的位置getTimebuf[1]--;if(getTimebuf[1]==0xff){getTimebuf[1]=0x59;}if(getTimebuf[1]==0x4f){getTimebuf[1]=0x49;}if(getTimebuf[1]==0x3f){getTimebuf[1]=0x39;}if(getTimebuf[1]==0x2f){getTimebuf[1]=0x29;}if(getTimebuf[1]==0x1f){getTimebuf[1]=0x19;}if(getTimebuf[1]==0x0f){getTimebuf[1]=0x09;}time[3]=(getTimebuf[1])/16+48;//格式化时间分time[4]=(getTimebuf[1])%16+48;write_1602com(0x80+0x40+3);//在分的位置write_1602data(time[3]);write_1602com(0x80+0x40+4);//在分的位置write_1602data(time[4]);write_1602com(0x80+0x40+4);//让光标在分的位置闪烁break;case 3://在时的位置getTimebuf[2]--;if(getTimebuf[2]==0xff){getTimebuf[2]=0x23;}if(getTimebuf[2]==0x1f){getTimebuf[2]=0x19;}if(getTimebuf[2]==0x0f){getTimebuf[2]=0x09;}time[0]=(getTimebuf[2])/16+48;//格式化时间小时time[1]=(getTimebuf[2])%16+48;write_1602com(0x80+0x40+0);//在小时的位置write_1602data(time[0]);write_1602com(0x80+0x40+1);write_1602data(time[1]);write_1602com(0x80+0x40+1);break;case 4://在星期的位置getTimebuf[5]--;if(getTimebuf[5]==0){getTimebuf[5]=0x07;}if((getTimebuf[5]%10)*3==21){//轮完了重新开始week[0]=weeklist[0];week[1]=weeklist[1];week[2]=weeklist[2];}else{week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期week[1]=weeklist[(getTimebuf[5]%10)*3+1];week[2]=weeklist[(getTimebuf[5]%10)*3+2];}write_1602com(0x80+12);write_1602com(0x80+13);write_1602data(week[1]);write_1602com(0x80+14);write_1602data(week[2]);write_1602com(0x80+14);break;case 5://在日的位置getTimebuf[3]--;if(getTimebuf[3]==0){getTimebuf[3]=0x31;}if(getTimebuf[3]==0x2f){getTimebuf[3]=0x29;}if(getTimebuf[3]==0x1f){getTimebuf[3]=0x19;}if(getTimebuf[3]==0x0f){getTimebuf[3]=0x09;}date[8]=(getTimebuf[3])/16+48;date[9]=(getTimebuf[3])%16+48;write_1602com(0x80+9);write_1602data(date[8]);write_1602com(0x80+10);write_1602data(date[9]);write_1602com(0x80+10);break;case 6://在月的位置getTimebuf[4]--;if(getTimebuf[4]==0){getTimebuf[4]=0x12;}if(getTimebuf[4]==0x0f){getTimebuf[4]=0x09;}date[5]=(getTimebuf[4])/16+48;date[6]=(getTimebuf[4])%16+48;write_1602com(0x80+6);write_1602data(date[5]);write_1602com(0x80+7);write_1602com(0x80+7);break;case 7://在年的位置getTimebuf[6]--;if(getTimebuf[6]==0xff){getTimebuf[6]=0x99;}if(getTimebuf[6]==0x8f){getTimebuf[6]=0x89;}if(getTimebuf[6]==0x7f){getTimebuf[6]=0x79;}if(getTimebuf[6]==0x6f){getTimebuf[6]=0x69;}if(getTimebuf[6]==0x5f){getTimebuf[6]=0x59;}if(getTimebuf[6]==0x4f){getTimebuf[6]=0x49;}if(getTimebuf[6]==0x3f){getTimebuf[6]=0x39;}if(getTimebuf[6]==0x2f){getTimebuf[6]=0x29;}if(getTimebuf[6]==0x1f){getTimebuf[6]=0x19;}if(getTimebuf[6]==0x0f){getTimebuf[6]=0x09;}date[2]=(getTimebuf[6])/16+48;date[3]=(getTimebuf[6])%16+48;write_1602com(0x80+3);write_1602data(date[2]);write_1602com(0x80+4);write_1602data(date[3]);write_1602com(0x80+4);break;}}if(alarm!=0){switch(alarm){case 1://调节闹钟的开与关if(isOpen==0){isOpen=1;write_1602com(0x80+0x40+13);write_1602data(' ');write_1602data('O');write_1602data('N');}else{isOpen=0;write_1602com(0x80+0x40+13);write_1602data('O');write_1602data('F');write_1602data('F');}//防止写后地址自动向后加一光标闪烁看不到write_1602com(0x80+0x40+15);break;case 2://调节闹钟的分fen--;if(fen<0){fen=59;}display_alarm(0x80+0x40+8,fen);break;case 3://调节闹钟的小时shi--;if(shi<0){shi=23;}display_alarm(0x80+0x40+5,shi);break;}}}}if(key_set_alarm==0){//检测是否按下delay(10);//消抖if(key_set_alarm==0){//再次检测是否按下while(!key_set_alarm);//检测是否松开delay(10);//延时消抖while(!key_set_alarm);//再次检测是否松开if(count==0){//时间在正常走动的时候才能设置闹钟init_alarm();alarm++;//说明进入闹钟设置界面if(alarm==4){alarm=0;//说明闹钟设置完毕write_1602com(0x01);//清屏以便显示时间write_1602com(0x0c);//关闭光标//显示设置成功或取消的提示if(isOpen){write_1602com(0x80+2);for(i=0;i<11;i++){write_1602data(tips1[i]);}}else{write_1602com(0x80+1);for(i=0;i<14;i++){write_1602data(tips2[i]);}}//延时2ms后清屏显示时间delay(2000);write_1602com(0x01);}else{switch(alarm){case 1:write_1602com(0x80+0x40+15);break;case 2:write_1602com(0x80+0x40+9);break;case 3:write_1602com(0x80+0x40+6);break;}write_1602com(0x0f);}}}}}void beep(){//检测闹钟并且报警if(time[0]==int_to_char(shi/10)&&time[1]==int_to_char(shi%10)&&time[3]==int_to_char(fe n/10)&&time[4]==int_to_char(fen%10)){isRing=1;//闹钟响起,此时如果进入闹钟设置界面改变时分,闹钟就关闭了bee=0;delay(250);bee=1;delay(250);}else{isRing=0;//关闭闹钟或者一分钟后闹钟自动关闭bee=1;}}void delay1(int i){while(i--);}void ds18b20_init(){uchar x=0;dq = 1; //DQ复位delay1(8); //稍做延时dq = 0; //单片机将DQ拉低delay1(80); //精确延时大于480usdq = 1; //拉高总线delay1(14);x=dq; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay1(20);}uchar ds18b20_read(){//读一个字节uchar i=0;uchar dat = 0;for (i=8;i>0;i--){dq = 0; // 给脉冲信号dat>>=1;dq = 1; // 给脉冲信号if(dq)dat|=0x80;delay1(4);}return(dat);}void ds18b20_write(char dat){//写一个字节uchar i=0;for (i=8; i>0; i--){dq = 0;dq = dat&0x01;delay1(5);dq = 1;dat>>=1;}}int ds18b20_read_temp(){//读取温度uchar low;uchar high;unsigned long tmp;float value;int t;//温度ds18b20_init();ds18b20_write(0xCC); //跳过读序列号的操作ds18b20_write(0x44); //启动温度转换ds18b20_init();ds18b20_write(0xCC); //跳过读序列号的操作ds18b20_write(0xBE); //读取温度寄存器共九个前两个代表温度low=ds18b20_read();//低八位数据high=ds18b20_read();//高八位数据tmp=high;tmp<<=8;tmp=tmp|low;//此处有正负之分if(tmp>=63488){//ffff f000 0000 0000-->(f800)temp_flag=0;//8位全为1时,加1才进位if((~low)==0xff){//判断low取反加1之后是否进位high=(~high)+1;low=0;}else{high=~high;low=(~low)+1;}tmp=high*256+low;}else{temp_flag=1;}value=tmp*0.0625;t=value*10+((temp_flag==1)?+0.5:-0.5);//放大十倍输出并四舍五入return t;}void main(){init_1602();init_ds1302();while(1){if(isOpen){//只有开启闹钟的时候才检测beep();//不断检测闹钟}key_scan();if(count==0&&alarm==0){//没有设定时间也没有在闹钟界面的时候时间才显示display();}}}。
基于51单片机的简易电子钟设计

基于51单片机的简易电子钟设计一、设计目的现代社会对于时间的要求越来越精确,电子钟成为家庭和办公场所不可缺少的设备之一、本设计基于51单片机,旨在实现一个简易的电子钟,可以显示当前的时间,并且能够通过按键进行时间的调整和设置闹钟。
二、设计原理本设计主要涉及到51单片机的IO口、定时器、中断、LCD显示技术等方面知识。
1.时钟模块时钟模块采用定时器0的中断进行时间的累加和更新。
以1秒为一个时间单位,每当定时器0中断发生,就将时间加1,并判断是否需要更新小时、分钟和秒的显示。
同时,根据用户按键的操作,可以调整时间的设定。
2.显示模块显示模块采用16x2字符LCD显示屏,通过51单片机的IO口与LCD连接。
可以显示当前时间和设置的闹钟时间。
初次上电或者重置后,LCD显示时间为00:00:00,通过定时器中断和键盘操作,实现时间的更新和设定闹钟功能。
3.键盘模块键盘模块采用矩阵键盘连接到51单片机的IO口上,用于用户进行时间的调整和设置闹钟。
通过查询键盘的按键状态,根据按键的不同操作,实现时间的调整和闹钟设定功能。
4.中断模块中断模块采用定时器0的中断,用于1秒的定时更新时间。
同时可以添加外部中断用于响应用户按键操作。
三、主要功能和实现步骤1.系统初始化。
2.设置定时器,每1秒产生一次中断。
3.初始化LCD显示屏,显示初始时间00:00:00。
4.查询键盘状态,判断是否有按键按下。
5.如果按键被按下,根据不同按键的功能进行相应的操作:-功能键:设置、调整、确认。
-数字键:根据键入的数字进行时间的调整和闹钟设定。
6.根据定时器的中断,更新时间的显示。
7.判断当前时间是否与闹钟设定时间相同,如果相同,则触发闹钟,进行提示。
8.循环执行步骤4-7,实现连续的时间显示和按键操作。
四、系统总结和改进使用51单片机设计的简易电子钟可以显示当前时间,并且实现时间的调整和闹钟设定功能。
但是由于硬件资源有限,只能实现基本的功能,不能进行其他高级功能的扩展,例如闹铃的音乐播放、温度、湿度的显示等。
基于51单片机的数字时钟设计

一设计要求及方案证 (1)二系统基本方案选择和论证 (2)2.1单片机芯片的选择方案和论证 (2)2.2显示模块选择方案和论证 (3)2.3时钟芯片的选择方案和论证 (4)三系统的硬件设计和实现 (5)3.1电路设计框图 (5)3・2主要单元电路的设计 (5)3.2. 1晶体振荡电路 (5)3. 2.2分频器电路 (6)3. 2.3时间计数器电路 (6)3. 2.4内部时钟电路 (6)3. 2. 5复位电路 (7)3. 2.6按键部分 (8)3. 2.7声光报警电路 (8)四、电路原理分析 (9)4・1显示原理 (9)4.2键盘及读数原理 (9)4.3连击功能的实现 (9)五、程序设计思想和相关指令介绍 (9)5.1数据和代码转换 (9)5・2计时功能的实现和中断服务程序 (10)5.3时间控制功能和比较指令...................................10六、系统的软件设计................................................106.1主程序部分 (11)6.2计时显示中断子程序部分 (13)6. 3调时功能流程图 (14)6. 4程序.....................................................15七设计心得........................................................24一设计要求及方案证设计制作和调试一个由8051MCU单片机组成的数字时钟系统。
通过这个过程学习熟悉键盘控制和七段数码管得使用,掌握 51系列单片机控制和测试的方法。
设计以89S51单片机为核心,以 LED为显示方式的万年历时钟显示,完成基本要求。
1)数码管显示:年月日时分秒。
2)键盘输入修改时间、日期设置。
系统基本方案选择和论证2. 1单片机芯片的选择方案和论证方案采用89C51芯片作为硬件核心,其内部采用Flash ROM,具有 4KB ROM存储空间,能于3V的超低压工作,但运用于电路设计中时由于不具备ISP在线编程技术,烧入程序时需要专门的C编程器(当前可用的实验烧写开发板只支持具有 ISP在线编程功能的AT89S**系列的芯片),当在对电路进行调试时,更显麻烦,并且增加了造价,采用89S51芯片作为主控模块,AT89S51是MCS-51系列单片机目前运用较多的一种芯片,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且具备ISP在线编程技术,方便对电路进行调试•但由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。
基于单片机的电子时钟设计(带定时功能和温度显示)

基于单片机的电子时钟设计——带定时功能和温度显示班级: 11级质量2班学号: 1110132217姓名: 詹超专业: 产品质量指导老师: 王正家二零一四年六月摘要传统的数字电子时钟采用了较多的分立元器件,不仅占用了很大的空间而且利用率也比很低,随着系统设计复杂度的不断提高,用传统时钟系统设计方法很难满足设计需求。
单片机是集CPU、RAM、ROM、定时器/计数器和多种接口于一体的微控制器。
它体积小、成本低、功能强,广泛应用于智能产品和工业自动化上。
而51系列的单片机是各单片机中最为典型和最有代表性的一种。
,本次设计提出了系统总体设计方案,并设计了各部分硬件模块和软件流程,在用C语言设计了具体软件程序后,将各个模块完全编译通过过后,结果证明了该设计系统的可行性。
该设计给出了以AT89C51为核心,利用单片机的运算和控制功能,并采用系统化LED显示模块实时显示数字的设计方案,适当地解决了实际生产和日常生活中对计时高精确度的要求,因此该设计在现代社会中具有广泛的应用性。
关键词:电子时钟,单片机,C语言。
AbstractConventional digital electronic clock USES more discrete component, not only takes up a lot of space but also utilization ratio is low, with the constant improvement of the system design complexity, usingtraditional clock system design method is difficult to meet the design requirements.SCM is a set of CPU, RAM, ROM and timer/counter and a variety of interface in the integration of micro controller. Small volume, low cost, strong function, it is widely used in intelligent products andindustrial automation. And 51 series microcontroller is the single chip microcomputer in one of the most typical and most representative. , the design put forward the system overall design scheme, and designs the hardware modules and software process, the parts after using C language design a specific software program, the various modules after fully compiled through, the results proved the feasibility of the design system.This design USES AT89C51 as the nucleus is presented, the calculation and control function of microcontroller, and USES the systematic design of real-time display of digital LED display module, appropriate solutions to the practical production and daily life to therequirement of high precision timing, therefore the design has wide application in the modern society.Keywords: Electronic clock, SCM, C language。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于单片机的带温度显示的数字钟设计(c51语言编程)开题报告
电气工程及其自动化
一、课题研究意义及现状
1980年因特尔公司推出了MCS-51单片机,近30年来,其衍生系列
不断出现,从Atmel加入FLASH ROM,到philips加入各种外设,再到后
来的Cygnal推出C8051F,使得以8051为核心的单片机在各个发展阶段
的低端产品应用中始终扮演着一个重要的角色,其地位不断升高,资源越
来越丰富,历经30年仍在生机勃勃地发展,甚至在SoC时代仍占有重要
的一席之地。
单片机具有体积小、功能强、低功耗、可靠性高、价格低廉等一系列
优点,不仅已成为工业测控领域智能仪表、机电一体化、实时控制、国防
工业普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个
角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。
C语言已经成为当前举世公认的高效简洁而又贴近硬件的编程语言之一、将C语言向单片机8051上移植十余20世纪80年代的中后期,经过
几十年的努力,C语言已成为专业化单片机上的实用高级语言。
C语言是
一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语
言的功能。
此外,C语言程序具有完善的模块程序结构,从而为软件开发
中采用模块化程序设计方法提供了有力的保障。
与汇编语言相比,C51在功能、结构、可读性、可维护性上有明显的
优势,因而易学易用。
另外C51可以缩短开发周期,降低成本,可靠性,
可移植性好。
因此,使用C语言进行程序设计已成为软件开发的一个主流,用C语言进行8051单片机程序设计是单片机开发与应用的必然趋势。
随着人们生活水平的提高,对物质需求也越来越高,人们已不再满足
于钟表原先简单的报时功能,希望出现一些新的功能,诸如环境温度显示、日历的显示、重要日期倒计时、显示跑表功能等,用以带来更大的方便。
而所有这些,又都是以数字化的电子时钟为基础的,不仅应用了数字电路
技术,而且还加入了需要模拟电路技术和单片机技术。
其电路可以由时钟
模块、人机接口模块、环境温度检测模块等部分组成。
比机械式时钟具有
更高的直观性和准确性,调节起来方便,且无机械装置,能够使用更长时间,并且方便维护保养,因此得到了广泛的使用。
数字钟已成为人们日常
生活中必不可少的物品,广泛用于个人家庭以及车站、码头、剧院、办公
室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。
因此,研究实用数字钟及其扩展应用,具有很大的实用价值。
二、课题研究的主
要内容和预期目标
学习51单片机的基础知识熟悉其基本模块的使用、使用HD7279驱动LED数码管显示、键盘扫描和16位键盘的输入、以及温度传感器DS18B20
的温度采集等。
利用C51编程实现一个带温度计的
数字钟。
1)设计目标
熟悉单片机基础知识,了解51单片机的基本功能以及温度传感器
DS18B20的使用,熟悉开发板的特征,设计并利用C51进行编程实现要求
的功能,为将来从事单片机开发、和产品制造打下基础。
2)本设计的主要内容如下:
(1)利用HD7279驱动8位数码管显示。
(2)带有16键的键盘,用来对时钟进行时间设置和功能转换。
(3)用DS18B20检测环境温度并且在数码管上显示当前温度。
(4)时钟显示
精确到秒。
(5)可以显示年月日。
(6)可以键盘设定时间的初始植。
(7)可以自动处理闰年。
三、课
题研究的方法及措施
本课题重点是,利用DS18B20进行温度的采集,HD7279驱动数码管
显示。
在开发板上利用C51编程实现带温度显示的数字钟。
主控芯片为一块AT89C51单片机,利用开发板上的单片机时钟电路来
实现计数功能,利用HD7279驱动LED数码管,以及传感器DS18B20来进
行温度的实时检测,将采集来的数据显示在数码管上。
本课题的关键在于
系统的软件设计,要求利用C51编程来实现课题所要求的功能,设计其基
本功能模块,其中包括,数码管显示模块,按键模块,温度的采集和A/D
转换模块。
系统设计的原理示意图如下:数码管显示模块AT89C51单片机时钟模
块温度检测与转换模块键盘模块电源复位电路四、课题研究进度计划毕业设计期限:自2023年10月18日至2023年4月22日。
第一阶段(自2023年10月18日至2023年11月19日):查看分析
任务,收集资料相关所需的
各项准备工作做好开始系统总体方案设计
第二阶段(自2023年11月20日至2023年2月12日)撰写并完成
开题报告、文献综述、外文翻译的设计前期工作。
第三阶段(自2023年11月20日至2023年4月1日):熟悉开发板,了解其硬件电路图,设计DS18B20的电路图,构建软件整体框架,及各个
子程序的设计,算法研究及软件程序设计,撰写设计报告与论文。