木槿呀 2024-03-24 22:45 采纳率: 72.2%
浏览 11
已结题

蓝桥杯第九届led灯亮度等级输出有问题

我在做第九届的时候,发现当我按下S6进入设置界面之后,led灯就会出问题,当亮度调小时,所有的灯都会发生频闪,亮度调大就没有问题了。而且只要不在S6设置界面就没问题,这是为什么?怎么解决呢?
main.c

#include<STC15F2K60S2.H>
#include"hardware.h"
#include"iic.h"
bit sz=0;//设置界面
unsigned char stat=0;//s6
unsigned char flag=0;//数码管闪烁
bit flag2=0;//S7,0暂停,1启动
unsigned char flag3=0;
unsigned char LSB=0;
unsigned char MSB=0;
unsigned char dat_rb2=0;
unsigned char llevel=0;
unsigned char dj=0;//亮度等级
void Wire_24c02(unsigned char addr,unsigned char dat);
void Delay(unsigned int t);
//-------------------------------------------------------------------------
void Workingkey()
{
 if(timer10ms>=10)
 {
   timer10ms=0;
   Scankey();
   if(key_value==6 && key_stat==2 )
   {
      sz=1;
      switch(stat)
      {
         case 0:
           stat=1;
           //sz=0;          
         break;
         case 1:
           stat=2;//运行模式
           timer400ms=0;
    

         break;
         case 2:
           stat=3;//流转间隔
            timer400ms=0;

         break;
         case 3:
           stat=0;
           sz=0;

         break;
      }
   
  }
  else if(key_value==5 && key_stat==2 && sz==1)//设置+
  {
    if(stat==2)//运行
    {
      if(mode==4)
        mode=1;
      else
        mode++;
    }
    else if(stat==3)//流转
    {
      if(times==1200)
        times=400;
      else 
        times=times+100;
        MSB=times/256;
        LSB=times%256;
        Wire_24c02(0x01,MSB);
       Delay(3000);
      Wire_24c02(0x02,LSB);
      Delay(3000);
    }   
  }
   else if(key_value==4 && key_stat==2 && sz==1)//设置-
  {
    if(stat==2)//运行
    {
      if(mode==1)
        mode=4;
      else
        mode--;
    }
    else if(stat==3)//流转
    {
      if(times==400)
        times=1200;
      else 
        times=times-100;
        MSB=times/256;
       LSB=times%256;
       Wire_24c02(0x01,MSB);
       Delay(3000);
       Wire_24c02(0x02,LSB);
       Delay(3000);
    }   
  }
  else if(key_value==7 && key_stat==2 && stat==0)
  {
     flag3=1;
     flag2=~flag2;
     time_cd=0;
     bz_cd=0;     
  }
  else if(key_value==4 && key_stat>1 && sz==0)
  {
     dj=1;
  }
  else 
     dj=0;
 }
}
//---------------------------------------------------------------------------
void SMG_Display()
{
  if(dj==0)
   {
    if(stat==0)
    {
     SMG_buf[0]=16;
     SMG_buf[1]=16;
     SMG_buf[2]=16;
     SMG_buf[3]=16;
     SMG_buf[4]=16;
     SMG_buf[5]=16;
     SMG_buf[6]=16;
     SMG_buf[7]=16;
    }
   else if(sz==1)
    {
     if(stat==1)
     {
     SMG_buf[0]=17;
     SMG_buf[1]=mode;
     SMG_buf[2]=17;
     SMG_buf[3]=16;
      if(times/1000==0)
       {
        SMG_buf[4]=16;
        SMG_buf[5]=times/100;
        SMG_buf[6]=times%100/10;
        SMG_buf[7]=times%10;
       }
      else if(times/1000!=0)
      {
        SMG_buf[4]=times/1000;
        SMG_buf[5]=times%1000/100;
        SMG_buf[6]=times%100/10;
        SMG_buf[7]=times%10; 
      }
     }
     else if(stat==2)
     {
     SMG_buf[0]=17;
     SMG_buf[2]=17;
     SMG_buf[3]=16;
      if(times/1000==0)
       {
        SMG_buf[4]=16;
        SMG_buf[5]=times/100;
        SMG_buf[6]=times%100/10;
        SMG_buf[7]=times%10;
       }
      else if(times/1000!=0)
      {
        SMG_buf[4]=times/1000;
        SMG_buf[5]=times%1000/100;
        SMG_buf[6]=times%100/10;
        SMG_buf[7]=times%10; 
      }
     }
     else if(stat==3)
     {
     SMG_buf[0]=17;
     SMG_buf[1]=mode;
     SMG_buf[2]=17;
     SMG_buf[3]=16;
     }
    }
  }
  else if(dj==1)
  {
     SMG_buf[0]=16;
     SMG_buf[1]=16;
     SMG_buf[2]=16;
     SMG_buf[3]=16;
     SMG_buf[4]=16;
     SMG_buf[5]=16;
     SMG_buf[6]=17;
     SMG_buf[7]=llevel;
  }
}
//---------------------------------------------------------------------------
void SMG_ss()
{
  if(sz==1)
  {
    if(stat==2)
    {
      if(bz400ms==1)
      {
       bz400ms=0;
       switch(flag)
       {
         case 0:
           SMG_buf[1]=16;
           flag=1;
         break;
         case 1:
           SMG_buf[1]=mode;
           flag=0;
         break;
       }
      }
    }
    else if(stat==3)
    {
      if(bz400ms==1)
      {
       bz400ms=0;
       switch(flag)
       {
         case 0:
           SMG_buf[4]=16; 
           SMG_buf[5]=16;
           SMG_buf[6]=16;
           SMG_buf[7]=16;
           flag=1;
         break;
         case 1:
         if(times/1000==0)
         {
           SMG_buf[5]=times/100;
           SMG_buf[6]=times%100/10;
           SMG_buf[7]=times%10;
         }
         else if(times/1000!=0)
         {
          SMG_buf[4]=times/1000;
          SMG_buf[5]=times%1000/100;
          SMG_buf[6]=times%100/10;
          SMG_buf[7]=times%10;  
         }
           flag=0;
         break;
       }
      } 
    }
  }
}
//----------------------------------------------------------------------------
void Delay(unsigned int t)
{
  while(t--);
}
//----------------------------------------------------------------------------
void led_display()
{
 
  if(timer10ms2>=10)
  {
   timer10ms2=0;
   
   if(flag2==0 && flag3==1)
   {
     led_output();
   }
   else if(flag2==1)
   {        
       if(mode==1 || mode==2)
       {              
         if(bz_cd==1)
          {            
             bz_cd=0;
             led_output();
             if(++i==8)
             {
               flag2=0;
               i=0;
             }
          }
      }    
      else if(mode==3 || mode==4)
      {
         if(bz_cd==1)
          {            
             bz_cd=0;
             led_output();
             if(++i==8)
             {
               i=0;
             }
          }
      }        
   }  
 }
}
//---------------------------------------------------------------------------
void Wire_24c02(unsigned char addr,unsigned char dat)
{
  I2CStart();
  I2CSendByte(0xa0);
  I2CWaitAck();
  I2CSendByte(addr);
  I2CWaitAck();
  I2CSendByte(dat);
  I2CWaitAck();
  I2CStop();
}
//---------------------------------------------------------------------------
unsigned char Read_24c02(unsigned char addr)
{
   unsigned char tmp;
   I2CStart();
  I2CSendByte(0xa0);
  I2CWaitAck();
  I2CSendByte(addr);
  I2CWaitAck();

  I2CStart();
  I2CSendByte(0xa1);
  I2CWaitAck();
  tmp=I2CReceiveByte();
  I2CSendAck(1);
  I2CStop();
  return tmp;
}
//---------------------------------------------------------------------------
void Read_RB2()
{
  I2CStart();
  I2CSendByte(0x90);
  I2CWaitAck();
  I2CSendByte(0x03);
  I2CWaitAck();
  I2CStop();
  
  I2CStart();
  I2CSendByte(0x91);
  I2CWaitAck();
  dat_rb2=I2CReceiveByte();
  I2CSendAck(1);
  I2CStop(); 
}
//---------------------------------------------------------------------------
void level()
{
  if(dat_rb2<=64)
   {
    llevel=1;
    duty=5;
   }
  else if(dat_rb2>64 && dat_rb2 <=128)
  {
     llevel=2;
     duty=10;
  }
 else if(dat_rb2>128 && dat_rb2 <=192)
 {
     llevel=3;
     duty=15;
  }
  else if(dat_rb2>192 && dat_rb2 <=255)
  {
     llevel=4;
     duty=20;
  }
}
//---------------------------------------------------------------------------
void Pwm_dut()
{
 if(bz1s==1)
 {
  bz1s=0;
  if(cnt<=duty)
  {   
    led_output();
  }
  else if(cnt>duty && cnt<20)
  {
     P0=0xff;
  }
     SelectHC573(4);
    SelectHC573(0);
  
 }
}
//---------------------------------------------------------------------------
void Initsys()
{
  P0=0xff;
  SelectHC573(4);
  SelectHC573(0);
  ws_output();
}
//----------------------------------------------------------------------------
void main()
{
  Initsys();
  Timer1Init();
  //Timer0Init();
  MSB=Read_24c02(0x01);
  LSB=Read_24c02(0x02);
  times=(MSB<<8)|LSB;
  
  while(1)
  {
    Workingkey();
    SMG_Display();
    SMG_ss();
    led_display();
    
    if(timer100ms>=100)
    {
       timer100ms=0;
       Read_RB2();
    } 
    
    level();
    Pwm_dut();
  }
}


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 char led_buf[4][8] = 
{
{0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff},
{0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff},    
{0x81, 0x42, 0x24, 0x18, 0x81, 0x42, 0x24, 0x18},
{0x18, 0x24, 0x42, 0x81, 0x18, 0x24, 0x42, 0x81},
};
unsigned char ws_buf=0x00;
unsigned char SMG_buf[]={16,16,16,16,16,16,16,16};
unsigned int timer10ms=0;
unsigned int timer1ms=0;
unsigned int timer10ms2=0;
unsigned int timerpwm=0;
unsigned char duty=0;//占空比
unsigned int timer100ms=0;
unsigned int timer400ms=0;
unsigned int cnt=0;
bit bz1s=0;
unsigned int times=400;
unsigned int time_cd=0;
bit bz400ms=0;
bit bz_cd=0;
unsigned char key_stat=0;
unsigned char key_value=0;
unsigned char mode=1;//led流转模式
unsigned char i=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()
{      
  
    P0=~led_buf[mode-1][i];
    

    SelectHC573(4);
    SelectHC573(0);
}
//---------------------------------------------------------------------
void ws_output()
{
   
    P0=ws_buf;
    SelectHC573(5);
    SelectHC573(0);
}
//---------------------------------------------------------------------
void SMG_output()
{
   static unsigned char SMG_com=0;

  
    P0=0x00;
     SelectHC573(6);
    SelectHC573(0);

    
    P0=T_COM[SMG_com];
    SelectHC573(6);
    SelectHC573(0);

    
    P0=~t_display[SMG_buf[SMG_com]];
    SelectHC573(7);
    SelectHC573(0);

    if(++SMG_com>=8)
    {
      SMG_com=0;
    }
}
//---------------------------------------------------------------------
void ServiceTimer()interrupt 3
{
   SMG_output();
   timer10ms++;
   timer10ms2++;
   timer400ms++;
   timer1ms++;
   if(timer1ms>=1)
   {
     timer1ms=0;
     bz1s=1;
   }
   if(timer400ms>=400)
   {
     timer400ms=0;
     bz400ms=1;
   }
   time_cd++;
   if(time_cd>=times)
   {
     time_cd=0;
     bz_cd=1;
   }
   timer100ms++;
   cnt++;
   if(cnt>20)
     cnt=0;
}
//----------------------------------------------------------------------


//----------------------------------------------------------------------
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;
  }
}

  • 写回答

14条回答 默认 最新

  • 社区专家-Monster-XH 2024-03-25 09:03
    关注

    根本原因是PWM波形的频率不够高,Pwm_dut函数负责根据duty变量的值调整PWM输出,控制LED的亮度。duty值较低,LED只在很短的时间内被供电,导致观察到的频闪现象。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(13条)

报告相同问题?

问题事件

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

悬赏问题

  • ¥15 AnolisOs7.9如何安装 Qt_5.14.2的运行库
  • ¥20 求:怎么实现qt与pcie通信
  • ¥50 前后端数据顺序不一致问题,如何解决?(相关搜索:数据结构)
  • ¥15 基于蒙特卡罗法的中介效应点估计代码
  • ¥15 罗技G293和UE5.3
  • ¥20 Tesla 特斯拉K80显卡 如果需要使用该设备,你需要禁用系统上的另一个设备。
  • ¥30 QT调用百度智能云千帆模型无法取得返回文本
  • ¥50 CCD工业视觉相机检测出现光边
  • ¥60 二次元手游日常任务自动化代肝(相关搜索:自动化)
  • ¥15 mysql将查询的结果作为动态列名怎么实现