单片机时钟设计.docx
- 文档编号:6185605
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:16
- 大小:168.08KB
单片机时钟设计.docx
《单片机时钟设计.docx》由会员分享,可在线阅读,更多相关《单片机时钟设计.docx(16页珍藏版)》请在冰豆网上搜索。
单片机时钟设计
基于单片机控制的时钟设计报告
设计目的
单片机即单片机微型计算机,是集CPU、存储器、定时和多种接口于一体的微控制器。
它体积小,成本低,功能强,广泛应用于智能产品和工业自动化上。
这次设计通过对它的学习、应用,从而达到学习设计、开发软硬件的目的。
学习使用4×4矩阵键盘的设计方法,实践对比按键抖动对扫描键盘输出的影响。
学习数码管的动态显示功能以及对液晶、蜂鸣器和发光二极管的操作。
同时,学会应用keil软件
设计的具体要求
设计的电子时钟可以同时通过数码管和液晶显示,并能通过按键实现调整时间和设置闹钟的目的。
采用方式一对12MHZ的系统时钟进行定时计数,然后把秒、分、时计数器分成十位和各位在液晶上显示(数码管显示秒和分),数码管采用动态显示的方法,在处理过程中加入按键判断的程序,能对按键进行处理,系统扫描到按键确实有作用后使发光二极管灯亮。
系统设计
总体设计
经过分析论证,确定流程图如下:
矩阵键盘
AT89S52
单片机
1602A液晶
数码管
蜂鸣器
整套系统以AT89S52单片机为核心控制系统,利用其定时器采用方式1进行计时,并通过1602A液晶显示模块显示出来,同时,也加入了数码管动态显示功能,整个设计还可以实现闹钟功能,一旦到达闹钟设定时间,将进入中断开启蜂鸣器。
矩阵键盘右16个开关组成用来调时。
单片机最小系统的设计
设计原理
最小系统的设计晶振的作用非常大,它结合单片机内部的电路,产生单片机所需要的时钟频率,两旁的负载电容是为了提供晶振工作需要的并联谐振状态,最大限度的保证频率值的误差。
复位电路中,刚接通电源时,电容充电,10K电阻上出现电压,单片机复位。
几个毫秒后,充电停止,10K电阻电压为0,单片机正常工作。
工作期间,按下复位键电容放电,松手,电容充电,单片机复位,几毫秒后正常工作。
P0口上拉电阻的作用,P0作为开漏输出端口时,只有外接上拉电阻才能输出高电平。
单片机中断系统基本原理
本设计中,定时器/计数器T0用于时间计时。
选择方式1,重复定时,定时时间设为50ms,定时时间到则中断,在中断服务程序中用一个计数器对50ms计数,计20次则对秒单元加1,秒单元加到60则对分单元加1,同时秒单元清0;分单元加到60则对时单元加1,同时分单元清0;时单元加到24则对时单元清0,标志一天时间计满。
在对各单元计数的同时,把它们的值放到存储单元的指定位置。
定时器工作方式1
动态补偿的应用
产生单片机定时器溢出中断与CPU响应中断的时间误差有两个原因。
一是定时器溢出中断信号时,CPU正在执行某指令;二是定时器溢出中断信号时,CPU正在执行某中断服务程序。
理想情况下,TL0满了后向TH0进1,TL0变为0x00。
当TH0满了后,溢出中断,TH0变为0x00。
当处于前两种情况时,CPU不能及时响应定时器的溢出中断请求,从而产生了较大误差,本设计采用了动态补偿的方法来解决这个问题,详见软件设计。
矩阵键盘的设计
操作原理
以操作第1行为例,设置列信号为1111,设置行信号为1110,此时当第1行有一个键按下时,该键所在列信号变为0。
比如第1行第1列的键按下,信号就变为11101110,与0xff取位与(&)就能扫描出确实有键按下了,这时,读出矩阵键盘所接单片机接口的电平,以确定是哪个键按下。
操作其他行原理类似。
因为一般的开关在大约20ms内信号不稳定,存在所谓的“开关抖动”,会产生多个脉冲影响电路正常工作。
所以软件设计时要注意做防抖处理。
数码管设计
设计原理
数码管的设计采用动态显示原理,动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。
选亮数码管采用动态扫描显示。
所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
设计中使用了两个锁存器,给WELALL一个高电平,给DULALL一个低电平时,系统给D0~D7赋值,即决定了哪几位数码管有效。
给DULALL一个高电平,给WELALL一个低电平时,系统给D0~D7赋值,即决定了有效位显示什么数字。
很好地达到了动态显示的目的。
蜂鸣器模块
三极管的作用
通过对三极管基极的操作,起到对蜂鸣器开关的作用。
液晶显示模块的设计
发光二极管的设计
直接将发光二极管与10K电阻串联接入电路即可。
Proteus仿真电路
软件程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitdula=P3^6;
sbitwela=P3^7;
ucharcodetimer[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e,0xff};
ucharfixtime;
uinta,b,c,d,c1,d1,num1,num2,num3,num4,num5,num6,flag,flag1;
sbitred=P3^5;
sbitalarm=P3^3;
sbitRS=P3^0;
sbitE=P3^2;
ucharcodetable1[]=":
";
//延时函数
voiddelay(ucharz)
{
ucharx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//初始化并开启中断
voidunin()
{
a=0;b=0;c=0;d=0;
c1=0;d1=0;flag=0;flag1=0;
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
//矩阵键盘调时函数
voidchange()
{
uchartemp,key;
key=0;
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
red=1;
temp=P1;
switch(temp)
{
case0xed:
key=1;
break;
case0xdd:
key=2;
break;
case0xbd:
key=3;
break;
case0x7d:
key=4;
break;
}
while(temp!
=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
red=0;
}
if(key==1)
{
flag1++;
}
if(key==2)
{
if(flag1%2==0)c++;
if(flag1%2==1)c--;
}
if(key==3)
{
if(flag1%2==0)d++;
if(flag1%2==1)d--;
}
if(key==4)
{
flag++;
}
}
}
//时间自加函数
voidadd()
{
if(a>=15)
{
a=0;
b++;
if(b>=60)
{
b=0;
c++;
if(c>=60)
{
c=0;
d++;
if(d>=24)d=0;
}
}
}
}
//闹钟函数
voidbeep()
{
if(c==c1)
{if(d==d1)
if(flag%2==0)
{
alarm=0;
delay(10);
alarm=1;
delay(10);
alarm=0;
delay(10);
alarm=1;
delay(10);
}
}
}
//数码管显示函数
voidout()
{
num1=d/10;
num2=d%10;
num3=c/10;
num4=c%10;
num5=b/10;
num6=b%10;
wela=1;
P0=0xf1;
wela=0;
dula=1;
P0=timer[num3];
dula=0;
delay(5);
wela=1;
P0=0xf2;
wela=0;
dula=1;
P0=timer[num4];
dula=0;
delay(5);
wela=1;
P0=0xf4;
wela=0;
dula=1;
P0=timer[num5];
dula=0;
delay(5);
wela=1;
P0=0xf8;
wela=0;
dula=1;
P0=timer[num6];
dula=0;
delay(5);
}
//液晶显示函数
voidwrite_com(ucharcom)
{
RS=0;
P2=com;
delay(5);
E=1;
delay(5);
E=0;
delay(5);
}
voidwrite_date(uchardate)
{
RS=1;
P2=date;
delay(5);
E=1;
delay(5);
E=0;
delay(5);
}
voidwrite(uchardate,uchardot)
{
write_com(0x80+0x40+dot);
//delay(5);
write_date(0x30+date);
//delay(5);
}
voidunin1()
{
E=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80+0x40);
}
voidout1()
{
num1=d/10;
num2=d%10;
num3=c/10;
num4=c%10;
num5=b/10;
num6=b%10;
unin1();
write(num1,1);
write(num2,2);
write_com(0x80+0x40+3);
write_date(table1[0]);
write(num3,4);
write(num4,5);
write_com(0x80+0x40+6);
write_date(table1[0]);
write(num5,7);
write(num6,8);
}
//主函数
voidmain()
{
unin();
while
(1)
{
change();
add();
beep();
out();
out1();
}
}
//定时器中断服务程序
voidtime()interrupt1
{
EA=0;
TR0=0;
fixtime=TL0+0X0C;
TH0=0xFC+(char)CY;
EA=1;
TR0=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
a++;
}
设计制作流程
1、在PROTEUS中设计硬件
PROTEUS使用过程如下:
1)选择元器件
2)放置元器件
3)连线
4)添加程序
5)运行仿真
元器件清单如下:
2、在KEIL中编写程序,编译、连接形成HEX文件。
3、在PROTEUS中把HEX文件加载到单片机芯片上。
4、运行仿真看结果。
5、按照proteus仿真图进行焊接。
6、下载程序,看实物的运行结果。
7、写设计报告。
参考文献
郭天祥,《十天学会单片机》视频教程
卢胜利,《单片机原理与应用技术实践》,机械工业出版社,2009
吴友宇,《模拟电子技术基础》,清华大学出版社,2009
马德骏,《C语言程序设计》,科学出版社,2009
侯玉宝,《基于Proteus的51系列单片机设计与仿真
》,电子工业出版社,2008
总结
通过本设计熟悉了51单片机的使用,特别是知道了并行I/O接口、定时器、复位电路、时钟电路、中断逻辑等知识。
熟悉了矩阵键盘、数码管、液晶等模块的功能,并能熟练地控制其运作。
能够更娴熟的运用keil、protell、proteus软件。
提高了动手实践能力及发现问题解决问题的能力。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 时钟 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)