Hallo, nachdem ich für avr-gcc nichts passendes lauffähiges fand habe ich anhand von http://www.obersomer.com/furios-power/index.php?view=article&id=69%3Airnec&format=pdf&option=com_content&Itemid=66 und http://www.sbprojects.com/knowledge/ir/nec.htm einen auf einem ATmega32 lauffähigen Code erstellt. Die Adresse wird als uint16_t variable ausgespuckt und der Befehl als uint8_t, solange die Daten richtig erkannt wurden. Die lcd.h und lcd.c sind Teil der lib von Peter Fleury Gruß Patrick
Hallo Patrick, habe bin gerade durch Zufall hier gelandet und habe festegestellt, dass ich gerade vor dem selbem Problem stehe... Das ganze ist Teil meines Moodlight-Projekts, wofür ich eine Fernbedienung gekauft habe. Und nach einer Runde reverse-engineering und recherche weiß ich nun, dass sie mit dem NEC-Code sendet. Weitere Infos hier: http://madengineer.de/projekte/moodlight/ Ich würde mich freuen, wenn du deinen Code zur Verfügung stellen könntest... Viele Grüße Jan
Naja einen Bascom Link findet man schon in der PDF, die er oben verlinkt hat: http://www.mcselec.com/index.php?option=com_content&task=view&id=223&Itemid=57 Das Problem an diesem Code ist, dass er Interrupt gesteuert ist, hier könnte man dann Probleme mit Störungen bekommen, die dann den µC blockieren. Ich arbeite an einem Timerbasiertem Code, welchen ich in meine Soft-PWM integrieren kann. Aber das Prinzip ist das gleiche: Am Anfang der Routine wird der Port abgefragt, wenn sich im Vergleich zum Vorherigem Aufruf nichts geändert hat, dann wird die Routine wieder verlassen. Nach dieser Flankenerkennung könnte man dann den IRQ-basierten Code weiterverwenden.
Wenn ihr einen Code wollt, der "im Prinzip" auf Peters RC5 decoder aufbaut, hier... Es werden alle 32 empfangenen Bit zurückgegeben, bei der weiteren Auswertung kann man dann entscheiden, ob man Standard oder Erweiterten Code annimmt (8 oder 16 Bit Adresse) und ob man die Negierung zur Fehlererkennung ausnutzt...
1 | // read remote...
|
2 | necdata = get_nec_data(); |
3 | if (necdata != IRNEC_NOREC) |
4 | {
|
5 | set_cursor(0,0); |
6 | lcd_pstring (PSTR ("NEC: ")); |
7 | |
8 | if ((((uint8_t)(necdata >> 8) & 0xff) ^ (uint8_t)(necdata & 0x00ff)) != 0xff) |
9 | {
|
10 | lcd_pstring (PSTR ("error")); |
11 | }
|
12 | else
|
13 | {
|
14 | tmp = (necdata >> 24) & 0xff; |
15 | print_hex (tmp); |
16 | lcd_data (' '); |
17 | tmp = (necdata >> 16) & 0xff; |
18 | print_hex (tmp); |
19 | lcd_data (' '); |
20 | tmp = (necdata >> 8) & 0xff; |
21 | print_hex (tmp); |
22 | lcd_data (' '); |
23 | tmp = necdata & 0xff; |
24 | print_hex (tmp); |
25 | }
|
26 | }
|
bei mir werden interrupt nur zum wecken aus dem powerdown mode und der timer nur während des empfangens benutzt. Wird ein spike empfangen, kann der code auswerten, ob ein Startbit empfangen wurde (9ms pause) Bricht eine übertragung ab, gibt es ff,ff,ff,ff als ergebniss
1 | $regfile = "m88def.dat" |
2 | $crystal = 16000000 |
3 | '10khz |
4 | Config Timer2 = Timer , Prescale = 8 |
5 | Const Timer2vorgabe = 56 |
6 | On Timer2 Timer2_irq |
7 | Disable Timer2 |
8 | 'Remote variables |
9 | Dim Byte1 As Byte |
10 | Dim Byte2 As Byte |
11 | Dim Byte3 As Byte |
12 | Dim Byte4 As Byte |
13 | Dim Count As Byte |
14 | Dim B As Byte |
15 | 'interrupt nur für wakeup! |
16 | Config Portd.3 = Input |
17 | R_in1 Alias Pind.3 |
18 | Config Int1 = Low Level |
19 | On Int1 Rx_remo |
20 | |
21 | |
22 | 'main program |
23 | do
|
24 | if r_in1=0 then gosub nec_rx |
25 | loop
|
26 | end
|
27 | |
28 | |
29 | Rx_remo: |
30 | Gosub Set_hw |
31 | return
|
32 | |
33 | nec_rx: |
34 | Do
|
35 | Loop Until R_in1 = 0 |
36 | |
37 | Count = 0 |
38 | Start Timer2 |
39 | |
40 | Do
|
41 | Loop Until R_in1 = 1 |
42 | Stop Timer2 |
43 | |
44 | |
45 | If Count > 74 Then 'Start condition received?? |
46 | |
47 | Count = 0 |
48 | Start Timer2 |
49 | Do
|
50 | Loop Until R_in1 = 0 |
51 | Stop Timer2 |
52 | |
53 | Byte1 = 0 |
54 | Byte2 = 0 |
55 | Byte3 = 0 |
56 | Byte4 = 0 |
57 | |
58 | For B = 0 To 7 |
59 | Count = 0 |
60 | Do
|
61 | Loop Until R_in1 = 1 |
62 | Start Timer2 |
63 | |
64 | Do
|
65 | Loop Until R_in1 = 0 Or Count > 100 |
66 | Stop Timer2 |
67 | |
68 | |
69 | If Count > 8 Then Byte1.b = 1 |
70 | Next
|
71 | |
72 | For B = 0 To 7 |
73 | Count = 0 |
74 | Do
|
75 | Loop Until R_in1 = 1 |
76 | Start Timer2 |
77 | |
78 | |
79 | Do
|
80 | Loop Until R_in1 = 0 Or Count > 100 |
81 | Stop Timer2 |
82 | |
83 | If Count > 8 Then Byte2.b = 1 |
84 | Next
|
85 | |
86 | For B = 0 To 7 |
87 | Count = 0 |
88 | Do
|
89 | Loop Until R_in1 = 1 |
90 | Start Timer2 |
91 | |
92 | Do
|
93 | Loop Until R_in1 = 0 Or Count > 100 |
94 | |
95 | Stop Timer2 |
96 | If Count > 8 Then Byte3.b = 1 |
97 | Next
|
98 | |
99 | |
100 | For B = 0 To 7 |
101 | Count = 0 |
102 | Do
|
103 | Loop Until R_in1 = 1 |
104 | Enable Timer2 |
105 | |
106 | Do
|
107 | Loop Until R_in1 = 0 Or Count > 100 |
108 | |
109 | Disable Timer2 |
110 | If Count > 8 Then Byte4.b = 1 |
111 | Next
|
112 | Gosub Remo_auswert |
113 | End If 'start condition |
114 | |
115 | Return
|
116 | |
117 | Set_hw: |
118 | Enable Interrupts |
119 | 'Enable Timer0 |
120 | 'Start Timer0 |
121 | Enable Timer2 |
122 | Stop Timer2 |
123 | Disable Timer1 |
124 | Disable Spi |
125 | Stop Adc |
126 | Stop Ac |
127 | Disable Twi |
128 | Disable Int0 |
129 | Disable Int1 |
130 | Enable Urxc |
131 | Return
|
sorry der fehlt noch: Timer2_irq: Timer2 = Timer2vorgabe Incr Count Return
Hallo Bernhard, vielen Dank für deinen Code. Habe leider derzeit ein Hardwareproblem zu lösen, so dass ich das noch nicht testen könnte.. viele Grüße Jan
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.