Forum: Mikrocontroller und Digitale Elektronik RC5-Code-Empfangsprogramm für 8051er in Assembler


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Johann D. (khs)


Bewertung
0 lesenswert
nicht lesenswert
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

von Pittiplatsch (Gast)


Bewertung
1 lesenswert
nicht lesenswert
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.

von Johann D. (khs)


Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort, auch wenn ich nur Bahnhof verstehe.
Es sollte nur in Assembler für 8051er sein.

Gruß, Hans

von Günni (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
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.

von Route_66 H. (route_66)


Bewertung
0 lesenswert
nicht lesenswert
Hallo!
vielleicht hier:
https://www.instructables.com/TV-Remote-controlled-home-appliance-using-8051/

Das ist die einfachste Form mit Polling und Warteschleifen.

von Route_66 H. (route_66)


Angehängte Dateien:

Bewertung
2 lesenswert
nicht lesenswert
Hier noch eine Anleitung, wie es per Interrupt gemacht werden könnte.

von Johann D. (khs)


Bewertung
0 lesenswert
nicht lesenswert
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

von Andi B. (andi_b2)


Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
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.

von Anarchist (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Ich würde es in 8051 AH BASIC programmieren.
Das geht viel leichter als in Maschinensprache.

von Besserwisser (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Anarchist schrieb:
> Ich würde es in 8051 AH BASIC programmieren.

ich bin für camel forth, dann ist es auch performant!

von Peter D. (peda)


Angehängte Dateien:

Bewertung
5 lesenswert
nicht lesenswert
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.

von Jacko (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
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.

von Johann D. (khs)


Bewertung
0 lesenswert
nicht lesenswert
Und wenn man dazu die passende Fernbedienung nicht hat?

von Thorsten S. (thosch)


Bewertung
0 lesenswert
nicht lesenswert
Dann baut und programmiert man sich den Sender auch...

von Micromite (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von Johann D. (khs)


Bewertung
0 lesenswert
nicht lesenswert
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

von Jacko (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
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.

von Johann D. (khs)


Bewertung
2 lesenswert
nicht lesenswert
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?

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Bewertung
-4 lesenswert
nicht lesenswert
Hey wenn Du noch ein paar solch nett formulierter Postings hinterlässt,
wird man Dir bestimmt umso lieber helfen ....................

von Johann D. (khs)


Bewertung
0 lesenswert
nicht lesenswert
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

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]
  • [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.