本人是一个新手 对于下边的c程序每一个子函数能看懂,但是像这么多子函数放到一起
就晕了,想请亲们帮我把这个程序的流程梳理梳理中断是何时工作,各个子函数怎么在这个整体里运行 越详细越好,本人十分感谢!
/* 设计的秒表计数到小数点后两位,(ms)用到六个数码管一个小数点加两位小数*/
#include<reg52.h>
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
sbit KEY1=P2^4;
sbit KEY2=P2^5;
sbit KEY3=P2^6;
sbit KEY4=P2^7;
unsigned char code LedChar[] = { //数码管显示字符转换表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF //数码管显示缓存区
};
unsigned char KeySta[4]={1,1,1,1};
bit StopwatchRunning=0;
bit StopwatchRefresh=1;
unsigned char IntegerPart=0;//整数部分
unsigned char DecimalPart=0;//小数部分
void ConfigTimer0(unsigned int ms);
void StopwatchDisplay();
void KeyDriver();
void main()
{
EA=1;
ENLED=0;
ADDR3=1;
P2=0XFE;//P2.0置零选第四行按键
ConfigTimer0(2);//T0定时2ms
while(1)
{
if(StopwatchRefresh) //如果刷新需要调用显示函数
StopwatchRefresh=0;
StopwatchDisplay();
KeyDriver();
}
}
/*配置并启动T0 ms就是T0的定时时间*/
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp;
tmp=11059200/12;// 1/T=f频率
tmp=(tmp*ms)/1000; // ms/1000=1s f*T=机械周期个数
tmp=65536-tmp;
tmp=tmp+18;
T0RH=(unsigned char)(tmp>>8);
T0LH=(unsigned char)tmp;
TMOD&=0xF0;
TMOD|=0x01;
TH0=T0RH;
TL0=T0RL;
ET0=1;
TR0=1;
}
/*秒表计数显示函数*/
void StopwatchDisplay()
{
signed char i;
unsigned char buf[4];//同理数据转换的缓冲区
/*小数部分转换到低2位*/
LedBuf[0]=LedChar[DecimalPart%10];
LedBuf[1]=LedChar[DecimalPart/10];
/*整数部分换到高4位 注意这里和小数部分区别是要用到缓存*/
buf[0]= IntegerPart%10;
buf[0]= IntegerPart/10%10;
buf[0]= IntegerPart/100%10;
buf[0]= IntegerPart/1000%10;
for(i=3;i>=1;i++)//把高位为零的换成空字符
{
if(buf[i]==0)
LedBuf[i+2]=0xFF;//置空
else
break;
}
for(;i>=0;i--)
{
LedBuf[i+2]=LedChar[buf[i]];
}
LedBuf[i+2]=0x7F;//运行到整数的最后一位上顺便点亮小数点
}
/*秒表复位*/
void StopwatchReset()
{
StopwatchRunning=0; //停止秒表
IntegerPart=0;
DecimalPart=0;
StopwatchReset=1//重置刷新标志
}
/*秒表启停函数*/
void StopwatchAction()
{
if(StopwatchRunning)//若是已经启动则停止
StopwatchRunning=0;
else
StopwatchRunning=1;//若是已经停止则启动
}
/*按键驱动函数,检测到有按键动作,调度相应动作函数,只有两个按键另外四个。注意:需要在主函数调用*/
void KeyDriver()
{
unsigned char i;
static unsigned char backup[4]=[1,1,1,1];
for(i=0;i<4;i++)
{
if(backup[i]!=KeySta[i])
{
if(backup[i]!=0)
{
if(i==1)
StopwatchReset();
else if(i==2)
StopwatchAction();
}
backup[i]=KeySta[i];
}
}
}
/*数码管动态扫描刷新函数,注意:需在定时中断中调用*/
void LedScan()
{
static unsigned char i=0;
P0=0XFF;
P1=(P1&0xF8)|i;
P0=LedBUF[i];
if(i<5) //在C里,i>5 i=0 继续走!!!
i++;
else
i=0;
}
void KeyScan()
{
unsigned char i;
static unsigned char keybuff[4]={
0xFF,0xFF,0xFF,0xFF
};
keybuff[0]=(keybuff[0]<<1)| KEY1;
keybuff[1]=(keybuff[1]<<1)| KEY1;
keybuff[2]=(keybuff[2]<<1)| KEY1;
keybuff[3]=(keybuff[3]<<1)| KEY1;
for(i=0;i<4;i++)
{
if(keybuff[i]==0x00)//连续8次扫描为0, 2ms*8(得移动8位上面才能有结果)
{
KeySta[i]=0;
}
else if(keybuff[i]==0xFF)
{
KeySta[i]=1;
}
}
}
/* 秒表计数函数,每隔10ms调用一次进行秒表计数累加 */
void StopwatchCount()
{
if (StopwatchRunning) //当处于运行状态时递增计数值
{
DecimalPart++; //小数部分+1
if (DecimalPart >= 100) //小数部分计到100时进位到整数部分
{
DecimalPart = 0;
IntegerPart++; //整数部分+1
if (IntegerPart >= 10000) //整数部分计到10000时归零
{
IntegerPart = 0;
}
}
StopwatchRefresh = 1; //设置秒表计数刷新标志
}
}
/*T0中断函数,完成数码管扫描、按键扫描与秒表计数*/
void InterruptTimer0() interrupt 1
{
static unsigned char tmr10ms =0;
TH0=T0RH;
TL0=T0RL;
LedScan();
KeyScan();
//定时10ms进行一次秒表计数
tmr10ms++;
if(tmr10ms>=5) //2ms一次 2*5=10ms
{
tmr10ms=0;
StopwatchCount();
}
}