mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik S-Bus-Dekoder - Interpretations / Programm / Verständnisproblem


Autor: Andreas Denk (dandy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallöchen, ich bräuchte mal wieder Hilfe bei einem S-Bus Dekoder.

Ich möchte einen S-Bus -> PWM - Konverter programmieren. Dazu, versuche 
ich nun erst einmal den S-Bus zu dekodieren, um auf einem Display 
dezimal den Wertebereich jedes Kanals angezeigt zu bekommen. Doch egal 
was ich wie programmiere, ich bekomme immer nur Zahlenmüll angezeigt. 
Vielleicht habe ich die spezifikationen des Busses nicht verstanden, 
oder ich mache programmtechnisch einen Fehler.. ?!

Nun, zu meiner Hardware:

Ich benutze zum testen einen ATMega 16 mit 16 MHz externem 
Taktoszillator. Da der S-Bus ja ein invertierter serieller Bus sein 
soll, gebe ich das Signal, generiert aus einem FrSky X8R Empfänger 
invertiert auf den RX des Mega 16. (Bild - S-Bus-invert.png)
Ein Display 2x16 hängt am Port-C.

Die Hardware des Prozessors initialisiere ich wie folgt:
reset:        ldi r16, HIGH (RAMEND)
          out SPH, r16
          ldi r16, LOW(RAMEND)
          out SPL, r16      ;Stack
          ldi r16, 0xFF
          out DDRC, r16      ;Port-C-Ausgang
          com r16
          out PORTC, r16      ;Port-C-Low
          out DDRD, r16      ;Port-D-Eingang
          ldi r16, 0b11111110    
          out PORTD, r16      ;Pullups setzen, bis auf RX - PD-0
          ldi r16, 0b00000001
          out DDRB, r16      ;PB-0 ausgang, da dort eine LED hängt
          clr r16
          out PORTB, r16      
          out UBRRH, r16      ;Bit-Rate-Register-High nullen
          ldi r16, 9
          out UBRRL, r16      ;Bit Rate Register Low = 9 (UBBR = ( fosc/16*Baud) -1 ) = (16000000 / (16*100000)) = 10 -1 = 9 )
          ldi r16, 0b10010000
          out UCSRB, r16      ;RX Enable und RX Complete Interrupt Enable
          ldi r16, 0b10101110
          out UCSRC, r16      ;Gerade Paritaet / 2 Stop Bits (Obwohl für empfänger laut Datenblatt nicht konfigurierbar) und 8 Bit Charakter Size

Die UART (RX-Complete) Interrupt Routine (Zurzeit nach vielen 
versuchen):
uartrxok:      in r2, SREG
          push r20
          push r21
          push r22
          push YL
          push YH
          sbrc r19, 0      ;gesetzt wenn Startbyte empfangen wurde
          rjmp getdata    ;dann empfange Datenbates der einzelnen Kanäle
          in r21, UDR      ;Datenregister einlesen
          cpi r21, 0b11110000  ;mit Startbyte vergleichen
          brne enduartint    ;kein Startbyte dann ende
          sbr r19, 1      ;Statusbit für datenempfang setzen
          ldi r22, 24      ;Zähler für 24 Bytes einstellen
          sts $006C, r22    ;Zähler sichern
          ldi YL, LOW ($0070)  ;Ram Zeiger Setzen
          ldi YH, HIGH($0070)
          sts $006A, YL    ;Ram Zeiger sichern
          sts $006B, YH
          cbi PORTB, 0    ;LED aus schalten
          rjmp enduartint    ;und ende
getdata:      in r20, UDR      ;Datenregister einlesen
          lds YL, $006A    ;Aktuellen Ram-Zeiger laden
          lds YH, $006B
          lds r22, $006C    ;Aktuellen Byte Zähler laden
          st Y+, r20      ;Empfangenes Datenbyte ins Ram schreiben und Ram Zeiger um 1 erhöhen
          sts $006A, YL    ;Ram Zeiger wieder sichern
          sts $006B, YH
          dec r22        ; Byte Zähler um 1 verringern
          breq enddata    ;wenn alle bytes empfangen dann ->enddata
          sts $006C, r22    ;sonst Byte Zähler wieder sichern
          rjmp enduartint    ;und ende
enddata:      cbr r19, 1      ;Statusbyte wieder löschen
          sbr r19, 2      ;Statusbit für fertigen Empfang setzen
          sbi PORTB, 0    ;LED einschalten
enduartint:      pop YH
          pop YL
          pop r22
          pop r21
          pop r20
          out SREG, r2
          reti

Nachdem alle bytes empfangen wurden versuche ich einzig und alleine die 
Daten für den ersten Kanal heraus zu holen. Da die daten ja nahtlos 
zusammenhängen sollen (so wie ich es verstanden habe) und 11 Bit 
betragen und somit aus den ersten 8 Bits des ersten Bytes plus den 3 
Bits des zweiten Bytes bestehen und das höchstwertige Byte Rechts liegen 
soll schiebe ich die bits folgendermaßen in der nächsten Routine 
zurecht. Erst fünf mal nach rechts und dann 11 bits links in 2 leere 
register um das höchstwertige bit wieder links für die dezimal 
umrechnung zu haben)
ortbits:      push YL
          push YH
          push r20
          push r21
          push r22
          ldi YL, LOW ($0070)
          ldi YH, HIGH($0070)
          clr r21
          clr r22
          ld r17, Y+
          ld r18, Y
          ror r17
          ror r18
          ror r17
          ror r18
          ror r17
          ror r18
          ror r17
          ror r18
          ror r17
          ror r18
          ldi r20, 11
loop10:        ror r17
          ror r18
          rol r21
          rol r22
          dec r20
          brne loop10
          sts $0090, r21
          sts $0091, r22
          pop r22
          pop r21
          pop r20
          pop YH
          pop YL
          ret

danach erfolgt die dezimal Umwandlung dieser beiden ergebnis bytes (aus 
den Ram Zellen $0090 und $0091) und werden aufs Display ausgegeben. (Das 
funktioniert auch) Man sieht auch, dass sich die Zahlen ändern, wenn ich 
den Knüppel für kanal 1 bewege, aber eben total wirr, als wenn... tja 
wenn ich das wüsste... Als wenn ich die daten falsch interpretiere... 
als wenn der Uart nicht richtig konfiguriert und ich keine Ahnung welche 
Bytes erhalte... Als wenn ich falsch sortiere.. oder oder oder. Ich 
weiss es nicht. Mittlerweile verstehe ich nur noch Bahnhof.

Vielleicht hat ja jemand von euch den Bus schon erfolgreich über den 
UART decodiert und kann mir mal stützend unter die Arme greifen. Wäre 
echt dankbar, denn ich weiss grad nicht mehr weiter, geschweige denn was 
ich falsch mache.

Falls noch weitere infos benötigt werden, bitte sagen. Ansonsten erst 
mal besten Dank für eure mühe.

Gruß, Andy

Autor: Andreas Denk (dandy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls es hilft, das S-Bus protokoll habe ich aus folgendem PDF...

S-BUS protocol
Note- Much of this first page is from mbed, but it was written for the 
original s.bus using the "FASST MULT" mode. Here's the original page 
link-
http://mbed.org/users/Digixx/notebook/futaba-s-bus...
The protocol is 25 Byte long and is send every 14ms (analog mode) or 7ms 
(highspeed mode). One Byte = 1 startbit + 8 databit + 1 paritybit + 2 
stopbit (8E2), baudrate = 100'000 bit/s, so one bit takes 10 
microseconds.
The highest bit is send first, so data "00000000001" = 1024
The logic is inverted out of the receiver.
[startbyte] [data1] [data2] .... [data22] [flags][endbyte]
startbyte = 11110000b (0xF0)
data 1-22 = [ch1, 11bit][ch2, 11bit] .... [ch16, 11bit] (ch# = 0 bis 
2047) channel 1 uses 8 bits from data1 and 3 bits from data2 channel 2 
uses last 5 bits from data2 and 6 bits from data3 etc.
flags = bit7 = ch17 = digital channel (0x80) bit6 = ch18 = digital 
channel (0x40) bit5 = Frame lost, equivalent red LED on receiver (0x20) 
bit4 = failsafe activated (0x10) bit3 = n/a bit2 = n/a bit1 = n/a bit0 = 
n/a
endbyte = 00000000b (Prior to the s.bus2 capable receivers, and the 
R7003SB)

(as captured)
100001111100111111111100111011111000111111000000111111111100100111111100 
11110111100
011111110100011111111110011011111100011111011100011111111000011111111110 
01110111110
001111110110001111111111001011111110001111011110001111111010001111111111 
00110111111
0001111101110001111111100001111111111001111111111

(inverted before FC input)
011110000011000000000011000100000111000000111111000000000011011000000011 
00001000011
100000001011100000000001100100000011100000100011100000000111100000000001 
10001000001
110000001001110000000000110100000001110000100001110000000101110000000000 
11001000000
1110000010001110000000011110000000000110000000000

(inverted before FC input and grouped in 12 bit bytes)
011110000011 (Start byte)
000000000011 (data 1)
000100000111 CH1
000000111111 CH2
000000000011 CH3
011000000011 CH4
000010000111 CH5
000000010111 CH6
000000000011
001000000111 CH7
000001000111 CH8
000000001111
000000000011 CH9
000100000111 CH10
000000100111 CH11
000000000011
010000000111 CH12
000010000111 CH13
000000010111 CH14
000000000011
001000000111 CH15
000001000111 CH16
000000001111 (data 22)
000000000011 (flags byte) DCH1, DCH2, Frame lost, failsafe activated, 
rest are NA
000000000011 (11 added by dead space between frames)

Autor: Andreas Denk (dandy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat sich erledigt. Habs hin bekommen.

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.

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