LI252547281 发表于 2011-7-4 07:34:57

2051的做定时器,

晚上听收音机睡觉,听着就睡着了,被无台的噪音吵醒,所以做了这个.用89C2051做的.电源取自收音机,关断时,自身电源也全判断, 程序如下:
定时器0用于计时,定时器1用于刷新数码管,按键有4个,一个复位,复位后定时时间为2小时,一个按一下加10分钟,最高可定时99小时,一个按是按一下减10分钟,减到10分钟以下,关断加电源,这2个按键用的是中断0和中断1
最后一个按键,按了就直接关断了.
#include <reg52.h>
#include <absacc.h>

sbit JDQ=P1^7;
sbit key_up=P3^2;
sbit key_down=P3^3;
sbit smg_a=P1^3;
sbit smg_rck=P1^4; //刷新输出
sbit smg_sck=P1^5; //时钟
sbit smg1=P3^7;
sbit smg2=P1^0;
sbit smg3=P1^1;
sbit smg4=P1^2;
sbit stp=P3^4;

unsigned char code smg_s12[] =    //code表示存在ROM中,不占RAM空间
{

   0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79
   //0//1//2//3//4//5   //6//7 //8//9   
};
unsigned char code smg_f34[] =
{
   0x3f,0x30,0x5b,0x79,0x74,0x6d,0x6f,0x38,0x7f,0x7d
   //0//1//2//3//4//5   //6//7 //8//9
};

char time[] =
{
   1,59,59
//0 1 2 3 4         
};

unsigned char time_n=0;
unsigned char i=0;
unsigned char j=0;
unsigned char x=0; //中断扫描数码的位数

void ys_10ms(unsigned char n)
{
   
unsigned char y2 = 250;
   while(n--)
   while(y2--);
}

void smg_xs(char datb) //595传送一个8位数据
{
char ia;

smg_rck=0;
for(ia=0;ia<8;ia++)
{
    smg_sck = 0;
    if(datb&0x80)   smg_a = 1;        //与
        else {smg_a = 0;}
    smg_sck = 1;
    datb<<=1;
    smg_sck = 0;
}

smg_rck = 1;
}


void time0_int(void) interrupt 1 //晶振12M 定时时间50000*1uS=50mS 定时器中断
{
   
    time_n++;
    TH0=(655356 - 50000)/256;
    TL0=(655356 - 50000) & 0xff;
    TF0=0;
    TR0=1;


}

void time1_int(void) interrupt 3 //晶振12M 定时时间2000*1uS=2mS 定时器中断
{

   TH1=(8192 - 1000)/256;
   TL1=(8192 - 1000) & 0xff;
   TF1=0;//清中断标志位
   TR1=1;//开中断
   if ( x == 0)
{smg4 = 0;
j = smg_s12/10]; // 10 hours
smg_xs(j);       //595 -out


smg2 = 1;
}

if ( x == 1)
{smg2 = 0;
j = smg_s12%10] + i; // 1 hours
smg_xs(j);       //595 -out
smg1 = 1;


}

if ( x == 2)
{smg1 = 0;
j = smg_f34/10] + i; // 10 min
smg_xs(j);
smg3 = 1;


}

if ( x == 3)
{smg3 = 0;
j = smg_f34%10]; // 1 min
smg_xs(j);
smg4 = 1;


}

   x++;
if ( x == 4)
{
    x=0;
}


}

void int0_ser() interrupt 0//   按键+子程序   
{
   
   ys_10ms(5);
   if( key_up == 0);
   {   if(time <100 )
      {
         time = time+10;
if ( time > 60)
{
   time = time%10;//

   time = time + 1;
}

}

   }

}

void int1_ser() interrupt 2//按键- 子程序 
{
    //char jw=0;
    ys_10ms(5);
   if( key_down == 0);
   {
       time = time - 10;
       if (time < 0)        //小于0借位
       { //jw = ;
           time = time%10 + 60;
           time--;    //借位操做
           if (time < 0         ) // 借的最高小于0关掉.
           {
           JDQ = 0;
           ys_10ms(250);
           while(1);
              }

          }
   }
// while( key_down == 0);
}

void main(void)
{
   JDQ = 1;
ys_10ms(10);
smg_xs(0x00);
smg_xs(0x00);
smg1 = 0;
smg2 = 0;
smg3 = 0;
smg4 = 0;
stp = 1;
TMOD=0X01;//定时器都处于计晶振的1/12状态,定时器1为13位模式,定时器0为16位模式.

TH0=(655356 - 50000)/256;
TL0=(655356 - 50000) & 0xff;
ET0=1;      //充许定时器0中断
TR0=1;       //开定时器0

TH2=(8192 - 2000)/256;
TL2=(8192 - 2000) & 0xff;
ET1=1;      //充许定时器1中断
TR1=1;          //开定时器1
IT0=1;   //外部中断0下降沿捕捉方式产生中断
IT1=1;   //外部中断1下降沿捕捉方式产生中断
PT0 = 1; //设置定时器0为中断最高级
EX0=1;   //外部中断0 使能
EX1=1;   //外部中断1 使能

EA=1;
while(1)
{
   if(time_n == 19 )
    {
      time_n =0;
      time--;
         if ( time== -1 )
          {time = 59;
             time--;
             if ( time == -1)
            { time =59;
                time--;
                if (time == -1)
                  {JDQ =0;
                     ys_10ms(200);
                     
                                                        }
                        
            }

          }

    }
    if ( time_n >10 )      // 1秒LED闪一下
{
        i = 0;
}
if (time_n <10 )
{
        i = 0x80;
}

if ( stp == 0)
{ ys_10ms(10);
    if ( stp == 0)
    {
    JDQ =0;
    ys_10ms(200);
    while(1);
    }

}

}

}

d3b7 发表于 2011-7-4 13:15:08

这个,比收音机的耗电还多……

LI252547281 发表于 2011-7-4 15:32:29

收音机是变压器+车机+小音箱...前些时候论坛里买的35块的那个

lxa000 发表于 2011-7-4 20:41:06

一片2051就够了
怎么还多用了一个什么芯片??

millwood 发表于 2011-7-4 21:45:09

the timing is too complicated.

try this approach:

1) set up the interrupt every n ticks;
2) in the isr, increment a counter by n ticks;
3) check to see if the counter is more thanyour desired ticks;
4) if not, go back to sleep;
5) other wise, increment time.

this approach allows for much longer delays from any timer.

LI252547281 发表于 2011-7-4 23:26:40

回复 4# lxa000


那个芯片是74HC595做串转并,驱动数码管的.

lxa000 发表于 2011-7-5 19:59:24

本帖最后由 lxa000 于 2011-7-5 20:01 编辑

回复 6# LI252547281


    我给你一点思路做参考:
2051的8位P1口做共阴数码管的段驱动
2051的P3口用四个做位驱动
再用两个P3口分别做+10和 -10
同时按下+10-10后做为直接关闭控制
这时还节余一个P3口
还省掉了595

LI252547281 发表于 2011-7-6 07:44:52

本帖最后由 LI252547281 于 2011-7-6 08:19 编辑

回复 7# lxa000

呵呵,问题是我手上只有共阴的数码管,你说的驱动方式是要共阳的数码管才对,因为2051的P1口是拉电流的,最大20MA..另外多一个按键也并不花什么钱,为什么要用2个按键同时按下(这种小按键不好2个同时按的)的方式来达到关断的目地呢.另外还要一个IO输出控制继电器.

xiaozhuan 发表于 2011-7-6 22:28:05

楼主好厉害、、、

L北斗 发表于 2011-7-7 12:01:38

回复LI252547281


    我给你一点思路做参考:
2051的8位P1口做共阴数码管的段驱动
2051的P3口用四 ...
lxa000 发表于 2011-7-5 19:59 http://www.crystalradio.cn/bbs/images/common/back.gif


    :victory: :victory:

lxa000 发表于 2011-7-7 20:32:07

回复 10# L北斗


    你看懂我的意思了,谢谢

LI252547281 发表于 2011-7-7 23:14:39

回复L北斗


    你看懂我的意思了,谢谢
lxa000 发表于 2011-7-7 20:32 http://www.crystalradio.cn/bbs/images/common/back.gif


    :) 其实我也明白你的意思,用更少的硬件,达到同样的功能.

lxa000 发表于 2011-7-8 00:33:13

回复 12# LI252547281


    OK~~~~~~~~~~
我的经验:
玩单片机玩的是软件
不是硬件

LI252547281 发表于 2011-7-8 11:08:04

回复 13# lxa000


    呵呵.玩当然是一方面,但也要看实际情况...比如,不可能为做一个这样的东西再跑去买一个共阳的数码管...更多的情况是多利用手里现有的东西,软件上就是仁者见仁,智者见智了.

Paktu 发表于 2011-7-8 15:49:20

用STC12C4052单片机吧,AT89C2051的编程还是挺麻烦的,要编程器,STC12只要一个串口线就能写入程序了。
页: [1] 2
查看完整版本: 2051的做定时器,