Estoy tratando de tomar 3 LED RGB de ánodo comunes y conectar los cátodos de cada uno a tres de las salidas PWM en un ATMega328p y luego en un ISR, multiplexar entre todos. Sin embargo, el problema con el que me estoy topando es que incluso si, por ejemplo, solo quiero el rojo en el LED0 (de los LED 0 - 2) y solo enciendo el PWM para ese canal mientras el ánodo para ese LED está encendido (Lógica alta desde el ánodo común) Todavía me pongo rojo en TODOS los LED. Vea el esquema a continuación para ver cómo está configurado. Para simplificar las cosas, solo muestro el esquema y el código de uno de los canales LED.
void setup()
{
//Setup outputs for anodes
DDRB |= (_BV(PINB0) | _BV(PINB1) | _BV(PINB2));
//Setup Timer2 Interrupts
TCCR2A = _BV(COM2A1) | _BV(WGM21) | _BV(WGM20); //Fast PWM mode on OCR2A (PINB3 - Digital 11)
TCCR2B = _BV(CS22); //64 Prescaler
OCR2A = 255;
//Setup Multiplex ISR on Timer1
// set compare match register for ~50Khz
OCR1A = 300;
// turn on CTC mode
TCCR1B |= _BV(WGM12);
TCCR1B |= PRESCALE1_1;
// enable timer compare interrupt
TIMSK1 |= _BV(OCIE1A);
}
volatile uint8_t col = 0;
ISR(TIMER1_COMPA_vect)
{
//Set all anodes to LOW
PORTB &= ~(_BV(PINB0) | _BV(PINB1) | _BV(PINB2));
//Faking it here: Basically simulating that LED 0 is on but LEDs 1 and 2 are not.
//Note that because the PWM is on the cathode, 255 is OFF and 0 is full brightness.
if(col == 0)
OCR2A = 0;
else
OCR2A = 255;
//Turn on JUST the LED that we want.
PORTB |= _BV(col);
//Step through the LEDs
col++;
if(col > 2)
{
col = 0;
}
}
Entonces, lo que esperaría es que el LED0 esté encendido a 1/3 de brillo (ya que solo está encendido en 1 de cada tres veces a través del ISR) y los LED 1 y 2 están COMPLETAMENTE apagados. Sin embargo, en cambio, TODOS los LED están encendidos en todo momento y algunas veces parecen parpadear un poco.
Esto me ha dejado completamente perplejo. Debido a que la única vez que el PWM del LED debe estar encendido es en el LED 0 y para los tiempos en que los ánodos de los otros LED están encendidos, el PWM debe configurarse a un ciclo de trabajo del 0% (para un PWM de cátodo).
Obviamente, normalmente tengo una variable global que contiene datos de canal RGB para cada uno de los LED y los datos se extraen durante cada paso de ISR para establecer el ciclo de trabajo de PWM respectivo para ese LED. Esto se simplifica simplemente para facilitar la lectura, ya que ocurre independientemente del canal de color que esté usando.
¿Pensamientos?