Author : / Date : Mon-12-2009 12:25
View or add comments : ()
Average members rating : 0
Dit is een werkende ASM Code om DMX te ontvangen. Hij werkt op een Atmega88 met een 20mHz clock. De hardware is eenvoudig. Een driver chip de SN75176 word aangesloten op de RXD pin van de Atmega. Als uitgang worden drie PWM kanalen gebruikt: OCR0A, OCR0B en OCR2B. Een schema zal later gepost worden.

De vier kanalen worden naar CH1, CH2, CH3 en CH4 geschreven. Deze worden dan in de main loop weggeschreven naar de uitgang zodat er ook gemakkelijk iets anders gedaan kan worden met de kanalen.

Het kanaal waar de ontvanger op reageerd is te veranderen in de code maar het is ook mogelijk om deze uit te lezen via een poort. Dit zal ik later uit gaan werken.

Een werkende code voor een PIC 16f628a is hier te vinden.

Code:
.include "m88def.inc"

;berekenen baudrate
.equ CLOCK = 20000000
.equ BAUD = 250000
.equ UBRRVAL = CLOCK/(BAUD*16)-1

;instellen registernamen
.def TEMP = r16
.def TEM2 = r17
.def DATA = r18
.def CH1 = r19
.def CH2  = r20
.def CH3 = r21
.def CH4 = r22
.def DMX  = r23
.def CNT  = r24
.def ADR  = r25
rjmp init

;interupt
.org 0x012 ;uart RX complete
rjmp inte

init:
; Stackpointer initialisieren
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp

; Instellen poorten
ldi temp,255
out DDRB,temp ;poort b uitgang
ldi temp,0
out DDRC,temp ;poort c ingang
ldi temp,255
out DDRD,temp ;poort d uitgang

; Baudrate instellen
ldi temp, LOW(UBRRVAL)
sts UBRR0L, temp
ldi temp, HIGH(UBRRVAL)
sts UBRR0H, temp

; Frame-Format: 8 Bit en 2 stop bits
ldi temp, (1<<USBS0)|(3<<UCSZ00)
sts UCSR0C, temp

; Enable transmitter en receiver
ldi temp, (1 << TXEN0)|(1 << RXEN0|1 << RXCIE0)
sts UCSR0B, temp

; Enable PWM
ldi temp, (1 << WGM01)|(1 << WGM00|1 << COM0A1|0 << COM0A0|1 << COM0B1|0 << COM0B0)
out TCCR0A, temp

ldi temp, (0 << WGM02)|(1 << CS02|0 << CS01|0 << CS00)
out TCCR0B, temp

ldi temp, (1 << WGM21)|(1 << WGM20|1 << COM2A1|0 << COM2A0|1 << COM2B1|0 << COM2B0)
sts TCCR2A, temp

ldi temp, (0 << WGM22)|(1 << CS22|0 << CS21|0 << CS20)
sts TCCR2B, temp
; Clear registers
CLR DMX
CLR CH1

; Stel adres in
ldi ADR,10
mov CNT, ADR

; Set interupts
sei

; Ga naar main programma
rjmp main

; Framing error
FRe:
sbr DMX,1 ;Set bit FRe
reti ;Return interrupt

;Startbyte dectie
StartByte:
cpi data,0 ;compare if data = 0
brne return ;zo niet naar return
sbr DMX,2 ;zowel set startbyte bit
dec CNT ;verlaag CNT
reti ;return interrupt

;Channel 3
c3: mov CH3, data ;data naar CH2
sbr dmx, 16 ;set CH2 data bit
reti ;return interrupt

;Channel 2
c2: mov CH2, data ;data naar CH2
sbr dmx, 8 ;set CH2 data bit
reti ;return interrupt

; Interupt programma
inte:
lds temp,UCSR0A ;zet ontvang flags in register
lds data, UDR0 ;zet ontvangen data in register
sbrc temp,FE0 ;kijk of er een frame error is
rjmp FRe ;wel: ga naar FRe

sbrs DMX,0 ;niet: kijk of er een FRe is geweest
reti ;niet: return interrupt

sbrs DMX,1 ;wel: kijk of er een startbyte is geweest
rjmp StartByte ;niet: ga naar startbyte detectie

dec CNT ;wel: verlaag CNT
brge return ;als CNT niet 0 is naar return

sbrc DMX,4 ;wel nul: test als CH2 al geset is
rjmp c4 ;wel: dan naar channel 3

sbrc DMX,3 ;wel nul: test als CH2 al geset is
rjmp c3 ;wel: dan naar channel 3

sbrc DMX,2 ;wel nul: test als CH1 al geset is
rjmp c2 ;wel: dan naar channel 2

mov CH1, data ;niet: move data naar CH1
sbr DMX,4 ;set ch1 bit
reti ;return interrupt

c4: mov CH4, data ;move data naar CH2
mov CNT, ADR ;stel counter weer in
CLR DMX ;haal register leeg
;hierdoor begint hij weer van voor af aan
return:
reti ;return interrupt

; Start programma
main:
mul ch1,ch4 ;ch1 x master(ch4)
out OCR0A, r1 ;bovenste product(R1) naar uitgang
mul ch2,ch4 ;ch2 x master(ch4)
out OCR0B, r1 ;bovenste product(R1) naar uitgang
mul ch3,ch4 ;ch3 x master(ch4)
sts OCR2B, r1 ;bovenste product(R1) naar uitgang
rjmp main