www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DMX Senderoutine am PIC in C


Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Programmiere derzeit eine Senderoutine am PIC in C.
Sie funktioniert auch wunderbar, aber ich bin noch nicht zu 100% 
zufrieden.

Hier mal der Code
#include <16F876a.h>

#device adc=8
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use rs232(baud=250000,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9,stream=DMXX)
#bit bit_nine = 0x98.0

#use rs232(baud=115200,parity=N,xmit=PIN_B0,rcv=PIN_B1,bits=9,stream=PC)

#define        sn75176 PIN_C3    //high: transmit low: receive
#define        DMXANZ 10

unsigned char  value[DMXANZ];
unsigned int   dmxnum;  
unsigned int   status;
int            WAIT = 10;


#int_TIMER2
void TIMER2_isr()    //10ms
{
  
   set_adc_channel( 0 );        
   delay_us(WAIT);     
   value[3] = read_ADC();       //Wert für Kanal 3 per Poti einlesen
   
   set_adc_channel( 1 );
   delay_us(WAIT);
   value[2] = read_ADC();       //Wert für Kanal 3 per Poti einlesen
   
   set_adc_channel( 2 );
   delay_us(WAIT);
   value[1] = read_ADC();       //Wert für Kanal 3 per Poti einlesen
   
}

void init_dmx(void)
{
   set_uart_speed(250000, DMXX);      //Baudrate für Break bzw. Reset
   output_high(sn75176);       //RS458-Wandler auf Sendemodus versetzen; high: transmit low: receive

   status=1;                  //mit Break bzw. Reset beginnen
}

void main()
{
   enable_interrupts(GLOBAL);
   
   enable_interrupts(INT_TIMER2);
   setup_timer_2(T2_DIV_BY_16,195,16);    //10ms
   
   setup_adc_ports(AN0_AN1_AN3);
   setup_adc(ADC_CLOCK_INTERNAL);


  init_dmx();  
   
   value[0] = 0;
  value[1] = 0;
  value[2] = 0;
  value[3] = 0;
  value[4] = 0;
  value[5] = 0;
  value[6] = 0;
  value[7] = 0;
  value[8] = 0;
  value[9] = 0;

   while(1)
   {
       switch(status)
     {
         case 1:                //RESET (0 senden)
               set_uart_speed(4800, DMXX);   
               
               putc(0,DMXX);
               status = 2;
        break;
         
        case 2:         //1.Byte senden --> 1.Byte immer 0!
               delay_us(30);
               set_uart_speed(250000, DMXX); 
               
               putc(0,DMXX);
               status = 3;
               
               dmxnum = 1;
         break;
         
         case 3:        //DMX-Daten senden                     
               delay_us(10);
               
               putc(value[dmxnum],DMXX);    // Sende den aktuellen DMX Wert
               dmxnum++;
               If (dmxnum == DMXANZ)
               {
                  status = 1;
               }
         break;
     }
   }
}

Wie ihr seht is die ganze Sendegeschichte in einer while(1)-Schleife, 
und das gefällt mir eigentlich garnicht, da ich nämlich so gut wie 
nichts anderes mehr machen kann.
Wenn ich beispielsweise etwas am Display ausgeben will, hängt sich alles 
auf.
Gibts ev. eine Alternative für die while(1)-Schleife, wie beim AVR 
sowas:
ISR (USART_TXC_vect)
{
..Senderoutine..
}
? Nur eben fürn PIC
Hab mich auch schon mit Timer & CO gespielt, jedoch jedes mal ohne 
Erfolg...

Bin kein Profi, deshalb Frag ich auch so blöd xDD

mfg Emanuel

Autor: Master Snowman (snowman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich weiss jetzt nicht, ob dein PIC einen interrupt auslösen kann, wenn 
er mit senden fertig ist. falls die schnittstelle so konfiguriert werden 
kann, könntest du in der interrupt-routine jeweils das nächste zu 
übertragende byte ins senderegister schreiben usw.

Autor: heinzhorst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Master Snowman schrieb:
> ich weiss jetzt nicht, ob dein PIC einen interrupt auslösen kann

Kann er.

Benutzt er ja auch hier:

void TIMER2_isr()


Welchen Compiler benutzt du denn?

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
heinzhorst schrieb:
> Welchen Compiler benutzt du denn?

picc Compiler

Autor: Master Snowman (snowman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@heinzhorst: klar, es gäbe noch die möglichkeit den 
interrupt-on-pin-change, dann muss er einfach immer im richtigen moment 
für ein byte auf die taste drücken - hahaha :-) lies mal den ganzen 
satz, den du zitierst, da ist nämlich noch ein "wenn".

Autor: Master Snowman (snowman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich sehe im datenblatt, dass der PIC das kann (siehe kapitel 10.2.1.). 
also den TXIF-interrupt gebrauchen, um neue daten ins TXREG-register zu 
schreiben. in der zwichenzeit kann dein programm im main sich rumtummeln 
so viel er will.

Autor: Emanuel J. (e-sound)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Master Snowman schrieb:
> ich sehe im datenblatt, dass der PIC das kann (siehe kapitel 10.2.1.).
> also den TXIF-interrupt gebrauchen, um neue daten ins TXREG-register zu
> schreiben. in der zwichenzeit kann dein programm im main sich rumtummeln
> so viel er will.

ok, was heißt das jetzt konkret? meinst du ev diesen interrupt?
#int_TBE
TBE_isr() 
{

}

wenn ja, hab ich schon ausprobiert; jedoch ohne Erfolg.

Emanuel

Autor: Master Snowman (snowman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich kenne deinen compiler nicht, weiss also auch nicht, was "TBE_isr" 
ist resp. durch was er ausgellöst wird. du musst den interrupt 
verwenden, der ausgelöst wird, der im oben erwähnten kapitel behandelt 
wird. wie der bei deinem compiler heisst, musst du mit der hilfe deines 
compilers herausfinden. suche mal nach "serial" und "interrupt", da 
wirst du am schnellsten fündig.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.