单片机-篮球比赛计分器 - 图文 下载本文

单片机课程设计

电路,节省资源[6]。

AT89C2051内部资源主要有:2k字节Flash闪速存储器,128字节内部RAM,15个I/O口线(其中P1是一个完整的8位双向I/O口),两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口(可编程串行UART通道),精密模拟比较器,片内振荡器以及时钟电路。

AT89C2051引脚如图3.2所示。

RST/VPP (RXD)P3.0 (TXD)P3.1 XTAL2 XTAL1 (INT0)P3.2 (INT1)P3.3 (T0)P3.4 (T1)P3.5 GND 1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11 VCC P1.7 P1.6 P1.5 P1.4 P1.3 P1.2

P1.1(AIN1) P1.0(AIN0) P3.7

图3.2 AT89C2051引脚图

AT89C2051I/O口功能说明:

1.P0口:P0口是一组8位漏极开路型双向I/O口,也即地址/数据总线复用口。作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。

2.P1口:P1口是一组8位双向I/0口,P1.2~P1.7提供内部上拉电阻,由于P1.0和P1.1是内部精密比较器的同相输入端(AIN0)和反相输入端(AIN1),所以内部无上拉电阻,如果需要作为通用I/O口,应在外部接上拉电阻。Pl口输出缓冲器可灌入20mA电流并可直接驱动LED。当P1口引脚写入“1”时可作输入端,当引脚P1.2~P1.7用作输入并被外部拉低时,它们因内部上拉电阻的作用而输出电流(IIL)。

3.P3口:P3口的P3.0~P3.5、P3.7是带有内部上拉电阻的7个双向I/O口。P3.6没有引出管脚,它作为一个通用I/O口但不可访问,可作为片内比较器的输出信号,P3口缓冲器可吸收20mA电流。当P3口写入“1”时,它们被内部上拉电

5

单片机课程设计

阻拉高并可作为输入端口。作输入端时,被外部拉低的P3口由于上拉电阻的存在而输出电流(IIL)。

P3口还可以用于特殊的功能,如下表所示。

表3-1 P3口引脚功能

引脚 P3.0 P3.1 P3.2 P3.3 P3.4 P3.5

功能特性 RXD(串行输入口) TXD(串行输出口) INT0(外中断0) INT1(外中断1) T0(定时器/计数器0外部输入) T1(定时器/计数器1外部输入) ________4.ALE/:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲可用于锁存地址的低八位字节。即使不访问外部存储器,ALE仍以时钟振荡频率的1/6输出固定的正脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个ALE脉冲。对Flash存储器编程期间,该引脚还用于输入编程脉冲。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。该位置置位后,只有一条MOVX和MOVC指令ALE才会被激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE无效。

5. EA/VPP:外部访问允许。欲使CPU仅访问外部数据存储器(地址为0000H—FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编成,复位时内部会锁存EA端状态。如EA端为高电平(接Vcc端),CPU则执行内部程序存储器中的指令。Flash存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件使用12V编程电压Vpp。

6.XTAL1:振荡器反相放大器及内部时钟发生器的输入端。 7.XTAL2:振荡器反相放大器的输出端。

6

单片机课程设计

开始计时

图3.2 主程序流程图

加减分处理 开始/暂停 按钮按下? 停止计时 TR0位取反 开始/暂停 按钮按下? 显示时间和比分 TR0=0

7

单片机课程设计

2.4 主程序代码设计

根据流程图,设计主程序代码如下: #include #define uchar unsigned char

#define uint unsigned int 初始化 sbit P10=P1^0; 按键k1 sbit P11=P1^1; 按键k2 sbit P12=P1^2; 按键k3 sbit P13=P1^3; 按键k4

uchar code tab[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}; void main() { uchar k1=0;

while(1)

{ if(P10 == 0)

{ k1 += 1; 分数加1

while(P10 == 0);}

if(P11 == 0)

{ k1 += 2; 分数加2

while(P11 == 0);}

if(P12 == 0)

{ k1 += 3; 分数加3

while(P12 == 0);}

if(P13 == 0)

{ k1 -= 1; 分数减1

while(P13 == 0);}

if(k1 > 1000) 分数大于999,归0

k1 = 0;

百位

8

P0 = tab[S1/100];