定时器中断法扫描数码管及秒表的实现
程序源码
/*-----------------------包含头文件区域-------------------------*/
#include<reg52.h> //单片机头文件
/*-----------------------数据类型定义区域-----------------------*/
typedef unsigned char u8; //定义类型unsigned char别名为u8
typedef unsigned int u16; //定义类型unsigned int别名为u16
/*-----------------------用户自定义数据区域---------------------*/
#define FOSC 11059200L //系统时钟
#define Timer_value (65536-(FOSC/12/1000)*1)//定时器值=(定时器溢出值-(系统时钟/12T模式/1000=定时1ms的定时器值))*定时时间ms)
//共阳数码管显示字符数组,分别对应的字符为“0123456789ABCDEF-”
code u8 LED_Table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xBF,0xFF};
u8 LED_show[8]; //数码管显示的数据数组
u8 second; //秒
/*-----------------------函数声明区域---------------------------*/
void Timer0_Init(void); //定时器0初始化函数声明
void LED_Scan(void); //数码管扫描函数声明
/*-----------------------主函数区域-----------------------------*/
void main()
{
second=0; //初始化设定秒
LED_show[6]=LED_Table[second/10]; //第7个数码管显示秒的十位
LED_show[7]=LED_Table[second%10]; //第8个数码管显示秒的个位
//第1~6个数码管显示0
LED_show[0]=LED_Table[0];
LED_show[1]=LED_Table[0];
LED_show[2]=LED_Table[0];
LED_show[3]=LED_Table[0];
LED_show[4]=LED_Table[0];
LED_show[5]=LED_Table[0];
Timer0_Init(); //定时器初始化
while(1); //死循环,主程序停留在此不再往下执行
}
/*-----------------------定时器0中断函数区域--------------------*/
void Timer0()interrupt 1
{
static u16 count1s;
TH0=Timer_value>>8; //重置定时器值的高8位
TL0=Timer_value; //重置定时器值的低8位
LED_Scan(); //数码管扫描
if(++count1s>=1000) //自增1后判断是否大于等于1000ms
{
count1s=0; //清0重新计数
LED_show[6]=LED_Table[second/10]; //第7个数码管显示秒的十位
LED_show[7]=LED_Table[second%10]; //第8个数码管显示秒的个位
if(++second>99) //自加1如果秒>99
{
second=0;//秒清0
}
}
}
/*----------------------------------------------------------------
函数名称:Timer0_Init()
函数功能:定时器0初始化
函数形参:无
返 回 值:无
----------------------------------------------------------------*/
void Timer0_Init(void)
{
TMOD=0x01; //设置定时器0为模式1(16位计数模式)
TH0=Timer_value>>8; //设定定时器值的高8位
TL0=Timer_value; //设定定时器值的低8位
TR0=1; //定时器0计数器开始计数
ET0=1; //允许定时器0中断
EA=1; //打开总中断
}
/*----------------------------------------------------------------
函数名称:LED_Scan()
函数功能:数码管扫描
函数形参:无
返 回 值:无
----------------------------------------------------------------*/
void LED_Scan(void)
{
static u8 i=0;
P0=0xFF; //显示消影(消影电平跟有效电平相反,如果先使能位选再显示段选数据那么消影就是段选,反则消影位选)
P2=~(0x01<<i); //使能第(i+1)个数码管位选
P0=LED_show[i]; //显示第(i+1)位数码管段选数据
i=(i+1)%8; //显示8个数码管
}