课程设计基于单片机AT89C52电子时钟课程设计说明书.docx

上传人:聆听****声音 文档编号:8965704 上传时间:2023-05-16 格式:DOCX 页数:26 大小:143.23KB
下载 相关 举报
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第1页
第1页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第2页
第2页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第3页
第3页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第4页
第4页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第5页
第5页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第6页
第6页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第7页
第7页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第8页
第8页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第9页
第9页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第10页
第10页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第11页
第11页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第12页
第12页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第13页
第13页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第14页
第14页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第15页
第15页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第16页
第16页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第17页
第17页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第18页
第18页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第19页
第19页 / 共26页
课程设计基于单片机AT89C52电子时钟课程设计说明书.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

课程设计基于单片机AT89C52电子时钟课程设计说明书.docx

《课程设计基于单片机AT89C52电子时钟课程设计说明书.docx》由会员分享,可在线阅读,更多相关《课程设计基于单片机AT89C52电子时钟课程设计说明书.docx(26页珍藏版)》请在冰点文库上搜索。

课程设计基于单片机AT89C52电子时钟课程设计说明书.docx

一、课程设计内容

单片机课程设计报告

1)显示时间功能,能正确显示“时”、“分”。

2)显示日期功能,能显示“月”、“日”。

3)闹钟功能,可按设定的时间闹时。

4)具有校准月、日、时、分的功能。

二、元器件介绍

本次课程设计我使用的单片机是至强51蓝精灵版,而实验中使用到的关键元器件主要有:

STC85C52RC,4*4按键,蜂鸣器,数码管等。

下面是STC85C52RC的简单介绍:

AT89C52是本设计最核心的部件,它是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含8Kbytes的可反复擦写的Flash只读程序存储

器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,与标准MCS-51指令系统及8052产品引脚兼容,片内

置通用8位中央处理器(CPU)和Flash存储单元,功能强大。

AT89C52单片机适用于许多较为复杂的控制应用场合。

下图是AT89C52最常见的一种封装。

如上图所示,AT89C52共有40个管脚,其各个功能如下:

·VCC ——运行时加+5V

·VSS ——接地

·XTAL1 ——振荡器反相放大器及内部时钟发生器的输入端

·XTAL2 ——振荡器反相放大器的输出端

·RST ——复位输入,高电平有效,在晶振工作时,在RST引脚上作用2

个机器周期以上的高电平,将使单片机复位。

·EA/VPP ——片外程序存储器访问允许信号。

欲使CPU仅访问外部程序存

储器(地址为0000H-FFFFH),EA端必须保持低电平(接地),如果EA端为

高电平(接Vcc端),CPU则执行内部程序中的指令。

·LAE/PROG



——当访问外部程序存储器或数据存储器时,ALE(地址允许锁

存)输出脉冲用于锁存地址的低8位位数字节。

一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。

要注意的是:

每当访问外部数据存储器时将跳过一个ALE脉冲。

对Flash存储器编程期间,该引脚还用于输入编程脉冲(第二功能)。

·PSEN:

程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当

AT89C52

由外部存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两

个脉冲。

在此期间,当访问外部数据存储器,将跳过两次PSEN信号。

·P0口 ——是一组8位漏极开路双向I/O口,也即地址/数据总线复用口。

作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口P0写“1”时,可作为高阻抗输入端用。

·P1口 ——是一个内部带上拉电阻的8位准双向I/O口。

在对EPROM型单片机编程和验证程序时,它接收低8位地址。

P1能驱动(吸收或输出电流)4个

LSTTL电路。

P1.0还被用作定时器/计数器2的外部计数输入端,即专用功能T2。

P1.1被用作专用功能端T2EX,即定时器T2的外部控制端。

参见下表。

P1.1和P1.1的第二功能

引脚号

功能特性

P1.0

T2(定时/计数器2外部计数脉冲输入),时钟输出

P1.1

T2XE(定时/计数器2捕获/重装载触发和方向控制)

·P2口——是一个带有内部上拉电阻的8位准双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。

对端口写“1”,通过内部的上拉电阻,某个引脚外部信号拉低是会输出一个电流。

·P3口 ——是一组带有内部上拉电阻的8位准双向I/O口。

P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。

对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。

此时,被外部拉低的P3口将用上拉电阻输出电流。

P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能,如下表所示:

P3口各位的第二功能

端口引脚

第二功能

P3.0

RXD (串行输入口)

P3.1

TXD (串行输出口)

P3.2

INT0 (外部中断0)

P3.3

INT1 (外部中断1)

P3.4

T0 (定时/计数器0)

P3.5

T1 (定时/计数器1)

P3.6

WR (外部数据存储器写选通)

P3.7

RD (外部数据存储器读选通)

三、设计方案

1)实物图

2)实验程序流程图

T0初始化,中断初始化,启动定时器

·主程序

开 始

调用compare()函数比较现在显示的时间是否和闹钟时间相同

调用子程序keyhandle()根据键盘扫描的返回值进行处理

调用启停子程序

keysure()

键盘扫描

while

(1)死循环调用子程

voidmain()

{

init();while

(1)

{

keysure();keyhandle();compare();

}

}

·初始化函数

voidinit()

{TMOD=0x01;

TH0=0xdc;TL0=0x00;

EA=1;

ET0=1;

TR0=1;

keytemp=8;//这是为了还没有扫描按键时给keyhandle()函数处理用的//

}

实验中只是用了T0这一个定时器,也只是使用了T0这个中断。

实验中设置TMOD=0x01使T0工作于方式1。

并且由公式t=(65535-M)

*6/12MHz,而t为中断溢出时间,为10ms,所以得出初值M=3340=0xdc。

·键盘扫描函数

键盘是否

真的被按下?

调用scankey(),根据按下键位返回值给keyhandle()处理

调用keysure()函数用以扫描键盘是否真正被按下

voidkeysure()

{staticbitflag1;

P1=0xf0;

if(P1!

=0xf0)

{

Delay_1ms(15);if(P1!

=0xf0)

{

keytemp=scankey(); flag1=1;

}

}

·键盘返回值函数scankey()

ucharscankey(void)//键盘扫描后返回值//

{

uchari,j,temp,Buffer[4]={0xef,0xdf,0xbf,0x7f};for(j=0;j<4;j++)

{

P1=Buffer[j];

_nop_();

_nop_();

_nop_();temp=0x01;

for(i=0;i<4;i++)

{

if(!

(P1&temp))

{

return(i+j*4);

}

temp<<=1;//temp从0x01一直位移到10000000//

}

}

return(0);

}

·键盘处理程序

voidkeyhandle()

{if(keytemp==8)//此显示当前时间//

{s2=min;s1=hour;who=1;led1=0;led2=1;

}

if(keytemp==9)//此时显示闹钟//

{s1=nhour;s2=nmin;who=2;led1=1;led2=0;

}

if(keytemp==10)//此时显示日期//

{s1=month;s2=day;who=3;

}

if(keytemp==12)//此左移//

{which=1;led4=1;led3=0;

switch(who)//返回显示,不然就没有循环动态扫描了//

{

case1:

keytemp=8;break;

case2:

keytemp=9;break;case3:

keytemp=10;break;default:

break;

}

}

if(keytemp==13)//此右移//

{which=2;

led4=0;led3=1;switch(who)

{

case1:

keytemp=8;break;case2:

keytemp=9;break;case3:

keytemp=10;break;default:

break;

}

}

if(keytemp==14&&flag==1)//此做加数//

{if(which==1)switch(who)

{

case1:

hour++;keytemp=8;if(hour>59)

hour=0;break;

case2:

nhour++;keytemp=9;if(nhour>24)

nhour=0;break;

case3:

month++;keytemp=10;if(month>12)

month=0;break;

default:

break;

}

if(which==2)//此减数//switch(who)

{

case1:

min++;keytemp=8;

if(min>59)min=0;

break;case2:

nmin++;keytemp=9;if(nmin>59)

nmin=0;break;

case3:

day++;keytemp=10;if(day>30)

day=0;break;

default:

break;

}

flag=0;

}

if(keytemp==15&&flag==1)//此减数//

{if(which==1)switch(who)

{

case1:

hour--;keytemp=8;if(hour<0)

hour=23;break;

case2:

nhour--;keytemp=9;if(nhour<0)

nhour=23;break;

case3:

month--;keytemp=10;if(month<0)month=12;

break;

default:

break;

}

if(which==2)switch(who)

{

case1:

min--;keytemp=8;if(min<0)

min=59;break;

case2:

nmin--;keytemp=9;if(nmin<0)

nmin=59;break;

case3:

day--;keytemp=10;if(day<0)

day=30;break;

default:

break;

}

flag=0;

}

flag=0;

}

·中断子程序

手动重装初值

循环次数加一

Y

分位清0

循环数i到100

否?

N

Y

N

60S到否?

Y

N

60分到否?

时位加1

分位加1

秒个位清0

秒个位加1

N

24时到

了?

天数加1

时位清0

Y

调用display()LED动态扫描函数

voidtiem0(void)interrupt1

{ staticunsignedchari=0;TH0=0xdc;

TL0=0x00;i++;

if(i>199)

{sec++;i=0;

}

if(sec>59)

{sec=0;min++;

}

if(min>59)

{min=0;hour++;

}

if(hour>23)

{day++;hour=0;

}

display();//每次中断程序中都调用一次LED扫描程序//

}

LED扫描子程序

voiddisplay()

{staticchari=0;

chardisbuf[4];disbuf[1]=s1%10;disbuf[0]=s1/10;

disbuf[3]=s2%10;disbuf[2]=s2/10;

P0=0xff;

P2=b[i];

P0=duanma[disbuf[i]];i++;

if(i>3)i=0;

if((sec&0x01)&& i==2)P0&=0x7f;

}

3)实验中使用电路模块电路图

·LED显示模块

·蜂鸣器模块

·键盘扫描模块

D0~D7分别对应IO口的P1.0~P1.7

以下是全部源程序

#include#defineucharunsignedchar#defineuintunsignedint

#include

ucharcodeduanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,

0x82,0xf8,0x80,0x90,0xbf};

unsignedchar codeb[]={0xfe,0xfd,0xfb,0xf7};

charsec=0,min=0,hour=2,nsec=0,nmin=1,nhour,month=12,day=1,keytemp;bitflag=0;

charwho=0;charwhich=1;sbitled1=P3^0;sbitled2=P3^1;sbitled3=P3^2;sbitled4=P3^3;

sbitSPK=P3^6;//蜂鸣器的接口//#defineuintunsignedint

chars1,s2;

voiddisplay()

{staticchari=0;

chardisbuf[4];disbuf[1]=s1%10;disbuf[0]=s1/10;

disbuf[3]=s2%10;disbuf[2]=s2/10;

P0=0xff;P2=b[i];

P0=duanma[disbuf[i]];i++;

if(i>3)i=0;

if((sec&0x01)&&i==2)P0&=0x7f;

}

voidinit()

{TMOD=0x01;

TH0=0xdc;TL0=0x00;EA=1;ET0=1;TR0=1;

keytemp=8;//这是为了没有扫描到按键时给keyhandle()函数处理用的//

}

voidtiem0(void)interrupt1

{ staticunsignedchari=0;TH0=0xdc;

TL0=0x00;i++;

if(i>199)

{sec++;i=0;

}

if(sec>59)

{sec=0;min++;

}

if(min>59)

{min=0;hour++;

}

if(hour>23)

{day++;hour=0;

}

display();

}

ucharscankey(void)

{

uchari,j,temp,Buffer[4]={0xef,0xdf,0xbf,0x7f};for(j=0;j<4;j++)

{

P1=Buffer[j];

_nop_();

_nop_();

_nop_();

temp=0x01;for(i=0;i<4;i++)

{

if(!

(P1&temp))

{

return(i+j*4);

}

temp<<=1;

}

}

return(0);

}

voidkeyhandle()

{if(keytemp==8)//此显示时间//

{s2=min;s1=hour;who=1;led1=0;led2=1;

}

if(keytemp==9)//此时显示闹钟//

{s1=nhour;s2=nmin;who=2;led1=1;led2=0;

}

if(keytemp==10)//此时显示日期//

{s1=month;s2=day;who=3;

}

if(keytemp==12)//此左移//

{which=1;led4=1;led3=0;

switch(who)//返回显示,不然就没有循环动态扫描了//

{

case1:

keytemp=8;break;case2:

keytemp=9;break;case3:

keytemp=10;break;default:

break;

}

}

if(keytemp==13)//此右移//

{which=2;

led4=0;led3=1;

switch(who)

{

case1:

keytemp=8;break;case2:

keytemp=9;break;case3:

keytemp=10;break;default:

break;

}

}

if(keytemp==14&&flag==1)//此加数//

{if(which==1)switch(who)

{

case1:

hour++;keytemp=8;if(hour>59)

hour=0;break;

case2:

nhour++;keytemp=9;if(nhour>24)

nhour=0;break;

case3:

month++;keytemp=10;if(month>12)

month=0;break;default:

break;

}

if(which==2)//此减数//switch(who)

{

case1:

min++;keytemp=8;if(min>59)

min=0;break;case2:

nmin++;keytemp=9;if(nmin>59)

nmin=0;break;

case3:

day++;keytemp=10;if(day>30)

day=0;break;default:

break;

}

flag=0;

}

if(keytemp==15&&flag==1)//此减数//

{if(which==1)switch(who)

{

case1:

hour--;keytemp=8;if(hour<0)

hour=23;break;

case2:

nhour--;keytemp=9;if(nhour<0)

nhour=23;

break;case3:

month--;keytemp=10;if(month<0)month=12;

break;default:

break;

}

if(which==2)switch(who)

{

case1:

min--;keytemp=8;if(min<0)

min=59;break;

case2:

nmin--;keytemp=9;if(nmin<0)

nmin=59;break;

case3:

day--;keytemp=10;if(day<0)

day=30;

break;default:

break;

}

flag=0;

}

flag=0;

}

voidDelay_1ms(uinti)

{

ucharx,j;for(j=0;j

}

voidkeysure()

{staticbitflag1;

P1=0xf0;

if(P1!

=0xf0)

{

Delay_1ms(15);if(P1!

=0xf0)

{

keytemp=scankey(); flag1=1;

}

}

elseif(flag1)

flag=1;

}

voidcompare()

{if(nmin==min&&nhour==hour&&nsec==sec)

SPK=0;

if(keytemp==11)SPK=1;

}

voidmain()

{

init();

while

(1)

{

keysure();keyhandle();compare();

}

}

四、总结

总结就删掉啦,上传这篇东西希望能帮到有需要的童鞋们,但最好就不要down下来就什么都不学,连程序都看不懂就交了。

但也是说说而已,该怎么着始终还是会怎么着的。

本课程设计纯属梦呓,存在许多缺点,如有不爽,敬请无视。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2