Ik heb de volgende code geschreven om DMX met een pic16f877a binnen te halen:
code:
#define aantalkanalen 8
unsigned int ch_count=0, offset, i,adres;
unsigned char data[aantalkanalen]={0}, startcode, nutteloos, brk=0;
const unsigned char mask[8]={1,2,4,8,16,32,64,128};
void init_usart()
{
TRISC = 0xFF;
SPBRG = 0x04;
TXSTA.BRGH = 1;
TXSTA.SYNC = 0;
PIE1=0;
PIE1.RCIE = 1;
RCSTA.RX9 = 1;
nutteloos=RCREG;
nutteloos=RCREG;
nutteloos=RCREG;
RCSTA.CREN = 1;
RCSTA.SPEN = 1;
INTCON.PEIE=1;
INTCON.GIE=1;
}
void interrupt()
{
if (PIR1.RCIF)
{
if (RCSTA.OERR)
{
RCSTA.SPEN=0;
RCSTA.SPEN=1;
nutteloos=RCREG;
nutteloos=RCREG;
nutteloos=RCREG;
ch_count=0;
brk=0;
}
else
{
if (RCSTA.FERR)
{
nutteloos=RCREG;
ch_count=0;
offset=0;
brk=0xFF;
}
else
{
if (brk==0xFF)
{
if (ch_count==0) startcode=RCREG;
else
{
if (adres<1)
{
nutteloos = RCREG;
for (i=0; i<aantalkanalen; i++) data[i]=0;
}
else
{
//------------------------------ Hier adres controleren en evt. uitlezen
if (ch_count>=adres & ch_count<adres+aantalkanalen & startcode==0)
{
data[offset] = RCREG;
offset++;
}
else nutteloos = RCREG;
}
//------------------------------
}
ch_count++;
}
else
{
nutteloos = RCREG;
ch_count=0;
}
}
}
PIR1.RCIF=0;
}
}
void main ()
{
TRISB = 0xFF;
TRISD = 0x00;
init_usart();
PORTD=0;
while(1)
{
adres = PORTB;
for (i=0; i<aantalkanalen; i++)
{
if (data[i]>0x80) PORTD = (PORTD&(~mask[i])) + mask[i];
else PORTD = PORTD&(~mask[i]);
}
}
}
De code is geschreven in MikroC. Op de uC zijn op PORTB 8 dipswitches aangesloten. Op PORTD zitten 8 leds. De uC draait overigens op 20Mhz om de informatie even compleet te maken .
De software haalt 8 kanalen binnen vanaf het ingestelde startadres. Wanneer een kanaal een hogere waarde heeft dan 128 wordt de bijbehorende led aan gezet.
Nu komt het volgende, wanneer het signaal om wat voor reden ook weg valt blijft de laatst gestuurde data in de data-array zitten, met als gevolg dat de uitgang blijft uitsturen.
Ik wil het op een of andere manier afvangen dat zodra het signaal wegvalt alle kanalen naar 0 gezet worden. De kanalen op 0 zetten kan met de volgende regel:
code:
for (i=0; i<aantalkanalen; i++) data[i]=0;
Dit gebruik ik ook wanneer het start-adres op '0' wordt gezet.
Nu is mijn vraag, hoe kan ik het detecteren wanneer er geen signaal binnen komt? Er worden namelijk geen interrupts meer gegenereerd als er geen DMX binnenkomt. Dit heb ik geprobeerd.