Hallo, ich wende mich mit einem mir unerklärlichem Phänomen an dieses
Forum und hoffe irgendwer kann mir helfen.
Ich habe bei einem Projekt die Aufgabe bekommen einen RDS-Datenstrom mit
einem ATmega8 einzulesen und auszuwerten. Das RDS-Signal liegt dabei
seriell an (Data/Clk). Das eigentliche einlesen erfolgt über eine
Interrupt Routine.
1 | volatile uint16_t data;
|
2 |
|
3 | GIMSK |=(1<<INT0);
|
4 | MCUCR |= _BV(ISC01) | _BV(ISC00); // INT0 interrupt on rising edge
|
5 | PORTD |= ( 1 << PD2 );
|
6 |
|
7 | DDRD = 0x00;
|
8 | PORTD |= ( 1 << PD0 ); // Port PD0 = Datenleitung
|
9 |
|
10 | ISR(INT0_vect)
|
11 | {
|
12 | /* read RDS-data*/
|
13 | data=data << 1;
|
14 | if( bit_is_set(PIND,PD0) ) data|=0x01;
|
15 | }
|
Ein Block der RDS Übertragung ist 26 Bit lang. Aus diesen 26 Bit wird
mit der Funktion Calculate_Syndrom das Syndrom berechnet.
1 | /********************************************************************************
|
2 | * int Calculate_Syndrom(unsigned long Data)
|
3 | * Funktion: Syndrom berechnen
|
4 | * Parameter: 32Bit Datenwort
|
5 | * zur�ck: 10Bit Syndrom
|
6 | *********************************************************************************/
|
7 | unsigned int Calculate_Syndrom(unsigned long Data)
|
8 | {
|
9 | unsigned int MSB16, LSB16;
|
10 |
|
11 | MSB16 = (Data>>16) & 0x03FF; //16 Bit rechts schieben und ausmaskieren
|
12 | LSB16 = Data;
|
13 |
|
14 | MSB16 &= 0x3FFF; // nur 26 Bit verwenden
|
15 | if((LSB16 & 0x0001) == 0x0001) // Multiplikation des empfangen Wortes mit
|
16 | MSB16 ^= 0x031B; // der Kontrollmatrix
|
17 | if((LSB16 & 0x0002) == 0x0002)
|
18 | MSB16 ^= 0x038F;
|
19 | if((LSB16 & 0x0004) == 0x0004)
|
20 | MSB16 ^= 0x02A7;
|
21 | if((LSB16 & 0x0008) == 0x0008)
|
22 | MSB16 ^= 0x00F7;
|
23 | if((LSB16 & 0x0010) == 0x0010)
|
24 | MSB16 ^= 0x01EE;
|
25 | if((LSB16 & 0x0020) == 0x0020)
|
26 | MSB16 ^= 0x03DC;
|
27 | if((LSB16 & 0x0040) == 0x0040)
|
28 | MSB16 ^= 0x0201;
|
29 | if((LSB16 & 0x0080) == 0x0080)
|
30 | MSB16 ^= 0x01BB;
|
31 | if((LSB16 & 0x0100) == 0x0100)
|
32 | MSB16 ^= 0x0376;
|
33 | if((LSB16 & 0x0200) == 0x0200)
|
34 | MSB16 ^= 0x0355;
|
35 | if((LSB16 & 0x0400) == 0x0400)
|
36 | MSB16 ^= 0x0313;
|
37 | if((LSB16 & 0x0800) == 0x0800)
|
38 | MSB16 ^= 0x039F;
|
39 | if((LSB16 & 0x1000) == 0x1000)
|
40 | MSB16 ^= 0x0287;
|
41 | if((LSB16 & 0x2000) == 0x2000)
|
42 | MSB16 ^= 0x00B7;
|
43 | if((LSB16 & 0x4000) == 0x4000)
|
44 | MSB16 ^= 0x016E;
|
45 | if((LSB16 & 0x8000) == 0x8000)
|
46 | MSB16 ^= 0x02DC;
|
47 |
|
48 | // MSB16 = 0x00FF;
|
49 | return MSB16;
|
50 | }
|
Jetzt zu meinem Problem:
Bei folgendem Datenstrom sollte das Syndrom = 0 sein:
11111111111111110011001101 [0x03FFFCCD]
Wenn ich jetzt diesen Datenstrom an den Mikrocontroller anlege und über
die Interrupt-Routine einlese so kommt leider nicht 0 heraus. Wobei die
Routine einliest und die eingelesenen Bits richtig sind. Das Merkwürdige
ist jedoch, wenn ich den Wert direkt an Calculate_Syndrom() übergebe ist
das Ergebnis korrekt. Auch wenn ich die ISR-Routine simmuliere in dem
ich 26mal linksschiebe und die letzte Stelle entsprechend setzte kommt
auch 0 heraus.
Ich vermute das irgendwie die 26 Bit nicht richtig eingelesen werden,
denn meine Funktion zum Syndrom berechnen funktioniert ja.
Wenn jemand eine Idee hat wäre das super, ich bin mit meinem Latein am
Ende.
mfG Johannes