channel PWM reimplemeted

This commit is contained in:
King Kévin 2013-10-19 22:17:59 +02:00
parent 7f637bc705
commit bdc953feff
1 changed files with 26 additions and 32 deletions

View File

@ -90,13 +90,14 @@ uint16_t burst[PULSE_MAX]; /* pulse times forming a burst (from timer) */
/* channel variables */ /* channel variables */
#define LEVELS 10 /* the number of PWM levels */ #define LEVELS 10 /* the number of PWM levels */
volatile uint8_t ch_tick = 0; /* the tick counter for the channel PWM */ volatile uint8_t ch_tick = 0; /* to tick for the channel PWM */
uint8_t on[CHANNELS_1+CHANNELS_2]; /* at which tick turn the channel on */
uint8_t off[CHANNELS_1+CHANNELS_2]; /* at which tick turn the channel off */
/* flags, set in the interrupts and handled in the main program */ /* flags, set in the interrupts and handled in the main program */
volatile bool uart_flag = false; /* an incoming activity on the UART */ volatile bool uart_flag = false; /* an incoming activity on the UART */
volatile bool power_flag = false; /* a change in the power or fan */ volatile bool power_flag = false; /* a change in the power or fan */
volatile bool ir_flag = false; /* to process a burst */ volatile bool ir_flag = false; /* to process a burst */
volatile bool pwm_flag = false; /* to trigger a PWM tick */
volatile bool channel_flag = false; /* indicate a change in the channel PWM values */ volatile bool channel_flag = false; /* indicate a change in the channel PWM values */
volatile bool learn_flag = false; /* learn an IR command for an action */ volatile bool learn_flag = false; /* learn an IR command for an action */
enum IR_ACTIONS to_learn = IR_ACTION_END; /* IR action to learn */ enum IR_ACTIONS to_learn = IR_ACTION_END; /* IR action to learn */
@ -163,8 +164,23 @@ ISR(TIMER1_COMPA_vect) { /* timer 1 OCR1A match interrupt vector */
/* timer 0 interrupt used generate a PWM for the channels */ /* timer 0 interrupt used generate a PWM for the channels */
ISR(TIMER0_COMPA_vect) { /* timer 0 OCR0A match interrupt vector */ ISR(TIMER0_COMPA_vect) { /* timer 0 OCR0A match interrupt vector */
ch_tick = (ch_tick+1)%LEVELS; ch_tick++;
pwm_flag = true; if (pwr_ok) {
for (int i=0; i<CHANNELS_1+CHANNELS_2; i++) {
if (on[i]==ch_tick) {
if (on[i]!=off[i]) {
*(PORTS[i]) |= (1<<BITS[i]);
} else if (brightness[mode][i]==0) {
*(PORTS[i]) &= ~(1<<BITS[i]);
} else {
*(PORTS[i]) |= (1<<BITS[i]);
}
} else if (off[i]==ch_tick && brightness[mode][i]!=0xff) {
*(PORTS[i]) &= ~(1<<BITS[i]);
}
}
PIND = (1<<LED);
}
} }
/* disable watched when booting */ /* disable watched when booting */
@ -245,7 +261,7 @@ void ioinit(void)
TCCR0B &= ~(1<<CS02); TCCR0B &= ~(1<<CS02);
TCCR0B |= (1<<CS01); TCCR0B |= (1<<CS01);
TCCR0B &= ~(1<<CS00); TCCR0B &= ~(1<<CS00);
OCR0A = 0xff; /* set PWM frequency (with prescale=8, 0x00=2304kHz-0xff=9kHz) */ OCR0A = 0x40; /* set PWM frequency (with prescale=8, 0x00=2304kHz-0xff=9kHz) */
TIFR0 = (1<<OCF0A); /* clear timer 0 compare interrupt flag */ TIFR0 = (1<<OCF0A); /* clear timer 0 compare interrupt flag */
TIMSK0 |= (1<<OCIE0A); /* enable timer 0 compare interrupt */ TIMSK0 |= (1<<OCIE0A); /* enable timer 0 compare interrupt */
@ -280,10 +296,6 @@ int main(void)
ir_data.command = 0; ir_data.command = 0;
uint8_t ir_repeat = 0; /* number of times the IR data has been repeated */ uint8_t ir_repeat = 0; /* number of times the IR data has been repeated */
uint8_t on[CHANNELS_1+CHANNELS_2]; /* times when to switch on the output on the channels */
uint8_t off[CHANNELS_1+CHANNELS_2]; /* times when to switch off the output on the channels */
channel_flag = true; /* calculate above values later */
puts("LED dimmer up & running"); puts("LED dimmer up & running");
/* load (or initialize) settings */ /* load (or initialize) settings */
@ -299,6 +311,7 @@ int main(void)
load_settings(); load_settings();
puts("settings loaded"); puts("settings loaded");
} }
channel_flag = true; /* calculate channel values later */
/* switch power supply as saved */ /* switch power supply as saved */
if (power) { if (power) {
@ -312,32 +325,12 @@ int main(void)
while (channel_flag) { while (channel_flag) {
uint8_t start = 0; uint8_t start = 0;
for (uint8_t i=0; i<CHANNELS_1+CHANNELS_2; i++) { for (uint8_t i=0; i<CHANNELS_1+CHANNELS_2; i++) {
on[i] = (start)%LEVELS; on[i] = start;
off[i] = (on[i]+brightness[mode][i])%LEVELS; start += brightness[mode][i];
start = (start+brightness[mode][i])%LEVELS; off[i] = start;
} }
channel_flag = false; channel_flag = false;
} }
/* generate PWM for channel */
while (pwm_flag) {
if (pwr_ok) {
for (int i=0; i<CHANNELS_1+CHANNELS_2; i++) {
if (on[i]==ch_tick) {
if (on[i]!=off[i]) {
*(PORTS[i]) |= (1<<BITS[i]);
} else if (brightness[mode][i]==0) {
*(PORTS[i]) &= ~(1<<BITS[i]);
} else {
*(PORTS[i]) |= (1<<BITS[i]);
}
} else if (off[i]==ch_tick) {
*(PORTS[i]) &= ~(1<<BITS[i]);
}
}
PIND |= (1<<LED);
}
pwm_flag = false;
}
/* handle UART input */ /* handle UART input */
while (uart_flag) { while (uart_flag) {
/* echo back */ /* echo back */
@ -553,6 +546,7 @@ void uart_action(char* str)
goto error; goto error;
} }
brightness[mode][channel] = (uint8_t)br; brightness[mode][channel] = (uint8_t)br;
channel_flag = true;
} }
} else { } else {
goto error; goto error;