木槿呀 2024-03-28 15:50 采纳率: 72.2%
浏览 8
已结题

蓝桥杯单片机十二届第一场,led灯的状态改变有问题

我在做蓝桥杯单片机第十二届省赛第一场的时候,led灯的改变状态出现了问题。完整代码在最下面。
void led_display()本来是这样:

void led_display()
{
  other_led_stat=led_buf&0xf1;
  if(timer10ms2>=10)
  {
    timer10ms2=0;
    if(mode==0)
    {
      led_buf=other_led_stat|0x0c;
      led_output(); 
    }
    else if(mode==1)
    { 
      led_buf=other_led_stat|0x0a;
      led_output();    
    }
    else if(mode==2)
    {
      led_buf=other_led_stat|0x06;
      led_output();
    }
    if(stat==0)//放后面
    {
      led_buf=led_buf&0xfe;
      led_output();
    }
    else if(stat==1)
    {
      led_buf=led_buf|0x01;
      led_output();
    }
  }
}


如果我把他改成这样,也就是把L1的亮灭变化判断挪到最前面,L1就会以很小的亮度的闪烁,不能正常的亮灭,为什么?

void led_display()
{
  other_led_stat=led_buf&0xf1;
  if(timer10ms2>=10)
  {
    timer10ms2=0;
    if(stat==0)
    {
      led_buf=led_buf&0xfe;
      led_output();
    }
    else if(stat==1)
    {
      led_buf=led_buf|0x01;
      led_output();
    }
    if(mode==0)
    {
      led_buf=other_led_stat|0x0c;
      led_output(); 
    }
    else if(mode==1)
    { 
      led_buf=other_led_stat|0x0a;
      led_output();    
    }
    else if(mode==2)
    {
      led_buf=other_led_stat|0x06;
      led_output();
    }

  }
}


完整代码如下:
main.c

#include<STC15F2K60S2.H>
#include"hardware.h"
#include"onewire.h"
#include"intrins.h"
#include"iic.h"
unsigned char mode=0;//S4
unsigned int temp=0;//温度
unsigned int temp2=25;//温度参数
float u=0.0;
unsigned int u_int=0;
unsigned int temp3=0;
bit stat=0;//模式
unsigned char other_led_stat=0xff;
//-----------------------------------------------------------------------------
void Working()
{
  if(timer10ms>=10)
  {
    timer10ms=0;
    Scankey();
    if(key_value==4 && key_stat==2)
    {
      switch(mode)
      {
        case 0:
         mode=1;//参数设置
        break;
        case 1:
         mode=2;//DAC输出界面
        break;
        case 2:
         mode=0;//温度设置界面
        break;
      }
    }
    else if(key_value==8 && key_stat==2 && mode==1)//-
    {
       if(temp2==0)
         temp2=99;
       else
         temp2--;
    }
    else if(key_value==9 && key_stat==2 && mode==1)//+
    {
       if(temp2==99)
         temp2=0;
       else
         temp2++;
    }
    else if(key_value==5 && key_stat==2 )//模式切换
    {
       stat=~stat;
    }    
  }
}
//-----------------------------------------------------------------------------
void SMG_display()
{
  if(mode==0)
  {
    SMG_buf[0]=12;
    SMG_buf[1]=16;
    SMG_buf[2]=16;
    SMG_buf[3]=16;
    SMG_buf[4]=temp3/1000;
    SMG_buf[5]=temp3%1000/100+32;
    SMG_buf[6]=temp3%100/10;
    SMG_buf[7]=temp3%10;
  }
  else if(mode==1)
  {
    SMG_buf[0]=24;
    SMG_buf[1]=16;
    SMG_buf[2]=16;
    SMG_buf[3]=16;
    SMG_buf[4]=16;
    SMG_buf[5]=16;
    SMG_buf[6]=temp2/10;
    SMG_buf[7]=temp2%10;
  }
  else if(mode==2)
  {
    SMG_buf[0]=10;
    SMG_buf[1]=16;
    SMG_buf[2]=16;
    SMG_buf[3]=16;
    SMG_buf[4]=16;
    SMG_buf[5]=u_int/100+32;
    SMG_buf[6]=u_int%100/10;
    SMG_buf[7]=u_int%10;
  }
}
//-----------------------------------------------------------------------------
void Delay(unsigned int t)
{
  while(t--);
}
//-----------------------------------------------------------------------------
void Read_temp()
{
  unsigned char LSB,MSB;
  init_ds18b20();
  Write_DS18B20(0xcc);
  Write_DS18B20(0x44);

  Delay(1000);

  init_ds18b20();
  Write_DS18B20(0xcc);
  Write_DS18B20(0xbe);
  LSB=Read_DS18B20();
  MSB=Read_DS18B20();
  temp=MSB;
  temp=(temp<<8)|LSB;
  if((temp & 0xf800)==0x0000)
  {
    temp3=temp*6.25;

  }
  else if((temp&0xf800)==0xf800)
  {
    temp=(~temp+1)&0x07ff;
    temp3=temp*6.25;
  }

}
//-----------------------------------------------------------------------------
void Delay750ms()        //@12.000MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 35;
    j = 51;
    k = 182;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}
//-----------------------------------------------------------------------------
void DAC_Read(unsigned char dat)
{
  I2CStart();
  I2CSendByte(0x90);
  I2CWaitAck();
  I2CSendByte(0x40);
  I2CWaitAck();
  I2CSendByte(dat);
  I2CWaitAck();
  I2CStop();
}
//-----------------------------------------------------------------------------
void DAC_output()
{
 if(timer200ms>=200)
 {
  timer200ms=0;
  if(stat==0 && mode!=1)
  {
    if(temp3<(temp2*100))
    {
       u=0;
       u_int=(unsigned int)(u * 100);
      DAC_Read(0);
    }
    else
    {
       u=5;
       u_int=(unsigned int)(u * 100);
      DAC_Read(255);
    }
  }
  else if(stat==1)
  {
    if(temp3<=2000)
    {
      u=1;
      u_int=(unsigned int)(u * 100);
      DAC_Read(102);
    }
    else if(temp3>2000 && temp3<=4000)
    {
      u=(temp3/100)*(3.0/20)-2;
      u_int=(unsigned int)(u * 100);
      DAC_Read(u/(5.0/255));
    }
    else
    {
       u=4;
       u_int=(unsigned int)(u * 100);
       DAC_Read(u/(5.0/255));
    }
  }
 }
}
//-----------------------------------------------------------------------------
void led_display()
{
  other_led_stat=led_buf&0xf1;
  if(timer10ms2>=10)
  {
    timer10ms2=0;
    if(mode==0)
    {
      led_buf=other_led_stat|0x0c;
      led_output(); 
    }
    else if(mode==1)
    { 
      led_buf=other_led_stat|0x0a;
      led_output();    
    }
    else if(mode==2)
    {
      led_buf=other_led_stat|0x06;
      led_output();
    }
    if(stat==0)//放后面
    {
      led_buf=led_buf&0xfe;
      led_output();
    }
    else if(stat==1)
    {
      led_buf=led_buf|0x01;
      led_output();
    }
  }
}
//-----------------------------------------------------------------------------
void main()
{
  led_output();
  ws_output();
  Timer1Init();
  Read_temp();
  Delay750ms();
  Read_temp();
  while(1)
  {   
    Working();
    DAC_output();
    SMG_display();
      if(timer500ms>=500)
    {
       timer500ms=0;
       Read_temp();
    }
    led_display();
  }
}



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=0xff;
unsigned char ws_buf=0x00;
unsigned char SMG_buf[]={16,16,16,16,16,16,16,16};
unsigned int timer10ms=0;
unsigned int timer10ms2=0;
unsigned int timer200ms=0;
unsigned int timer500ms=0;
unsigned char key_stat=0;
unsigned char key_value=0;
unsigned char key_values[4][4]=
{
    {4,8,12,16},
    {5,9,13,17},
    {6,10,14,18},
    {7,11,15,19},
};
//----------------------------------------------------------------------

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;
    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++;
    timer200ms++;
    timer500ms++;
}
//----------------------------------------------------------------------
void Scankey()
{
  unsigned char R,C;
  P3=0x0f;
  P4=0x00;
  if(~P3&0x0f)
  {
     if(key_stat<255)
       key_stat++;
     if(P33==0)
       R=0;
     if(P32==0)
       R=1;
     if(P31==0)
       R=2;
     if(P30==0)
       R=3;

       P3=0xf0;
       P4=0xff;
       if(P44==0)
         C=0;
       if(P42==0)
         C=1;
       if(P35==0)
         C=2;
       if(P34==0)
         C=3;
     key_value=key_values[R][C];

  }
  else 
  {
    key_stat=0;
    key_value=0;
  }
}

#ifndef _HARDWARE_H_
#define _HARDWARE_H_
#include<STC15F2K60S2.H>
extern unsigned char code t_display[];
extern unsigned char code T_COM[];
extern unsigned char led_buf;
extern unsigned char ws_buf;
extern unsigned char SMG_buf[];
extern unsigned int timer10ms;
extern unsigned int timer10ms2;
extern unsigned int timer200ms;
extern unsigned int timer500ms;
extern unsigned char key_stat;
extern unsigned char key_value;



void Timer1Init();
void SelectHC573(unsigned char channel);
void led_output();
void ws_output();
void SMG_output();
void Scankey();

#endif

#ifndef _ONEWIRE_H_
#define _ONEWIRE_H_

void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);


#endif

#ifndef _IIC_H_
#define _IIC_H_
#include<STC15F2K60S2.H>

static void I2C_Delay(unsigned char n);
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);



#endif


  • 写回答

1条回答 默认 最新

  • 关注

    木槿呀 下午好🌅🌅🌅
    本答案参考ChatGPT-3.5

    根据你提供的代码,我发现在 led_display() 函数中,你将 L1 的亮灭变化判断挪到了最前面。导致 L1 的亮度会闪烁或变得非常暗。

    这是因为在之前的代码中,你是根据变量 other_led_stat 来判断 L1 的亮灭状态的。而在新的代码中,你将 L1 的亮灭状态的判断放在了最前面,此时 other_led_stat 的值可能还没有被更新。导致 other_led_stat 的值不正确。

    为了解决这个问题,请按照以下步骤进行修改:

    1. if (stat == 0)else if (stat == 1) 的判断放回到原来的位置,也就是在判断 mode 之后。
    2. 确保在判断完 modestat 之后,再更新 other_led_stat 的值。
    3. 最后进行 LED 输出。

    修改后的代码如下所示:

    void led_display()
    {
      if (timer10ms2 >= 10)
      {
        timer10ms2 = 0;
    
        if (mode == 0)
        {
          led_buf = other_led_stat | 0x0c;
          led_output();
        }
        else if (mode == 1)
        {
          led_buf = other_led_stat | 0x0a;
          led_output();
        }
        else if (mode == 2)
        {
          led_buf = other_led_stat | 0x06;
          led_output();
        }
    
        if (stat == 0)
        {
          led_buf = led_buf & 0xfe;
          led_output();
        }
        else if (stat == 1)
        {
          led_buf = led_buf | 0x01;
          led_output();
        }
      }
    }
    

    通过以上修改,LED 灯的状态改变应该就能正常工作了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

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

悬赏问题

  • ¥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将查询的结果作为动态列名怎么实现