首页 > 编程知识 正文

单片机时钟(51单片机时钟程序)

时间:2023-05-04 12:04:19 阅读:75239 作者:4263

目录

要点3

一、实训目的4

二、具体内容4

三、方案讨论5

四模拟电路5

4.1、模拟流程5

4.2、仿真电路图6

五.编程6

六.程序流程图12

七、方案分析13

八、制作PCB图14

九、腐蚀/开孔/焊接15

要求摘要

数字钟具有性能稳定、精度高、成本低、易十产品化,并具有万便、实用等特点。 适用于家庭、公司、机构等很多地方。 为人们的日常生活、旅行安排提供了便利,成为人们日常生活中不可缺少的一部分。

近年来,随着科学技术的发展和社会的进步,人们对数字钟表的要求也越来越高,传统钟表已不能满足人们的需要。 多功能数字时钟在性能和风格上都发生着质的变化,如电子表、数字闹钟等。 单片机在多功能高精度钟表中的应用已经非常普遍,人们非常熟悉高精度钟表的功能和工作顺序,但很少了解其内部结构和工作原理。 单片机作为数字钟的核心控制器,通过用其时钟信号计时来实现计时功能,并通过单片机输出该时间数据,在液晶显示器上显示。 可以用键盘进行定时、定时功能。 输出设备显示器可以使用液晶显示技术和数码管显示技术。

一、实训目的

《单片机原理及接口技术》课程后,要学习理论知识的实际运用,培养动手能力和解决实际问题的能力,以加深对理论知识的理解。 熟悉Ptoteus及Keil软件的调试与仿真。 通过实验提高对单片机的认识。 通过实验提高焊接、布局、电路检测能力。 通过实验提高软件调试能力。 进一步熟悉和掌握单片机的结构和工作原理。 通过课程设计,掌握以单片机为核心的电路设计的基本方法和技术。 通过实际的编程和调试,逐步掌握模块化的编程方法和调试技术。

二、具体内容应具体实时显示1秒、分、时、星期(可自动或手动设置显示) )。

23个按钮实现时间调节(加/减/切换)

3在调整模式下,液晶屏屏幕需要相应的提示

2 .方案设计

使用1602液晶屏进行时间显示,使用at89c52单片机作为主控芯片,使用轻触开关调整时间

三.方案讨论

89c52单片机有4个I/O端口,液晶屏数据传输需要独占一个I/O端口。 将P0端口用作I/O端口时,需要施加上拉电阻,因此制作成本增加,电路变得复杂。 因此,数据传输端口采用P0端口1602液晶屏需要连接RS、RW、e三个端口控制数据的读写,同时还必须考虑系统的稳定性。 如上所述,最终将液晶面板的数据传输接口分别连接到P1端口、RS、RW、e连接到P37、P36、P35端口,并连接到密钥key0、key1、key3端口

a ) stc89c521

b )液晶屏16021

c )钥匙开关3

d )石英晶体振动1

e )独石电容器2

f )排针4

四模拟电路

4.1、模拟流程

1 .在计算机上打开" PROTEUS8"仿真软件。

2 .创建新项目,然后在start模块中选择new project。 选择要存储项目文件的路径,单击“下一步”,选择项目所需的电路板大小,然后单击“下一步”,选择不创建pcb,单击“下一步”,再单击“固件项目计划”

在keil4中创建模拟程序,首先创建新项目,选择项目-新建项目,显示对话框,填写并确定项目名称。 然后选择您使用的AT89C51芯片进行确定。 然后单击文件File—New,创建并确认新文件。 然后,将新创建的文件添加到项目中,并开始编写代码,如果没有错误,则创建并编译hex文件。

在keil4制作的hex文件中完成电路图并加载,最终实现模拟。 4.2、仿真电路图

五.编程

程序论:

a )时序可以通过两种方式实现:

I .方式1:自定义延时函数,缺点:精度不高

ii .方式23360使用89c52单片机自带的定时器实现,优点:精度高,易于实现

iii .为了综合两种方式,采用方式2,单片机自带的定时器计时,最终采用定时器0方式1,初始值为50000微妙,20个周期为1秒

b )按钮只有三个,但是需要实现星期、小时、分钟、秒的加减,因此需要用一个按钮切换应该变更的参数。 用其他两个按钮实现加和减的I )切换可以定义一个flag,按下切换按钮可以加一个flag的值,由flag判断是否修改具体等参数,需要修改的参数为:周此外,由于需要使flag值不能大于4,所以在flag4的情况下,需要追加flag=0的判定条件;

ii .时间的加法和减法有两个按钮,所以需要定义两个函数来实现时间的加法和减法。 在调用时间加法/减法函数时,将flag传递给该函数。 通过确定flag的值,该函数可以准确地确定需要加法或减法的内容

参数
c) 程序中有了flag这个参数,所以程序能清楚的知道它要调整的参数,而用户不知道,需要将正在调整什么项目显示到液晶屏幕上,所以需要另外定义个dispset函数来显示用户正在调整的参数,同时这个函数需要将flag的值传递过去
d) 同时需要考虑,时间调整到一个极值就不能继续增加或减小,如一天中只有0点到23点,如果超过23点,则会变成0点,同理,星期只有1-7,分钟只有0-59,如果超过这个极值,程序会自动将其赋值为初始值
2. 最终程序:
#include <reg51.h>
#define DATAPORT P1//定义数据端口
#define uchar unsigned char
sbit RS=P3^7; //定义RS 数据/命令选择接口
sbit RW=P3^6; //定义RW 读/写选择接口
sbit E=P3^5; //定义使能接口
sbit key0=P2^7;//加
sbit key1=P2^6;//减
sbit key2=P2^5;//切换
int timeflag=0;//调整时间flag
uchar tablew1[]=“MTWTFSS”;
uchar tablew2[]=“ouehrau”;
uchar tablew3[]=“neduitn”;
uchar tablew4[]="…"; //周的数组( Mon. Tue. Wed. Thu. Fri. Sat. Sun.)
uchar tablesetweek[]=“set week”;//显示设置周
uchar tablesethour[]=“set hour”; //显示设置小时
uchar tablesetminute[]=“set minute”; //显示设置分钟
uchar tablesetsecond[]=“set second”; //显示设置秒
uchar tablesetnull[]=“LkwCxwPhl”;
char d[]={‘0’,‘0’,’:’,‘0’,‘0’,’:’,‘0’,‘0’};//定义初始化值
uchar week=0,hour=0,minute=0,second=0,count=20; //定义秒分时周
void transfer();
void init(); //初始化函数声明
void writeCOM(uchar i); //写命令函数声明
void writeData(uchar j); //写数据函数声明
void fbusy(); //检查忙函数声明
void timechange(int t); //时间调整函数
void disp(); //声明显示函数
void dispset(int timeflag);//显示设置
void timeadd(int timeflag);
void timecut(int timeflag);
int i; //全局变量i
void delay(int num){
int j,k;
for(j=0;j<=num;j++){
for(k=0;k<=120;k++);
}
}
int main(void){
EA=1; //使能=1
ET0=1;
TMOD=0x01;//定时器0方式1
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //初值为50000微秒
TR0=1;
init();

while(1){transfer(); //秒分时周转换disp(); //显示时间dispset(timeflag); //显示设置if(key2==0){init();delay(200);timeflag++;if(timeflag>4){ //让flag小于等于4timeflag=0;init();}}if(key0==0){ //按下后减小数值delay(200);timeadd(timeflag);}if(key1==0){ //按下后增加数值delay(200);timecut(timeflag);}}

}
void disp(){ //显示时间函数

writeCOM(0x80); //写入显示缓冲区起始地址为第1行第2列writeData(tablew1[week]);writeCOM(0x81);writeData(tablew2[week]);writeCOM(0x82);writeData(tablew3[week]);writeCOM(0x83);writeData(tablew4[week]);writeCOM(0xc0);for(i=0;i<8;i++){writeData(d[i]);}

}
void dispset(int timeflag){ //显示设置状况函数
switch(timeflag){
case(0):
writeCOM(0x87);
for(i=0;i<10;i++){
writeData(tablesetnull[i]);
}
break;
case(1):
writeCOM(0x87);
for(i=0;i<8;i++){
writeData(tablesetweek[i]);
}
break;
case(2):
writeCOM(0x87);
for(i=0;i<8;i++){
writeData(tablesethour[i]);
}
break;
case(3):
writeCOM(0x87);
for(i=0;i<10;i++){
writeData(tablesetminute[i]);
}
break;
case(4):
writeCOM(0x87);
for(i=0;i<10;i++){
writeData(tablesetsecond[i]);
}
break;
}
}
void init(){
writeCOM(0x01); //清屏
writeCOM(0x38); //开显示,读8位数据,显示两行,使用5*7的字型
writeCOM(0x0c); //显示器开,光标关,字符不闪烁
writeCOM(0x06); //字符不动,光标自动右移一位
}
void writeCOM(uchar i){ //写命令
fbusy();
RS=0;
RW=0;
E=1;
DATAPORT=i;
E=0; //负脉冲写
}
void writeData(uchar j){ //写数据
fbusy();
RS=1;
RW=0;
E=1;
DATAPORT=j;
E=0; //负脉冲写
}
void fbusy(){//检查忙函数
DATAPORT=0xff; //读之前向端口写1,确保读数正确
RS=0;RW=1;
E=0;
E=1; //正脉冲读
while(DATAPORT&0x80){ //忙,等待
E=0;
E=1;
}
}

void transfer(){ //用于秒分时周的显示
d[0]=hour/10+0x30;
d[1]=hour%10+0x30;
d[3]=minute/10+0x30;
d[4]=minute%10+0x30;
d[6]=second/10+0x30;
d[7]=second%10+0x30;
}
void clock() interrupt 1{ //计时
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
while(–count==0){
count=20; //50毫秒*20等于1秒
second++;
if(second>=60){
second=0; //秒到分钟
minute++;
if(minute>=60){ //分钟到小时
minute=0;
hour++;
if(hour>=24){ //小时到天
hour=0;
week++;
if(week>=7){ //星期天到星期一
week=0;
}
}
}
}
}
}

void timeadd(int flag){//时间加
switch(flag){
case(1):
if(week6){
week=0;
break;
}
week++; //增加星期的值
break;
case(2):
if(hour23){
hour=0;
break;
}
hour++; //增加小时的值
break;
case(3):
if(minute59){
minute=0;
break;
}
minute++; //增加分钟的值
break;
case(4):
if(second59){
second=0;
break;
}
second++; //增加秒的值
break;
default:
break;
}
}
void timecut(int flag){ //时间减
switch(flag){
case(1):
if(week0){
week=6;
break;
}
week–; //减少星期的值
break;
case(2):
if(hour0){
hour=23;
break;
}
hour–; //减少小时的值
break;
case(3):
if(minute0){
minute=59;
break;
}
minute–; //减小分钟的值
break;
case(4):
if(second0){
second=59;
break;
}
second–; //减少秒的值
break;
default:
break;
}
}
六、 程序流程图
该流程图先对电路进行初始化,然后程序main函数开始顺序执行,进入主程序,在主程序中调用各个子程序,在运行时可对时钟进行调整,key2键是选择调整对象,key0键是进行增加,key1键是进行减少。

七 、程序分析

使用单片机P1口输出数据

使用单片机P2口的567引脚进行按键检测

使用P3口对lcd屏RS/RW的控制

使用flag标识实现对分/时/星期 的修改定位

定时器采用定时器0方式1,设置初值为50000

timeflag的值为1就改变星期的值,为2就改变小时的值,为3就改变分钟的值,为4就改变秒钟的值,为其他就不做任何操作.

通过key1/key0的按下去调用时间加/减的函数,并将timeflag的值传递到时间加/减的函数中.
八、 绘制PCB图

绘制原理图库
a) 测量各个元器件引脚的数量,准确的将原理图库绘制出来
a) 测量元器件具体大小,绘制各元器件的封装

绘制原理图
a) 参考方正电路绘制出原理图,并加上晶振电路,电源电路,和排针
b) 最终原理图效果:

原理图导入pcb完成布线工作

九、腐蚀/打孔/焊接

焊接好之后需要用万用表检测是否通路,有引脚短路最终实物图将预先编译好的hex程序文件烧录至单片机测试各项功能是否正常

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。