Geschätztes Forum
Ein kleines Beispiel eines RDS-Decoders.
Benötigt werden die Signale eines Rohdatendecoders Takt und Data.
Der RDS-Decoder kann die RDS-Daten auf dem Display darstellen,
die RDS-Gruppen am 2-Wire Ausgang zur Verfügung stellen (als Slave) und
die RDS-Rohdaten, also den Datenstrom am USART / RS232-Ausgang zur
weiteren Verarbeitung ausgeben.
Alle Funktionen sind gleichzeitig nutzbar.
Man könnte auch nur die LEDs nutzen für die Visualisierung der
RDS-Datenqualität :-)
TMC hätte ich gern noch implementiert, vielleicht hat jemand von Euch
schon damit Erfahrungen gesammelt?
Im Display werden u.a. folgende Informationen zur Verfügung gestellt:
- Stationsname
- Radiotext
- Alternativfrequenzen
- gesendete Gruppentypen
- Zeit
- Programm und Senderinformationen
- Statistik
LEDs:
- grün - RDS Daten sind fehlerfrei
- gelb - RDS Daten sind fehlerbehaftet (keine Synchronisation)
- rot - ERROR im Programm
- blinken grün - Interrupt Error
- blinken gelb - schwerer Programmfehler, z.B. Stacküberlauf
Die RDS-Gruppen werden für TWI und das Display in je einem 256 Byte
großen Puffer zwischengespeichert, d.h 32 Gruppen (ca. 3 Sekunden RDS
Daten), ohne Datenverlust.
Der µC benötigt mindestens ca. 4MHz Prozessortakt, denn in den
Interruptroutinen werden einige Berechnungen durchgeführt
(z.B. Prüfbitberechnung).
Programmaufbau:
Bei jedem RDS-Takt wird bei fallender Flanke ein externer Interrupt
ausgeführt und der RDS-Data Pin abgefragt und ein Bit in den
Zwischenpuffer geschoben und eine CRC-Prüfbitberechnung durchgeführt
und die Blöcke A+B+C+D gesammelt.
Wenn eine RDS-Gruppe fehlerfrei empfangen wurde, ist der Datenstrom
synchronisiert und die 8 Datenbits (je 2 Bytes Block A, B C und D)
werden in die 256 Byte großen Datenpuffer (Display / TWI) zur weiteren
Verarbeitung zwischengespeichert.
Die LOOP-Schleife greift auf den Display-Datenpuffer zu, leert und
verarbeitet ihn. Wird dieser Display-Datenpuffer nicht rechtzeitig
geleert, entsteht Datenverlust, dann kommt es zu einer Fehlermeldung.
Der TWI-Datenpuffer lässt Datenverlust zu, die ältesten Daten werden
überschrieben, was kann der Slave dazu, dass der Master die Daten nicht
abruft... selber Schuld.
Das TWi Datenprotokoll ist relativ einfach gehlaten:
<Start MR> <AH> <AL> <BH>.....<DL> <Start MR> oder <STOPP>
Sind keine Daten mehr im TWI Puffer, dann sind alle Datenbites NULL.
Hier findet Ihr ev. noch weitere Informationen:
Beitrag "RDS CRC Prüfbit Berechnung"Beitrag "RDS DECODER analog Schaltung ohne IC gesucht, für Rohdatengewinnung"Beitrag "Si4735 RDS Radio UKW LW MW KW AM FM - TA TP AF GT TMC CT RT Pi PS ATmega8 Assembler"
Der Assemblercode ist nicht hochgradig optimiert, hier gibt es bestimmt
noch Verbesserungsbedarf.
Für Anregungen und Hinweise bin ich sehr dankbar.
Bernhard
SUPER :)
gleich mal eine Tip wie du den Code etwas schneller bekommst
alt:
1
RDS_GRUPPENTYP_A:
2
; CRC Kopie
3
mov temp3,temp5 ; CRC (berechnet)
4
mov temp4,temp6 ; CRC (berechnet)
5
; "CRC"mit OFFSET_WORD_A verknüpfen
6
ldi temp,low(OFFSET_WORD_A)
7
eor temp3,temp
8
ldi temp,high(OFFSET_WORD_A)
9
eor temp4,temp
10
; Vergleich mit empfangenem "CRC"
11
cp temp1,temp3 ; CRC(empfangen)
12
brne RDS_GRUPPENTYP_NO_A
13
cp temp2,temp4 ; CRC(empfangen)
14
brne RDS_GRUPPENTYP_NO_A
15
; ERGEBNIS
16
LDS temp4,(adr_RDS_DATA3) ; aus SRAM laden
17
LDS temp3,(adr_RDS_DATA2)
18
STS(adr_RDS_GRUPPE_AH_ROH),temp4 ; im SRAM ablegen
19
STS(adr_RDS_GRUPPE_AL_ROH),temp3
20
ldi temp1,1 ; RÜCKGABEWERT
21
ret
22
RDS_GRUPPENTYP_NO_A:
neu:
1
RDS_GRUPPENTYP_A:
2
; Lowbyte "CRC"mit OFFSET_WORD_A verknüpfen
3
ldi temp,low(OFFSET_WORD_A)
4
eor temp,temp5
5
cp temp,temp1 ; CRC(empfangen)
6
brne RDS_GRUPPENTYP_NO_A
7
; Highbyte "CRC"mit OFFSET_WORD_A verknüpfen
8
ldi temp,high(OFFSET_WORD_A)
9
eor temp,temp6
10
cp temp,temp2 ; CRC(empfangen)
11
brne RDS_GRUPPENTYP_NO_A
12
; ERGEBNIS
13
LDS temp,(adr_RDS_DATA3) ; aus SRAM laden
14
STS (adr_RDS_GRUPPE_AH_ROH),temp ; im SRAM ablegen
15
LDS temp,(adr_RDS_DATA2)
16
STS (adr_RDS_GRUPPE_AL_ROH),temp
17
ldi temp1,1 ; RÜCKGABEWERT
18
ret
19
RDS_GRUPPENTYP_NO_A:
Vorteile:
-du sparst das kopieren der berechneten CRC
-der Programmteil wird bereits verlassen, wenn das erste Byte des CRC
nicht stimmt
-du sparst Register temp3 und tmp4
Auch wenn der Beitrag schon sehr alt ist, möchte ich dazu mal als
Neuling eine Frage setllen:
Geschrieben ist der Code für einen ATmega8.
Ließe sich der auch auf einen Arduino Nano (ATmega 328) verwenden?
So alt das Projekt auch ist, ist es für mich gerade aktuell...
Vielen Dank schon mal.
Vielen Dank.
Nur zur Vorwarnung für mich (nicht dass ich hinterher geschockt umfalle
;) ): Um welche Besonderheiten geht es?
Allgemein für den Hintergrund:
Es gibt unmassen Schaltpläne für RDS-Decoder - nur mit dem Nachteil,
dass man da nen PIC programmieren muss - und mit dem Arduino wäre es
sicher etwas einfacher (denke ich mal so leichtsinnigerweise).
Dann würde ich dann mir das Material (Arduino, TDA7330, Display) zulegen
und das mal in Angriff nehmen.
Ich bin noch Fan von eher älteren Radios (vor Allem RFT / REMA).
Jedoch würde ich Denen gerne diese zusätzliche Anzeige spendieren.
Zur Portierung muß man die Registernamen und IRQnamen anpassen, sowie
bei den Timern genau darauf achten, daß das gleiche passiert, wie im
ursprünglich verwendeten µC. Hierzu ist ein genauerer Blick in beide
Datenblätter zusammen mit etwas Erfahrung nötig. Oder man lernt dies bei
dieser Gelegenheit.
mfg
OK, würde mich als Neuanfänger evtl. da doch etwas überfordern...
Evtl. blöde Frage:
Wenn ich jetzt ein UNO3-Bord nehme, den 328 gegen einen 8 ersetze
(Pincompatibel sind sie ja) müsste das dann meines Erachtens
funktionieren... oder liege ich da falsch?
Zum wirklichen Lernen würden dann (wenn ich hiermit erstmal ein für mich
nützliches Startprojekt erfolgreich am Laufen habe) folgen... Idee'n
gibt es genug ;)
Hübsches Projekt, aber kann der Prozessor nicht den rds Rohdaten decoder
gleich mit machen?
So hoch sind die Frequenzen doch nicht. Klar muss man das Signal vor den
ganzen Filtern angreifen, aber da muss man den Rohdatendecoder auch hin
setzen.
Wäre das noch möglich?
Die Filterung der Frequenzen und soweit ich mich da mal eingelesen habe
da auch noch mit der Phasenlage im ATmel zu zaubern, dürfte wohl nicht
möglich sein... und wenn, dann nur mit extrem hohem
programmiertechnischem Aufwand, der in keinem Verhältnis steht.
Da ist es sinvoller eine Platine mit nem TDA7330:
https://pdf1.alldatasheet.com/datasheet-pdf/view/25129/STMICROELECTRONICS/TDA7330.html
zu basteln, zumal die Ringsrumbeschaltung minimal ist.
Das lässt sich mühelos auf einer Lochrasterplatine "zusammenbraten" ;)
@Bernhard D.
Beim Datenblatt zum TDA7330 ist mir aufgefallen, dass der einen Ausgang
(PIN 14) für Anzeige "RDS-Qualität" hat.
Dafür hast Du am ATmega die grüne LED "RDS-OK" eingebunden.
Wäre es dann bei Verwendung des TDA7330 sinnvoller, statt der LED am
Atmega dann die LED am TDA zu betreiben?
Mike schrieb:> Geschrieben ist der Code für einen ATmega8.> Ließe sich der auch auf einen Arduino Nano (ATmega 328) verwenden?
Vermutlich schon. Der ATmega328 müsste die 32k-Flash-Variante des
ATmega8 sein.
Bernd schrieb:> Vermutlich schon. Der ATmega328 müsste die 32k-Flash-Variante des> ATmega8 sein.
Der ATmega328 ist die 32K-Flash-Variante des ATmega88, nicht des uralten
ATmega8.
Sooo,
ich habe jetzt (auf einem Breadboard) soweit die reine Decoder-Schaltung
(ohne Rohdatendecoder) aufgebaut.
Ich habe jedoch ein 20x4-Deisplay verwendet.
Die ensprechenden Zeilen habe ich in der RDSLCD_LCD_ini.asm
auskommentiert und dafür die beiden zeilen für 16x4 kommentiert.
Ber irgendwie scheinen wohl trotzdem nicht alle 20Zeichen pro Zeile
genutzt zu werden.
Aber das ist aktuell noch nicht wirklich das eigentliche Problem.
Das Zweite ist:
Auch wenn ich keine Daten (aufgrund fehlenden Rohdatendekoders empfange)
müsste doch das Display auf die anderen Anzeigen umschalten, wenn ich
den Menü-Taster betätige. Das passiert jedoch nicht...
Zum Anderen:
Wenn die Daten fehlen, müsste doch eigentlich die gelbe LED für
"RDS-Error" leuchten... - Die bleibt jedoch dunkel.
Beim Starten des Dekoders läuft die "Test-Ampel" jedoch sauber durch.
Habe ich was übersehen und falsch verstanden?
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