兰州大学萃英电子联盟 2024-02-29 20:05 采纳率: 88.9%
浏览 28
已结题

蓝桥杯单片机第十三届国赛PWM的问题

蓝桥杯单片机第十三届国赛中的 PWM功能,题目要求周期为1ms.为确保准确我采用定时器计时,设定的是200us进一次中断,但是速度太快造成一个问题,由于端口输出时候使用的也是P0口,会将之前的P0口的值覆盖掉,所以造成LED与数码管乱闪的问题,我预先的解决方法是在中断中重新显示一遍,但只能解决LED乱闪的问题,数码管扫描时间太长不适合放在中断中执行.所以希望得到一种解决方法。
下面是我选用不同573时候用的代码

void SelectHC573(unsigned char channel,unsigned char dat)
{
    P0=dat;
    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;
    }
    P2=(P2&0x1f)|0x00;
}

  • 写回答

3条回答 默认 最新

  • 檀越@新空间 2024-02-29 20:06
    关注

    Hans_Rudle 晚上好🌙🌙🌙
    本答案参考通义千问

    问题: 在蓝桥杯单片机比赛中,使用PWM控制LED和数码管时,由于定时器中断频率过高导致P0口数据被快速覆盖,导致LED乱闪和数码管显示不正常。如何解决这个问题?

    解决方案:

    1. 降低PWM频率

      • 调整定时器的设定,减小PWM的周期(例如从200us改为500us或更长),这样可以减少中断次数,从而降低数据被覆盖的频率。
      // 假设新设置的中断周期为1ms
      unsigned int new_period = 1000; // 1ms
      // 更新定时器的设定,例如使用定时器1,计数初值和溢出标志等
      T1CTL = TMOD | (new_period / 256); // 新周期/2,因为T1工作方式2
      
    2. 分时复用P0口

      • 在中断服务函数中,只更新LED部分的数据,保留数码管的显示。在主循环中再处理数码管的显示,这样可以避免在中断中影响数码管的扫描。
      // LED部分
      P0 ^= dat; // XOR操作,仅改变需要更改的位
      
      // 数码管部分(假设数码管在P1口)
      for (int i = 0; i < 7; ++i) {
          if (digit_data[i]) {
              P1 |= (1 << (7 - i)); // 显示当前数码管段
          } else {
              P1 &= ~(1 << (7 - i)); // 清除当前数码管段
          }
      }
      
      // 在主循环中处理数码管的完整扫描
      if (数码管需要更新) {
          UpdateDigitDisplay(); // 自定义函数来更新数码管显示
      }
      
    3. 数码管显示优化

      • 如果数码管的更新速度较慢,可以考虑使用流水线技术,每次更新一部分数码管,而不是一次性全部更新,以减少对CPU的影响。
    4. 硬件层面优化

      • 如果条件允许,可以尝试使用其他I/O口(如P1、P3等)来控制数码管,避免在中断中影响P0口。

    通过上述调整,你应该能有效地解决PWM控制下LED和数码管乱闪的问题。

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

报告相同问题?

问题事件

  • 系统已结题 3月12日
  • 已采纳回答 3月4日
  • 修改了问题 2月29日
  • 修改了问题 2月29日
  • 展开全部