diff --git a/module04/ex00 copy/main.c b/module04/ex00 copy/main.c deleted file mode 100644 index 9b9e6ca..0000000 --- a/module04/ex00 copy/main.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "header.h" - -// 14.3.3 : alternate functions on port D -// PD2 : - INT0 (External Interrupt 0 Input) -// - PCINT18 (Pin Change Interrupt 18) -// 12.4 : Interrupt Vectors in ATmega328 and ATmega328P -// - INT0 : External Interrupt Request 0 - -typedef enum { - DOWN, - UP -} State; -volatile uint8_t button_state = UP; - -// Table 13-2 : interrupt types -#define INT0_LOW ((0 << ISC01) | (0 << ISC01)) -#define INT0_LOGICAL ((0 << ISC01) | (1 << ISC01)) -#define INT0_FALLING ((1 << ISC01) | (0 << ISC01)) -#define INT0_RAISING ((1 << ISC01) | (1 << ISC01)) - -// use interruption to change led1 state when button1 is pressed -int main() { - MODE_OUTPUT(LED1); - CLEAR_ELEM(LED1); - MODE_INPUT(BUTTON1); - PULLUP_ON(BUTTON1); - - SREG |= ENABLE_GLOBAL_INTERRUPT; - - EIMSK = (1 << INT0); // 13.2.2 : Enable INT0 interrupt (EIMSK – External Interrupt Mask Register) - EICRA = INT0_LOGICAL; // Table 13-2 : trigger type (EICRA – External Interrupt Control Register A) - - while (1); -} - -ISR(INT0_vect) { - _delay_ms(50); - button_state = (button_state == UP) ? DOWN : UP; - if (button_state == UP) { - TOGGLE_ELEM(LED1); - } - // EIFR = (1 << INTF0); // 13.2.3 : clear flag, why ? i think it only indicates that a trigger event has occured -} diff --git a/module04/ex00 copy/Makefile b/module04/ex01/Makefile similarity index 100% rename from module04/ex00 copy/Makefile rename to module04/ex01/Makefile diff --git a/module04/ex00 copy/bitmanip.h b/module04/ex01/bitmanip.h similarity index 100% rename from module04/ex00 copy/bitmanip.h rename to module04/ex01/bitmanip.h diff --git a/module04/ex00 copy/header.h b/module04/ex01/header.h similarity index 84% rename from module04/ex00 copy/header.h rename to module04/ex01/header.h index b4fe0d1..5934f5d 100644 --- a/module04/ex00 copy/header.h +++ b/module04/ex01/header.h @@ -8,6 +8,7 @@ #include "utils.h" #include "bitmanip.h" #include "interrupt.h" +#include "timer.h" // // PROTOTYPES diff --git a/module04/ex00 copy/interrupt.h b/module04/ex01/interrupt.h similarity index 100% rename from module04/ex00 copy/interrupt.h rename to module04/ex01/interrupt.h diff --git a/module04/ex01/main.c b/module04/ex01/main.c new file mode 100644 index 0000000..48ffb91 --- /dev/null +++ b/module04/ex01/main.c @@ -0,0 +1,58 @@ +#include "header.h" + +// 14.3.1 : alternate functions for led2 PB1 +// - OC1A (Timer/Counter1 Output Compare Match A Output) +// - 16.11.1 controlled by COM1A1:0 in TCCR1A +// - Table 16-2 : Compare Output Mode, Fast PWM +// (1 << COM1A1) | (0 << COM1A0) -> non-inverting mode +// - Table 16-4 : set timer 1 in fast PWM mode, with top as ICR1 or OCR1A +// - ICR1 : Input Capture Register ((1 << WGM13) | (1 << WGM12) | (1 << WGM11) | (0 << WGM10)) +// - OCR1A : Output Compare Register ((1 << WGM13) | (1 << WGM12) | (1 << WGM11) | (1 << WGM10)) +// -> if OCR1A is top, it's also duty cycle, so changing duty cycle will also change frequency +// -> if ICR1 is top, OCR1A is duty cycle, so it can be changed independantly +// - PCINT1 (Pin Change Interrupt 1) : to interrupt when pin change, in input mode only + +// calulations +// - frequency is 16Mhz -> it means that the clock runs 16 000 000 times per seconds +// - and the timer1 can store 16 bits value of cycle -> which is 2^16 = 65536 +// - so it will only last 65536/16000000 = 0,004096 second +// - if i want my cycle to be 0.001 second, prescaler 1 is enough +// - 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 + +// 16.9.3 : timer1 fast PWM + +#define LED1_PWM_PRESCALER 8 // can be 1, 8, 64, 256, 1024 +#define DUTY_CYCLE_PERCENT 9 +#define FRQUENCY_MS 1 + +// use timers interruptions to varie led1 intensity using duty cycle, from 0% to 100% to 0% in 1 second +// timer1 sets the led duty cycle, timer0 change the duty cycle percentage +int main() { + MODE_OUTPUT(LED1); + CLEAR_ELEM(LED1); + MODE_OUTPUT(LED2); + CLEAR_ELEM(LED2); + + SREG |= ENABLE_GLOBAL_INTERRUPT; + + TCCR1A = (1 << WGM11); // Table 16-4 : set fast PWM mode with TOP ICR1, so we can use OCR1A for duty cycle and keep ICR1 for frequency + TCCR1B = (1 << WGM13) | (1 << WGM12); + + TCCR1A |= (1 << COM1A1); // Table 16-2 : set non-inverting mode to trigger OC1A on fast PWM + + TCCR1B |= PRESCALE_SET(LED1_PWM_PRESCALER); // Table 16-5 : set the appropriate prescale values + + ICR1 = TIME_MS(FRQUENCY_MS, LED1_PWM_PRESCALER); // top value for Xms + + OCR1A = PERCENT(DUTY_CYCLE_PERCENT, ICR1); // duty cycle frequence + + while (1); +} diff --git a/module04/ex00 copy/timer.h b/module04/ex01/timer.h similarity index 100% rename from module04/ex00 copy/timer.h rename to module04/ex01/timer.h diff --git a/module04/ex00 copy/usart.h b/module04/ex01/usart.h similarity index 100% rename from module04/ex00 copy/usart.h rename to module04/ex01/usart.h diff --git a/module04/ex00 copy/utils.h b/module04/ex01/utils.h similarity index 100% rename from module04/ex00 copy/utils.h rename to module04/ex01/utils.h