原创 定时器程序

2009-9-23 10:37 2007 3 3 分类: MCU/ 嵌入式
 



#include <REGX52.H>     //AT89S52头文件
#define uint unsigned int
#define uchar unsigned char


uchar code dispcode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,   //共阳数码管字库
      0x80,0x90,0xFF};  
//变量定义                        
uchar timecount,Hour,Minute,Second,T_Min,T_Sec,qian,bai,shi,ge,
   biao,keytemp,disH,disL,THour,TMinute;


bit biaoA,biaoB;


/*硬件端口定义*/


sbit led0=P1^0;    //**数码管位选
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;


sbit LED="P3"^2;   //倒计时 指示灯


    
sbit K0=P2^0;   //**按键接口
sbit K1=P2^1;
sbit K2=P2^2;
sbit K3=P2^3;



//子程序声明
void display();   //显示处理子程序
void key();    //按键检测处理子程序
void LED_out();   //数码管显示子程序
uchar UpDown(char dd,uchar max,uchar min); //加减按键子程序
void DaoTime(void); //倒计时处理


void delay(uchar i)    /***延时1ms***/
{ uint x;
for(;i>0;i--)
   for(x=114;x>0;x--);   //11.0592=114
}


void initTimer(void)   //定时/计数器初始化
{
TMOD=0x1;
TH0=0x20;
TL0=0x35;
}


void main(void)    //主程序
{
initTimer();
TR0=1;
ET0=1;
EA=1;
Hour=12;
Minute=34;
while(1)
{
key();
display();
}
}



/***T1***中***断***函***数***/
void timer0(void) interrupt 1 using 3    //T2中断,使用寄存器组3
{
TH0=0x20;
TL0=0x35;
timecount++;     //timecount变量加1, timecount加到16为1秒
if((timecount%8)==0)
biaoA=~biaoA;
if(timecount==16)    //如果1秒时间到?
{timecount=0;    // timecount清零
Second++;     //秒加1
if(biaoB==0)DaoTime();    
if(Second==60)    //如果1分时间到?
   {Second=0;    //秒清零
   Minute++;     //分加1
   if(Minute==60)   //如果1小时时间到?
    {Minute=0;   //分清零
    Hour++;    //小时加1
    if(Hour==24) //如果1天时间到?
     Hour="0";   //小时清零
    }
   }
}
switch (biao)
{
case 0: disH="Hour";disL=Minute;   //显示时,分
   break;
case 1: disH="T"_Min;disL=T_Sec;   //显示倒计时时间
   break;
}


       
}
/***显***示***函***数***/
void display()
{
if(disH==100)   //如果显示缓冲高位等于100
   {qian=10;bai=10;shi=disL/10;ge=B;}         //数码管千位,百位不显示
else      //如果显示缓冲高位不为100
   {if(disL==100) //如果显示缓冲低位等于100
    {qian=disH/10;bai=B;shi=10;ge=10;}     //数码管十位,个位不显示
   else    //如果显示缓冲低位不为100
    {qian=disH/10;bai=B;shi=disL/10;ge=B;} //数码管千位,百位,十位,个位同时显示
   }
if(biao>3|biaoB)
   if(timecount>8)
    {
    switch (keytemp)
     {
     case 0: {qian=10;bai=10;}
      break;
     case 1: {shi=10;ge=10;}
       break;
     case 2: {qian=10;bai=10;}
      break;
     }
    }


LED_out();
}
/**显示缓冲送数码管显示**/
void LED_out()
{
if(qian){       //千位处理
P0=dispcode[qian];
led0=0;delay(2);led0=1;}
/*
if(biaoA&&(biao<2))    //百位处理
P0=dispcode[bai]&0x7f;
else   */
P0=dispcode[bai];   
led1=0;delay(2);led1=1;


if(biaoA&&(biao<2))   //十位处理
P0=dispcode[shi]&0x7f;
else   
P0=dispcode[shi];   
led2=0;delay(2);led2=1;

if(biaoA&&(biao<2)) //个位处理
P0=dispcode[ge]&0x7f;
else   
P0=dispcode[ge];
led3=0;delay(2);led3=1;
}
/****按键检测****/
void key()
{ uchar temp;
if(K3==0)      
{delay(5);if(K3==0)
   {while(!K3)
    {display();
    temp++;
    if(temp==125)
     {if(biao==0)
      {biao=4;THour=Hour;TMinute=Minute;keytemp=0;break;} //进入设定时间
     else
      {temp=0;break;}
     }
    }


   if((temp!=125)&&(biao==4))    //选择设定(时,分)
    {keytemp++;
    if(keytemp==2)
    keytemp="0";
    }
   else
    {if(biao<2)    //切换显示(实时时间,倒计时间)
     {
     biao++;
     if(biao==2)
      {
      biao="0";
      keytemp="0";
      biaoB="0";
      }
     }
    }
   while(!K3)display();
   }
   temp="0";
}
switch (biao)
{
case 1: {if(K2==0){delay(5);if(K2==0)     //进入设定倒计时间
     {keytemp++;biaoB=1;LED=1;
      if(keytemp==3)
      {keytemp=0;biaoB=0;if((T_Min||T_Sec)!=0)LED=0;}    //倒计启动点亮LED
     }
     while(!K2)display();
    }
    if(biaoB)
     {
     if(keytemp==2){T_Min=UpDown(T_Min,90,0);} //设定倒计时小时
     if(keytemp==1){T_Sec=UpDown(T_Sec,59,0);} //设定倒计时分钟
     }
    }
   break;
  
case 4:{if(keytemp==0){THour=UpDown(THour,23,0);disH=THour;disL=TMinute;display();} //设定当前时间小时
    if(keytemp==1){TMinute=UpDown(TMinute,59,0);disH=THour;disL=TMinute;display();} //设定当前时间分钟
    if(K2==0){delay(5);if(K2==0)   //保存数据并退出
      {TR0=0;Second=0;timecount=0;Hour=THour;
      Minute="TMinute";TR0=1;biao=0;
      while(!K2)display();}}}
   break;
}
}
/*加减按键子程序*/
uchar UpDown(char dd,uchar max,uchar min)
{uint x="35";       //定义连续调整的间隔延时
if(K1==0){delay(5);if(K1==0){ //K1按下参数dd加一
dd++;
if(dd>max) dd="min";    //如果参数dd大于上限值dd返回最小值
while(--x){display();if(K1)break;} //循环显示一段时间参数继续加一   
}}
if(K0==0){delay(5);if(K0==0){ //K0按下参数dd减一
dd--;
if(dd<min)dd=max;    //如果参数dd小于下限值dd返回最大值
while(--x){display();if(K0)break;} //循环显示一段时间参数继续减一   
}}
return dd;
}
/*倒计时处理*/
void DaoTime(void)
{
if(T_Min||T_Sec)
{
if(T_Sec)
   T_Sec--;   //秒倒计
else
   if(T_Min)
    {T_Min--;T_Sec=59;} //分倒计


if((T_Min||T_Sec)==0)LED=1; // 倒计时 时间到关闭LED
}
}



 
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条