CPLD 与AVR通信 PWM控制程序
扫描二维码
随时随地手机看文章
1 library ieee;
2
3 use ieee.std_logic_1164.all;
4
5 use ieee.std_logic_arith.all;
6
7 use ieee.std_logic_unsigned.all;
8
9
10
11 entity KBCtest is
12
13 port(
14
15 rst,clk:instd_logic;--时钟和复位信号
16
17 --AVR 读写相关信号线
18
19 ale,rd,wr:instd_logic;--地址锁存、读、写信号
20
21 ad:inoutstd_logic_vector(7 downto 0);--地址数据信号线
22
23
24
25 --指示灯
26
27 led1,led2:outstd_logic;
28
29
30
31 --PWM
32
33 pwm1,pwm2:outstd_logic
34
35
36
37 --放大增益控制
38
39
40
41 --AD8364读写操作信号线
42
43 );
44
45 end KBCtest;
46
47
48
49 architecture art of KBCtest is
50
51 ------------------------------------------------全局信号定义-------------------------------------------------------------------
52
53 --AVR访问操作相关信号
54
55 signal adr: std_logic_vector(7 downto 0); --地址寄存器
56
57 signal data_buf: std_logic_vector(7 downto 0);
58
59 signal data_outctl:std_logic;
60
61
62
63
64
65 --pwm部分相关寄存器定义 寄存器暂时定义为8位
66
67 signal pwmfreq_reg:std_logic_vector(7 downto 0);
68
69 signal pwmocr1_reg:std_logic_vector(7 downto 0);
70
71 signal pwmocr2_reg:std_logic_vector(7 downto 0);
72
73
74
75 signal pwm_cnt:std_logic_vector(7 downto 0);
76
77
78
79 --时钟分频相关变量
80
81 signal clkcnt:std_logic_vector(16 downto 0);
82
83 signal adc_clk:std_logic;--ADC时钟信号
84
85 signal pwm_clk:std_logic;--pwm时钟信号
86
87
88
89 --led指示相关变量
90
91 signal led_clk:std_logic;--led时钟信
92
93 signal led1_cnt:std_logic_vector(7 downto 0);
94
95 signal led2_cnt:std_logic_vector(7 downto 0);
96
97 signal led1s:std_logic;
98
99 signal led2s:std_logic;
100
101
102
103 begin
104
105
106
107 ------------------------------------------------时钟分频-------------------------------------------------------------------
108
109 process(rst,clk) is
110
111 begin
112
113 if rst='0' then
114
115 clkcnt <= "00000000000000000";
116
117 elsif(clk'event and clk = '1') then
118
119 if(clkcnt = "11111111111111111") then
120
121 clkcnt<= "00000000000000000";
122
123 else
124
125 clkcnt <= clkcnt+1;
126
127 end if;
128
129 end if;
130
131 end process;
132
133 pwm_clk <= clkcnt(7);--分频PWM时钟
134
135 led_clk <= clkcnt(16);--分频LED时钟
136
137
138
139 ------------------------------------------------AVR访问操作----------------------------------------------------------------
140
141 data_outctl <= (not ale) and (not rd) and (wr);
142
143 ad <= data_buf when (data_outctl='1') else "ZZZZZZZZ";
144
145
146
147 --锁存AVR地址数据
148
149 process(rst,ale) is
150
151 begin
152
153 if rst='0' then
154
155 adr <= "00000000";
156
157 elsif(ale'event and ale='0') then--在ale信号的下降沿锁存地址数据
158
159 adr <= ad;
160
161 end if;
162
163 end process;
164
165
166
167 -------------------------------------AVR写数据-----------------------------------
168
169 process(rst,wr,ale) is
170
171 begin
172
173 if rst='0' then--对各寄存器给定初值
174
175 pwmfreq_reg<="11111111";
176
177 pwmocr1_reg<="10000000";
178
179 elsif (wr='1' and wr'event) then--在wr信号上升沿进行写操作
180
181 if ale = '0' then
182
183 case adr is
184
185 when "00000001" =>pwmfreq_reg<=ad;
186
187 when "00000010" =>pwmocr1_reg<=ad;
188
189
190
191 when others =>
192
193 pwmfreq_reg <= pwmfreq_reg;
194
195
196
197 end case;
198
199 end if;
200
201 end if;
202
203 end process;
204
205
206
207 ------------------------------------AVR读数据-------------------------------------
208
209 process(rst,rd,ale) is
210
211 begin
212
213 if rst='0' then
214
215 data_buf<="00000000";
216
217 elsif (rd='0'and rd'event) then
218
219 case adr is
220
221 when "00000001" => data_buf <=pwmfreq_reg;
222
223 when "00000010" => data_buf <=pwmocr1_reg;
224
225 when "00000011" => data_buf <="00110011";
226
227 when others =>
228
229 data_buf <= "ZZZZZZZZ";
230
231 end case;
232
233 end if;
234
235 end process;
236
237 ------------------------------------LED指示-------------------------------------
238
239 process(led_clk)is
240
241 begin
242
243 if(led_clk'event and led_clk='1') then
244
245 led1_cnt <= led1_cnt+1;
246
247 if (led1_cnt >=pwmfreq_reg) then
248
249 led1s <= NOT led1s;
250
251 led1_cnt <="00000000";
252
253 end if;
254
255 end if;
256
257 end process;
258
259 led1<=led1s;
260
261 process(led_clk)is
262
263 begin
264
265 if(led_clk'event and led_clk='1') then
266
267 led2_cnt <= led2_cnt+1;
268
269 if (led2_cnt >=pwmocr1_reg) then
270
271 led2s <= NOT led2s;
272
273 led2_cnt <="00000000";
274
275 end if;
276
277 end if;
278
279 end process;
280
281 led2<=led2s;
282
283
284
285 --------------------------------------PWM---------------------------------------
286
287 process(pwm_clk) is
288
289 begin
290
291 if rst='0' then
292
293 pwm_cnt<="00000000";
294
295 elsif(pwm_clk'event and pwm_clk='1') then
296
297 if(pwm_cnt > pwmfreq_reg) then
298
299 pwm_cnt <= "00000000";
300
301 else
302
303 pwm_cnt<=pwm_cnt+1;
304
305 end if;
306
307
308
309 --数据比较模块
310
311 if(pwm_cnt>=pwmocr1_reg) then
312
313 pwm1<= '1';
314
315 else
316
317 pwm1<= '0';
318
319 end if;
320
321 end if;
322
323 end process;
324
325 end;
326
327