本博客为本人学生时代的技术博客,工作后10年已经不再更新,需要关注可以访问geekpm.com,点击访问!

CPLD被STM32读写VHDL程序

  1  
  2 
  3 --本程序用来测试STM32对CPLD的读写操作
  4 
  5 --测试功能如下:
  6 
  7 --向0x05地址写入0x01,LED灯停止闪烁,写入其他数据闪烁继续
  8 
  9 --0x03,0x04寄存器为定值,可以通过STM32读取然后使用串口输出看看是否一致
 10 
 11  
 12 
 13 --文件名:AD.vhd
 14 
 15 library ieee;
 16 
 17 use ieee.std_logic_1164.all;
 18 
 19 use ieee.std_logic_unsigned.all;
 20 
 21  
 22 
 23 entity AD is
 24 
 25 port(
 26 
 27 -- 系统信号线
 28 
 29     CLK:         in      std_logic;
 30 
 31 LED: out std_logic;
 32 
 33 -- ARM相连的信号线
 34 
 35     Adr_L:       in      std_logic_vector(7 downto 0); --A7...A0,只使用了低八位地址线
 36 
 37     D:           inout   std_logic_vector(7 downto 0); --只使用了低八位数据线
 38 
 39     FSMC_NE4:    in      std_logic;  
 40 
 41     FSMC_NOE:    in      std_logic;
 42 
 43     FSMC_NWE:    in      std_logic
 44 
 45 );
 46 
 47 end AD;
 48 
 49  
 50 
 51 architecture art of AD is
 52 
 53 --设置存储数据的寄存器
 54 
 55 signal AD0_H_data,AD0_L_data,AD1_H_data,AD1_L_data,LED_ctrl:  std_logic_vector(7 downto 0); 
 56 
 57 --数据缓冲寄存器
 58 
 59 signal data_buf: std_logic_vector(7 downto 0);
 60 
 61 --数据输出控制
 62 
 63 signal data_outctl: std_logic;
 64 
 65 signal datacnt:integer range 0 to 4000000;--分频计数
 66 
 67 --LED闪烁使能
 68 
 69 signal LED_flag: std_logic;
 70 
 71  
 72 
 73  
 74 
 75 --统一编址,地址线数据线为八位,每个地址数据宽度8位
 76 
 77 --"00000001" AD0_H_data0x01
 78 
 79 --"00000010" AD0_L_data0x02
 80 
 81 --"00000011" AD1_H_data0x03
 82 
 83 --"00000100" AD1_L_data0x04
 84 
 85 --"00000101" LED_ctrl0x05
 86 
 87  
 88 
 89 begin
 90 
 91  
 92 
 93 AD1_H_data <="10100001";
 94 
 95 AD1_L_data <="00010001";
 96 
 97 --LED 闪烁,用作CPLD运行指示
 98 
 99  
100 
101 process(LED_ctrl) is
102 
103 begin
104 
105 if(LED_ctrl="00000001") then
106 
107 LED_flag <= '0';
108 
109 else
110 
111 LED_flag <= '1';
112 
113 end if;
114 
115 end process;
116 
117  
118 
119 process(CLK)is
120 
121 begin
122 
123  
124 
125  
126 
127 if(CLK'event and CLK='1') then
128 
129 if(LED_flag='1') then
130 
131 datacnt<=datacnt+1;
132 
133 if (datacnt>2000000) then
134 
135 LED <= '1';
136 
137 end if;
138 
139 if (datacnt>=4000000) then
140 
141 LED <='0';
142 
143 datacnt <=0;
144 
145 end if;
146 
147 end if;
148 
149 end if;
150 
151 end process;
152 
153  
154 
155 --当读取CPLD数据时用来判断何时向总线上输出数据
156 
157 data_outctl <= (not  FSMC_NE4) and (not FSMC_NOE) and (FSMC_NWE);  
158 
159 D <=  data_buf when (data_outctl='1') else "ZZZZZZZZ";--向数据线输出数据,否则保持为高阻态
160 
161  
162 
163 -- 写操作,模式1,时序图在数据手册P331
164 
165 process(FSMC_NE4,FSMC_NWE,Adr_L,FSMC_NOE) is  --,FSMC_NBL,D,RESET
166 
167 begin
168 
169 if(FSMC_NWE'event and FSMC_NWE='1') then
170 
171 if((FSMC_NOE and (not FSMC_NE4))='1') then
172 
173 case (Adr_L) is
174 
175 when "00000001" =>  
176 
177 AD0_H_data<= D; --0x01
178 
179 when "00000010" =>  
180 
181 AD0_L_data<= D; --0x02
182 
183 when "00000101" =>  
184 
185 LED_ctrl<= D;--0x05
186 
187 when others =>
188 
189 AD0_H_data<= AD0_H_data;
190 
191 AD0_L_data<= AD0_L_data;
192 
193 end case;
194 
195 end if;
196 
197 end if;
198 
199 end process;
200 
201  
202 
203 --读操作,模式1,P331
204 
205 process(FSMC_NE4,FSMC_NWE,Adr_L,FSMC_NOE) is 
206 
207 begin
208 
209 if(FSMC_NOE='0' and FSMC_NOE'event) then --直接在NOE的下降沿更新数据
210 
211 case (Adr_L) is
212 
213 when "00000001" =>   
214 
215 data_buf <= AD0_H_data; --0x01
216 
217 when "00000010" =>  
218 
219 data_buf <= AD0_L_data; --0x02
220 
221 when "00000011" =>  
222 
223 data_buf <= AD1_H_data; --0x03
224 
225 when "00000100" => 
226 
227 data_buf <= AD1_L_data; --0x04
228 
229 when others =>  data_buf <= "ZZZZZZZZ";
230 
231 end case; 
232 
233 end if;
234 
235 end process;
236 
237 end;
238 
239  
240 
241  
242 
243  
posted @ 2011-01-23 19:00  emouse  阅读(1951)  评论(0编辑  收藏  举报