RC5-Code-Empfangsprogramm für 8051er in Assembler

OP #6471528
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
Gast #6471603
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.
Gast #6471977
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.
OP #6472609
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
#6473200
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.
Angehängte Dateien:
OP #6474538
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
Gast #6474722
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.
OP #6474911
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?
OP #6475963
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren