Hallo, wenn ich ein RS485-Protokoll verwenden möchte, so muss ich in der Lage sein 9 Bits pro Byte übertragen zu können. Das neunte Bit kennzeichnet ob es sich um eine Adresse oder ein Datenbyte handelt. Bei Visual Basic 2005 kann man aber nur "SerialPort1.DataBits = x" einstellen, wobei x = 5,6,7 oder 8 Bits sein kann. Leider gehts nicht mit 9 Bits. Hat jemand eine Idee, wie man sauber 9 Bits pro Byte über die Schnittstelle übertragen kann? Gruß gruser
> Hat jemand eine Idee, wie man sauber 9 Bits pro Byte über die > Schnittstelle übertragen kann? Beim normalen PC meines Wissens gar nicht. Ein echtes hardwarebasiertes 9bit-Protokoll inklusive Parity und Start/Stop-Bits wie bei Mikrocontrollern ist beim PC-UART nicht vorgesehen. Es gibt Würgarounds, wie z.B. hier beschrieben: http://electronicdesign.com/Articles/Index.cfm?AD=1&ArticleID=6245 Ansonsten geht's nur mit zusätzlicher Hardware, z.B. einem Mikrocontroller mit zwei UARTs als "Übersetzer".
Hi, > Hat jemand eine Idee, wie man sauber 9 Bits pro Byte über die > Schnittstelle übertragen kann? Kommt drauf an, wie du sauber definierst. Es gibt keinen UART, der 9 _Daten_bits unterstützt, nur eben 8 plus Parity. Aber Parität hat vier mögliche Zustände, even, odd, mark und space, das heisst, du musst eben mit Mark und Space arbeiten, dann klappt das, so hab ich es in VB & Co. auch immer gemacht. Ralf
Habe mir erst die Mühe gemacht die Dezimalzahl in einen Binärwert umzurechnen, um dann die Quersumme zu bestimmen. Je nach Ergebnis habe ich dann von ODD auf EVEN (oder umgekehrt) geschaltet. Jetzt sehe ich mit MARK und SPACE geht es ja noch einfacher, wenn mein Master sendet setzte ich einfach MARK, wenn die Slaves senden schalte ich um auf SPACE. Schönen Dank für eure Hilfe! Olaf
Hmmm... ein neues Problem habe ich mit den 9 Bits: Vom PC (Master) aus verschicke ich testweise den Wert 170 an einen PIC-Controller (Slave). Egal ob ich das Byte mit MARK oder SPACE an den PIC schicke, in der Variablen "addr" steht offensichtlich immer nur der Wert 170, da mein Lämpchen an- und wieder ausgeht (s.u.). Ich hätte gedacht wenn ich RX9=1 setze, könnte ich "addr" mit 9 Bit füllen. Ziel ist es anschließend das 9. Bit zu maskieren, so dass der PIC klar erkennt dass es sich um eine Adresse handelt. Sorry wenn ich mich ein wenig kompliziert ausgedrückt haben sollte, aber ich habe keine Ahnung mehr woran es liegen könnte, eventuell in der Initialisierung? Vielleicht habt wieder eine gute Idee ;-) Den Code habe ich im wesentlichen mal hier reinkopiert. void InitUSART() { BRGH=1; SPBRG=20; // 57600 baud @ 20MHz input clock SPEN = 1; // Set_Serial_Pins; SYNC = 0; // Set_Async_Mode; TX9 = 0; // Set_8bit_Tx; RX9 = 1; // Set_9bit_Rx; CREN = 1; // Enable_Rx; TXEN = 1; // Enable_Tx; RCIE=0; // Rx Interrupt aus } //******* Hauptprogramm ************************************************* void main(void) { uns16 a; char n; char w; uns16 addr; // habe Adresse mal als uns16 definiert uns16 test1; uns16 test2; TRISA = 0b.0000.0000; // PortA als Ausgang definieren TRISB = 0b.0000.0000; // PortB als Ausgang definieren TRISE = 0b.0000.0000; // PortE als Ausgang definieren TRISD = 0b.0000.0000; PORTD = 0b.0000.0000; TRISC=0b.1011.1100; // RC6>TX, RC7>RX InitUSART(); // Hardwareschnittstelle des PICs einstellen while (1) { // Empfangen von Daten pause(500); pause(500); pause(500); pause(500); pause(500); pause(500); PORTA = 0b.0000.0000; // Lampe schaltet aus while(!RCIF); // Warte auf Empfang addr=RCREG; // Empfange Adressnummer if (addr==170) { PORTA = 0b.1111.1111; // Lampe schaltet ein pause(500); PORTD = 0b.0000.0010; delay_mks(1000); TXREG = addr; while(!TRMT==1); // Solange hier warten bis Transmittpuffer leer ist delay_mks(1000); PORTD = 0b.0000.0000; delay_mks(1000); } } }
Tja, ich kenne mich mit PICs nicht aus, komme aus der 8051er-Ecke, aber mir fallen zwei Sachen auf: 1. Beim 8051 muss man nach dem Senden/Empfangen eines Zeichens das entsprechende Interrupt-Flag löschen (auch bei Polling-Betrieb, da dieses Flag als Erkennung genutzt wird). Das sehe ich bei dir nicht. Wird das Flag automatisch beim Lesen durch die Hardware gelöscht oder hast du das vergessen? Würde man das Rx-Flag eines 8051 nicht löschen, wird man ständig dasselbe Zeichen auslesen, bis ein anderes kommt, und das dann wieder permanent auslesen... 2. Ich sehe nirgends deine Auswertung, ob es sich um Adressen oder Daten handelt? Also die Auswertung des 9.Bits... Ralf
Das hin- und her schicken der Daten klappt ja... dabei brauchte ich keine Flags zu löschen. Mich wundert es halt nur dass ich die Variable nicht mit einem 9 Bit langen Datenwort füllen kann, offenbar ist immer noch bei 255 Ende. In der "addr" steht offensichtlich der Wert 170, sonst hätte mein Lämpchen nicht angefangen zu blinken ;) Nachdem ich das gesehen habe, habe ich den Teil mit dem Maskieren wieder herausgenommen, macht ja keinen Sinn das 9. Bit zu maskieren wenn es nicht da ist.
Dann ist dein Fehler klar. Du gehst fälschlicherweise davon aus, dass du mit 9 Bit als ganzes arbeitest, aber es sind real 8 + 1 Bit. Das heisst, du kannst IMMER nur maximal 255 (0xFF) empfangen, das 9. Bit musst du separat auswerten. Wenn du einen größeren Wert als 255 empfangen willst, musst du ihn auf zwei Bytes aufteilen und auch als Bytes senden... Ralf
Ja aber warum gibt es in der Beschreibung die Unterscheidung: RX9 = 0; // Set_8bit_Rx RX9 = 1; // Set_9bit_Rx Irgendwie muss der Empfänger doch dieses 9. Bit auswerten können, sonst macht es doch keinen Sinn. Auf dem Oszi sehe ich dass ein Byte (mit MARK bzw. SPACE am Ende) rausgeht - damit muss der PIC doch etwas anfangen können...
Beim 8051 wird beim Senden das 9.Bit vorher in ein Flag eines SFRs geladen, der UART sendet diesen Bitzustand dann mit. Beim Empfang wird das 9.Bit in einem weiteren Flag eines SFRs gespeichert, sodass es die Software auswerten kann. Ich würde sagen, das ist bei deinem PIC auch so. Das steht dann im UART-Kapitel des Datenblattes, wie es funktioniert. Ralf
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.