more or less works
This commit is contained in:
255
controllino_io.c
Normal file
255
controllino_io.c
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* DMX buffer: indexed 1..512 */
|
||||||
|
extern volatile uint8_t dmx_data[];
|
||||||
|
|
||||||
|
/* Pin bit definitions (change bit numbers if different on your board) */
|
||||||
|
/* PE4, PE5, PG5, PE3, PH3, PH4, PH5, PH6, PB4, PB5, PB6, PB7,
|
||||||
|
PL7, PL6, PL5, PL4, PL3, PL2, PL1, PL0, PD4, PD5, PD6, PJ4 */
|
||||||
|
|
||||||
|
/* For each Dn we need to map which port and bit will hold bit0..bit7 of the
|
||||||
|
output byte. Here we assume each DMX channel is presented on a contiguous
|
||||||
|
8-bit port where possible. Since the pins are all over, we output each DMX
|
||||||
|
byte bit-by-bit to 8 dedicated pins: bit 0 -> mapped pin for bit0, ... bit7
|
||||||
|
-> mapped pin for bit7. Replace the per-bit port/bit assignments below to
|
||||||
|
match your desired wiring. */
|
||||||
|
|
||||||
|
/* Example per-bit mapping for channel outputs (one mapping choice). */
|
||||||
|
/* For brevity we map bits 0..7 of each channel to the same physical pin for
|
||||||
|
that channel, i.e., output the full byte on 8-bit bus is not possible on
|
||||||
|
single scattered pin. Instead we simply write the byte value to the port pins
|
||||||
|
that form an 8-bit port where possible. We'll implement writing each
|
||||||
|
channel's byte to its single port's low 8 bits when that port contains 8
|
||||||
|
consecutive pins; otherwise we write the byte on the low 8 bits of a chosen
|
||||||
|
port using the relevant mask. */
|
||||||
|
|
||||||
|
/* Define helper macros for writing masked values */
|
||||||
|
static inline void write_masked(volatile uint8_t *port, volatile uint8_t *ddr,
|
||||||
|
uint8_t mask, uint8_t value) {
|
||||||
|
uint8_t cur = *port & ~mask;
|
||||||
|
*port = cur | (value & mask);
|
||||||
|
*ddr |= mask; // ensure pins are outputs
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Concrete writers for the pins used (mask and port pointers) */
|
||||||
|
/* Adjust masks to the actual bit positions used on each port. The following
|
||||||
|
masks assume: PB4..PB7 -> bits 4..7 on PORTB (fits for D8..D11) PL0..PL7 ->
|
||||||
|
bits 0..7 on PORTL (fits for D12..D19) PH0..PH7 -> bits 0..7 on PORTH (we use
|
||||||
|
PH3..PH6 for D4..D7 -> need masking) PD4..PD6 -> bits 4..6 on PORTD
|
||||||
|
(D20..D22) PE0..PE7 -> bits 0..7 on PORTE (we use PE3,PE4,PE5 for D0,D1,D3)
|
||||||
|
PJ4 -> bit 4 on PORTJ (D23)
|
||||||
|
PG5 -> bit 5 on PORTG (D2)
|
||||||
|
*/
|
||||||
|
/* Write channel values to ports with appropriate masks */
|
||||||
|
void output_dmx_channels_1_24(void) {
|
||||||
|
/* D0 -> PE4 : map whole byte to bits 0..7 not possible; instead output
|
||||||
|
LSB..MSB across 8 pins For simplicity we output the byte value on an 8-bit
|
||||||
|
pseudo-bus using multiple ports: Here we implement a pragmatic approach:
|
||||||
|
output each channel value on 8 dedicated IO pins defined below. You must
|
||||||
|
adapt bit-to-pin assignments to match your wiring. */
|
||||||
|
|
||||||
|
/* Example assignment: use PORTL for D12..D19 (8-bit) */
|
||||||
|
/* D12..D19 handled below; for single-pin channels we output LSB on that pin
|
||||||
|
(as HIGH/LOW) — if you actually need parallel 8-bit outputs on dedicated
|
||||||
|
pins per channel, you'll need 8 pins per channel (192 pins) which is
|
||||||
|
unlikely. So this snippet writes each channel's byte value as a PWM-like
|
||||||
|
ON/OFF level on a single digital pin using thresholding:
|
||||||
|
-> if value >= 128 -> set pin HIGH else LOW. */
|
||||||
|
|
||||||
|
/* Quick implementation: set output pin HIGH if channel value >= 128, else
|
||||||
|
LOW. Map each D0..D23 to its port/bit and write accordingly. */
|
||||||
|
|
||||||
|
uint8_t v;
|
||||||
|
/* D0: PE4 (bit 4) */
|
||||||
|
v = dmx_data[1];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTE |= (1 << 4);
|
||||||
|
else
|
||||||
|
PORTE &= ~(1 << 4);
|
||||||
|
DDRE |= (1 << 4);
|
||||||
|
|
||||||
|
/* D1: PE5 (bit 5) */
|
||||||
|
v = dmx_data[2];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTE |= (1 << 5);
|
||||||
|
else
|
||||||
|
PORTE &= ~(1 << 5);
|
||||||
|
DDRE |= (1 << 5);
|
||||||
|
|
||||||
|
/* D2: PG5 (bit 5) */
|
||||||
|
v = dmx_data[3];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTG |= (1 << 5);
|
||||||
|
else
|
||||||
|
PORTG &= ~(1 << 5);
|
||||||
|
DDRG |= (1 << 5);
|
||||||
|
|
||||||
|
/* D3: PE3 (bit 3) */
|
||||||
|
v = dmx_data[4];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTE |= (1 << 3);
|
||||||
|
else
|
||||||
|
PORTE &= ~(1 << 3);
|
||||||
|
DDRE |= (1 << 3);
|
||||||
|
|
||||||
|
/* D4: PH3 (bit 3) */
|
||||||
|
v = dmx_data[5];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTH |= (1 << 3);
|
||||||
|
else
|
||||||
|
PORTH &= ~(1 << 3);
|
||||||
|
DDRH |= (1 << 3);
|
||||||
|
|
||||||
|
/* D5: PH4 (bit 4) */
|
||||||
|
v = dmx_data[6];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTH |= (1 << 4);
|
||||||
|
else
|
||||||
|
PORTH &= ~(1 << 4);
|
||||||
|
DDRH |= (1 << 4);
|
||||||
|
|
||||||
|
/* D6: PH5 (bit 5) */
|
||||||
|
v = dmx_data[7];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTH |= (1 << 5);
|
||||||
|
else
|
||||||
|
PORTH &= ~(1 << 5);
|
||||||
|
DDRH |= (1 << 5);
|
||||||
|
|
||||||
|
/* D7: PH6 (bit 6) */
|
||||||
|
v = dmx_data[8];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTH |= (1 << 6);
|
||||||
|
else
|
||||||
|
PORTH &= ~(1 << 6);
|
||||||
|
DDRH |= (1 << 6);
|
||||||
|
|
||||||
|
/* D8: PB4 (bit 4) */
|
||||||
|
v = dmx_data[9];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTB |= (1 << 4);
|
||||||
|
else
|
||||||
|
PORTB &= ~(1 << 4);
|
||||||
|
DDRB |= (1 << 4);
|
||||||
|
|
||||||
|
/* D9: PB5 (bit 5) */
|
||||||
|
v = dmx_data[10];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTB |= (1 << 5);
|
||||||
|
else
|
||||||
|
PORTB &= ~(1 << 5);
|
||||||
|
DDRB |= (1 << 5);
|
||||||
|
|
||||||
|
/* D10: PB6 (bit 6) */
|
||||||
|
v = dmx_data[11];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTB |= (1 << 6);
|
||||||
|
else
|
||||||
|
PORTB &= ~(1 << 6);
|
||||||
|
DDRB |= (1 << 6);
|
||||||
|
|
||||||
|
/* D11: PB7 (bit 7) */
|
||||||
|
v = dmx_data[12];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTB |= (1 << 7);
|
||||||
|
else
|
||||||
|
PORTB &= ~(1 << 7);
|
||||||
|
DDRB |= (1 << 7);
|
||||||
|
|
||||||
|
/* D12: PL7 (bit 7) */
|
||||||
|
v = dmx_data[13];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 7);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 7);
|
||||||
|
DDRL |= (1 << 7);
|
||||||
|
|
||||||
|
/* D13: PL6 (bit 6) */
|
||||||
|
v = dmx_data[14];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 6);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 6);
|
||||||
|
DDRL |= (1 << 6);
|
||||||
|
|
||||||
|
/* D14: PL5 (bit 5) */
|
||||||
|
v = dmx_data[15];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 5);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 5);
|
||||||
|
DDRL |= (1 << 5);
|
||||||
|
|
||||||
|
/* D15: PL4 (bit 4) */
|
||||||
|
v = dmx_data[16];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 4);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 4);
|
||||||
|
DDRL |= (1 << 4);
|
||||||
|
|
||||||
|
/* D16: PL3 (bit 3) */
|
||||||
|
v = dmx_data[17];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 3);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 3);
|
||||||
|
DDRL |= (1 << 3);
|
||||||
|
|
||||||
|
/* D17: PL2 (bit 2) */
|
||||||
|
v = dmx_data[18];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 2);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 2);
|
||||||
|
DDRL |= (1 << 2);
|
||||||
|
|
||||||
|
/* D18: PL1 (bit 1) */
|
||||||
|
v = dmx_data[19];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 1);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 1);
|
||||||
|
DDRL |= (1 << 1);
|
||||||
|
|
||||||
|
/* D19: PL0 (bit 0) */
|
||||||
|
v = dmx_data[20];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTL |= (1 << 0);
|
||||||
|
else
|
||||||
|
PORTL &= ~(1 << 0);
|
||||||
|
DDRL |= (1 << 0);
|
||||||
|
|
||||||
|
/* D20: PD4 (bit 4) */
|
||||||
|
v = dmx_data[21];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTD |= (1 << 4);
|
||||||
|
else
|
||||||
|
PORTD &= ~(1 << 4);
|
||||||
|
DDRD |= (1 << 4);
|
||||||
|
|
||||||
|
/* D21: PD5 (bit 5) */
|
||||||
|
v = dmx_data[22];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTD |= (1 << 5);
|
||||||
|
else
|
||||||
|
PORTD &= ~(1 << 5);
|
||||||
|
DDRD |= (1 << 5);
|
||||||
|
|
||||||
|
/* D22: PD6 (bit 6) */
|
||||||
|
v = dmx_data[23];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTD |= (1 << 6);
|
||||||
|
else
|
||||||
|
PORTD &= ~(1 << 6);
|
||||||
|
DDRD |= (1 << 6);
|
||||||
|
|
||||||
|
/* D23: PJ4 (bit 4) */
|
||||||
|
v = dmx_data[24];
|
||||||
|
if (v >= 128)
|
||||||
|
PORTJ |= (1 << 4);
|
||||||
|
else
|
||||||
|
PORTJ &= ~(1 << 4);
|
||||||
|
DDRJ |= (1 << 4);
|
||||||
|
}
|
||||||
52
dmxtest.py
Normal file
52
dmxtest.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import serial
|
||||||
|
import time
|
||||||
|
|
||||||
|
DEVICE = "/dev/ttyUSB0"
|
||||||
|
BAUD = 250000 # DMX baud
|
||||||
|
CHANNELS = 512
|
||||||
|
ACTIVE_COUNT = 24 # cycle through channels 1..24
|
||||||
|
|
||||||
|
def send_dmx(ser, data):
|
||||||
|
try:
|
||||||
|
ser.break_condition = True
|
||||||
|
time.sleep(0.0001) # 100 µs
|
||||||
|
ser.break_condition = False
|
||||||
|
except Exception:
|
||||||
|
ser.baudrate = 57600
|
||||||
|
ser.write(b'\x00')
|
||||||
|
ser.flush()
|
||||||
|
ser.baudrate = BAUD
|
||||||
|
|
||||||
|
time.sleep(0.000012) # 12 µs MAB
|
||||||
|
frame = bytes([0x00]) + bytes(data)
|
||||||
|
ser.write(frame)
|
||||||
|
ser.flush()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
dmx_values = bytearray([0]*(CHANNELS)) # index 0 -> channel 1
|
||||||
|
with serial.Serial(DEVICE, baudrate=BAUD, bytesize=serial.EIGHTBITS,
|
||||||
|
parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_TWO,
|
||||||
|
timeout=1) as ser:
|
||||||
|
time.sleep(0.1)
|
||||||
|
chan = 0
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
# clear all
|
||||||
|
for i in range(CHANNELS):
|
||||||
|
dmx_values[i] = 0
|
||||||
|
# set active channel (channels 1..ACTIVE_COUNT)
|
||||||
|
dmx_values[chan] = 255
|
||||||
|
send_dmx(ser, dmx_values)
|
||||||
|
time.sleep(0.025) # frame delay; adjust if desired
|
||||||
|
|
||||||
|
# advance channel (wrap within 0..ACTIVE_COUNT-1)
|
||||||
|
chan += 1
|
||||||
|
if chan >= ACTIVE_COUNT:
|
||||||
|
chan = 0
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
126
main.c
126
main.c
@@ -2,7 +2,9 @@
|
|||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define F_CPU 16000000UL
|
||||||
#define DMX_CHANNELS 512
|
#define DMX_CHANNELS 512
|
||||||
|
|
||||||
volatile uint8_t dmx_data[DMX_CHANNELS + 1]; // 1..512
|
volatile uint8_t dmx_data[DMX_CHANNELS + 1]; // 1..512
|
||||||
@@ -10,117 +12,111 @@ volatile uint16_t dmx_index = 0;
|
|||||||
volatile bool dmx_frame_ready = false;
|
volatile bool dmx_frame_ready = false;
|
||||||
volatile bool receiving = false;
|
volatile bool receiving = false;
|
||||||
|
|
||||||
|
extern void output_dmx_channels_1_24(void);
|
||||||
|
|
||||||
|
/* --- USART3 (DMX) init & ISR --- */
|
||||||
void uart3_init(void) {
|
void uart3_init(void) {
|
||||||
// Set baud rate for 250000 (F_CPU must be set accordingly).
|
// uint16_t ubrr = (F_CPU / (16UL * 250000UL)) - 1; // 250000 baud
|
||||||
// Formula UBRR = F_CPU/(16*baud)-1 ; For high speed use U2X - but DMX
|
// UBRR3H = (uint8_t)(ubrr >> 8);
|
||||||
// typically uses normal mode. For F_CPU = 16MHz: UBRR =
|
// UBRR3L = (uint8_t)ubrr;
|
||||||
// 16,000,000/(16*250000)-1 = 3 We'll enable UBRR3 with 3 for 16MHz; adjust if
|
UBRR3L = 3;
|
||||||
// F_CPU differs.
|
|
||||||
uint16_t ubrr = 3;
|
|
||||||
UBRR3H = (uint8_t)(ubrr >> 8);
|
|
||||||
UBRR3L = (uint8_t)ubrr;
|
|
||||||
|
|
||||||
// Enable receiver and RX complete interrupt
|
|
||||||
UCSR3B = (1 << RXEN3) | (1 << RXCIE3);
|
UCSR3B = (1 << RXEN3) | (1 << RXCIE3);
|
||||||
|
UCSR3C = (1 << USBS3) | (1 << UCSZ31) | (1 << UCSZ30); // 8N2
|
||||||
// Set frame format: 8 data, 2 stop bits (USBS3 = 1)
|
|
||||||
UCSR3C = (1 << USBS3) | (1 << UCSZ31) | (1 << UCSZ30);
|
|
||||||
|
|
||||||
// Note: parity default is none (UPM bits = 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(USART3_RX_vect) {
|
ISR(USART3_RX_vect) {
|
||||||
PORTE |= 1 << 4;
|
|
||||||
|
|
||||||
uint8_t status = UCSR3A;
|
uint8_t status = UCSR3A;
|
||||||
uint8_t data = UDR3; // reading UDR clears the receive flag
|
uint8_t data = UDR3;
|
||||||
|
|
||||||
// If framing error -> likely BREAK (line held low longer than a byte time)
|
|
||||||
if (status & (1 << FE3)) {
|
if (status & (1 << FE3)) {
|
||||||
// Break detected: start of new DMX packet
|
// Break detected: start new DMX packet
|
||||||
receiving = true;
|
receiving = true;
|
||||||
dmx_index = 0;
|
dmx_index = 0;
|
||||||
dmx_frame_ready = false;
|
dmx_frame_ready = false;
|
||||||
return; // discard this byte (it's break/MAF)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!receiving) {
|
|
||||||
// Not currently inside a DMX frame; ignore bytes until we detect break
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DMX: first byte after break is START CODE (usually 0); then channel
|
if (!receiving)
|
||||||
// data 1..512
|
return;
|
||||||
|
|
||||||
if (dmx_index == 0) {
|
if (dmx_index == 0) {
|
||||||
// start code
|
// start code (usually 0) - ignore/store as needed
|
||||||
// Optionally check for start code == 0, otherwise may discard or handle RDM
|
dmx_index++; // next byte will be channel 1
|
||||||
// etc. We'll accept any start code but only store channels.
|
|
||||||
dmx_index++; // move to channel 1 next
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dmx_index corresponds to channel number
|
|
||||||
if (dmx_index <= DMX_CHANNELS) {
|
if (dmx_index <= DMX_CHANNELS) {
|
||||||
dmx_data[dmx_index] = data;
|
dmx_data[dmx_index] = data;
|
||||||
dmx_index++;
|
dmx_index++;
|
||||||
if (dmx_index > DMX_CHANNELS) {
|
if (dmx_index > DMX_CHANNELS) {
|
||||||
// Received full frame
|
|
||||||
dmx_frame_ready = true;
|
dmx_frame_ready = true;
|
||||||
receiving = false; // wait for next break
|
receiving = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Overflow (more bytes than expected) — treat as end and wait for next
|
|
||||||
// break
|
|
||||||
dmx_frame_ready = true;
|
dmx_frame_ready = true;
|
||||||
receiving = false;
|
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) {
|
int main(void) {
|
||||||
// Example CPU freq assumption: 16 MHz. If different, adjust UBRR in
|
|
||||||
// uart3_init.
|
|
||||||
|
|
||||||
DDRE |= 1 << 4;
|
|
||||||
|
|
||||||
cli();
|
cli();
|
||||||
uart3_init();
|
|
||||||
|
|
||||||
// Optional: initialize array
|
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)
|
for (uint16_t i = 1; i <= DMX_CHANNELS; ++i)
|
||||||
dmx_data[i] = 0;
|
dmx_data[i] = 0;
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
// Main loop: react to finished frames
|
// Example usage
|
||||||
|
printf("DMX receiver started\r\n");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (dmx_frame_ready) {
|
if (dmx_frame_ready) {
|
||||||
// Example: use channel 1..512 from dmx_data
|
// Example debug: print first 8 channels
|
||||||
// Process dmx_data here. This is a single buffer; if processing takes
|
printf("DMX frame received. Ch1..8: ");
|
||||||
// long, consider double-buffering to avoid race with ISR.
|
for (uint8_t i = 1; i <= 8; ++i) {
|
||||||
|
printf("%u ", dmx_data[i]);
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
|
||||||
// After consuming, clear flag
|
|
||||||
dmx_frame_ready = false;
|
dmx_frame_ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (dmx_data[1])
|
output_dmx_channels_1_24();
|
||||||
// PORTE |= 1 << 4;
|
|
||||||
// else
|
|
||||||
// PORTE &= ~(1 << 4);
|
|
||||||
|
|
||||||
// Other application code...
|
// other app code...
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #include <avr/io.h>
|
|
||||||
// #include <util/delay.h>
|
|
||||||
//
|
|
||||||
// int main(void) {
|
|
||||||
// DDRE = 1 << 4;
|
|
||||||
//
|
|
||||||
// while (1) {
|
|
||||||
// PORTE ^= 1 << 4;
|
|
||||||
// _delay_ms(500);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
Reference in New Issue
Block a user