这个秒表目前可实现:开始计时、停止计时和清零三个功能。这个秒表的设计思路是这样的:首先需要一个8位数码管(因为要显示分、秒、毫秒),用3-8译码器位选。再任选一个8位IO口进行段码传输;按键的控制是使用74HC165芯片对键盘数据读入单片机(并行转串行);主要是使用定时器及其中断,我使用的是Timer0,它配置见程序中的Timer0Init()函数。
单片机源程序如下:
- #include "reg52.h"
- #include "intrins.h"
- typedef unsigned char u8;
- typedef unsigned int u16;
- u8 code smgduan[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
- 0x7c,0x39,0x5e,0x79,0x71}; //共阴
- u8 code clear[8] = {0x3f,0x3f,0x40,0x3f,0x3f,0x40,0x3f,0x3f}; //8位数码管归零
- u8 Digdisplay[8]; //储存分 秒 毫秒
- //全局变量
- u8 ssec, sec, min;
- u16 num;
- //3-8译码器控制引脚
- sbit LSA = P1^0;
- sbit LSB = P1^1;
- sbit LSC = P1^2;
- //74HC165芯片引脚
- sbit SF_LD = P1^3;
- sbit CLK = P1^4;
- sbit IN_data = P1^5;
- /****************************************
- 延时函数,延时大约10μs
- ****************************************/
- void delay(u16 i)
- {
- while(i--);
- }
- /****************************************
- 74HC165芯片读独立按键数据函数
- ****************************************/
- u8 Read74HC165()
- {
- u8 i;
- u8 indata = 0x00;
- SF_LD = 0;
- _nop_();
- SF_LD = 1;
- for(i = 0; i < 8; i++)
- {
- indata = indata << 1;
-
- CLK = 0;
- _nop_(); //低电平一段时间,写入数据
- indata |= IN_data; //写数据
-
- CLK = 1;
- }
- return indata;
- }
- /****************************************
- 秒表控制函数
- 用于秒表的开始、暂停和归零
- ****************************************/
- void KeyPros()
- {
- u8 hc = Read74HC165();
- if(hc == 0xfe) //开始计时
- {
- TR0 = 1;
- }
- else if(hc == 0xfd)
- {
- TR0 = 0;
- }
- else if(hc == 0xfb)
- {
- ssec = 0;
- sec = 0;
- min = 0;
- }
- }
- /****************************************
- 数码管扫描函数(使用3-8译码器)
- ****************************************/
- void DigPros()
- {
- u8 i;
- for(i = 0; i < 8; i++)
- {
- switch(i)
- {
- case 0: LSA = 0; LSB = 0; LSC = 0; break;
- case 1: LSA = 1; LSB = 0; LSC = 0; break;
- case 2: LSA = 0; LSB = 1; LSC = 0; break;
- case 3: LSA = 1; LSB = 1; LSC = 0; break;
- case 4: LSA = 0; LSB = 0; LSC = 1; break;
- case 5: LSA = 1; LSB = 0; LSC = 1; break;
- case 6: LSA = 0; LSB = 1; LSC = 1; break;
- case 7: LSA = 1; LSB = 1; LSC = 1; break;
- }
- P0 = Digdisplay[i]; //发送段码
- delay(100); //隔一段时间扫描
- P0 = 0x00; //防止重影,清空数码管
- }
- }
- /****************************************
- 分、秒、毫秒数据写入全局数组
- ****************************************/
- void DigtalPros()
- {
- Digdisplay[0] = smgduan[min/10];
- Digdisplay[1] = smgduan[min%10];
- Digdisplay[2] = 0x40;
- Digdisplay[3] = smgduan[sec/10];
- Digdisplay[4] = smgduan[sec%10];
- Digdisplay[5] = 0x40;
- Digdisplay[6] = smgduan[ssec/10];
- Digdisplay[7] = smgduan[ssec%10];
- }
- /****************************************
- Timer0定时器配置
- ****************************************/
- void Timer0Init()
- {
- TMOD |= 0x01; //选择定时器T0
- TH0 = 0xd8;
- TL0 = 0xf0; //设定初值55536 计时10ms
- ET0 = 1; //允许T0中断
- EA = 1; //开启总中断
- //TR0 = 1; //开启定时器T0
- // TR0 = 0; //关闭定时器T0
- }
- /****************************************
- 分、秒、毫秒处理函数
- ****************************************/
- void M_SEC_SSEC()
- {
- if(ssec >= 100)
- {
- ssec = 0; //清零
- sec++;
- if(sec >= 60)
- {
- sec = 0; //清零
- min++;
- if(min >= 60)
- {
- min = 0; //清零
- }
- }
- }
- }
- void main(void)
- {
- // GPIO_LED = 1; //初始化LED
- Timer0Init(); //初始化定时器T0
- while(1)
- {
- KeyPros(); //控制秒表函数
- M_SEC_SSEC();
- DigtalPros();
- DigPros(); //扫描数码管
- }
- }
- /****************************************
- Timer0中断处理函数
- ****************************************/
- void Time0() interrupt 1
- {
- TH0 = 0xd8;
- TL0 = 0xf0; //重装载初值
- ssec++; //中断一百次,ssec=100,即1s
- num++;
- }
复制代码
以上程序51hei提供下载:
电子秒表.rar
(25.26 KB, 下载次数: 15)
|