1.案例要求
利用定时器T0,数码管模块和两个独立按键S4和S5设计一个秒表,具有清零,暂停,启动功能
- 显示格式:XX-XX-XX(分—秒—毫秒)
08-26-18表示:8分26秒900毫秒
- 独立按键S4为暂停/启动
独立按键S5为清零
按键均为按下有效
2.编程思路
本案例我们使用模块化编程的思路,我们需要用到定时器,数码管,独立按键。
(1)、HC138选通
.c文件
#include <REGX52.H>
void Select_HC138(unsigned char channel)//HC138选通函数
{
switch(channel)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
头文件
#ifndef __HC138_H
#define __HC138_H
void Select_HC138(unsigned char channel);
#endif
(2)、延时函数
注意:本文件是在stc-isp软件上生成的
生成一个延时1ms的函数,自己再改写为可以延时任意时长的函数
.c文件
#include <REGX52.H>
void Delay(unsigned char t)
{
unsigned char i, j;
while(t--)
{
i = 15;
j = 90;
do
{
while (--j);
} while (--i);
}
}
头文件
#ifndef __DELAY_H
#define __DELAY_H
void Delay(unsigned char t);
#endif
(3)、数码管
.c文件
#include <REGX52.H>
#include "HC138.h"
extern unsigned char code SMG_duanma[18] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
void SHOW_SMG(unsigned char pos,unsigned char duanma)
{
Select_HC138(6);
switch(pos)
{
case 1:
P0 = 0x01;
break;
case 2:
P0 = 0x02;
break;
case 3:
P0 = 0x04;
break;
case 4:
P0 = 0x08;
break;
case 5:
P0 = 0x10;
break;
case 6:
P0 = 0x20;
break;
case 7:
P0 = 0x40;
break;
case 8:
P0 = 0x80;
break;
}
Select_HC138(7);
switch(duanma)
{
case 0:
P0 = SMG_duanma[0];
break;
case 1:
P0 = SMG_duanma[1];
break;
case 2:
P0 = SMG_duanma[2];
break;
case 3:
P0 = SMG_duanma[3];
break;
case 4:
P0 = SMG_duanma[4];
break;
case 5:
P0 = SMG_duanma[5];
break;
case 6:
P0 = SMG_duanma[6];
break;
case 7:
P0 = SMG_duanma[7];
break;
case 8:
P0 = SMG_duanma[8];
break;
case 9:
P0 = SMG_duanma[9];
break;
case 10:
P0 = SMG_duanma[16];
break;
}
}
头文件
#ifndef __SMG_H
#define __SMG_H
void SHOW_SMG(unsigned char pos,unsigned char duanma);
#endif
(4)、独立按键
.c文件
#include <REGX52.H>
#include "Delay.h"
extern unsigned char KEY_NUM_S4 = 0;
extern unsigned char KEY_NUM_S5 = 0;
void Scan_Key()
{
if(P3_3 == 0)
{
Delay(20);
if(P3_3 == 0)
{
Delay(20);
if(KEY_NUM_S4 == 0)
KEY_NUM_S4 = 1;
else
KEY_NUM_S4 = 0;
while(P3_3 == 0);
}
}
if(P3_2 == 0)
{
Delay(20);
if(P3_2 == 0)
{
Delay(20);
KEY_NUM_S5 = 1;
while(P3_2 == 0);
}
}
}
头文件
#ifndef __KEY_H
#define __KEY_H
extern unsigned char KEY_NUM_S4;
extern unsigned char KEY_NUM_S5;
void Scan_Key();
#endif
(5)、定时器
.c文件
#include <REGX52.H>
#include "KEY.h"
extern unsigned int t_50ms = 0;
extern unsigned int t_s = 0;
extern unsigned int t_min = 0;
void Timer0Init() //50毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xB0; //设置定时初值
TH0 = 0x3C; //设置定时初值
TF0 = 0; //清除TF0标志
ET0 = 1;//使能定时/计数器中断
EA = 1; //打开总中断
if(KEY_NUM_S4 == 1)
{
TR0 = 1;//启动定时器
}
else
{
TR0 = 0;//关闭定时器
}
}
void TM0_Server() interrupt 1
{
t_50ms++;
if(t_50ms == 20)
{
t_s++;
t_50ms = 0;
if(t_s == 60)
{
t_min++;
t_s = 0;
if(t_min == 100)
{
t_min = 0;
}
}
}
}
头文件
#ifndef __TM0_H
#define __TM0_H
extern unsigned int t_50ms;
extern unsigned int t_s;
extern unsigned int t_min;
void Timer0Init();
void TM0_Server();
#endif
(6)、主函数文件
#include <REGX52.H>
#include "HC138.h"
#include "Delay.h"
#include "SMG.h"
#include "KEY.h"
#include "TM0.h"
void main()
{
while(1)
{
Timer0Init();
Scan_Key();
if(KEY_NUM_S5 == 1)
{
t_50ms = 0;
t_s = 0;
t_min = 0;
KEY_NUM_S5 = 0;
KEY_NUM_S4 = 0;
}
SHOW_SMG(8,t_50ms%10);
Delay(1);
SHOW_SMG(7,t_50ms/10);
Delay(1);
SHOW_SMG(6,10);
Delay(1);
SHOW_SMG(5,t_s%10);
Delay(1);
SHOW_SMG(4,t_s/10);
Delay(1);
SHOW_SMG(3,10);
Delay(1);
SHOW_SMG(2,t_min%10);
Delay(1);
SHOW_SMG(1,t_min/10);
Delay(1);
}
}
3.文件管理
代码文件夹放这里了: