木槿呀 2024-03-21 23:06 采纳率: 72.2%
浏览 10
已结题

蓝桥杯省赛第八届,为什么时钟设置界面数码管闪烁刚开始正常,后面又闪得快了?

我在做第八届省赛的时候,在实现第一个功能,数码管选中的单元以1s为间隔闪烁时,刚开始的那两三下是正常按照1s闪烁的,但是接下来就会有以下闪的快一些,然后又正常几个,接着又有一个闪得快些,这是为什么呢?应该怎么改呢?
main.c

#include<STC15F2K60S2.H>
#include"hardware.h"
unsigned char mode=0;//时钟显示
unsigned char stat=0;
unsigned char t_h=23;
unsigned char t_m=59;
unsigned char t_s=50;
//-----------------------------------------------------------------
void Workingkey()
{
   if(timer10ms>=10)
   {
      timer10ms=0;
      Scankey();
      if(key_value==7 && key_stat==2)
      {
        timer500ms=0;
        stat=0;
        switch(mode)
        {
          case 0:
            mode=1;//h
          break;
          case 1:
            mode=2;    //m
            SMG_buf[0]=t_h/10;
            SMG_buf[1]=t_h%10;
          break;
          case 2:
            mode=3;    //s
            SMG_buf[3]=t_m/10;
            SMG_buf[4]=t_m%10;
          break;
           case 3:
            mode=0;    
            SMG_buf[6]=t_s/10;
            SMG_buf[7]=t_s%10;
          break;
        } 
      }
   }
}
//-----------------------------------------------------------------
void SMG_Display()
{
   if(mode==0)
   {
     SMG_buf[0]=t_h/10;
     SMG_buf[1]=t_h%10;
     SMG_buf[2]=17;
     SMG_buf[3]=t_m/10;
     SMG_buf[4]=t_m%10;
     SMG_buf[5]=17;
     SMG_buf[6]=t_s/10;
     SMG_buf[7]=t_s%10;
   }
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
void SMG_ss()
{
   if(timer500ms>=500)
   {
      timer500ms=0;
      if(mode==1)
      {
        if(stat==0)
        
          {
            SMG_buf[0]=16;
            SMG_buf[1]=16;       
            stat=1;
           }
          else if(stat==1)
          {
            SMG_buf[0]=t_h/10;
            SMG_buf[1]=t_h%10;
            stat=0;
        }
                    
        
      }
      else if(mode==2)
      {
        if(stat==0)
        
          {
            SMG_buf[3]=16;
            SMG_buf[4]=16;       
            stat=1;
           }
          else if(stat==1)
          {
            SMG_buf[3]=t_m/10;
            SMG_buf[4]=t_m%10;
            stat=0;
        }
      }
      else if(mode==3)
      {
        if(stat==0)
        
          {
            SMG_buf[6]=16;
            SMG_buf[7]=16;       
            stat=1;
           }
          else if(stat==1)
          {
            SMG_buf[6]=t_s/10;
            SMG_buf[7]=t_s%10;
            stat=0;
        }
      }
     }
 }


//-----------------------------------------------------------------
void main()
{
  led_output();
  ws_output();
  Timer1Init();
  while(1)
   {
     Workingkey();
     SMG_Display();
     SMG_ss();
   }
}

hardware.c

#include<STC15F2K60S2.H>
#include"hardware.h"
/*************  本地常量声明    **************/
unsigned char code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

unsigned char code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码
unsigned int timer10ms=0;
unsigned int timer500ms=0;
unsigned char led_buf=0xff;
unsigned char ws_buf=0x00;
unsigned char SMG_buf[]={2,3,17,5,9,17,5,0};
unsigned char key_stat=0;
unsigned char key_value=0;
//---------------------------------------------------------------------------------
void Timer1Init()        //1毫秒@12.000MHz
{
    AUXR |= 0x40;        //定时器时钟1T模式
    TMOD &= 0x0F;        //设置定时器模式
    TL1 = 0x20;        //设置定时初值
    TH1 = 0xD1;        //设置定时初值
    TF1 = 0;        //清除TF1标志
    TR1 = 1;        //定时器1开始计时
    ET1=1;
    EA=1;
}
//---------------------------------------------------------------------------------
void SelectHC573(unsigned char channel)
{
    switch(channel)
    {
       case 4:
         P2=(P2&0x1f)|0x80;
       break;
       case 5:
         P2=(P2&0x1f)|0xa0;
       break;
       case 6:
         P2=(P2&0x1f)|0xc0;
       break;
       case 7:
         P2=(P2&0x1f)|0xe0;
       break;
       case 0:
         P2=(P2&0x1f)|0x00;
       break;
    }
}
//---------------------------------------------------------------------------------
void led_output()
{
   SelectHC573(4);
   P0=led_buf;
   SelectHC573(0);
}
//----------------------------------------------------------------------------------
void ws_output()
{
  SelectHC573(5);
   P0=ws_buf;
   SelectHC573(0); 
}
//----------------------------------------------------------------------------------
void SMG_output()
{
   static unsigned char SMG_com=0;

   SelectHC573(6);
   P0=0x00;
   SelectHC573(0);
   
   SelectHC573(6);
   P0=T_COM[SMG_com];
   SelectHC573(0);
   
   SelectHC573(7);
   P0=~t_display[SMG_buf[SMG_com]];
   SelectHC573(0);
   
   if(++SMG_com>=8)
   {
         SMG_com=0;
   }  
}
//----------------------------------------------------------------------------------
void ServiceTimer1()interrupt 3
{
   SMG_output();
   timer10ms++;
   timer500ms++;
}
//---------------------------------------------------------------------------------
void Scankey()
{
  P3|=0x0f;
  if(~P3 & 0x0f)
  {
     if(key_stat<255)
       key_stat++;
     if(P33==0)
       key_value=4;
     if(P32==0)
       key_value=5;
     if(P31==0)
       key_value=6;
     if(P30==0)
       key_value=7;
  }
  else 
  {
    key_stat=0;
    key_value=0;
  }
}

  • 写回答

3条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-03-21 23:06
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    这个问题可能是由定时器中断和程序延时不等引起的。建议使用定时器产生精确的时间间隔,并避免使用延时函数。 例如,可以使用定时器1来控制数码管的闪烁。在定时器中断中,将闪烁标志位toggle,并在主程序中根据该标志位来设置数码管的显示。 修改后的代码示例: main.c
    #include <STC15F2K60S2.H>
    #include "hardware.h"
    unsigned char mode = 0;
    unsigned char stat = 0;
    unsigned char t_h = 23;
    unsigned char t_m = 59;
    unsigned char t_s = 50;
    unsigned char blink_flag = 0;
    void Workingkey(){
      Scankey();
      if(key_value == 7 && key_stat == 2)
      {
        timer500ms = 0;
        stat = 0;
        switch(mode)
        {
          case 0:
            mode = 1;//h
            break;
          case 1:
            mode = 2;//m
            SMG_buf[0] = t_h/10;
            SMG_buf[1] = t_h%10;
            break;
          case 2:
            mode = 3;//s
            SMG_buf[3] = t_m/10;
            SMG_buf[4] = t_m%10;
            break;
          case 3:
            mode = 0;
            SMG_buf[6] = t_s/10;
            SMG_buf[7] = t_s%10;
            break;
        }
      }
    }
    void SMG_Display(){
      switch(mode)
      {
        case 0:
          SMG_buf[0] = t_h/10;
          SMG_buf[1] = t_h%10;
          SMG_buf[2] = 17;
          SMG_buf[3] = t_m/10;
          SMG_buf[4] = t_m%10;
          SMG_buf[5] = 17;
          SMG_buf[6] = t_s/10;
          SMG_buf[7] = t_s%10;
          break;
        case 1:
          SMG_buf[0] = t_h/10;
          SMG_buf[1] = t_h%10;
          SMG_buf[2] = blink_flag ? 16 : 17;
          SMG_buf[3] = t_m/10;
          SMG_buf[4] = t_m%10;
          SMG_buf[5] = 17;
          SMG_buf[6] = t_s/10;
          SMG_buf[7] = t_s%10;
          break;
        case 2:
          SMG_buf[0] = t_h/10;
          SMG_buf[1] = t_h%10;
          SMG_buf[2] = 17;
          SMG_buf[3] = t_m/10;
          SMG_buf[4] = t_m%10;
          SMG_buf[5] = blink_flag ? 16 : 17;
          SMG_buf[6] = t_s/10;
          SMG_buf[7] = t_s%10;
          break;
        case 3:
          SMG_buf[0] = t_h/10;
          SMG_buf[1] = t_h%10;
          SMG_buf[2] = 17;
          SMG_buf[3] = t_m/10;
          SMG_buf[4] = t_m%10;
          SMG_buf[5] = 17;
          SMG_buf[6] = blink_flag ? 16 : t_s/10;
          SMG_buf[7] = blink_flag ? 16 : t_s%10;
          break;
      }
    }
    void main(){
      led_output();
      ws_output();
      Timer1Init();
      while(1)
      {
        Workingkey();
        SMG_ss();
        if(timer500ms >= 500)
        {
          timer500ms = 0;
          blink_flag = !blink_flag;
        }
        SMG_Display();
      }
    }
    

    hardware.c

    #include <STC15F2K60S2.H>
    #include "hardware.h"
    unsigned int timer10ms = 0;
    unsigned int timer500ms = 0;
    void led_output()
    {
      P1M0 = 0;
      P1M1 = 0;
      LED = 0;
    }
    void ws_output()
    {
      P_CLK = 0;
      P_DIN = 0;
      P_CS = 1;
      P_CLK = 1;
    }
    void SMG_ss(){
      static unsigned char smg_index = 0;
      P_SMG = SMG_SEL[smg_index];
      P_LED = LED_SEL[smg_index];
      P_DOUT = SMG_TAB[SMG_buf[smg_index]];
      smg_index++;
      if(smg_index >= 8)
      {
        smg_index = 0;
      }
    }
    void Timer1Init()
    {
      TMOD = 0x10;
      TH1 = (65536 - FOSC/12/1000);
      TL1 = (65536 - FOSC/12/1000);
      EA = 1;
      ET1 = 1;
      TR1 = 1;
    }
    void Timer1ISR() interrupt 3
    {
      timer10ms++;
      timer500ms++;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 4月1日
  • 已采纳回答 3月24日
  • 创建了问题 3月21日

悬赏问题

  • ¥20 c语言写的8051单片机存储器mt29的模块程序
  • ¥60 求直线方程 使平面上n个点在直线同侧并且距离总和最小
  • ¥50 java算法,给定试题的难度数量(简单,普通,困难),和试题类型数量(单选,多选,判断),以及题库中各种类型的题有多少道,求能否随机抽题。
  • ¥50 rk3588板端推理
  • ¥250 opencv怎么去掉 数字0中间的斜杠。
  • ¥15 这种情况的伯德图和奈奎斯特曲线怎么分析?
  • ¥250 paddleocr带斜线的0很容易识别成9
  • ¥15 电子档案元素采集(tiff及PDF扫描图片)
  • ¥15 flink-sql-connector-rabbitmq使用
  • ¥15 zynq7015,PCIE读写延时偏大