分享一个51单片机做的秒表,有错误 如图:
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机源程序如下:
- #include "reg51.h"
- //******************************************
- //开始定义各个数字的字模
- char code cDISP_NumMod[16] =
- {
- 0x3F,0x06,0x5B,0x4F, 0x66,0x6D,0x7D,0x07,
- 0x7F,0x6F,0x77,0x40, 0x39,0x00,0x79,0x71
- };
- //定义各个数字位的位控制模型
- char code cDISP_BitMode[4] =
- {0xEF,0xDF,0xBF,0x7F};
- //开始定义全局变量
- char vDISP_Index ; //当前在显示哪一位?在中断服务中改变和使用
- char vDISP_SegValue[4]; //当前显示数字对应的字模,该变量在BitNum,Integer,Low,High等函数中进行设置 ,在中断服务程序中进行使用
- //char vDISP_Blink[4]; //控制哪些位需要闪烁。1:闪烁 0:正常显示。 是在SetBlink函数中进行设置,在中断服务中使用。
- //unsigned char vDISP_BlinkCount; //闪烁所需要的计数,0~255。<128时隐藏,>128时显示。是在中断服务程序中改变,每次中断+1。
- //******************************************
- //*******************************************
- //初始化函数,初始化全局变量
- //*******************************************
- void DISP_Init(void)
- {
- TH0 = 0x3C;
- TL0 = 0xBA;
- ET0 = 1;
- EA = 1;
- TR0 = 1;
- vDISP_Index = 0;
- vDISP_SegValue[0] = cDISP_NumMod[0];
- vDISP_SegValue[1] = cDISP_NumMod[0];
- vDISP_SegValue[2] = cDISP_NumMod[0];
- vDISP_SegValue[3] = cDISP_NumMod[0];
- //初始化定时器T0,中断频率位200Hz,初始化相关寄存器
- //初始化全局变量
- }
- //*******************************************
- //设置四位数码管上分别需要显示什么数字
- //D0 数码0上需要显示的数字,取值范围0~F
- //D1 数码0上需要显示的数字,取值范围0~F
- //D2 数码0上需要显示的数字,取值范围0~F
- //D3 数码0上需要显示的数字,取值范围0~F
- //*******************************************
- void DISP_BitNum(char D3,char D2,char D1,char D0,char dp) //分别改变四位
- {
- //根据入口参数D0的值,设定全局变量vDISP_SegValue[3]的值
- //如果D0>0x0F,则不改变当前显示的数字
- //否则使用D0去访问cDISP_NumMod常量,送入vDISP_SegValue[3] D0-> vDISP_SegValue[3]
- if(D0>0x0F)
- {}
- else
- vDISP_SegValue[3] = cDISP_NumMod[D0];
- //根据入口参数D1的值,设定全局变量vDISP_SegValue[2]的值 D1-> vDISP_SegValue[2]
- if(D1>0x0F)
- {}
- else
- vDISP_SegValue[2] = cDISP_NumMod[D1];
- //根据入口参数D2的值,设定全局变量vDISP_SegValue[1]的值 D2-> vDISP_SegValue[1]
- if(D2>0x0F)
- {}
- else
- vDISP_SegValue[1] = cDISP_NumMod[D2];
- //根据入口参数D3的值,设定全局变量vDISP_SegValue[0]的值 D3-> vDISP_SegValue[0]
- if(D3>0x0F)
- {}
- else
- vDISP_SegValue[0] = cDISP_NumMod[D3];
- switch (dp)
- {
- case 0: break;
- case 1: vDISP_SegValue[2] = vDISP_SegValue[2]|0x80;break;
- case 2: vDISP_SegValue[1] = vDISP_SegValue[1]|0x80;break;
- case 3: vDISP_SegValue[0] = vDISP_SegValue[0]|0x80;break;
- }
- }
- //*******************************************
- //设置4位数码管上需要显示的整数,同时设置4位
- //value 需要显示的整数数值,取值范围0~9999
- //*******************************************
- void DISP_Integer(long Value,char dp) // 同时改变四位
- {
- //如果Value<0,就让其等于0。
- //提取Value的千位存入局部变量D0,提取Value的百位存入D1,提取Value的十位存入D2,提取Value的个位存入D3
- //调用BitNum函数。
- char D3, D2, D1, D0;
- if (Value < 0)
- Value = 0;
- if (Value > 9999)
- {
- D0 = Value / 1000000;
- Value %= 1000000;
- D1 = Value / 10000;
- Value %= 10000;
- D2 = Value / 100;
- D3 = Value % 100;
- }
- else
- {
- D0 = Value / 1000;
- Value %= 1000;
- D1 = Value / 100;
- Value %= 100;
- D2 = Value / 10;
- D3 = Value % 10;
- }
- DISP_BitNum(D0, D1, D2, D3,dp);
- }
- //*******************************************
- //定时器
- //*******************************************
- void DISP_T0_ISR(void) interrupt 1
- {
- //给T0重新载入计数初值
- TH0 = 0x3C;
- TL0 = 0xBA;
- //设置段的控制端口
- P3 = cDISP_BitMode[vDISP_Index];
- //输出位的控制端口
- P2 = vDISP_SegValue[vDISP_Index]; //对这句话改变一下就可以实现闪烁
- //改变Index的值,并使其在0~3之间变化。
- vDISP_Index++;
- vDISP_Index &= 3;
-
-
- }
复制代码
错误程序:
秒表.7z
(14.29 MB, 下载次数: 398)
我这个有错误,大家可以参考:http://www.51hei.com/bbs/dpj-187643-1.html
|