設(shè)計背景:
紅外線(Infrared)是波長介乎微波與可見光之間的電磁波,波長在760納米(nm)至1毫米(mm)之間,比紅光長的非可見光。紅外線遙控是目前使用最廣泛的一種通信和遙控手段。由于紅外線遙控裝置具有體積小、功耗低、功能強(qiáng)、成本低等特點(diǎn),因而,繼彩電、錄像機(jī)之后,在錄音機(jī)、音響設(shè)備、空凋機(jī)以及玩具等其它小型電器裝置上也紛紛采用紅外線遙控。現(xiàn)在工業(yè)設(shè)備中,也已經(jīng)廣泛在使用。
設(shè)計原理:
紅外遙控系統(tǒng)主要由紅外的發(fā)送裝置和接收裝置組成,發(fā)送裝置可由按鍵,編碼模塊,發(fā)射電路等組成,接收裝置由紅外接收電路,遙控,解碼模塊等組成,此次設(shè)計我們用到的硬件平臺式是Altera的DE1_SOC,晶振為50MHZ。
在紅外的編碼中,我們對1 和 0 的編碼是通過38KHZ的脈沖來定義的,在紅外的的編碼中每個脈沖的為256.25us長的38KHZ載波頻率(26.3us),對0,1的脈沖的定義的時間如下圖
紅外的數(shù)據(jù)格式為包括引導(dǎo)碼,用戶碼,數(shù)據(jù)碼和數(shù)據(jù)糾錯碼,停止位編碼總為32位。數(shù)據(jù)反碼是數(shù)據(jù)碼反相后的編碼,可用于對數(shù)據(jù)的糾錯。此外第二段的用戶碼可以在遙控應(yīng)用電路中設(shè)置為第一段用戶碼的反碼。
數(shù)據(jù)格式如下圖:
一幀數(shù)據(jù)在發(fā)送時先發(fā)送9MS的高電平,然后發(fā)送4.5MS的低電平的起始位,然后發(fā)送用戶碼,數(shù)據(jù)碼,數(shù)據(jù)反碼。然后再發(fā)送一位的停止位。不發(fā)送數(shù)據(jù)時數(shù)據(jù)線一直為低。
發(fā)送的時序圖如下:
接受的時,接收到的時序和發(fā)送的時序恰恰相反,如發(fā)送時先發(fā)送9ms的高,4.5ms的低,接收為接收9ms的低電平,4.5ms低電平。
接收的控制器我們用的時紅外遙控裝置,按鍵發(fā)送的數(shù)據(jù)如下圖所示
設(shè)計架構(gòu)圖:
設(shè)計的總框架如下圖:
在我們的設(shè)計中分頻模塊提供所需要的38KHZ的時鐘,當(dāng)按鍵按下時發(fā)送我們的發(fā)送模塊發(fā)送一個給定的數(shù)值,我的設(shè)計中用戶碼為8’b0第二段用戶碼為8’hff,然后發(fā)送給定的數(shù)據(jù)碼,和數(shù)據(jù)反碼。上電后我們的設(shè)計會發(fā)一次我們給定的數(shù)據(jù)碼,然后在接受模塊會接受到其發(fā)送的數(shù)據(jù)并在數(shù)碼管上顯示出來,之后我們可以用我們我的遙控鍵盤來發(fā)送數(shù)據(jù),接收模塊接收顯示出來,通過驗證我們接收和發(fā)送的正確。
設(shè)計代碼:
頂層代碼:
00moduleinfrared(clk,rst_n,key,tx,seg1,seg2,rx);
01
02inputclk,rst_n;
03inputkey;
04outputtx;
05inputrx;
06wire[7:0]show_data;
07output[7:0]seg1,seg2;
08wire[31:0]data_n;
09wireclk_38khz;
10
11
12 clk_frep clk_frep_dut( //分頻模塊
13 .clk(clk),
14 .rst_n(rst_n),
15 .clk_38khz(clk_38khz)
16);
17
18
19 tttxxx tx_dut( //發(fā)送模塊
20 .clk(clk_38khz),
21 .rst_n(rst_n),
22 .data_n(data_n),
23 .tx(tx),
24 .key(key)
25);
26
27 seg seg01( //數(shù)碼管模塊
28 .clk(clk),
29 .rst_n(rst_n),
30 .seg7(seg1),
31 .data_in(show_data[3:0])
32);
33
34 seg seg02(
35 .clk(clk),
36 .rst_n(rst_n),
37 .seg7(seg2),
38 .data_in(show_data[7:4])
39);
40
41 rx_led led_dut( //接收模塊
42 .clk(clk_38khz),
43 .rst_n(rst_n),
44 .rx(rx),
45 .show_data(show_data)
46);
47
48
49endmodule
發(fā)送模塊:
000moduletttxxx(clk,rst_n,data_n,tx,key);
001
002inputclk,rst_n;
003inputkey;
004input[31:0]data_n;
005outputregtx;
006
007parameterT9ms=342;//9000/26.3
008parameterT4500us=171; //4.5ms 4500/26.3
009parameterT0=21; //(1125-562.25)/26.3
010parameterT1=63; //(2250-562.25)/26.3
011parameterT562us=21; // 562.25/26.3;
012parameterT=2666;// 一幀數(shù)據(jù)
013regT9_flag;
014regT45_flag;
015regT0_flag;
016regT1_flag;
017regT9_down;
018regT45_down;
019regT0_down;
020regT1_down;
021reg[9:0]cnt9;
022reg[9:0]cnt45;
023reg[9:0]cnt0;
024reg[9:0]cnt1;
025reg[9:0]cnt562;
026regt0_clk,t1_clk;
027reg[8:0]count;
028reg[2:0]state;
029regdata;
030reg[31:0]d_data;
031
032always@(posedgeclk)
033 if(!rst_n)
034 begin
035 count<=0;
036 state<=0;
037 tx<=0;
038 d_data<={8'b0,8'hff,8'b10100010,8'b01011101};//默認(rèn)的發(fā)送數(shù)據(jù)
039 end
040 else
041 case(state)
042 0:if(count<10)
043 begin
044 tx<=0;
045 count<=?count+1;
046 end
047 elseif(!key)
048 begin
049 count<=0;
050 state<=1;
051 T9_flag<=1;
052 tx<=1;
053 end
054
055 1:if(T9_down) //起始位 高電平9 ms
056 begin
057 state<=2;
058 T45_flag<=1;
059 tx<=0;
060 T9_flag<=0;
061 end
062 else
063 begin
064 tx<=1;
065 state<=1;
066 end
067
068 2:if(T45_down) // 低電平 4.5ms
069 begin
070 state<=3;
071 tx<=0;
072 T45_flag<=0;
073 end
074 else
075 tx<=0;
076
077 3:if(count<32)? ?//32位的數(shù)據(jù)編碼,如果那一位 ? ? ? 為1(0)跳轉(zhuǎn)4(5)狀態(tài)通過發(fā)送標(biāo)志結(jié)束來發(fā)送出位 1的時序
078 begin
079 count<=?count+1;
080 if(!d_data[31-count])
081 begin
082 T0_flag<=1;
083 state<=4;
084 T1_flag<=0;
085 end
086 else
087 begin
088 T1_flag<=1;
089 state<=5;
090 T0_flag<=0;
091 end
092 end
093 else
094 begin
095 count<=0;
096 state<=6;
097 T0_flag<=0;
098 T1_flag<=0;
099 end
100
101 4:if(T0_down) //位0的設(shè)置
102 begin
103 state<=3;
104 tx<=0;
105 end
106 else
107 begin
108 tx<=?t0_clk;
109 end
110
111 5:if(T1_down) //位1的設(shè)置
112 begin
113 state<=3;
114 tx<=0;
115 end
116 else
117 tx<=?t1_clk;
118
119 6:if(count
120 begin
121 count<=?count+1;
122 tx<=1;
123 end
124 else
125 begin
126
127 tx<=0;
128 end
129 default:state<=0;
130 endcase
131
132always@(posedgeclk) //計數(shù)一個9ms
133 if(!rst_n)
134 begin
135 T9_down<=0;
136 cnt9<=0;
137 end
138 elseif(T9_flag)
139 begin
140 if(cnt9
141 begin
142 T9_down<=0;
143 cnt9<=?cnt9+1;
144 end
145 else
146 begin
147 T9_down<=1;
148 cnt9<=0;
149 end
150 end
151
152always@(posedgeclk) //計數(shù)一個4.5ms
153 if(!rst_n)
154 begin
155 T45_down<=0;
156 cnt45<=0;
157 end
158 elseif(T45_flag)
159 begin
160 if(cnt45
161 begin
162 T45_down<=0;
163 cnt45<=?cnt45+1;
164 end
165 else
166 begin
167 T45_down<=1;
168 cnt45<=0;
169 end
170 end
171
172reg[9:0]cnt00;
173always@(posedgeclk) //產(chǎn)生位0的時序
174 if(!rst_n)
175 begin
176 t0_clk<=0;
177 T0_down<=0;
178 cnt0<=0;
179 cnt00<=0;
180 end
181 elseif(T0_flag)
182 begin
183 if(cnt0
184 begin
185 t0_clk<=1;
186 cnt0<=?cnt0+1;
187 T0_down<=0;
188 end
189 else
190 begin
191 if(cnt00
192 begin
193 cnt00<=?cnt00+1;
194 t0_clk<=0;
195 T0_down<=0;
196 end
197 else
198 begin
199 T0_down<=1;
200 cnt0<=0;
201 cnt00<=0;
202 end
203 end
204 end
205
206reg[9:0]cnt11;
207always@(posedgeclk) //產(chǎn)生位1的時序
208 if(!rst_n)
209 begin
210 t1_clk<=0;
211 T1_down<=0;
212 cnt1<=0;
213 cnt11<=0;
214 end
215 elseif(T1_flag)
216 begin
217 if(cnt1
218 begin
219 t1_clk<=1;
220 cnt1<=?cnt1+1;
221 T1_down<=0;
222 end
223 else
224 begin
225 if(cnt11
226 begin
227 cnt11<=?cnt11+1;
228 t1_clk<=0;
229 T1_down<=0;
230 end
231 else
232 begin
233 T1_down<=1;
234 cnt1<=0;
235 cnt11<=0;
236 end
237 end
238 end
239
240endmodule
接收模塊:
0modulerx_led(clk,rst_n,rx,show_data);
1
2inputclk,rst_n;
3inputrx;
4outputreg[7:0]show_data;
5
6reg[1:0]state;
7reg[7:0]cnt;
8regtemp;
9reg[9:0]num;
10regflag;
11reg[31:0]data;
12reg[1:0]state_s;
13regflag_x;
14reg[12:0]count;
15
16parameterT=2566;// 一幀數(shù)據(jù)的時間
17
18 //這個模塊是中因為接受的32位編碼數(shù)據(jù)中,不管是位0還是位1,接受的低電平都是相同的,
19 //我們可以通過來判斷高電平的時間來確定為位1 還是位0,位’1‘ 1.68MS,位0 562.25us
20always@(posedgeclk)
21 if(!rst_n)
22 begin
23 num<=0;
24 data<=0;
25 state_s<=0;
26 flag_x<=0;
27 count<=0;
28 end
29 else
30 begin
31 case(state_s)
32 0:if(!rx) //判斷起始位,是否接受=收數(shù)據(jù)
33 begin
34 state_s<=1;
35 flag_x<=0;
36 count<=?count+1;
37 end
38 else
39 begin
40 flag_x<=0;
41 state_s<=0;
42 count<=?count+1;
43 end
44
45 1:if(num<(342+171-1))//延遲9ms + 4.5ms的起始時間
46 begin
47 num<=?num+1;
48 state_s<=1;
49 count<=?count+1;
50 end
51 else
52 begin
53 num<=0;
54 state_s<=2;
55 count<=?count+1;
56 end
57
58 2:if(flag&&num<32)?//flag來的時候表示接到了位1 ,或者位0,
59 //通過移位寄存器來獲取32位數(shù)據(jù)
60 begin
61 data<={data[30:0],temp};
62 state_s<=2;
63 num<=?num+1;
64 count<=?count+1;
65 end
66 elseif(num==32)
67 begin
68 state_s<=3;
69 num<=0;
70 count<=?count+1;
71 end
72 else
73 state_s<=2;
74
75 3:if(num<21-1)?//延遲結(jié)束位的時間
76 begin
77 num<=?num+1;
78 count<=?count+1;
79 end
80 else
81 begin
82 if(count==T-1)//延遲一幀數(shù)據(jù)的時間后,發(fā)送一個標(biāo)志位
83 begin
84 num<=0;
85 state_s<=0;
86 flag_x<=1;
87 count<=0;
88 count<=?count+1;
89 end
90 else
91 count<=?count+1;
92 end
93 default:state_s<=0;
94 endcase
95 end
96
97always@(posedgeclk)
98 if(!rst_n)
99 begin
100 cnt<=0;
101 state<=0;
102 temp<=0;
103 flag<=0;
104 end
105 else
106 if(state_s>1&&state_s<3)
107 case(state)
108 0:if(rx)
109 begin
110 cnt<=?cnt+1;
111 state<=1;
112 flag<=0;
113 end
114 else
115 begin
116 state<=0;
117 flag<=0;
118 end
119
120 1:if(!rx)
121 begin
122 cnt<=?cnt;
123 state<=2;
124 end
125 else
126 cnt<=?cnt+1;
127
128 2:if(400
129 begin
130 temp<=0;
131 flag<=1;
132 state<=0;
133 cnt<=0;
134 end
135 elseif(1400
136 begin
137 temp<=1;
138 flag<=1;
139 state<=0;
140 cnt<=0;
141 end
142 else
143 begin
144 state<=0;
145 cnt<=0;
146 end
147 default:state<=0;
148 endcase
149
150always@(*) //接收完一幀數(shù)據(jù)后,當(dāng)標(biāo)志位來的時候通過對數(shù)據(jù)的糾錯來捕獲數(shù)據(jù)
151 //我們接收的數(shù)據(jù)用的是左移,而發(fā)送的時候先發(fā)的是低位
152 if(!rst_n)
153 show_data<=0;
154 elseif((data[7:0]==~data[15:8])&&(data[31:24]==~data[23:16])&&flag_x)
155 begin
156 show_data[0]<=?data[15];
157 show_data[1]<=?data[14];
158 show_data[2]<=?data[13];
159 show_data[3]<=?data[12];
160 show_data[4]<=?data[11];
161 show_data[5]<=?data[10];
162 show_data[6]<=?data[9];
163 show_data[7]<=?data[8];
164
165 end
166 else
167 show_data<=?show_data;
168
169endmodule
數(shù)碼管模塊:
0moduleseg(clk,rst_n,seg7,data_in);
1
2inputclk;
3inputrst_n;
4input[3:0]data_in;
5
6outputreg[7:0]seg7;
7
8
9 `defineT1ms 50_000//分頻出1k的時鐘
10 //`define T1ms 5
11reg[15:0]count;
12regflag;
13always@(posedgeclkornegedgerst_n)
14 if(!rst_n)
15 begin
16 count<=15'b0;
17 flag<=1;
18 end
19 else
20 if(count==`T1ms/2-1)
21 begin
22 count<=15'b0;
23 flag<=~flag;
24 end
25 else
26 begin
27 count<=?count+1'b1;
28 end
29
30always@(posedgeflag)
31 if(!rst_n)
32 seg7<=8'b1010_0100;
33 else
34 begin
35 case(data_in)
36 0:seg7<=8'b1100_0000;
37 1:seg7<=8'b1111_1001;
38 2:seg7<=8'b1010_0100;
39 3:seg7<=8'b1011_0000;
40 4:seg7<=8'b1001_1001;
41 5:seg7<=8'b1001_0010;
42 6:seg7<=8'b1000_0010;
43 7:seg7<=8'b1111_1000;
44 8:seg7<=8'b1000_0000;
45 9:seg7<=8'b1001_0000;
46 10:seg7<=8'b1000_1000;
47 11:seg7<=8'b1000_0011;
48 12:seg7<=8'b1100_0110;
49 13:seg7<=8'b1010_0001;
50 14:seg7<=8'b1000_0110;
51 15:seg7<=8'b1000_1110;
52 default:;
53 endcase
54 end
55endmodule
分頻模塊:
0moduleclk_frep(clk,rst_n,clk_38khz);
1
2inputclk,rst_n;
3outputregclk_38khz;
4
5reg[9:0]count;
6
7 //分頻出紅外模塊所用的38Khz的時鐘
8 //也可以用占空比為1:3的38khz的時鐘
9
10always@(posedgeclkornegedgerst_n)
11 if(!rst_n)
12 begin
13 count<=0;
14 clk_38khz<=1;
15 end
16 elseif(count==(50_000_000/38000/2-1))
17 begin
18 clk_38khz<=~clk_38khz;
19 count<=0;
20 end
21 else
22 count<=?count+1'd1;
23
24endmodule8
測試模塊:
0 `timescale1ns/1ps
1
2moduleinfrared_tb();
3
4regclk,rst_n;
5regkey;
6wiretx;
7wire[7:0]show_data;
8
9 //因為我們代碼中只發(fā)送一次數(shù)據(jù),所以可以把key一直拉低
10
11initialbegin
12 clk=1;
13 rst_n=0;
14 key=1;
15
16 #100.1rst_n=1;
17
18 #200key=0;
19
20end
21
22always#10clk=~clk;
23
24 infrared dut(
25 .clk(clk),
26 .rst_n(rst_n),
27 .key(key),
28 .tx(tx),
29 .rx(rx),
30 .seg1(seg1),
31 .seg2(seg2)
32);
33
34endmodule
仿真圖:
仿真中我們可以把數(shù)碼管模塊的計數(shù)器的值改小一點(diǎn),便于仿真
如圖中所示的我們發(fā)的是32’h00ffa25d,那么數(shù)據(jù)為是8’b1010_0010,那么先發(fā)送時就時就按下面的序列開始0100_0101接收到的為45,所以工程正確。
-
紅外線
+關(guān)注
關(guān)注
14文章
611瀏覽量
55885 -
編碼
+關(guān)注
關(guān)注
6文章
915瀏覽量
54651
原文標(biāo)題:FPGA學(xué)習(xí)系列:34. 紅外線遙控系統(tǒng)的設(shè)計
文章出處:【微信號:FPGAer_Club,微信公眾號:FPGAer俱樂部】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論