功能:
1.按下S6,清零并停止计时
2.按下S5,暂停计时
3.按下S4,开始计时
计时时,LED为流水灯状态,计时显示格式为 分-秒-毫秒
main.c
/*******************************************************************************
* 文件名:main.c
* 描 述:1.按下S6,停止计时并清零
2.按下S5,暂停计时
3.按下S4,开始/继续计时
* 作 者:小默haa
* 版本号:v1.0.0
* 日 期: 2019年1月30日
* 备 注:独立按键控制LED流水灯
*
*******************************************************************************/
#include
#include "sys.h"
u8 sec = 0, min = 0; //分 秒
u16 point = 0; //毫秒
u8 Led_dat; //led显示状态
u8 KeySta[4] = {1,1,1,1}; //当前按键状态
u8 Key_backup[4] = {1,1,1,1}; //按键状态备份,保存前一次的按键值
u8 flag = 0;
void main(void)
{
u8 i;
All_Init();
Time0_Init();
Time1_Init();
Led_dat = 0x7f;
EA = 1;
while(1)
{
for(i = 0;i < 4;i++)
{
if(Key_backup[i] != KeySta[i])
{
if(Key_backup[i] == 0) //说明按键时弹起状态
Key_Drive(i);
Key_backup[i] = KeySta[i];
}
}
Show_Num();
}
}
sys.c
#include "sys.h"
/*******************************************************************************
* 函数名 :All_Init
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月15日
* 功能描述:外设初始化
* 备注 :关闭所有外设
*******************************************************************************/
void All_Init(void)
{
P2 = (P2 & 0x1f) | 0x80; //打开Y4C(LED)
P0 = 0xff; //关闭LED
P2 = (P2 & 0x1f) | 0xe0; //打开Y7C(数码管)
P0 = 0xff; //关闭数码管
P2 = (P2 & 0x1f) | 0xa0; //打开Y5C
P0 = 0x00; //关闭蜂鸣器、继电器
P2 = P2 & 0x1f; //关闭Y4C,Y5C,Y6C,Y7C
}
//定时器0初始化
void Time0_Init(void)
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x9a; //设置定时初值2ms
TH0 = 0xa9; //设置定时初值2ms
TF0 = 0; //清除TF0标志
ET0 = 1; //允许定时器0中断
TR0 = 1; //定时器0开始计时
}
/*******************************************************************************
* 函数名 :Timer0
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月30日
* 功能描述:定时器0中断服务程序
* 备注 :2ms执行一次按键扫描和数码管显示
*******************************************************************************/
void Timer0(void) interrupt 1
{
Key_Scan();
if (flag == 1)
TR1 = 1;
else if (flag == 2)
TR1 = 0;
else if (flag == 3)
{
TR1 = 0;
min = 0;
sec = 0;
point = 0;
}
Nixie_Scan();
}
//定时器1初始化
void Time1_Init(void)
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x9a; //设置定时初值2ms
TH1 = 0xa9; //设置定时初值2ms
TF1 = 0; //清除TF0标志
ET1 = 1; //允许定时器0中断
}
/*******************************************************************************
* 函数名 :Timer1
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月30日
* 功能描述:定时器1中断服务程序
* 备注 :实现计时功能
*******************************************************************************/
void Timer1(void) interrupt 3
{
static u16 t0 = 0;
t0 ++;
if(t0 % 5 == 0) //10ms
{
point ++;
if(point == 100)
{
sec ++;
if(sec == 60)
{
min ++;
if(min == 60)
min = 0;
sec = 0;
}
point = 0;
}
if(t0 == 50) //100ms
{
Led_dat = _crol_(Led_dat, 1);
Led_illume(Led_dat); //点亮LED
t0 = 0;
}
Show_Num();
}
}
sys.h
#ifndef _SYS_H_
#define _SYS_H_
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#include
#include
//全局变量定义
#define FOSC 11059200L //系统时钟
//外部变量
extern u8 sec, min;
extern u8 Led_dat, flag;
extern u8 KeySta[4],Key_backup[4];
extern u16 point;
//sys.c
void All_Init(void);
void Time0_Init(void);
void Time1_Init(void);
//led.c
void Led_illume(u8 dat);
//key.c
sbit s4 = P3^3;
sbit s5 = P3^2;
sbit s6 = P3^1;
sbit s7 = P3^0;
void Key_Scan(void);
void Key_Drive(u8 key);
//drive.c
sbit Relay = P0^4;
sbit Beep = P0^6;
void Drive_ON(void);
void Drive_OFF(void);
//Nixie_tube.c
void Nixie_Scan(void);
void Nixie_Show(void);
void Show_Num(void);
#endif
key.c
#include "sys.h"
/*******************************************************************************
* 函数名 :Key_Scan
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月20日
* 功能描述:独立按键扫描
* 备注 :检测按键状态(按下/松开)
*******************************************************************************/
void Key_Scan(void)
{
u16 i;
static u8 keybuff[] = {0xff,0xff,0xff,0xff};
keybuff[0] = (keybuff[0] << 1) | s4;
keybuff[1] = (keybuff[1] << 1) | s5;
keybuff[2] = (keybuff[2] << 1) | s6;
keybuff[3] = (keybuff[3] << 1) | s7;
for(i = 0;i < 4;i ++)
{
if(keybuff[i] == 0xff) //连续扫描8次都是1,16ms内都是弹起状态,按键已松开
{
KeySta[i] = 1;
}
else if(keybuff[i] == 0x00) //连续扫描8次都是0,16ms内都是按下状态,按键已按下
{
KeySta[i] = 0;
}
else //其他状态键值不稳定,不作处理
{}
}
}
/*******************************************************************************
* 函数名 :Key_Drive
* 输入值 :有活动的按键 key
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月30日
* 功能描述:独立按键驱动
* 备注 :根据独立按键转态,执行相应操作
*******************************************************************************/
void Key_Drive(u8 key)
{
switch(key)
{
case 0: flag = 1; break;
case 1: flag = 2; break;
case 2: flag = 3; break;
// case 3: flag = 3; break;
}
}
led.c
#include "sys.h"
/*******************************************************************************
* 函数名 :Led_illume
* 输入值 :led数据
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月20日
* 功能描述:LED点亮程序
* 备注 :根据传输进来的数据值,点亮相应LED
*******************************************************************************/
void Led_illume(u8 dat)
{
P2 = (P2 & 0x1f) | 0x80; //打开Y4C(LED)
P0 = dat; //关闭LED
P2 = P2 & 0x1f;
}
Nixie_tube.c
/*******************************************************************************
* 文件名:Nixie_tube.c
* 描 述:数码管相关程序
* 作 者:小默haa
* 版本号:v1.0
* 日 期: 2019年1月28日
* 备 注:与数码管相关的所有函数
*
*******************************************************************************/
#include "sys.h"
u8 code Nixie[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共阳数码管码字
u8 NixieBuff[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; //数码管显示缓冲区,初值0xff确保启动时都不亮
u8 code Symbol[] = {0xff,0xbf}; //全灭,-
u8 smg1 = 0, smg2 = 0, smg3 = 0, smg4 = 0, smg5 = 0, smg6 = 0, smg7 = 0, smg8 = 0;
/*******************************************************************************
* 函数名 :Nixie_Scan
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月29日
* 功能描述:数码管扫描函数
* 备注 :根据数码管显示数组,点亮数码管
*******************************************************************************/
void Nixie_Scan(void)
{
static u8 index = 0;
P2 = (P2 & 0x1f) | 0xe0; //数码管消隐
P0 =0xff;
P2 = (P2 & 0x1f) | 0xc0; //数码管片选
P0 = 0x01 << index;
P2 = (P2 & 0x1f) | 0xe0; //数码管段选
P0 = NixieBuff[index];
P2 &= 0x1f;
index ++;
index &= 0x07;
}
/*******************************************************************************
* 函数名 :Nixie_Show
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月29日
* 功能描述:数码管显示函数
* 备注 :根据每一位的数码管需要显示内容,选择相应码子存放进数码管显示数组
*******************************************************************************/
void Nixie_Show(void)
{
NixieBuff[3] = Nixie[smg1];
NixieBuff[2] = Nixie[smg2];
NixieBuff[1] = Symbol[smg3];
NixieBuff[0] = Nixie[smg4];
NixieBuff[7] = Nixie[smg5];
NixieBuff[6] = Symbol[smg6];
NixieBuff[5] = Nixie[smg7];
NixieBuff[4] = Nixie[smg8];
}
/*******************************************************************************
* 函数名 :Show_Num
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月29日
* 功能描述:数值显示处理
* 备注 :将数值每一位分离,存放进每一位数码管显示指示变量smg中
*******************************************************************************/
void Show_Num(void)
{
smg8 = point % 10;
smg7 = point / 10;
smg6 = 1;
smg5 = sec % 10;
smg4 = sec / 10;
smg3 = 1;
smg2 = min % 10;
smg1 = min / 10;
Nixie_Show();
}