时钟设计.docx
《时钟设计.docx》由会员分享,可在线阅读,更多相关《时钟设计.docx(17页珍藏版)》请在冰点文库上搜索。
时钟设计
评分:
单片机实验报告
<<课程设计>>
一、实验目的:
1.进一步掌握8255A编程原理、掌握解键盘电路的工作原理、掌握键盘接口电路的编程方法。
2.进一步掌握定时器的使用和编程方法。
掌握七段数码显示数字的原理。
掌握用一个段锁存器,一个位锁存器同时显示多位数字的技术。
3.掌握电子时钟的设计方法。
二、实验设备:
CPU挂箱、8031CPU模块。
三、实验内容:
使用8051制作数字电子时钟,这个时钟使用键盘和6个共阳七段显示器组成。
键盘按键用来设置时间,6个七段显示器则用来显示时间。
一下为数字时钟的基本功能;
1、6个七段显示器用来显示时分秒,每个占2位。
2、用户可以设置数字时钟的时间。
设置时间必须单击模式选择键,进入时间调整模式,然后单击确定按键进入正确的时间。
3、数字时钟只有两种模式,分别是显示时间和调整时间模式。
四、实验原理
(一)键盘扫描原理
1、识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如所读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
本实验例程采用的是行反转法。
行反转法识别键闭合时,要将行线接一并行口,先让它工作于输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口往各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上的输入值,那么,在闭合键所在的行线上的值必定为0。
这样,当一个键被按下时,必定可以读得一对唯一的行线值和列线值。
2、程序设计时,要学会灵活地对8255A的各端口进行方式设置。
3、程序设计时,可将各键对应的键值(行线值、列线值)放在一个表中,将要显示的0~F字符放在另一个表中,通过查表来确定按下的是哪一个键并正确显示出来。
实验题目
(二)数码管显示原理
1、利用实验箱上的8255A可编程并行接口芯片和矩阵键盘,编写程序,做到在键盘上每按一个时间数字,用发光二极管将该代码显示出来。
2、本试验采用动态显示。
动态显示就是一位一位地轮流点亮显示器的各个位(扫描)。
将8031CPU的P1口当作一个位锁存器使用,74LS273作为段锁存器。
四、实验接线
1、将键盘RL10~RL17接8255A的PB0~PB7;KA10~KA12接8255A的PA0~PA2;PC0~PC7接发光二极管的L1~L8;8255A芯片的片选信号8255CS接CS0。
2、将P1口的P1.0~P1.5与数码管的输入LED1~LED6相连,74LS273的O0~O7与LED-A~LED-Dp相连,片选信号CS273与CS1相连。
去掉短路子连接。
五、实验电路图
6、
程序框图
主函数
中断函数:
n
y
N
Y
7、电子时钟程序如下:
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitduan=P2^6;//设置段选端口
sbitwei=P2^7;//设置位选端口
sbitset=P3^4;//设置时间
ucharcodetable[]=
{0X3f,0X06,0X5b,0X4f,0X66,
0X6d,0X7d,0X07,0X7f,0X6f,0x40};
ucharsecondH,secondL,minuteH,minuteL,hourH,hourL;
ucharsecond1,second2,minute1,minute2,hour1,hour2;
ucharcount,key;
voiddelayms(uintxms)//延时函数
{uinti,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
voiddisplay(ucharsecondL,ucharsecondH,ucharminuteL,ucharminuteH,ucharhourL,ucharhourH)//显示函数
{
duan=1;
P0=table[hourH];
duan=0;
P0=0xff;//锁存器清零
wei=1;
P0=0xfe;//选中第一个数码管
wei=0;
delayms
(2);//延时
duan=1;//单开段选锁存器
P0=table[hourL];
duan=0;
P0=0xff;//清零锁存器
wei=1;
P0=0xfd;//选中第二个数码管
wei=0;
delayms
(2);
duan=1;
P0=table[minuteH];
duan=0;
P0=0xff;
wei=1;
P0=0xfb;
wei=0;
delayms
(2);
duan=1;
P0=table[minuteL];
duan=0;
P0=0xff;
wei=1;
P0=0xf7;
wei=0;
delayms
(2);
duan=1;
P0=table[secondH];
duan=0;
P0=0xff;
wei=1;
P0=0xef;
wei=0;
delayms
(2);
duan=1;
P0=table[secondL];
duan=0;
P0=0xff;
wei=1;
P0=0xdf;
wei=0;
delayms
(2);
}
voidinit()//初始化函数
{
count=0;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;//开中断
ET0=1;//开定时器0中断
TR0=1;//开定时器0
}
ucharkeyscan()//键盘扫描
{
uchartemp;
P3=0xfe;//检测键盘第一行
temp=P3;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delayms(10);//延时10毫秒防抖
temp=P3;
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P3;
switch(temp)
{
case0xee:
key=0;
break;
case0xde:
key=1;
break;
case0xbe:
key=2;
break;
case0x7e:
key=3;
break;
}
while(temp!
=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfd;//检测键盘第二行
temp=P3;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P3;
switch(temp)
{
case0xed:
key=4;
break;
case0xdd:
key=5;
break;
case0xbd:
key=6;
break;
case0x7d:
key=7;
break;
}
while(temp!
=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfb;//检测键盘第三行
temp=P3;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P3;
switch(temp)
{
case0xeb:
key=8;
break;
case0xdb:
key=9;
break;
}
while(temp!
=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
returnkey;
}
voidmain()
{
ucharflag;
flag=0;
init();
while
(1)
{
if(set==0)//设置时间模式
{
delayms(50);
if(set==0)
{
TR0=0;
flag++;
if(flag>6)
{
flag=0;
}
}
}
switch(flag)
{
case0:
TR0=1;
display(second1,second2,minute1,minute2,hour1,hour2);
break;
case1:
//按一下调整小时
hour2=keyscan();
if(hour2>=2)
{
hour2=2;
}
display(10,10,10,10,10,hour2);
break;
case2:
hour1=keyscan();
if(hour2>=2&hour1>=3)
{
hour1=3;
}
display(10,10,10,10,hour1,hour2);
break;
case3:
//按三下调整分钟
minute2=keyscan();
if(minute2>=6)
{
minute2=5;
}
display(10,10,10,minute2,hour1,hour2);
break;
case4:
minute1=keyscan();
display(10,10,minute1,minute2,hour1,hour2);
break;
case5:
//按五下调整秒
second2=keyscan();
if(second2>=6)
{
second2=5;
}
display(10,second2,minute1,minute2,hour1,hour2);
break;
case6:
second1=keyscan();
display(second1,second2,minute1,minute2,hour1,hour2);
break;
default:
break;//按七下回到计时模式
}
}
}
voidtimer0()interrupt1//定时器0中断程序
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==20)
{
count=0;
second1++;
if(second1>9)
{
second1=0;
second2++;
if(second2>6)
{
second2=0;
minute1++;
if(minute1>9)
{
minute1=0;
minute2++;
if(minute2>6)
{
minute2=0;
hour1++;
if(hour1>9)
{
hour1=0;
hour2++;
}
else
{
if(hour1>=3&hour2>=2)
{
hour1=0;
hour2=0;
}
}
}
}
}
}
}
}
8、实验现象:
9、实验心得: