mod02 ex03

This commit is contained in:
hugogogo
2025-03-07 17:03:21 +01:00
parent b05b9f0298
commit 652a7913de
3 changed files with 47 additions and 46 deletions

View File

@@ -107,6 +107,7 @@
#define FAST_PWM_TOP_OCR1A_IN_TCCR1A (1<<WGM11 | 1<<WGM10) #define FAST_PWM_TOP_OCR1A_IN_TCCR1A (1<<WGM11 | 1<<WGM10)
#define FAST_PWM_TOP_ICR1_IN_TCCR1B (1<<WGM13 | 1<<WGM12) #define FAST_PWM_TOP_ICR1_IN_TCCR1B (1<<WGM13 | 1<<WGM12)
#define FAST_PWM_TOP_ICR1_IN_TCCR1A (1<<WGM11 | 0<<WGM10) #define FAST_PWM_TOP_ICR1_IN_TCCR1A (1<<WGM11 | 0<<WGM10)
// 16.11.8 : Timer/Counter1 Interrupt Mask Register
#define INTERRUPT_ENABLE_CHANNEL_A (1 << OCIE1A) #define INTERRUPT_ENABLE_CHANNEL_A (1 << OCIE1A)
#define INTERRUPT_DISABLE_CHANNEL_A (0 << OCIE1A) #define INTERRUPT_DISABLE_CHANNEL_A (0 << OCIE1A)

View File

@@ -107,6 +107,7 @@
#define FAST_PWM_TOP_OCR1A_IN_TCCR1A (1<<WGM11 | 1<<WGM10) #define FAST_PWM_TOP_OCR1A_IN_TCCR1A (1<<WGM11 | 1<<WGM10)
#define FAST_PWM_TOP_ICR1_IN_TCCR1B (1<<WGM13 | 1<<WGM12) #define FAST_PWM_TOP_ICR1_IN_TCCR1B (1<<WGM13 | 1<<WGM12)
#define FAST_PWM_TOP_ICR1_IN_TCCR1A (1<<WGM11 | 0<<WGM10) #define FAST_PWM_TOP_ICR1_IN_TCCR1A (1<<WGM11 | 0<<WGM10)
// 16.11.8 : Timer/Counter1 Interrupt Mask Register
#define INTERRUPT_ENABLE_CHANNEL_A (1 << OCIE1A) #define INTERRUPT_ENABLE_CHANNEL_A (1 << OCIE1A)
#define INTERRUPT_DISABLE_CHANNEL_A (0 << OCIE1A) #define INTERRUPT_DISABLE_CHANNEL_A (0 << OCIE1A)
@@ -136,13 +137,6 @@ char uart_rx(void) {
int main() { int main() {
uart_init(); 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;
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; char received_char;
while(1) { while(1) {
received_char = uart_rx(); received_char = uart_rx();

View File

@@ -1,6 +1,6 @@
#include <avr/io.h> #include <avr/io.h>
#include <util/delay.h> #include <util/delay.h>
#include <avr/interrupt.h> #include <avr/interrupt.h> // https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
// mathematics // mathematics
#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) // https://stackoverflow.com/a/18067292 #define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) // https://stackoverflow.com/a/18067292
@@ -85,6 +85,10 @@
#define RECEIVER_ENABLED (1<<RXEN0) #define RECEIVER_ENABLED (1<<RXEN0)
#define TRANSMITTER_DISABLED (0<<TXEN0) #define TRANSMITTER_DISABLED (0<<TXEN0)
#define TRANSMITTER_ENABLED (1<<TXEN0) #define TRANSMITTER_ENABLED (1<<TXEN0)
#define INTERRUPT_RECEIVER_DISABLED (0<<RXCIE0)
#define INTERRUPT_RECEIVER_ENABLED (1<<RXCIE0)
#define INTERRUPT_TRANSMITTER_DISABLED (0<<TXCIE0)
#define INTERRUPT_TRANSMITTER_ENABLED (1<<TXCIE0)
// TIMER // TIMER
#define PERIOD 2000 #define PERIOD 2000
@@ -107,9 +111,13 @@
#define FAST_PWM_TOP_OCR1A_IN_TCCR1A (1<<WGM11 | 1<<WGM10) #define FAST_PWM_TOP_OCR1A_IN_TCCR1A (1<<WGM11 | 1<<WGM10)
#define FAST_PWM_TOP_ICR1_IN_TCCR1B (1<<WGM13 | 1<<WGM12) #define FAST_PWM_TOP_ICR1_IN_TCCR1B (1<<WGM13 | 1<<WGM12)
#define FAST_PWM_TOP_ICR1_IN_TCCR1A (1<<WGM11 | 0<<WGM10) #define FAST_PWM_TOP_ICR1_IN_TCCR1A (1<<WGM11 | 0<<WGM10)
// 16.11.8 : Timer/Counter1 Interrupt Mask Register
#define INTERRUPT_ENABLE_CHANNEL_A (1 << OCIE1A) #define INTERRUPT_ENABLE_CHANNEL_A (1 << OCIE1A)
#define INTERRUPT_DISABLE_CHANNEL_A (0 << OCIE1A) #define INTERRUPT_DISABLE_CHANNEL_A (0 << OCIE1A)
// text
#define SWITCH_CASE(ch) (((ch) >= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch))
// END MACROS // END MACROS
void uart_init() { void uart_init() {
@@ -118,34 +126,32 @@ void uart_init() {
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) { 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) 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) UDR0 = (unsigned char) c; // 20.11.1 : Put data into buffer, UDRn USART I/O Data Register (read and write)
} }
char uart_rx(void) { ISR(USART_RX_vect) { // Table 12-7 : we select the code for USART Receive
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) // char received_char = uart_rx();
return UDR0; // 20.11.1 : get data in buffer, UDRn USART I/O Data Register (read and write) 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` // `screen /dev/ttyUSB0 115200`
int main() { int main() {
uart_init(); uart_init();
TCCR1A |= CTC_TOP_OCR1A_IN_TCCR1A; // Table 16-4 : set timer in CTC (Clear Time on Compare) mode sei(); // enable global interrupts
TCCR1B |= CTC_TOP_OCR1A_IN_TCCR1B;
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 while(1);
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);
}
} }