diff --git a/module04/ex01/main.c b/module04/ex01/main.c index 696726a..8711ec1 100644 --- a/module04/ex01/main.c +++ b/module04/ex01/main.c @@ -20,12 +20,12 @@ // - if i want my cycle to be 0.01 second, which prescaler ? // - 8 * 0,004096 = 0.032768 -> it is enough // - 64 * 0,004096 = 0.262144 -> it is largely enough -// - if i choose prescaler 1 for a duration of 0.001 seconds, i need to restart the clock after how many cycles : -// - (16000000 / 1) * 0.001 = 16000 ticks -> set ICR1 = 16000 -// - if i choose prescaler 8 for a duration of 0.01 seconds, i need to restart the clock after how many cycles : -// - (16000000 / 8) * 0.01 = 20000 ticks -> set ICR1 = 20000 -// - if i choose prescaler 64 for a duration of 0.01 seconds, i need to restart the clock after how many cycles : -// - (16000000 / 64) * 0.01 = 2500 ticks -> set ICR1 = 2500 +// - after how many "ticks" do i need to reset my clock, for a duration of 0.01s, for every prescalers : +// - 1 : (16000000 / 1) * 0.01 = 16000000 * 0.01 = 160000 "ticks" +// - 8 : (16000000 / 8) * 0.01 = 2000000 * 0.01 = 20000 "ticks" +// - 64 : (16000000 / 64) * 0.01 = 250000 * 0.01 = 2500 "ticks" +// - 256 : (16000000 / 256) * 0.01 = 62500 * 0.01 = 625 "ticks" +// - 1024 : (16000000 / 1024) * 0.01 = 15625 * 0.01 = 156,25 "ticks" // alternatively, can use the default values : // - Fast PWM, 8-bit, TOP 0x00FF (255) @@ -49,12 +49,22 @@ // 16.9.3 : timer1 fast PWM -#define LED1_PWM_PRESCALER 256 // can be 1, 8, 64, 256, 1024 -#define DUTY_CYCLE_PERCENT 9 -#define FREQUENCY_MS 1 -#define TOP_VALUE 1000 +// TIMER 1 +#define T1_PWM_PRESCALER 256 // can be 1, 8, 64, 256, 1024 +#define T1_DUTY_CYCLE_PERCENT 9 +// #define FREQUENCY_MS 1 +#define T1_TOP_VALUE 1000 +// TIMER 0 +#define T0_PWM_PRESCALER 256 // can be 1, 8, 64, 256, 1024 +#define T0_FREQUENCY_MS 20 -volatile uint8_t duty_cycle = DUTY_CYCLE_PERCENT; +typedef enum { + DOWN, + UP +} Slope; + +volatile uint8_t duty_cycle = T1_DUTY_CYCLE_PERCENT; +volatile Slope slope = UP; void blink_led_1() { TCCR1A = (1 << WGM11); // Table 16-4 : set timer1 in fast PWM mode 14, with TOP ICR1, so we can use OCR1A for duty cycle and keep ICR1 for frequency @@ -63,25 +73,21 @@ void blink_led_1() { TCCR1A |= (1 << COM1A1); // Table 16-2 : set non-inverting mode to trigger OC1A on fast PWM (14.3.1 : OC1A is alternate function of PB1) - TCCR1B |= PRESCALE_SET(LED1_PWM_PRESCALER); // Table 16-5 : set the appropriate prescale values + TCCR1B |= T1_PRESCALE_SET(T1_PWM_PRESCALER); // Table 16-5 : set the appropriate prescale values for timer 1 - // ICR1 = TIME_MS(FREQUENCY_MS, LED1_PWM_PRESCALER); // top value for Xms - ICR1 = TOP_VALUE; + // ICR1 = TIME_MS(FREQUENCY_MS, T1_PWM_PRESCALER); // top value for Xms + ICR1 = T1_TOP_VALUE; OCR1A = PERCENT(duty_cycle, ICR1); // 16.9.3 : duty cycle } -vary_duty() { - // TCCR0A = (1 << WGM11); // Table 15-8 : set timer0 in CTC mode, with TOP OCRA - // TCCR1B = (1 << WGM13) | (1 << WGM12); +void vary_duty() { + TCCR0A = (1 << WGM11); // Table 15-8 : set timer0 in CTC mode, with TOP OCRA (15.9.1 : WGM11 in register TCCR0A) - // TCCR1A |= (1 << COM1A1); // Table 16-2 : set non-inverting mode to trigger OC1A on fast PWM (14.3.1 : OC1A is alternate function of PB1) + OCR0A = TIME_MS(T0_FREQUENCY_MS, T0_PWM_PRESCALER); // 15.9.4 : compare value to trigger an Output Compare interrupt on register A - // TCCR1B |= PRESCALE_SET(LED1_PWM_PRESCALER); // Table 16-5 : set the appropriate prescale values - - // // ICR1 = TIME_MS(FREQUENCY_MS, LED1_PWM_PRESCALER); // top value for Xms - // ICR1 = TOP_VALUE; - // OCR1A = PERCENT(duty_cycle, ICR1); // 16.9.3 : duty cycle + TCCR0B |= T0_PRESCALE_SET(T0_PWM_PRESCALER); // 15.9.2 : set the appropriate prescale values for timer 0 + TIMSK0 = (1 << OCIE0A); // 15.9.6 : set OCIE0A in TIMSK0 to enable Compare Match A interrupt in Timer0 } // use timers interruptions to varie led1 intensity using duty cycle, from 0% to 100% to 0% in 1 second @@ -103,3 +109,20 @@ int main() { while (1); } + +ISR(TIMER0_COMPA_vect) { + if (slope == UP) { + if (duty_cycle >= 100) { + slope = DOWN; + } else { + duty_cycle += 2; + } + } + if (slope == DOWN) { + if (duty_cycle <= 0) { + slope = UP; + } else { + duty_cycle -= 2; + } + } +} \ No newline at end of file diff --git a/module04/ex01/timer.h b/module04/ex01/timer.h index 2493232..df4eaaa 100644 --- a/module04/ex01/timer.h +++ b/module04/ex01/timer.h @@ -1,8 +1,18 @@ #ifndef TIMER_H #define TIMER_H -// table 16-5 : prescale sets -#define PRESCALE_SET(value) \ +// table 15-9 : timer 0 prescale sets +#define T0_PRESCALE_SET(value) \ + ((value) == 1 ? (0<