微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 用这个程序做电子闹钟,板上的LED灯闪的时间不是一秒钟亮暗一次,但不知道问题出现在哪里

用这个程序做电子闹钟,板上的LED灯闪的时间不是一秒钟亮暗一次,但不知道问题出现在哪里

时间:10-02 整理:3721RD 点击:
#include<reg2051.h>
#define uint  unsigned int
#define uchar unsigned char       
uchar bdata m_key,key;//定义键沿有效寄存器和电平有效寄存器(bdata是可位寻址片内RAM)
sbit wx1=P3^0;//位选
sbit wx2=P3^1;
sbit wx3=P3^2;
sbit wx4=P3^3;
sbit k1=m_key^0;
sbit k2=m_key^1;
sbit k3=m_key^2;
sbit k4=m_key^3;//按键键沿标志
sbit buz=P3^7;
bit  shan;//闪烁标志位
sbit s=P1^7;//秒控制位
bit  nao; //闹钟标志
uchar code sm_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83};
uchar code sszymmh[]={        6,2,3,      5,2,1,      3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,
                                      6,2,4,      3,2,2,      5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,
                                      6,1,1,      5,2,1,      3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,
                                      5,2,1,      6,2,1,      3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,
                                      2,2,1,      1,2,1,      6,1,1, 1,2,1, 5,1,6, 0,0,0
                                      };//世上只有妈妈好
                         // 音节频率 高八位
uchar  code FREQH[]={    0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,
                                0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i
                                0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
                                0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
                               } ;
                         // 音节频率 低八位
uchar code FREQL[]={     0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
                         0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
                         0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,
                         0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
                                };
uchar k,i,sm_sz,mkcnt,tz,scnt,shancnt,s_cnt,timer0h,timer0l,time,ncnt,sz0,sz1,sz2,sz3,sz4;
uchar xs,fz;//小时和分钟变量
uchar nxs,nfz;//闹钟小时和分钟变量
void init();//闪烁
void pdnz(void); //判断闹钟
void sjtz(void); //调整时钟
void nzsj(void); //闹钟设置
void nzx(void);         //闹钟歌曲
void disp(); //数显
void MKYscan(void);         //按键扫描
void main()
{
  init();
  while(1)
        {         
                while(!TF0); //判断5ms是否到了?
                TF0=0;
                TH0=0XEC;//初始化赋值5mS
                TL0=0X78;
                MKYscan();
                disp();
                scnt++;
                if(scnt>=100)
                  {
                    s=~s;//秒控制位取反          ,500ms一次
                        scnt=0;
                        s_cnt++; //秒计数
                  }  
                  if(s_cnt>=120)         //120*500=60000为60秒,分钟加一
                  {
                    s_cnt=0;
                    fz++;
                  
                    if(fz>=60)
                     {
                           fz=0;
                           xs++;
                          
                           if(xs>=24)
                              xs=0;
                          }
                   }
                    sz0=fz%10;
                    sz1=fz/10;
                        sz2=xs%10;
                        sz3=xs/10;
                if(k1)
                  {
                  tz++;
                  if(tz>=3)
                  tz=0;
                  }
        switch(tz)          //散转
                {
                 case 0:pdnz();break;//闹钟判断
                 case 1:sjtz();break;//时间调整
                 case 2:nzsj();break; //闹钟时间设定
                 case 3:nzx(); break;  //闹钟响
                 default:break;
                }
         }
}
void MKYscan(void)//矩阵键盘扫描
{
   uchar r1,r2,zs;
   zs=P3;
   P3=0xff;
   P3=0xdf;//扫键
   r1=P3;
   P3=0xff;
   r1=r1^0xff;
   r1>>=1;
   if(r1)//有键?
   {
            mkcnt++;
         if(mkcnt>=4)//20ms
          {
                  mkcnt=0;
                m_key=r1;
          }
          else
             m_key=key;
    }
   else
   {
    m_key=0;
    mkcnt=0;
   }
   r2=m_key;
   m_key=m_key&(key^m_key);//沿提取
   key=r2;
   P3=zs|0x0f;
}

void init()
{
TMOD=0x11;//中断定时/计数
TH0=0XEC; //定时5ms
TL0=0X78;
EA=1;
TR0=1;                                 
TF0=0;
i=0;
s=0;
mkcnt=0;
key=0;
shancnt=0;//数码管闪烁计数
tz=0;
shan=0;
s_cnt=0;
nao=0;
}
void sjtz(void)
{
   shancnt++;
   if(shancnt>=100)
      {shan=~shan;shancnt=0;}         //500取反
   //s=1;
   if(k2)
    {
        xs++;
        if(xs>=24)
          xs=0;
        }
   if(k3)
    {
        fz++;
        if(fz>=60)
        fz=0;
        }
}
void disp()//扫描数码管
   {   if(!shan)
       {
                wx1=1;//位选关
                wx2=1;
                wx3=1;
                wx4=1;               
                sm_sz++;        //数码散转
                if(sm_sz>=4)
                {
                sm_sz=0;
                }                    
                switch(sm_sz)
                        {                               
                                case 0:wx4=0; //选数码管一
                                           P1=0xff;//取反,低电平
                                           P1=sm_tab[sz0];        //分钟低                       
                                       break;
                                case 1:wx3=0;
                                       P1=0XFF;
                                           P1=sm_tab[sz1];         //分钟高
                                       break;
                                case 2: wx2=0;
                                                P1=0xff;
                                                P1=sm_tab[sz2];        //小时低
                                      break;
                                case 3: wx1=0;
                                       P1=0XFF;
                                           P1=sm_tab[sz3];          //小时高
                                      break;                                               
                        }
                }
                else
                {wx1=1;wx2=1;wx3=1;wx4=1;}       
       }
void nzsj(void) //闹钟时间
  {
   s=0;//秒控制标志位
   shan=0;//闪烁标志位
   if(k2)
     {
     nao=1;
       
     nxs++;
         if(nxs>=24)
           nxs=0;
         }
        sz3=nxs/10;
        sz2=nxs%10;
        if(k3)
         {
          nao=1;
          nfz++;
          if(nfz>=60)
          nfz=0;
         }
         sz0=nfz%10;
     sz1=nfz/10;
       
  }
void nzx(void)
  {
     ET1=1;
       
          if(k4)
      {nao=0;tz=0;}//按键按下闹钟标志位为零停止中断
        if(!ncnt)
        {
       
          TR1=0;
      k=sszymmh[i]+7*sszymmh[i+1]-1;//去音符振荡频率所需数据  
          TH1=FREQH[k];
      TL1=FREQL[k];
      time=sszymmh[i+2];
      i=i+3;
          ncnt=time*30;
           TR1=1;
         }
        ncnt--;       
        if(i>=100)
          {i=0;nao=0;tz=0;}
}
void TIM1_ISR() interrupt 3
{
TR1=0;      
buz=~buz;//取反
TH1=FREQH[k];
TL1=FREQL[k];
TR1=1;
}
    void pdnz(void) //判断闹钟模块
{
   buz=1;
   ET1=0;
   if(xs==nxs&&fz==nfz&&nao==1) //闹钟时间到
              {
                tz=3;
                        if(k4)
                         {nxs=0;nfz=0;}
                        }
  }


程序不对把,灯是由P1.7控制的

程序的s定义的就是1.7口,那个对应的就是LED

灯一秒亮一秒灭 可以考虑写在中断里

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top