#include #include #include #include #include #define F_CPU 16000000UL #define DMX_CHANNELS 512 volatile uint8_t dmx_data[DMX_CHANNELS + 1]; // 1..512 volatile uint16_t dmx_index = 0; volatile bool dmx_frame_ready = false; volatile bool receiving = false; extern void output_dmx_channels_1_24(void); /* --- USART3 (DMX) init & ISR --- */ void uart3_init(void) { // uint16_t ubrr = (F_CPU / (16UL * 250000UL)) - 1; // 250000 baud // UBRR3H = (uint8_t)(ubrr >> 8); // UBRR3L = (uint8_t)ubrr; UBRR3L = 3; UCSR3B = (1 << RXEN3) | (1 << RXCIE3); UCSR3C = (1 << USBS3) | (1 << UCSZ31) | (1 << UCSZ30); // 8N2 } ISR(USART3_RX_vect) { uint8_t status = UCSR3A; uint8_t data = UDR3; if (status & (1 << FE3)) { // Break detected: start new DMX packet receiving = true; dmx_index = 0; dmx_frame_ready = false; return; } if (!receiving) return; if (dmx_index == 0) { // start code (usually 0) - ignore/store as needed dmx_index++; // next byte will be channel 1 return; } if (dmx_index <= DMX_CHANNELS) { dmx_data[dmx_index] = data; dmx_index++; if (dmx_index > DMX_CHANNELS) { dmx_frame_ready = true; receiving = false; } } else { dmx_frame_ready = true; receiving = false; } } /* --- USART0 (printf/debug) init & putchar --- */ void uart0_init(uint32_t baud) { // uint16_t ubrr = (uint16_t)((F_CPU / (16UL * baud)) - 1UL); // UBRR0H = (uint8_t)(ubrr >> 8); // UBRR0L = (uint8_t)ubrr; UBRR0L = 8; UCSR0B = (1 << TXEN0); // enable transmitter UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 data, 1 stop, no parity } int uart0_putchar(char c, FILE *stream) { if (c == '\n') uart0_putchar('\r', stream); // CRLF while (!(UCSR0A & (1 << UDRE0))) ; // wait until buffer empty UDR0 = (uint8_t)c; return 0; } /* Create a FILE stream for stdout */ static FILE uart0_stdout = FDEV_SETUP_STREAM(uart0_putchar, NULL, _FDEV_SETUP_WRITE); int main(void) { cli(); DDRJ |= 1 << 5; // enable rs485 receiver uart3_init(); uart0_init(115200); // debug baud // Hook stdout to UART0 stdout = &uart0_stdout; // init DMX buffer for (uint16_t i = 1; i <= DMX_CHANNELS; ++i) dmx_data[i] = 0; sei(); // Example usage printf("DMX receiver started\r\n"); while (1) { if (dmx_frame_ready) { // Example debug: print first 8 channels printf("DMX frame received. Ch1..8: "); for (uint8_t i = 1; i <= 8; ++i) { printf("%u ", dmx_data[i]); } printf("\r\n"); dmx_frame_ready = false; } output_dmx_channels_1_24(); // other app code... } return 0; }