原创 可预置的倒计时

2008-5-8 09:27 2417 5 5 分类: MCU/ 嵌入式


带键盘设置的秒计时器
;功能:倒计时的秒计时器,从59倒计到0,然后又从59开始倒计到0;
;各个键的功能
;S1:开始运行
;S2:停止运行
;S3:高位加1,按一次,数码管的十位加1,从0-5循环变化
;S4:低位加1,按一次,数码管的个位加1,从0-9循环变化
;本例可用ledkey.dll实验仿真板验证
;如使用DSB-1A型实验板,将提供相应的程序
**************************************************/
#include "reg51.h"
#define uchar unsigned char
#define uint  unsigned int


#define Hidden 0x10; //消隐字符在字形码表中的位置
uchar code BitTab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};
uchar DispBuf[8]; //6字节的显示缓冲区
bit Sec;   //1s到的标记
uchar SecVal;  //秒计数值
bit KeyOk;
bit StartRun;
uchar SetSecVal; //秒的预置值


uchar code TH0Val=63266/256;
uchar code TL0Val=63266%256;//当晶振为11.0592时,定时2.5ms的定时器初值
//经过精确调整,在值为63266时,定时时间为1.00043362s


void Timer0() interrupt 1
{ uchar tmp;
 static uchar dCount; //计数器,显示程序通过它得知现正显示哪个数码管
 static uint Count;  //秒计数器
 const uint CountNum="100"; //预置值(正确值为400)
 TH0=TH0Val;
 TL0=TL0Val; 
 tmp=BitTab[dCount];  //根据当前的计数值取位值
 P2=P2|0xff;    //P2与11111100B相或,将高6位置1
 P2=P2&tmp;    //P2与取出的位值相与,将某一位清零
 tmp=DispBuf[dCount]; //根据当前的计数值取显示缓冲待显示值 
 tmp=DispTab[tmp];  //取字形码
 P0=tmp;     //送出字形码
 dCount++;    //计数值加1
 if(dCount==8)   //如果计数值等于6,则让其回0
  dCount=0; 
//以下是秒计数的程序行
 Count++;    //计数器加1
 if(Count>=CountNum)  //到达预计数值
 { Count=0;   //清零 
  if(StartRun)  //要求运行
  { if((SecVal--)==0)
    SecVal=SetSecVal; //减到0后重置初值
  }
 }
}
/*延时程序
  由Delay参数确定延迟时间
*/
void mDelay(unsigned int Delay) 
{ unsigned int i;
 for(;Delay>0;Delay--)
 { for(i=0;i<124;i++)
  {;}
 }
}


void KeyProc(uchar KValue) //键值处理
{ if((KValue&0x10)==0) //Start
  StartRun=1;
 if((KValue&0x20)==0) //Stop
  StartRun=0;
 if((KValue&0x40)==0)
 { StartRun=0;   //停止运行
  DispBuf[6]++;
  if(DispBuf[6]>=6) //次高位由0加到5
   DispBuf[6]=0; 
  SetSecVal=DispBuf[6]*10+DispBuf[7]; //计算出设置值
  SecVal=SetSecVal;
 }
 if((KValue&0x80)==0)
 { StartRun=0;   //停止运行
  DispBuf[7]++;
  if(DispBuf[7]>=10) //末位由0加到9
   DispBuf[7]=0; 
  SetSecVal=DispBuf[6]*10+DispBuf[7]; //计算出设置值
  SecVal=SetSecVal;
 }
}
uchar Key()
{ uchar KValue;
 uchar tmp;
 P1|=0xf0;   //将P3口的接键盘的中间四位置1
 KValue=P1;
 KValue|=0x0f;  //将未接键的4位置1
 if(KValue==0xff) //中间4位均为1,无键按下 
  return(0);  //返回
 mDelay(10);  //延时10ms,去键抖
 KValue=P1;
 KValue|=0x0f;  //将未接键的4位置1
 if(KValue==0xff) //中间4位均为1,无键按下 
  return(0);  //返回
//如尚未返回,说明一定有1或更多位被按下
 for(;;)
 { tmp=P1;  
  if((tmp|0x0f)==0xff)
   break;  //等待按键释放
 }
 return(KValue);
}
void Init()
{ TMOD=0x01;
 TH0=TH0Val;
 TL0=TL0Val; 
 ET0=1;    //开T0中断
 EA=1;    //开总中断
 TR0=1;    //T0开始运行
}
void main()
{ uchar KeyVal;
 uchar i;
 Init();     //初始化
 for(i=0;i<=6;i++)
  DispBuf=Hidden; //显示器前四位消隐
 DispBuf[6]=SecVal/10;
 DispBuf[7]=SecVal%10;
 for(;;)
 { KeyVal=Key();
  if(KeyVal)
   KeyProc(KeyVal);
  DispBuf[6]=SecVal/10;
  DispBuf[7]=SecVal%10;
 }
}

文章评论0条评论)

登录后参与讨论
我要评论
0
5
关闭 站长推荐上一条 /2 下一条