📄 基于at89s51秒表设计.txt
字号:
基于AT89S51秒表设计,可精确到0.01S
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
void delay_ms(uint ms); // 延时毫秒@12M,ms最大值255
void key_scan(); // 按键扫描
/*标准LED共阴字形代码*/
uchar code dis_code[10] = {0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
/*位码*/
uchar data dis[4]= {0x80,0x40,0x20,0x10}; // dis[0]为百分之一秒值,dis[1]为十分之一秒值
// dis[2]为秒个位值,dis[3]为秒十位值
uint data sec = 0; // 秒计数器(00s-59s)
uchar data wei = 0;
uchar data dis_b; // dis_b为位码选通数码管
uchar data dis_r; // dis_r为取段码时的偏移量
sbit K3 = P1^7; //清零操作
sbit K2 = P1^6; //暂停操作
sbit K1 = P1^5; //确定操作
sbit sp14=P1^4; //秒的各位加一
sbit sp13=P1^3; //秒的十位加一
sbit bell=P2^0;
void main()
{
P0 = 0x3f;
P2 = 0xff; // 开所有数码管
P1 = 0xff; // p1为准双向口,作输入时先写1
dis_b = 0x80; // 初始选通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(K1 != 1) // 有键按下
{
delay_ms(10); // 延时10ms去抖
if(K1 != 1) // 确定是有键按下
{
TR0 = 1; // 启动定时器0
}
} //////////////////////////
if(K2 != 1) // 有键按下
{
delay_ms(10); // 延时10ms去抖
if(K2 != 1) // 确定是有键按下
{
TR0 = 0; // 关闭定时器0
}
} //////////////////////////
if(K3 != 1) // 有键按下
{
delay_ms(10); // 延时10ms去抖
if(K3 != 1) // 确定是有键按下
{
//dot = 0; // 四个计数器清零
sec = 0;
TR0 = 0; // 关闭定时器0
}
} //////////////////////////
if(sp14!=1) // 有键按下
{
delay_ms(10); // 延时10ms去抖
if(sp14!= 1) // 确定是有键按下
{
while(sp14!= 1); // 等待键松开
sec=sec+100; // 按键处理
}
} //////////////////////////////p14
if(sp13 != 1) // 有键按下
{
delay_ms(10); // 延时10ms去抖
if(sp13 != 1) // 确定是有键按下
{
while(sp13 != 1); // 等待键松开
sec=sec+1000; // 按键处理
if(sec>=10000)
{
sec=sec-10000;
}
}
}
}
}
void tiem0(void) interrupt 1 // T/C0中断服务程序(产生10ms时基信号)
{
sec--; // 百分之一秒计数器加1
if(sec==0)
{
TR0 = 0;
bell = 1;
dis[0]=0;
dis[1]=0;
dis[2]=0;
dis[3]=0;
delay_ms(2000);
}
TH0 = 0xd8; // 重置定时常数
TL0 = 0xf0;
}
void time1(void) interrupt 3 // T/C1中断服务程序(延时1ms数码管动态显示)
{
dis[3]= sec/1000; //提取十位值
dis[2]=(sec%1000)/100; //提取个位值
dis[1]=((sec%1000)%100)/10; //提取十分位值
dis[0]=((sec%1000)%100)%10; //提取百分位值
// 判断位码如果为显示P2.5,P2.3,P2.1则对应段码应加上小数点显示
// 和0x7f(01111111)做与操作使原段码加上小数点变为新段码
// 位码送P2口
P0 = dis_code[dis[dis_r]]; // 段码送P0口
dis_r++; // 偏移量加1,下次中断时显示下个数
if(dis_r==4)
dis_r=0;
dis_b = _cror_(dis_b,1); // 位码循环右移,下次中断时选通下个数码管
if(dis_b==0xef)
dis_b=0xfe;
wei++;
if(wei==1)
{
P2=0x10; }
if(wei==2)
P2=0x20;
if(wei==3)
P2=0x40;
if(wei==4)
{ P2=0x80;
wei=0;
}
TH1 = 0xfc; // 重置定时常数
TL1 = 0x18;
}
void delay_ms(uint ms) // 延时毫秒@12M,ms最大值255
{
uchar i;
while(ms--)
for(i = 0; i < 124; i++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -