From 652a7913de9fae57a935da420d7af4e76bc33eb4 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Fri, 7 Mar 2025 17:03:21 +0100 Subject: [PATCH] mod02 ex03 --- module02/ex01/main.c | 1 + module02/ex02/main.c | 8 +---- module02/ex03/main.c | 84 ++++++++++++++++++++++++-------------------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/module02/ex01/main.c b/module02/ex01/main.c index fb8bfb9..eb5f809 100644 --- a/module02/ex01/main.c +++ b/module02/ex01/main.c @@ -107,6 +107,7 @@ #define FAST_PWM_TOP_OCR1A_IN_TCCR1A (1< #include -#include +#include // https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html // mathematics #define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) // https://stackoverflow.com/a/18067292 @@ -62,29 +62,33 @@ // USART // Table 20-1 : Baud Rate Calculation -#define USART_BAUDRATE 115200 -#define BAUD_PRESCALER (DIV_ROUND_CLOSEST(F_CPU, (16 * USART_BAUDRATE)) - 1) +#define USART_BAUDRATE 115200 +#define BAUD_PRESCALER (DIV_ROUND_CLOSEST(F_CPU, (16 * USART_BAUDRATE)) - 1) // Table 20-8 : Mode Selection (USART Mode SELect) -#define ASYNCHRONOUS (0<= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) + // END MACROS void uart_init() { - UBRR0H = (unsigned char) (BAUD_PRESCALER >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0H = (unsigned char) (BAUD_PRESCALER >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers UBRR0L = (unsigned char) BAUD_PRESCALER; - UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format + UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format - UCSR0B |= RECEIVER_ENABLED | TRANSMITTER_ENABLED; // 20.11.3 : enable Receiver and/or Transmitter + UCSR0B |= RECEIVER_ENABLED | TRANSMITTER_ENABLED | INTERRUPT_RECEIVER_ENABLED; // 20.11.3 : enable Receiver and Transmitter, and interrupt on receiver } +// char uart_rx(void) { +// while (TEST(UCSR0A, RXC0) == 0); // 20.11.2 : do nothing until there are unread data in the receive buffer (UDRn), (RXCn flag in UCSRnA register set to 1 when buffer has data) +// return UDR0; // 20.11.1 : get data in buffer, UDRn – USART I/O Data Register (read and write) +// } + void uart_tx(char c) { - while (TEST(UCSR0A, UDRE0) == 0); // 20.11.2 : do nothing until UDRn buffer is empty, (UDREn flag in UCSRnA register set to 1 when buffer empty) - UDR0 = (unsigned char) c; // 20.11.1 : Put data into buffer, UDRn – USART I/O Data Register (read and write) + while (TEST(UCSR0A, UDRE0) == 0); // 20.11.2 : do nothing until UDRn buffer is empty, (UDREn flag in UCSRnA register set to 1 when buffer empty) + UDR0 = (unsigned char) c; // 20.11.1 : Put data into buffer, UDRn – USART I/O Data Register (read and write) } -char uart_rx(void) { - while (TEST(UCSR0A, RXC0) == 0); // 20.11.2 : do nothing until there are unread data in the receive buffer (UDRn), (RXCn flag in UCSRnA register set to 1 when buffer has data) - return UDR0; // 20.11.1 : get data in buffer, UDRn – USART I/O Data Register (read and write) +ISR(USART_RX_vect) { // Table 12-7 : we select the code for USART Receive + // char received_char = uart_rx(); + char received_char = UDR0; // Read received character + uart_tx(SWITCH_CASE(received_char)); // Toggle case and send back } -// send back caracters received on serial port +// send back caracters received on serial port with case toggling, using interupt and empty infinite loop // `screen /dev/ttyUSB0 115200` int main() { uart_init(); - TCCR1A |= CTC_TOP_OCR1A_IN_TCCR1A; // Table 16-4 : set timer in CTC (Clear Time on Compare) mode - TCCR1B |= CTC_TOP_OCR1A_IN_TCCR1B; + sei(); // enable global interrupts - OCR1A = TIME_MS(PERIOD); // Table 16-4 : set CTC compare value on channel A, the counter is cleared to zero when the counter value (TCNT1) matches the OCR1A register - - TCCR1B |= (PRESCALE_SET(PRESCALE_VALUE)); // 16.4 : set timer according to prescale value, in register TCCR1B, table 16-5 : prescale sets - - char received_char; - while(1) { - received_char = uart_rx(); - uart_tx(received_char); - } + while(1); } +