ATTiny85 PWM适用于4个LED

时间:2019-01-30 16:18:41

标签: avr led atmel pwm attiny

我需要通过ATTiny85上的PWM控制4个单独的LED。我发现了很多有关如何控制3个LED的信息。但是显然要用PWM控制4,必须将85真正扭成一圈。有没有更简单的方法来处理85上的4个LED,还是最好过渡到84?如果我使用84,那我可能会碰到与85相同的砖墙吗?

我在85上找到了用于控制4的代码,但它超出了我的技能水平。有人看到任何问题吗?

/* Four PWM Outputs */

// ATtiny85 outputs
const int Red = 0;
const int Green = 1;
const int Blue = 4;
const int White = 3;
volatile uint8_t* Port[] = {&OCR0A, &OCR0B, &OCR1A, &OCR1B};

void setup() {
  pinMode(Red, OUTPUT);
  pinMode(Green, OUTPUT);
  pinMode(Blue, OUTPUT);
  pinMode(White, OUTPUT);
  // Configure counter/timer0 for fast PWM on PB0 and PB1
  TCCR0A = 3<<COM0A0 | 3<<COM0B0 | 3<<WGM00;
  TCCR0B = 0<<WGM02 | 3<<CS00; // Optional; already set
  // Configure counter/timer1 for fast PWM on PB4
  TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 7<<CS10;
  GTCCR = 1<<PWM1B | 3<<COM1B0;
  // Interrupts on OC1A match and overflow
  TIMSK = TIMSK | 1<<OCIE1A | 1<<TOIE1;
}

ISR(TIMER1_COMPA_vect) {
  if (!bitRead(TIFR,TOV1)) bitSet(PORTB, White);
}

ISR(TIMER1_OVF_vect) {
  bitClear(PORTB, White);
}

// Sets colour Red=0 Green=1 Blue=2 White=3
// to specified intensity 0 (off) to 255 (max)
void SetColour (int colour, int intensity) {
  *Port[colour] = 255 - intensity;
}  

void loop() {
  for (int i=-255; i <= 254; i++) {
    OCR0A = abs(i);
    OCR0B = 255-abs(i);
    OCR1A = abs(i);
    OCR1B = 255-abs(i);
    delay(10);
  }
}

2 个答案:

答案 0 :(得分:0)

一种简单的策略是将4个LED多路复用到单个PWM引脚上。这样总共可以使用5个引脚来独立控制ATTINY上每个LED的亮度。

例如,您可以将所有4个阴极连接在一起,并将它们连接到单个PWM引脚。然后,将4个阳极中的每个阳极连接到不同的IO引脚。

在任何给定时刻,只有一个阳极处于输出模式-其他阳极则保持浮动。这意味着最多1个单个LED处于活动状态,并且其亮度由PWM占空比控制。

然后,您可以将溢出ISR用于PWM定时器,以在每个PWM周期之后激活序列中的下一个LED。您还可以更新PWM匹配以反映下一个LED的亮度。

如果通过LED快速旋转(快于每秒60次),那么从视觉上看,它们看起来都像是在所需的亮度下点亮。毕竟,PWM只是使LED闪烁太快而看不到,因此我们只是在上面增加了第二个维度。

一个缺点:由于任何时候都只有一个LED点亮,因此理论上最大总亮度是单独驱动所有LED时的1/4。实际上,这可能是一个问题,因为如果您尝试同时点亮所有LED,则ATTINY仅限于其所有引脚都可以流过多少电流。

一个提示:设置PWM定时器时,make为使LED在循环开始时熄灭,而在中间点亮。当所有LED都熄灭时,这将使ISR有时间进入下一个LED。最好这样做是因为在不应该打开的情况下很容易看到一个LED,而在不应该打开的情况下却很不容易看到一个LED。

一个建议:我会为此感到恼火,但是这样做时您可以省去任何限流电阻,因为每个LED最多只能打开1/4的时间。这将为您提供更多的亮度并使其发光,这样您就可以降低PWM占空比,从而在每个周期的开始都有更多的关闭时间,以进入下一个LED。

我已经成功地使用了这项技术很多次,甚至能够将6个RGB LED(每个3个通道)多路复用到一个芯片上,并且效果很好。

如果对细节有任何疑问,请更新问题!

答案 1 :(得分:0)

如果您想以更复杂的策略为代价来节省引脚,则可以通过将LED分为两组(两个这样)来连接,从而只用3个引脚就可以了。

enter image description here

除了使用内置的PWM外,您还需要通过设置计时器来手动执行PWM,然后在每次计时器到期时更改每个引脚的INPUT / OUTPUT和ON / OFF。

+-----+----------+----------+----------+
| LED |    A     |    B     |    C     |
+-----+----------+----------+----------+
|   1 | OUTPUT 1 | INPUT    | OUTPUT 0 |
|   2 | OUTPUT 0 | INPUT    | OUTPUT 1 |
|   3 | INPUT    | OUTPUT 1 | OUTPUT 0 |
|   4 | INPUT    | OUTPUT 0 | OUTPUT 1 |
+-----+----------+----------+----------+

如果需要有关此策略的更多详细信息,请更新或评论。