first ai miss
This commit is contained in:
56
Makefile
Normal file
56
Makefile
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
TARGET = main
|
||||||
|
SRCS := $(shell find -name '*.c')
|
||||||
|
FILES = $(SRCS:%.c=%)
|
||||||
|
MCU = atmega2560
|
||||||
|
PROGC = m2560
|
||||||
|
CC = avr-gcc
|
||||||
|
#TOOL = stk500 -P /dev/ttyUSB0
|
||||||
|
TOOL = atmelice_isp
|
||||||
|
#TOOL = avrispmkii
|
||||||
|
#TOOL = usbasp-clone
|
||||||
|
|
||||||
|
BUILDDIR = Builds
|
||||||
|
|
||||||
|
DEFINES = -DF_CPU=16000000UL
|
||||||
|
|
||||||
|
CFLAGS =-mmcu=$(MCU) -O2 -Wall -Wpedantic $(DEFINES) -std=c99 -ffunction-sections -fdata-sections
|
||||||
|
LDFLAGS =-mmcu=$(MCU) -Wl,--gc-sections
|
||||||
|
|
||||||
|
LDFILES = $(foreach FILE,$(FILES),$(BUILDDIR)/$(FILE).o)
|
||||||
|
|
||||||
|
all: clean $(BUILDDIR)/$(TARGET).elf
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.o: %.c
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $(BUILDDIR)/$*.o
|
||||||
|
|
||||||
|
$(BUILDDIR)/$(TARGET).elf: $(LDFILES)
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
$(CC) $(LDFLAGS) $(LDFILES) -o $(BUILDDIR)/$(TARGET).elf
|
||||||
|
|
||||||
|
$(BUILDDIR)/$(TARGET).hex : $(BUILDDIR)/$(TARGET).elf
|
||||||
|
avr-objcopy -j .data -j .text -O ihex $< $@
|
||||||
|
|
||||||
|
load: $(BUILDDIR)/$(TARGET).hex
|
||||||
|
avrdude -p $(PROGC) -c $(TOOL) -U flash:w:$(BUILDDIR)/$(TARGET).hex -v -B 4MHz
|
||||||
|
|
||||||
|
program: clean load
|
||||||
|
|
||||||
|
reset:
|
||||||
|
avrdude -p $(PROGC) -c $(TOOL)
|
||||||
|
|
||||||
|
size: $(BUILDDIR)/$(TARGET).elf
|
||||||
|
avr-size -C --mcu=$(MCU) $(BUILDDIR)/$(TARGET).elf
|
||||||
|
|
||||||
|
.PHONY=clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
|
|
||||||
|
#Fuse m1284p external Osz. Long startuptime
|
||||||
|
# avrdude -c usbasp-clone -p m1284p -U lfuse:w:0xff:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m
|
||||||
|
|
||||||
|
#Fuse m1284p internal Osz. Long startuptime
|
||||||
|
# avrdude -c usbasp-clone -p m1284p -U lfuse:w:0xe2:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m
|
||||||
|
|
||||||
|
|
||||||
126
main.c
Normal file
126
main.c
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
void uart3_init(void) {
|
||||||
|
// Set baud rate for 250000 (F_CPU must be set accordingly).
|
||||||
|
// Formula UBRR = F_CPU/(16*baud)-1 ; For high speed use U2X - but DMX
|
||||||
|
// typically uses normal mode. For F_CPU = 16MHz: UBRR =
|
||||||
|
// 16,000,000/(16*250000)-1 = 3 We'll enable UBRR3 with 3 for 16MHz; adjust if
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
PORTE |= 1 << 4;
|
||||||
|
|
||||||
|
uint8_t status = UCSR3A;
|
||||||
|
uint8_t data = UDR3; // reading UDR clears the receive flag
|
||||||
|
|
||||||
|
// If framing error -> likely BREAK (line held low longer than a byte time)
|
||||||
|
if (status & (1 << FE3)) {
|
||||||
|
// Break detected: start of new DMX packet
|
||||||
|
receiving = true;
|
||||||
|
dmx_index = 0;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMX: first byte after break is START CODE (usually 0); then channel
|
||||||
|
// data 1..512
|
||||||
|
if (dmx_index == 0) {
|
||||||
|
// start code
|
||||||
|
// Optionally check for start code == 0, otherwise may discard or handle RDM
|
||||||
|
// etc. We'll accept any start code but only store channels.
|
||||||
|
dmx_index++; // move to channel 1 next
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dmx_index corresponds to channel number
|
||||||
|
if (dmx_index <= DMX_CHANNELS) {
|
||||||
|
dmx_data[dmx_index] = data;
|
||||||
|
dmx_index++;
|
||||||
|
if (dmx_index > DMX_CHANNELS) {
|
||||||
|
// Received full frame
|
||||||
|
dmx_frame_ready = true;
|
||||||
|
receiving = false; // wait for next break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Overflow (more bytes than expected) — treat as end and wait for next
|
||||||
|
// break
|
||||||
|
dmx_frame_ready = true;
|
||||||
|
receiving = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// Example CPU freq assumption: 16 MHz. If different, adjust UBRR in
|
||||||
|
// uart3_init.
|
||||||
|
|
||||||
|
DDRE |= 1 << 4;
|
||||||
|
|
||||||
|
cli();
|
||||||
|
uart3_init();
|
||||||
|
|
||||||
|
// Optional: initialize array
|
||||||
|
for (uint16_t i = 1; i <= DMX_CHANNELS; ++i)
|
||||||
|
dmx_data[i] = 0;
|
||||||
|
|
||||||
|
sei();
|
||||||
|
|
||||||
|
// Main loop: react to finished frames
|
||||||
|
while (1) {
|
||||||
|
if (dmx_frame_ready) {
|
||||||
|
// Example: use channel 1..512 from dmx_data
|
||||||
|
// Process dmx_data here. This is a single buffer; if processing takes
|
||||||
|
// long, consider double-buffering to avoid race with ISR.
|
||||||
|
|
||||||
|
// After consuming, clear flag
|
||||||
|
dmx_frame_ready = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (dmx_data[1])
|
||||||
|
// PORTE |= 1 << 4;
|
||||||
|
// else
|
||||||
|
// PORTE &= ~(1 << 4);
|
||||||
|
|
||||||
|
// Other application code...
|
||||||
|
}
|
||||||
|
|
||||||
|
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