Stopwatch数码管显示-实用秒表

来源:本站
导读:目前正在解读《Stopwatch数码管显示-实用秒表》的相关信息,《Stopwatch数码管显示-实用秒表》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《Stopwatch数码管显示-实用秒表》的详细说明。
简介:单片机开源项目之Stopwatch数码管显示-实用秒表此程序是在51hei单片机开发板上面做的,如需要移植到自己的电路上,修改相应的端口即可。

/**

****************************************************************************************

*file : main.c

*author : xr

*date : 2014年4月15日10:08:26- 2014年4月15日12:40:51

*version: V1.2.3

*brief : Stopwatch数码管显示-实用秒表 单片机STC89C52RC MCU 晶振 11.0592MHZ

****************************************************************************************

*/

#include

//74HC138

sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;

//矩阵按键

sbit KEY_IN_1 = P2^4;//列

sbit KEY_IN_2 = P2^5;

sbit KEY_IN_3 = P2^6;

sbit KEY_IN_4 = P2^7;

//数码管编码

unsigned char code LedTable[] = {

0xC0, //"0"

0xF9, //"1"

0xA4, //"2"

0xB0, //"3"

0x99, //"4"

0x92, //"5"

0x82, //"6"

0xF8, //"7"

0x80, //"8"

0x90, //"9"

0x88, //"A"

0x83, //"B"

0xC6, //"C"

0xA1, //"D"

0x86, //"E"

0x8E //"F"

};

//数码管显示缓冲区

unsigned char LedBuff[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

bit flag10ms = 0;//10ms标志位

bit stopwatchRunning = 0;//秒表启动和停止标志

unsigned char thr0, tlr0;//T0重载值的高低字节

unsigned char decimal = 0;//小数位

unsigned int integer = 0;//整数位

static unsigned char volatile KeySta[4] = {1, 1, 1, 1}; //保存按键的当前值(static 保存在静态存储区,加上volatile关键字使KeySta[i]的值每次都从静态存储区读取,避免读取错误!)

/****************function definition**********************/

void Initial();

void ConfigTimer0(unsigned long xms);

void StopwatchDisplay();

void KeyAction();

/*主程序main()*/

void main(void)

{

Initial();

ConfigTimer0(1);//定时1ms

while (1)

{

KeyAction(); //检测按键动作

if (flag10ms) //10ms检测秒表的运行状态,当stopwatchRunning标志=1时进行计时++,否则就停止计时

{

flag10ms = 0;

if (stopwatchRunning) //10ms刷新秒表计数

{

decimal++;

if (decimal >= 100)

{

decimal = 0;

integer++;

if (integer >= 10000)

{

integer = 0;

}

}

StopwatchDisplay();//分解decimal和integer,存入LedBuff数码管缓冲区

}

}

}

}

/*程序初始化*/

void Initial()

{

ADDR3 = 1;

ENLED = 0;//选择数码管

P2 = 0xFE;//选择第四行按键检测(原理图上是第四列)

P0 = 0xFF;//默认关闭段选

LedBuff[0] = LedTable[decimal % 10]; //初始显示0.00

LedBuff[1] = LedTable[decimal / 10 % 10];

LedBuff[2] = LedTable[integer % 10];

LedBuff[2] &= 0x7F;//点亮小数点

}

/*配置定时器T0*/

void ConfigTimer0(unsigned long xms)

{

unsigned long tmp;//32bit 注意:此处必须用unsigned long 数据,因为11059200已经超出了16位unsigned int

tmp = 11059200/12;//单片机的机器周期频率

tmp = (tmp * xms) / 1000;//定时xms所需的频率

tmp = 65536-tmp;//定时xms的初始装载值

tmp += 18;//补偿值

thr0 = (unsigned char)(tmp >> 8);

tlr0 = (unsigned char)tmp;

TMOD &= 0xF0;//清零T0控制位

TMOD |= 0x01;//配置T0工作在方式1,16位可设定定时器

TH0 = thr0;

TL0 = tlr0;

TR0 = 1;

ET0 = 1;

EA = 1;

}

/*数码管刷新*/

void LedCharRefresh()

{

static unsigned char j = 0;

P0 = 0xFF;//消隐

P1 = (P1 & 0xF8) | j;//先清零P1口低三位,再|j

P0 = LedBuff[j++];

if (j > 5)

j = 0;

}

/*分解decimal和integer,存入LedBuff数码管缓冲区*/

void StopwatchDisplay()

{

signed char i = 0;

unsigned char buf[6];

buf[0] = decimal % 10;

buf[1] = decimal / 10 % 10;

buf[2] = integer % 10;

buf[3] = integer / 10 % 10;

buf[4] = integer / 100 % 10;

buf[5] = integer / 1000 % 10;

for (i = 5; i >= 3; i--) //去掉无效位

{

if (buf[i] == 0)

buf[i] = 0xFF;

else

break;

}

//处理有效位

for (; i >=0; i--)

{

buf[i] = LedTable[buf[i]]; //转为实际的数字

}

//拷贝

for (i = 0; i <= 5; i++)

{

LedBuff[i] = buf[i];//拷贝到显示缓冲区

}

LedBuff[2] &= 0x7F;//点亮小数点

}

/*秒表启动和停止*/

void StopwatchAction()

{

if (stopwatchRunning) //当前状态为运行

{

stopwatchRunning = 0; //停止运行

}

else

{

stopwatchRunning = 1; //启动

}

}

/*秒表复位*/

void StopwatchReset()

{

stopwatchRunning = 0;//停止秒表计时

decimal = 0;

integer = 0;//清零

StopwatchDisplay();//显示

}

/*按键动作*/

void KeyAction()

{

static unsigned char keybackup[4] = {1, 1, 1, 1};//按键的备份值(前一次按键值) 必须是静态的

unsigned char i = 0;

for (i = 0; i < 4; i++)

{

if (keybackup[i] != KeySta[i]) //按键的上一次的状态和当前状态不相同,即按键有动作

{

if (keybackup[i] != 0) //如果上一次按键的值是1,则此时按键是按下动作

{

switch (i)

{

case 1: StopwatchReset(); break; //ESC键秒表复位

case 2: StopwatchAction(); break;//Enter键控制秒表的启动和停止

default: break;

}

}

keybackup[i] = KeySta[i];//备份当前按键值

}

}

}

/*按键扫描函数*/

void KeyScan()

{

static unsigned char KeyBuf[4] = {0xFF, 0xFF, 0xFF, 0xFF}; //按键扫描缓冲区

unsigned char i = 0;

//检测一行按键的状态并存入按键检测缓冲区中

KeyBuf[0] = (KeyBuf[0] << 1) | KEY_IN_1;

KeyBuf[1] = (KeyBuf[1] << 1) | KEY_IN_2;

KeyBuf[2] = (KeyBuf[2] << 1) | KEY_IN_3;

KeyBuf[3] = (KeyBuf[3] << 1) | KEY_IN_4;

//更新消抖后按键的值(1ms检测一次,8ms检测)

for (i = 0; i < 4; i++)

{

if ((KeyBuf[i] & 0xFF) == 0x00)

KeySta[i] = 0;//8次检测按键状态都是0,即按键稳定按下

else if ((KeyBuf[i] & 0xFF) == 0xFF)

KeySta[i] = 1;//8次检测按键的状态都是1,即按键稳定弹起

}

}

/*定时器Timer0中断服务*/

void Timer0_ISP() interrupt 1

{

static unsigned char counter = 0;//计数器

TH0 = thr0;

TL0 = tlr0;//重新装载定时器初值

counter++;

LedCharRefresh();//数码管刷新

KeyScan(); //按键扫描

if (counter >= 10)

{

counter = 0;

flag10ms = 1;

}

}

提醒:《Stopwatch数码管显示-实用秒表》最后刷新时间 2024-03-14 01:09:35,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《Stopwatch数码管显示-实用秒表》该内容的真实性请自行鉴别。