Avr 用于4个LED的ATTiny85 PWM

Avr 用于4个LED的ATTiny85 PWM,avr,led,atmel,pwm,attiny,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 =

我需要通过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);
  }
}
/*四个PWM输出*/
//ATtiny85输出
常数int Red=0;
常数int绿色=1;
常数int蓝色=4;
常数int白色=3;
易失性uint8_t*端口[]={&OCR0A和&OCR0B,&OCR1A和&OCR1B};
无效设置(){
pinMode(红色,输出);
引脚模式(绿色,输出);
pinMode(蓝色,输出);
pinMode(白色,输出);
//为PB0和PB1上的快速PWM配置计数器/定时器0

TCCR0A=3一个简单的策略是将4个LED多路复用到一个PWM引脚上。这将允许总共使用5个引脚独立控制阁楼上每个LED的亮度

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

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

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

如果你快速旋转LED(速度超过,比方说,每秒60次),那么从视觉上看,它们看起来都像是在期望亮度下打开的。毕竟,PWM只是LED闪烁太快而看不见,所以我们只是在其上添加了第二个维度

一个缺点:由于任何时候只有一个LED亮起,因此理论上最大总亮度将是单独驱动所有LED时的1/4。实际上,这可能是一个问题,因为如果您尝试在s点点亮所有LED,阁楼的电流限制为一次通过所有引脚的电流同一时间

一个提示:当设置PWM定时器时,使LED在周期的开始时断开,并在中间打开。这将使ISR时间在所有LED都关闭时进入下一个LED。这是更好的,因为它很容易看到一个LED,当它不应该是,但不那么容易看到一个LED是关闭时,它应该是B。继续

一个建议:我会为此而被点燃,但你可以在这样做的时候省去任何限流电阻,因为每个LED最多只有1/4的时间是亮的。这将给你更多的亮度,也使你可以调低PWM占空比,这样你在每个周期开始时就有更多的关闭时间进入下一个LED

我已经多次成功地使用这种技术,甚至能够将6个RGB LED(每个三个通道)复用到一个芯片上,效果非常好


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

一个简单的策略是将4个LED多路传输到一个PWM引脚上。这将使阁楼上的每个LED的亮度可以使用总共5个引脚独立控制

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

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

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

如果你快速旋转LED(速度超过,比方说,每秒60次),那么从视觉上看,它们看起来都像是在期望亮度下打开的。毕竟,PWM只是LED闪烁太快而看不见,所以我们只是在其上添加了第二个维度

一个缺点:由于任何时候只有一个LED亮起,因此理论上最大总亮度将是单独驱动所有LED时的1/4。实际上,这可能是一个问题,因为如果您尝试在s点点亮所有LED,阁楼的电流限制为一次通过所有引脚的电流同一时间

一个提示:当设置PWM定时器时,使LED在周期的开始时断开,并在中间打开。这将使ISR时间在所有LED都关闭时进入下一个LED。这是更好的,因为它很容易看到一个LED,当它不应该是,但不那么容易看到一个LED是关闭时,它应该是B。继续

一个建议:我会为此而被点燃,但你可以在这样做的时候省去任何限流电阻,因为每个LED最多只有1/4的时间是亮的。这将给你更多的亮度,也使你可以调低PWM占空比,这样你在每个周期开始时就有更多的关闭时间进入下一个LED

我已经多次成功地使用这种技术,甚至能够将6个RGB LED(每个三个通道)复用到一个芯片上,效果非常好


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

如果您想以牺牲更复杂的策略来节省管脚,您可以通过将LED连接为两组两个这样的方式,仅使用3个管脚

与使用内置PWM不同,您需要手动执行PWM,方法是设置计时器,然后在每次计时器过期时更改每个引脚的输入/输出和开/关

+-----+----------+----------+----------+
| 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 |
+-----+----------+----------+----------+
如果您想了解此策略的更多详细信息,请更新或发表评论。