计数器设计.docx

上传人:b****1 文档编号:19413551 上传时间:2023-04-24 格式:DOCX 页数:27 大小:96.65KB
下载 相关 举报
计数器设计.docx_第1页
第1页 / 共27页
计数器设计.docx_第2页
第2页 / 共27页
计数器设计.docx_第3页
第3页 / 共27页
计数器设计.docx_第4页
第4页 / 共27页
计数器设计.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

计数器设计.docx

《计数器设计.docx》由会员分享,可在线阅读,更多相关《计数器设计.docx(27页珍藏版)》请在冰豆网上搜索。

计数器设计.docx

计数器设计

专业项目设计

&综合项目设计

 

题目警报计数器的设计与实现

学院计算机学院

专业计算机科学与技术

班别10级(6)班

学号

姓名

指导老师

 

2014年1月10日

目录

前言2

一、课程设计目的3

二、运行环境3

三、需求分析3

四、详细设计3

1、AT89C52介绍3

2、AT89C52系列单片机外引脚功能4

3、仿真电路图5

4、警报电路设计5

5、矩阵键盘设计6

6、主要功能函数代码6

五、各模块详细功能8

1.计数功能8

2.设置计数初值功能9

3.设置警报9

六、心得与体会10

七、参考文献10

八、附录:

(源代码)11

前言

摘要:

单片机在电子产品中的应用越来越广泛,其具有使用方便、价格低廉等优势,其中计数器在单片机电子产品中得到广泛的应用,例如电子时钟,秒表,各类检测器等。

本设计是基于AT89C52的一个警报计数器,包括74HC245,7445,7SEG-MPX8-CC,能够实现警报,计数,设置的多功能计数器。

所有功能能够通过按钮实现,符合人们实际的生活所需,具有整体性好、人性化强、可靠性高等优点

关键词:

计数器AT89C524X4矩阵键盘7SEG-MPX8-CC

一、课程设计目的

1.掌握MCS-51系列单片机的基本结构和原理。

2.学会用C语言对单片机的内部和外围器件的编程。

3.掌握计数器中断处理程序的编程。

4.掌握ProtuesISIS仿真环境。

二、运行环境

Proteus7Professional,KeiluVision4,MicrosoftVisualStudio2010

三、需求分析

基于AT89C52芯片开发功能性需求如下:

1.设计一个计数器,使其能够进行顺数,倒数计数。

2.能够自由设置计数初值。

3.计数器具有警报功能。

4.能够自由设置警报值

四、详细设计

系统主要由3部分组成,分别是7SEG-MPX8-CC、74HC245、7445组成的显示时间模块、4X4矩阵输入模块、蜂鸣警报器模块。

用AT89C52芯片作为核心主控芯片。

1、AT89C52介绍

AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的AT89C52单片机可为您提供许多较复杂系统控制应用场合。

AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2 个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。

其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。

2、AT89C52系列单片机外引脚功能

AT89C52有PDIP、PQFP/TQFP及PLCC等三种封装形式,以适应不同产品的需求。

主要功能特性:

兼容MCS51指令系统·8k可反复擦写(>1000次)FlashROM

·32个双向I/O口·256x8bit内部RAM

·3个16位可编程定时/计数器中断·时钟频率0-24MHz

·2个串行中断·可编程UART串行通道

·2个外部中断源·共6个中断源

·2个读写中断口线·3级加密位

·低功耗空闲和掉电模式·软件设置睡眠和唤醒功能

3、仿真电路图

定义P0为段输出口,定义P2为位输出口,定义P1为矩阵键盘接口,定义P3为警报器接口

4、警报电路设计

因为单片机的IO口驱动能力不够让蜂鸣器发出声音,所以我们通过三极管放大驱动电流,从而可以让蜂鸣器发出声音,你要是输出低电平,三极管导通,集电极电流通过蜂鸣器让蜂鸣器发出声音,当输出高电平时,三极管截止,没有电流流过蜂鸣器,所以就不会发出声音。

5、矩阵键盘设计

P1口接矩阵键盘,其中P1.0~P1.3接行线,P1.4~P1.7接列线。

本设计使用的方法就是通过给单片机的端口赋值两次,最后得出所按键的值。

例如:

1.我们给P1口赋值0x0f,即00001111,假设7键按下了,则这时P1口的实际值为00000001;

2.我们给P1口再赋值0xf0,即11110000,如果0键按下了,则这时P1口的实际值为00010000;

3.我们把两次P1口的实际值相加得00010001,即0x11。

由此我们便得到了按下7键时所对应的数值0x11,以此类推可得出其他15个按键对应的数值,8键为00000001|00100000=0x21有了这种对应关系,矩阵键盘编程问题也就解决了,

6、主要功能函数代码

矩阵键盘扫描:

ucharbutton_scan(void)/**扫描按键函数-2步判别扫描法**/

{

ucharreadkey,rereadkey;

ucharx_temp,y_temp;

BUTTON_PORT=0x0f;

x_temp=BUTTON_PORT&0x0f;

if(x_temp==0x0f)return(0xff);/*无按键,退出*/

BUTTON_PORT=0xf0;

y_temp=BUTTON_PORT&0xf0;

readkey=x_temp|y_temp;

time(8);/*延时10ms后再测按键*/

BUTTON_PORT=0x0f;

x_temp=BUTTON_PORT&0x0f;

if(x_temp==0x0f)return(0xff);/*无按键,退出*/

BUTTON_PORT=0xf0;

y_temp=BUTTON_PORT&0xf0;

rereadkey=x_temp+y_temp;

if(readkey==rereadkey){/*2次一致*/

return(~rereadkey);

}

return(0xff);

}

按键处理程序:

voidbutton_process(void)/*键值处理程序*/

{

switch(button_value)/*根据中断源分支*/

{

/*按第1行键*/

case0x11:

dt=7;

i++;

printf("Key(R1,C1)ispressed\n");

/*输入数字7*/

break;

case0x21:

dt=8;

i++;

printf("Key(R1,C2)ispressed\n");

/*输入数字8*/

break;

…………………………………………(省略若干按键功能详述)

case0x88:

flag=1;

if(bt==1)//警报设置赋值

{

bgg=g1*10+g2;

bhh=h1*10+h2;

bmm=m1*10+m2;

bss=s1*10+s2;

gg=0;

hh=0;

mm=0;

ss=0;

}

if(bt==0)//计数设置赋值

{

gg=g1*10+g2;

hh=h1*10+h2;

mm=m1*10+m2;

ss=s1*10+s2;

}

printf("Key(R4,C4)ispressed\n");

/*确定按钮*/

break;

default:

break;

}

if(flag==-1)

{

if(i==1)g1=dt;

if(i==2)g2=dt;

if(i==3)h1=dt;

if(i==4)h2=dt;

if(i==6)m1=dt;

if(i==7)m2=dt;

if(i==8)s1=dt;

if(i==9)s2=dt;

}

}

五、各模块详细功能

1.计数功能

顺数,从0计数到10

倒数,从15倒数至5,在15时先按下顺数/倒数键,再按启动/暂停键,进行倒数,到5时再按启动/暂停键

2.设置计数初值功能

按下设置键,输入12334556,然后按下确定键,再按启动进行计算(若按设置键前是顺数计数则顺数计数)

3.设置警报

按下设置警报键,设置警报值12345678,然后按下确定键,再按启动进行计算

等到到达警报值,蜂鸣器连续响7下以示警报,然后继续计数。

若不进行设置初始警报值为学号后四位6097

六、心得与体会

本次的专项设计不仅仅是单片机知识的应用,其中还包含了很多其他科目的知识应用其中,例如电工学,C语言设计等,使得项目变得更具综合性,使我的综合专业知识得到了一定的提高。

在本次的设计中,最难的部分就是蜂鸣器的电路设计,由于自己的电工学知识略显不足,三极管的不正确运用使得蜂鸣器的驱动电路无法正常运行,为此还数次请教指导老师,在老师的帮助下,自己对三极管的应用有了更深的了解,最终还是完成了该功能。

其次就是矩阵电路的设计和编程,矩阵键盘却没有自己想的那么灵敏,大概是自己使用行列法而非状态法的原因吧,使得其效率较低,但由于自己的知识有限,只能暂时挑选较为简单的行列法。

最后的问题就是I/O口的运用问题,第一次出来的电路图I/O口浪费十分严重,以至于后面的扩展功能无法加入,但经过老师指导和上网搜集资料,改为使用段位显示的7SEG-MPX8-CC,配合老师推荐的74HC245,7455,为此省下了不少的I/O口来扩展功能。

在这次专项设计中,不仅学习到了不少的专业知识,更重要的是锻炼了自己的自学能力,看似不能完成的任务,其实可以通过自己力所能及的能力一点一点的做起来。

倘若我们都不去走第一步,那么我们未开始就注定失败,倘若一步一脚印的走来,我们可能虽不是最成功的,但我们终究有收获的,最后感谢老师的悉心指导。

七、参考文献

[1]谭浩强.C程序设计.北京:

清华大学出版社,2005.

[2]张齐.单片机原理与嵌入式系统设计.北京:

电子工业出版社,2011

[3]秦曾煌.电工学.北京:

高等教育出版社,2010

[4]陈赜.ARM嵌入式技术原理与应用.北京:

北京航空航天大学出版社,2002

八、附录:

(源代码)

#include"common.h"

#include

#defineTRUE1

#definedataPortP0/*定义P0为段输出口*/

#defineledConPortP2/*定义P2为位输出口*/

#defineBUTTON_PORTP1/*按键接在BUTTON_PORT口*/

//gg……ss分别为显示管从左到右的两位数,g1……s2分别是他们的高低四位

intgg=0,hh=0,mm=0,ss=0,g1=0,g2=0,h1=0,h2=0,m2=0,m1=0,s1=0,s2=0,dt=0;

intbgg=0,bhh=0,bmm=60,bss=97;//警报初值

intpacket=0,start=0,bt=0,flag=-1;//paket,start,flag分别为顺数倒数,清零启动,设置警报,设置计数的标志

ucharbutton_value=0xff;//存放键值

ucharbutton_scan(void);//扫描按键函数-2步判别扫描法

voidbutton_process(void);//键值处理程序

unsignedchari=0;//显示计数变量

unsignedcharcodech[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//LED灯0~9译码

unsignedcharcounter;

sbitbell_set=P3^0;//警报设置按钮

sbitbell=P3^1;//蜂鸣器

voidtime(unsignedintucMs);//延时单位:

ms

voiddisplay();

voiddisplay2();

voidinit();

voidbell_scan();//警报设置函数

voidmain(void)

{

bell=1;

initUart();//初始化串口

TMOD=0x10;//设置定时器1为工作方式1

TH0=-50000>>8;TL0=-50000%256;

TH1=-10000>>8;TL1=-10000%256;//定时器1每10000计数脉冲发生1次中断,12MHz晶振,定时时间10000us

TCON=0x55;

IE=0x8f;//打开定时器中断

TR0=0;

button_value=0xff;

bell_scan();//警报按键扫描

while(TRUE)

{

bell_scan();

if(button_value==0x48)//启动/暂停切换

{

if(TR0==0)

{

TR0=1;

}

elseTR0=0;

}

if(button_value==0x28)//顺数、倒数切换

{

TR0=0;

if(packet==0)

{

packet=1;

}

elsepacket=0;

}

if(button_value==0x81)//清零

{

TR0=0;

init();

while

(1)

{

button_process();//键值处理程序

display2();

if(start==1)break;

}

start=0;

gg=g1*10+g2;

hh=h1*10+h2;

mm=m1*10+m2;

ss=s1*10+s2;

button_value=0xff;//重置键值

}

if(button_value==0x84)//如果按下设置键

{

init();

bt=0;

while

(1)

{

button_process();//键值处理程序

display2();

if(flag==0||flag==1)break;

}

dt=0;

flag=-1;

i=0;

button_value=0xff;//重置键值

}

display();

}

}

/*******************************************************************************************/

voidtimer1int3(void)interrupt3

{

TH1=0xd8;TL1=0xf0;//定时器1每10000计数脉冲发生1次中断,12MHz晶振,定时时间10000us

button_value=button_scan();

}

voidtimer1int0(void)interrupt1

{

TH0=0x08;TL0=0x88;//定时器0每10000计数脉冲发生1次中断,12MHz晶振,定时时间10000us

if(gg==bgg&hh==bhh&mm==bmm&ss==bss&&bt==0)

{

inti;

TR0=0;

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

{

bell=0;

time(500);

bell=1;

time(500);

}

TR0=1;

}

if(packet==0)//顺数计数

{

ss++;

if(ss>=100)

{

ss=0;

mm++;

}

if(mm>=100)

{

mm=0;

hh++;

}

if(hh>=100)

{

hh=0;

gg++;

}

if(gg>=100)

{

gg=0;

}

}

if(packet==1)//倒数计数

{

ss--;

if(ss<0)

{

ss=100;

mm--;

}

if(mm<0)

{

mm=99;

hh--;

}

if(hh<0)

{

hh=99;

gg--;

}

if(gg<0)

{

gg=99;

}

}

}

voidbell_scan()//警报设置函数

{

if(bell_set==0)

{

init();

bt=1;

while

(1)

{

button_process();//键值处理程序

display2();

if(flag==0||flag==1)break;

}

dt=0;

flag=-1;

i=0;

button_value=0xff;//重置键值

}

}

voidbutton_process(void)/*键值处理程序*/

{

switch(button_value)/*根据中断源分支*/

{

/*按第1行键*/

case0x11:

dt=7;

i++;

printf("Key(R1,C1)ispressed\n");

/*输入数字7*/

break;

case0x21:

dt=8;

i++;

printf("Key(R1,C2)ispressed\n");

/*输入数字8*/

break;

case0x41:

dt=9;

i++;

printf("Key(R1,C3)ispressed\n");

/*输入数字9*/

break;

case0x81:

printf("Key(R1,C4)ispressed\n");

/*清零按钮*/

break;

/*按第2行键*/

case0x12:

dt=4;

i++;

printf("Key(R2,C1)ispressed\n");

/*输入数字4*/

break;

case0x22:

dt=5;

i++;

printf("Key(R2,C2)ispressed\n");

/*输入数字5*/

break;

case0x42:

dt=6;

i++;

printf("Key(R2,C3)ispressed\n");

/*输入数字6*/

break;

case0x82:

flag=0;

bt=0;

printf("Key(R2,C4)ispressed\n");

/*取消按钮*/

break;

/*按第3行键*/

case0x14:

dt=1;

i++;

printf("Key(R3,C1)ispressed\n");

/*输入数字1*/

break;

case0x24:

dt=2;

i++;

printf("Key(R3,C2)ispressed\n");

/*输入数字2*/

break;

case0x44:

dt=3;

i++;

printf("Key(R3,C3)ispressed\n");

/*输入数字3*/

break;

case0x84:

printf("Key(R3,C4)ispressed\n");

/*设置按钮*/

break;

/*按第4行键*/

case0x18:

dt=0;

i++;

printf("Key(R4,C1)ispressed\n");

/*输入数字0*/

break;

case0x28:

printf("Key(R4,C2)ispressed\n");

/*顺数倒数切换按钮*/

break;

case0x48:

start=1;

printf("Key(R4,C3)ispressed\n");

/*启动暂停切换*/

break;

case0x88:

flag=1;

if(bt==1)//警报设置赋值

{

bgg=g1*10+g2;

bhh=h1*10+h2;

bmm=m1*10+m2;

bss=s1*10+s2;

gg=0;

hh=0;

mm=0;

ss=0;

}

if(bt==0)//计数设置赋值

{

gg=g1*10+g2;

hh=h1*10+h2;

mm=m1*10+m2;

ss=s1*10+s2;

}

printf("Key(R4,C4)ispressed\n");

/*确定按钮*/

break;

default:

break;

}

if(flag==-1)

{

if(i==1)g1=dt;

if(i==2)g2=dt;

if(i==3)h1=dt;

if(i==4)h2=dt;

if(i==6)m1=dt;

if(i==7)m2=dt;

if(i==8)s1=dt;

if(i==9)s2=

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

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1