renebiemans.nl

Elektronica · 27 maart 2011

DMX Merger met ADC

Dit is een script voor een DMX merger. De merger heeft 1 DMX ingang en 1 uitgang maar plaatst daar een analoog signaal bij tussen.

#include <avr/io.h>
#include <stdint.h>
#include <stdbool.h> 
#include <util/delay.h>
#include <avr/interrupt.h>
#define FOSC 20000000   // Clock Speed
#define BAUD 250000     //Baud rate for DMX
#define MYUBRR FOSC/16/BAUD-1

volatile uint8_t CH[512];
volatile uint8_t waarde;
//initialisation functions

//Instellen poorten
void InitPorts(void)
{
    DDRB = 0xFF;    //PORT B input
    DDRD = 0xFF;
    //instellen ADC
    ADMUX=0x20;;
    ADCSRA = 0xEF;
}

//Instellen UART
void USART_Init( unsigned int ubrr)
{
    UBRR0=ubrr;
    UCSR0B = (1<<RXEN0)|(1<<TXEN0|1<<UDRIE0|1<<RXCIE0);             //enable RX/TX 
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);            //8bits 2stopbits
}

//main
int main()
{
    InitPorts();            //instellen poortenADIF 4 90
    USART_Init ( MYUBRR );  //instellen uart
    sei();
    for(;;){
        for (int i = 0; i<11; i++) {
            if(waarde >= CH[i+10]){
                CH[i+10]=waarde;
            }
        }
    }
    return 0;
}

//interrupt voor zenden van DMX
ISR(USART_UDRE_vect){
    static uint16_t Counter;
    static uint8_t delayCounter;
    if(Counter == 512) {
        UCSR0B = (1<<RXEN0)|(1<<UDRIE0|1<<RXCIE0);  //uitzetten tx
        PORTD=0;        //signaal laag maken
        if(delayCounter == 16) {
            UCSR0B = (1<<RXEN0)|(1<<TXEN0|1<<UDRIE0|1<<RXCIE0); //uart weer aanzetten
            UDR0=0; //startbyte verzenden
            delayCounter = 0;
            Counter = 0;
        } else {
            delayCounter++;
        }
    } else {
        UDR0=CH[Counter];
        Counter++;
    }
}

//interrupt voor ontvangen van uart RX
ISR(USART_RX_vect){ 
    static bool Break = false;
    static bool Mab = false;
    static int Counter;
    uint8_t dummy;
    if (UCSR0A & (1<<FE0)){ //test of er een framing error is geweest
            Break = true;       //zo ja: zet break op true
            Mab = false;        //en MAB of false zodat deze weer gecontroleerd word
            dummy = UDR0;
    } else if(UDR0 == 0 && Break == true) { //test of alles klopt
        Break = false;
        Mab = true;         //als alles klopt: zet MAB op true
        Counter = 0;        //en counter op 0
    } else if(Mab == true) {    //test of er echt DMX ontvangen is
        CH[Counter-1] = UDR0;
    }  
    Counter++;  //counter verhogen zodat volgend kanaal gelezen word
}

//interrupt voor ADC
ISR(ADC_vect){
    waarde=ADCH;
}