I want to wrote a receiver for DMX512 packets (it is an strange serial comunication).
Does anybody has some experience with this ?
 
This code from the firmware of a working moving-head projector for lighting. It reads 16 channels from dmx and stores the values in a buffer.
 
        ORG        0023h
;
        JBC        RI, spi    ;serial port int
        RETI
;
; serial port interrupt
;
spi:
        PUSH       ACC
        PUSH       PSW
        ORL        PSW, #00001000b    ;bank 1
        JB         RB8, dmx
        MOV        A, SBUF            ;a break is received
        JNZ        clr_brk
        MOV        R0, #dmxs_buf      ;start of buffer
        MOV        R2, A              ;index = 0
        MOV        R3, A
        SETB       break_fl
        SETB       start_fl
        CLR        grant_fl
        POP        PSW
        POP        ACC
        RETI
start:  MOV        A, SBUF            ;data is start code
        JNZ        clr_brk    ;start code is not zero - no valid data
        SJMP       next_ch
dmx:    JNB        break_fl, spi_x    ;a dmx data is received
        JBC        start_fl, start
        JB         grant_fl, get_data
        MOV        A, l_dmx_ad        ;dmx address low
        CJNE       A, AR2, next_ch
        MOV        A, h_dmx_ad        ;dmx address high
        CJNE       A, AR3, next_ch
        SETB       grant_fl
get_data:
        MOV        @R0, SBUF
        INC        R0
        CJNE       R0, #(dmxs_buf + 16), next_ch    ;end of buffer?
        SETB       ready_fl   ;data ready
clr_brk:
        CLR        break_fl
next_ch:
        INC        R2         ;next channel
        CJNE       R2, #0, spi_x
        INC        R3
spi_x:  POP        PSW
        POP        ACC
        RETI
 
Same code in C (not checked !!!)
 
int dmx_address;    // global
char dmx_buffer[16];
char ready_fl;
 
void sp_interrupt(void) interrupt 4 using 1
 {
    static char count;
    static int index;
    static char break_fl = 0, grant_fl;
 
    if (!RB8)
    {
        if (SBUF != 0)
        {
            break_fl = 0;
 
            return;
        }
 
        count = 0;
        index = 0;
 
        break_fl = 1;
        grant_fl = 0;
    }
    else if (break_fl)
    {
        if (index == 0)
        {
            index++;
           
            if (SBUF != 0)
                break_fl = 0;
           
            return;
        }
 
        if (!grant_fl)
        {
            if (index != dmx_address)
            {
                index++;
 
                return;
            }
 
            grant_fl = 1;
        }
 
        dmx_buffer[count++] = SBUF;
 
        if (count == 16)
        {
            ready_fl = 1;
            break_fl = 0;
        }
    }
   
    return;
 }
You have to set the serial port in 9-bit UART mode at 250Kbaud.
 
Fiorenzo Ramaglia
Italy
fd.ramaglia@tin.it