Habe vor eine 8051er Steuerung (AT89S52) mit einer IR-Fernbdienung zu steuern. Habe dazu im Forum auch schon viele Beiträge gefunden, meistens aber für AVR µCs oder das Empfangsprogramm von Peter Danegger. Habe aber immer noch nicht C gelernt und bin auch mit den AVR-Assemblerbefehlen nicht so vertraut. Bevor ich mich selber ans programmieren mache, kann mir jemand einen Link zu einem RC5-Code-Empfangsprogramm für 8051er in Assembler geben? Gruß, Hans
Ich hab leider nur Verilog:
1 | //////////////////////////////////////////////////// |
2 | //功能:红外读码,返回读码结果 |
3 | // |
4 | //子模块:无 |
5 | // |
6 | //版本:V0.00 |
7 | // |
8 | //日期:20131003 |
9 | //////////////////////////////////////////////////// |
10 | module ir_module( |
11 | //Clock Input:48M |
12 | input clk_1m, |
13 | input ir, |
14 | input rst, |
15 | //Return Value |
16 | output reg [7:0]Code |
17 | ); |
18 | |
19 | reg [2:0]IR_reg; |
20 | initial IR_reg = 3'b0; |
21 | always @ (posedge clk_1m) //1us |
22 | begin |
23 | IR_reg[0] <= ir; |
24 | IR_reg[1] <= IR_reg[0]; |
25 | IR_reg[2] <= IR_reg[1]; |
26 | end |
27 | |
28 | wire IR_pos = (IR_reg[0]==1'b1) & (IR_reg[1]==1'b0); |
29 | wire IR_pos2= (IR_reg[1]==1'b1) & (IR_reg[2]==1'b0); |
30 | wire IR_neg = (IR_reg[0]==1'b0) & (IR_reg[1]==1'b1); |
31 | wire IR_neg2= (IR_reg[1]==1'b0) & (IR_reg[2]==1'b1); |
32 | |
33 | //状态 |
34 | parameter ST_START_L = 3'b000, ST_CODE_P = 3'b001 , ST_VALUE_P = 3'b010; |
35 | parameter ST_START_H = 3'b011, ST_CODE_N = 3'b100 , ST_VALUE_N = 3'b101; |
36 | //宽度 |
37 | parameter START_H = 16'd4096; //us |
38 | parameter START_L = 16'd8192; //us |
39 | parameter CODE_0 = 16'd512 + 16'd512 ; //us |
40 | parameter CODE_1 = 16'd1536 + 16'd512 ; //us |
41 | |
42 | reg [2:0]state; |
43 | initial state = ST_START_L; |
44 | reg [15:0]cnt_h; |
45 | initial cnt_h = 16'b0; |
46 | reg [15:0]cnt_l; |
47 | initial cnt_l = 16'b0; |
48 | reg [31:0]T_Value; |
49 | initial T_Value = 32'b0; |
50 | |
51 | reg [31:0]IR_Value; |
52 | initial IR_Value = 32'b0; |
53 | |
54 | reg [15:0]cnt_val; |
55 | initial cnt_val = 16'b0; |
56 | |
57 | reg Flag_LVL; |
58 | initial Flag_LVL = 1'b0; |
59 | |
60 | reg Flag_HVL; |
61 | initial Flag_HVL = 1'b0; |
62 | |
63 | always @ (posedge clk_1m or posedge ir) |
64 | begin |
65 | if(ir) //高电平复 |
66 | cnt_l <= 16'b0; |
67 | else if(cnt_l[15] & cnt_l[10]) //低计数溢出复 |
68 | cnt_l <= 16'b0; |
69 | else |
70 | cnt_l <= cnt_l + 1'b1; //低电平计数 |
71 | end |
72 | |
73 | always @ (negedge clk_1m) |
74 | begin |
75 | if(cnt_l == START_L) |
76 | Flag_LVL <= 1'b1; |
77 | else if(IR_pos2) |
78 | Flag_LVL <= 1'b0; |
79 | end |
80 | |
81 | |
82 | always @ (posedge clk_1m or negedge ir) |
83 | begin |
84 | if(!ir) //低电平复 |
85 | cnt_h <= 16'b0; |
86 | else if(cnt_h[15] & cnt_h[10]) //高计数溢出复 |
87 | cnt_h <= 16'b0; |
88 | else |
89 | cnt_h <= cnt_h + 1'b1; //高电平计数 |
90 | end |
91 | |
92 | |
93 | always @ (negedge clk_1m) |
94 | begin |
95 | if(cnt_h == START_H) |
96 | Flag_HVL <=1; |
97 | else if(IR_neg2) |
98 | Flag_HVL <= 1'b0; |
99 | end |
100 | |
101 | reg [15:0]IR_code; |
102 | always @ (posedge clk_1m or posedge IR_neg) |
103 | begin |
104 | if(IR_neg) |
105 | begin |
106 | cnt_val <= 16'b0; |
107 | end |
108 | else if(state == ST_CODE_P) |
109 | begin |
110 | if(cnt_val == CODE_0) |
111 | begin |
112 | IR_code <= CODE_0; |
113 | cnt_val <= cnt_val + 1'b1; |
114 | end |
115 | else if(cnt_val == CODE_1) |
116 | begin |
117 | IR_code <= CODE_1; |
118 | cnt_val <= cnt_val + 1'b1; |
119 | end |
120 | else |
121 | cnt_val <= cnt_val + 1'b1; |
122 | end |
123 | end |
124 | |
125 | |
126 | wire fault = cnt_h[15] | cnt_l[15]; //错误 |
127 | reg [5:0]cnt_num; |
128 | initial cnt_num = 6'b0; |
129 | |
130 | |
131 | always @ (posedge clk_1m) //1us |
132 | begin |
133 | |
134 | if( rst == 1 ) |
135 | begin |
136 | // IR_Value[8] <= 0; IR_Value[9] <= 0; IR_Value[10] <= 0; IR_Value[11] <= 0; |
137 | // IR_Value[12] <= 0; IR_Value[13] <= 0; IR_Value[14] <= 0; IR_Value[15] <= 0; |
138 | Code <= 0; |
139 | end |
140 | ; |
141 | case(state) |
142 | ST_START_L: |
143 | begin |
144 | cnt_num <= 6'b0; |
145 | if((IR_pos == 1'b1) & (Flag_LVL==1'b1)) |
146 | begin |
147 | state <= ST_START_H; |
148 | end |
149 | else if(fault) |
150 | state <= ST_START_L; |
151 | end |
152 | ST_START_H : |
153 | begin |
154 | cnt_num <= 6'b0; |
155 | if((IR_neg == 1'b1) & (Flag_HVL==1'b1)) |
156 | begin |
157 | state <= ST_CODE_P; |
158 | end |
159 | else if(fault) |
160 | state <= ST_START_L; |
161 | end |
162 | ST_CODE_P : |
163 | begin |
164 | if((IR_neg)&(IR_code == CODE_1)) |
165 | begin |
166 | cnt_num = cnt_num + 1'b1; |
167 | IR_Value <= {IR_Value[30:0],1'b1}; |
168 | end |
169 | else if((IR_neg)&(IR_code == CODE_0)) |
170 | begin |
171 | cnt_num = cnt_num + 1'b1; |
172 | IR_Value <= {IR_Value[30:0],1'b0}; |
173 | end |
174 | else if(cnt_num==6'd32) |
175 | begin |
176 | cnt_num <= 6'b0; |
177 | T_Value <= IR_Value; |
178 | state <= ST_START_L; |
179 | Code <= {IR_Value[8],IR_Value[9],IR_Value[10],IR_Value[11],IR_Value[12],IR_Value[13],IR_Value[14],IR_Value[15]}; |
180 | end |
181 | end |
182 | default : state <= ST_START_L; |
183 | endcase |
184 | end |
185 | |
186 | endmodule |
Funktionieren tut er aber. Habe ich probiert.
Danke für die Antwort, auch wenn ich nur Bahnhof verstehe. Es sollte nur in Assembler für 8051er sein. Gruß, Hans
Das sollte man schon selber programmieren. Schließlich muss man entscheiden, wie der Empfang stattfinden und was der Prozessor in der übrigen Zeit tun soll. Man könnte den Eingangsport in kurzen Abständen per Timerinterrupt abfragen "polling", ob ein Signal hereinkommt. Dann kann man die Arbeit an anderen Programmteilen stoppen und nur das Signal verarbeiten, bis der Befehl zu Ende empfangen wurde. Für einige Applikationen ist ein solches Anhalten des Hauptprogramms nicht möglich. Oder man löst beim Empfang eine Signals einen Interrupt aus (Flankenerkennung am Port), oder, oder .... Was am besten ist, hängt auch von dem verwendeten 8051-Derivat ab und den Möglichkeiten, die der Prozessor bietet.
Hallo! vielleicht hier: https://www.instructables.com/TV-Remote-controlled-home-appliance-using-8051/ Das ist die einfachste Form mit Polling und Warteschleifen.
Hier noch eine Anleitung, wie es per Interrupt gemacht werden könnte.
Danke für die Antworten. In dem Link von Route_66 H. habe ich gefunden wonach ich suchte. Da konnte ich im Assemblerbeispiel der Empfangsroutine folgen und die Zeiteinstellungen auf die jeweilige Quartzfrequenz dürfte kein Problem sein. Da in meinem Programm schon alle 3 Timer in Verwendung sind, dürften Warteschleifen problemloser sein, als einen Timer für 2 Aufgaben zu verwenden. Gruß, Hans
In der UAT-0422/00 Part 2 sind Assembler Listings für den 8051 dabei. Könnte auch 70422002.pdf heißen. Etwas was ich mal dazu gefunden habe, im Anhang.
Anarchist schrieb: > Ich würde es in 8051 AH BASIC programmieren. ich bin für camel forth, dann ist es auch performant!
Anbei die C-Source und daraus der Assembler-Output. T0 wird in den Split-Mode gesetzt, d.h. alle 256 Takte ein Interrupt. Sind noch andere Interrupts vorhanden, muß er auf die höchste Priorität gesetzt werden, damit das Timing nicht gestört wird. Ist rc5_done gesetzt, dann enthält rc5_data die Daten. Für den nächsten Empfang muß rc5_done gelöscht werden.
Gähn! - Mach doch da nicht so ein Gewese drum: Wenn dir RC5 zu kompliziert ist, gibt es auch einfachere Codes mit variabler Pausen-, oder Pulslänge. Voll easy und auch betriebssicher.
Und wenn man dazu die passende Fernbedienung nicht hat?
Dann baut und programmiert man sich den Sender auch...
Johann D. schrieb: > Habe aber immer noch nicht C gelernt und bin auch mit > den AVR-Assemblerbefehlen nicht so vertraut. Dann nimm doch so etwas einfaches: https://avrhelp.mcselec.com/index.html?config_rc5.htm
Ich will ja hier kein ganz neues Projekt beginnen, sondern eine bestehende Steuerung, die ich bisher mit einem Laptop über die RS232 einstellte, ohne PC bedienen können. Und das vorhandene Programm ist halt in Assembler. Bitte das Thema jetzt nicht auf Programmiersprachen ausdehnen. Gruß, Hans
Halt uns doch nicht für blöd: Wwoher soll denn deine RC5-Fernsteuerung wissen, was vorher über RS232 auch nur der 8051 kannte? Kenne keine Übersetzungslibrary von weiß-ich-nicht-RS232 auf weiß-ich-nich-RC5. Gilt für jede Programmiersprache.
Kannst Du den Titel dieses Themas nicht lesen, heisst es da RC5-Code-Empfangsprogramm oder heisst es da RC5-Code-Sendeprogramm? Glaubst Du, dass wenn überall jede Menge alte Fernbedienungen rumliegen ich so eine selber bauen und programmieren will? Wie glaubst Du, dass ich die Steuerung bisher einstellen konnte, wenn ich nicht weiß wie oder was über RS232 übertragen wurde? Glaubst Du, dass ich den IR-Sensor an den RX-Eingang anschliessen will?
Hey wenn Du noch ein paar solch nett formulierter Postings hinterlässt, wird man Dir bestimmt umso lieber helfen ....................
Für alle, die es noch nicht gelesen haben, am 11. 11. hatte ich schon gepostet, daß ich die gesuchte Hilfe gefunden habe. Und wenn einem dann danach noch unterstellt wird, daß mir der RC5-Code zu kompliziert wäre und dann auch noch zugetraut wird die serielle Verbindung mit dem PC 1 zu 1 mit der Fernbedienung ersetzen zu wollen.... Aber Du hast schon recht, auf nett formulierte Postings sollte man nicht mit nett formulierten Postings antworten - Tut mir leid. Gruß, Hans
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.