秒表-六位数码管有效显示

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

∙/************************************************************************** ∙* 标题: 秒表-六位数码管有效显示(C51)

∙* 作者: wentao

∙* 日期: 2007.3.3

∙* 软件: Keil C51 V8.02

∙* 芯片: AT89X51

∙* 说明: 实验板实测通过,数码管为8位共阳

∙* 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途!

∙**************************************************************************/∙

∙#include

∙#include

∙#define uchar unsigned char

∙void delay_ms(uchar ms); // 延时毫秒@12M,ms最大值255

∙void key_scan(); // 按键扫描

∙void key_to(); // 按键处理

∙uchar code dis_code[11] = {0xc0,0xf9,0xa4,0xb0,0x99, //段码表

∙// 0 1 2 3 4 对应内容

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

∙// 5 6 7 8 9 -

∙uchar data dis[8]; // dis[0]为百分之一秒值,dis[1]为十分之一秒值

∙// dis[2],dis[5]为'-'段码的偏移量

∙// dis[3]为秒个位值,dis[4]为秒十位值

∙// dis[6]为分个位值,dis[7]为分十位值

∙uchar data dot = 0; // 百分之一秒计数器(0.00s-0.99s)

∙uchar data sec = 0; // 秒计数器(00s-59s)

∙uchar data min = 0; // 分计数器(00m-99m)

∙uchar data dis_b; // dis_b为位码选通数码管

∙uchar data dis_r; // dis_r为取段码时的偏移量

∙uchar data key_t = 0; // 按键次数,初始为0

∙sbit K = P1^4; // K键与P1.4相连

∙void main()

∙ {

∙P2 = 0xff; // 关所有数码管

∙P1 = 0xff; // p1为准双向口,作输入时先写1

∙ dis[2] = 10; // '-'在段码表中偏移量为10

∙ dis[5] = 10; // '-'在段码表中偏移量为10

∙ dis_b = 0x7f; // 初始选通P2.7口数码管

∙ dis_r = 0; // 初始化偏移量为0

∙TMOD = 0x11; // 定时/计数器0,1工作于方式1

∙TH0 = 0xd8; // 预置定时常数55536(d8f0),产生10ms时基信号

∙TL0 = 0xf0;

∙TH1 = 0xfc; // 预置定时常数64536(fc18),产生1ms间隔用于动态显示∙TH1 = 0x18;

∙EA = 1; // 开总中断

∙ET0 = 1; // 定时/计数器0允许中断

∙ET1 = 1; // 定时/计数器1允许中断

∙TR0 = 0; // 关闭定时/计数器0

∙TR1 = 1; // 启动定时/计数器1

∙while(1)

∙ {

∙if(K != 1) // 有键按下

∙ {

∙ delay_ms(10); // 延时10ms去抖

∙if(K != 1) // 确定是有键按下

∙ {

∙while(K != 1); // 等待键松开

∙ key_to(); // 按键处理

∙ }

∙ }

∙ }

∙ }

∙void key_to() // 按键处理子程序

∙ {

∙ key_t++; // 按键次数加1

∙if(key_t == 1) // 第一次按下

∙TR0 = 1; // 启动定时器0

∙else

∙ {

∙if(key_t == 2) // 第二次按下

∙TR0 = 0; // 关闭定时器0

∙else

∙ {

∙if(key_t == 3) // 第三次按下

∙ {

∙ dot = 0; // 三个计数器清零

∙ sec = 0;

∙ min = 0;

∙ key_t = 0; // 按键次数清零

∙ }

∙ }

∙ }

∙ }

∙void tiem0(void) interrupt 1 // T/C0中断服务程序(产生10ms时基信号)

∙ {

∙ dot++; // 百分之一秒计数器加1

∙if(dot == 100) // 计数值到100

∙ {

∙ dot = 0; // 清零

∙ sec++; // 秒计数器加1(进位10ms*100=1s)

∙if(sec == 60) // 秒计数值到60

∙ {

∙ sec = 0; // 秒计数器清零

∙ min++; // 分计数器加1(进位60s=1m)

∙if(min == 100) // 分计数到100

∙ min = 0; // 分计数器清零

∙ }

∙ }

∙TH0 = 0xd8; // 重置定时常数

∙TL0 = 0xf0;

∙ }

∙void time1(void) interrupt 3 // T/C1中断服务程序(延时1ms数码管动态显示) ∙ {

∙ dis[0] = dot % 10; // 百分之一秒计数器个位分离出来赋绐dis[0]

∙ dis[1] = dot / 10; // 百分之一秒计数器十位分离出来赋绐dis[1]

∙ dis[3] = sec % 10; // 秒计数器个位赋绐dis[3]

∙ dis[4] = sec / 10; // 秒计数器十位赋绐dis[4]

∙ dis[6] = min % 10; // 分计数器个位赋绐dis[6]

∙ dis[7] = min / 10; // 分计数器十位赋绐dis[7]

∙P0 = dis_code[dis[dis_r]]; // 段码送P0口(dis[0]...dis[7])

∙P2 = dis_b; // 位码送P2口

∙ dis_r++; // 偏移量加1,下次中断时显示下个数

∙ dis_r &= 0x07; // dis_r增到8时自动清0(使之在0到7间循环) ∙

∙ dis_b = _cror_(dis_b,1); // 位码循环右移,下次中断时选通下个数码管

∙TH1 = 0xfc; // 重置定时常数

∙TL1 = 0x18;

相关文档
最新文档