标题:
分享自写码表单片机程序(共阴极数码管显示)
[打印本页]
作者:
brew9
时间:
2018-10-9 16:41
标题:
分享自写码表单片机程序(共阴极数码管显示)
/*
晶振频率11.0592MHz
程序修改说明:
第一版程序在开发板上运行时,虽能基本完成功能,但闪烁严重,复位后数组还有异常数据等,应是算法问题,此版寻求解决之道。
问题之一:闪烁严重
将FormatTimeWithMS(TotalMS)语句从定时器中断程序中移出,放到mian中,问题得到解决,与预计的FormatTimeWithMS函数占了太大的时间资源不一致。
但发现出现另一问题:最后(右)一位显示明显偏亮,运行别的程序时,各位显示一致,但亮度与前面所述最后一位一致,说明其实是前7位亮度偏暗。
经调试,发现原因为消影语句放置位置不妥,修改位置后,闪烁问题完全解决。
问题之二:保存数据的数据重置后数据异常
经调试,发现原因为数组设置与读取不正确,修改后正常。
*/
#include <reg52.h>
#include <string.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit seg_sel = P2^6;
sbit bit_sel = P2^7;
sbit start_key = P3^0;
sbit record_key = P3^1;
sbit reload_key = P3^2;
sbit reset_key = P3^3;
//共阴极数码管0-9和"-"编码0x40
unsigned char code seg_table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7,0x7F,0x6F,0x40};
//数码管位码(数组第1位对应数码管最左位)
unsigned char code bit_table[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
#define DATA P0
u8 timer;
//初始化显示数据
u8 TimeFormat[] = {0,0,1,0,0,1,0,0};
//数据记录数组,5组,每组8个数据
u8 ResultArray[5][8];
u8 ResultMax = 5;
u8 i,j,k,z;
unsigned long TotalMS;
u8 minS,minG,secS,secG,msS,msG;
bit IsReload;
void delay(u16 num)
{
u16 m,n;
for(m=num; m>0; m--)
for(n=113; n>0; n--);
}
//此函数将毫秒数转换成需要显示的时间格式(设置数组TimeFormat[])
void FormatTimeWithMS(long tms)
{
minS = (tms/60000)/10;
minG = (tms/60000)%10;
secS = (tms-(minS*10+minG)*60000)/1000/10;
secG = (tms-(minS*10+minG)*60000)/1000%10;
msS = (tms%1000)/100;
msG = (tms%1000)%100/10;
TimeFormat[0] = minS;
TimeFormat[1] = minG;
TimeFormat[3] = secS;
TimeFormat[4] = secG;
TimeFormat[6] = msS;
TimeFormat[7] = msG;
}
void TimeDisplay(void)
{
i = 0;
for (j=0; j<8; j++)
{
//移位
bit_sel = 1;
DATA = bit_table[j];
bit_sel = 0;
//显数
seg_sel = 1;
if ( i==2 | i==5 )
{
DATA = seg_table[10];
}else{
DATA = seg_table[TimeFormat[i]];
if (!IsReload)
{
DATA = seg_table[TimeFormat[i]];
}else{
DATA = seg_table[ResultArray[z][i]];
}
}
i++;
delay(1);
//消影
DATA = 0x00;
seg_sel = 0;
}
}
void StopTimer(void)
{
if(TR0){TR0=0;}
IsReload = 1;
TotalMS = 0;
FormatTimeWithMS(TotalMS);
}
void main(void)
{
DATA = 0x00;
P3 = 0xff;
seg_sel = 0;
bit_sel = 0;
TMOD = 0x01;
//单次溢出时间10ms之初值
TH0 = 0xdc;
TL0 = 0x00;
EA = 1;
ET0 = 1;
TotalMS = 0;
while(1)
{
//计时启停
if (start_key == 0)
{
delay(10);
if (start_key == 0)
{
TR0 = ~TR0;
}
while(!start_key);
}
//记录时间
if (record_key == 0)
{
delay(10);
if (record_key == 0)
{
//小于最大记录时,记录数据;达到最大值时,停止计时器
if (k < ResultMax)
{
ResultArray[k][0] = minS;
ResultArray[k][1] = minG;
ResultArray[k][2] = 1;
ResultArray[k][3] = secS;
ResultArray[k][4] = secG;
ResultArray[k][5] = 1;
ResultArray[k][6] = msS;
ResultArray[k][7] = msG;
k++;
if (k==ResultMax) if(TR0){TR0=0;}
}
}
while(!record_key);
}
//回显被记录的时间
if (reload_key == 0)
{
delay(10);
if (reload_key == 0)
{
//如果不是回显数据,那么z=0(此处加判断的意义是首次点击回显键时,数据从第一组开始显示)
if(!IsReload)
{
z = 0;
}else{
z++;
if( z > (ResultMax-1)){z=0;}
}
StopTimer();
}
while(!reload_key);
}
//重置(计时器停止,总显示时间清0,时间记录数组清0,回显数据状态置0)
if (reset_key == 0)
{
delay(10);
if (reset_key == 0)
{
StopTimer();
memset(ResultArray,0,sizeof(ResultArray));
IsReload = 0;
}
while(!reset_key);
}
//显示时间
FormatTimeWithMS(TotalMS);
TimeDisplay();
}
}
void timer0_service(void) interrupt 1
{
TH0 = 0xdc;
TL0 = 0x00;
//因为是每10ms溢出一次,故总时间累加10ms。
TotalMS = TotalMS+10;
}
复制代码
作者:
admin
时间:
2018-10-10 19:21
补全原理图或者详细说明一下电路连接即可获得100+黑币
作者:
brew9
时间:
2018-11-20 15:36
admin 发表于 2018-10-10 19:21
补全原理图或者详细说明一下电路连接即可获得100+黑币
stopwatch.rar
(20.15 KB, 下载次数: 10)
2018-11-20 15:35 上传
点击文件名下载附件
原理图和hex文件
下载积分: 黑币 -5
谢谢管理!
作者:
brew9
时间:
2018-11-20 15:37
stopwatch.rar
(20.15 KB, 下载次数: 7)
2018-11-20 15:37 上传
点击文件名下载附件
下载积分: 黑币 -5
附上原理图及hex文件,方便各位测试。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1