正在做数字示波器的题目,做起来才知道有很多问题哦,大家帮忙看看.
- UID
- 115233
- 性别
- 男
|
正在做数字示波器的题目,做起来才知道有很多问题哦,大家帮忙看看.
大概框图: ADC---> FPGA --> 双口RAM --> MCU ---> DAC ---> 显示
FPGA从AD采样速度是可调的.FPGA从AD采样受两个条件控制:1.外部一个周期触发信号给FPGA,只有当这个触发的上升沿来时才开始采样.2.每次采样1024个点.只有等1024个点采完后触发的上升沿才有效.从AD采样后的数据送双口RAM,再MCU从双口RAM读出数据,送DA转换并显示.
我写代码分三个模块.1.AD采样速度是可调的,所以要用一个可调的分频模块.2.控制AD采样.3.双口RAM控制.现在有几个问题请教各位:1.分频和AD控制的代码我帖在下面,各位帮忙看一下这样写有什么问题没? 2.这个双口RAM是用LPM做呢,还是用外部的比较容易控制点?
3.如果用LPM做的话控制RAM模块中就有一个元件例化的问题,不知道在process中能不能用元件例化呢?我把我写的代码帖在下面.刚学不久,可能很多东西都写得不对,有兴趣的帮忙改改. |
|
|
|
|
|
- UID
- 115233
- 性别
- 男
|
port:
port(clk:in std_logic; --系统时钟
clk1:inout std_logic; --采样时钟
oeut std_logic; --TLC5510输出使能
din:in std_logic_vector(7 downto 0); --来自TLC5510采样数据
doutut std_logic_vector(7 downto 0); --FPGA数据输出
pluse:in std_logic; --外部触发信号;
con_clk:in std_logic_vector(3 downto 0); --AD采样速度控制信号
rdclock:in std_logic; --读RAM时钟
rden:in std_logic; --读ram使能
raddress:in std_logic_vector(9 downto 0)); --读ram地址
信号:
signal clk0:std_logic;
signal wren:std_logic;
signal data:std_logic_vector(7 downto 0);
signal waddress:std_logic_vector(9 downto 0); |
|
|
|
|
|
- UID
- 115233
- 性别
- 男
|
分频进程:
process(clk,con_clk) --分频进程
variable q:integer range 0 to 250000;
begin
case con_clk is
when "0000"=> --200hz
if clk'event and clk='1' then
if q=250000 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=2500000 then clk0<='1';
else clk0<='0';
end if;
when "0001"=> --1000hz
if clk'event and clk='1' then
if q=50000 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=500000 then clk0<='1';
else clk0<='0';
end if;
when "0010"=> --4khz
if clk'event and clk='1' then
if q=12500 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=12500 then clk0<='1';
else clk0<='0';
end if;
when "0011"=> --20khz
if clk'event and clk='1' then
if q=2500 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=2500 then clk0<='1';
else clk0<='0';
end if;
when "0100"=> --100khz
if clk'event and clk='1' then
if q=500 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=500 then clk0<='1';
else clk0<='0';
end if;
when "0101"=> --400khz
if clk'event and clk='1' then
if q=125 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=125 then clk0<='1';
else clk0<='0';
end if;
when "0110"=> --2Mhz
if clk'event and clk='1' then
if q=25 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=25 then clk0<='1';
else clk0<='0';
end if;
when "0111"=> --10Mhz
if clk'event and clk='1' then
if q=5 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=5 then clk0<='1';
else clk0<='0';
end if;
when "1000"=> --20Mhz
if clk'event and clk='1' then
if q=3 then
q:=0;
else q:=q+1;
end if;
end if;
if q>=3 then clk0<='1';
else clk0<='0';
end if;
when others => clk0<='0';
end case;
clk1<=clk0;
end process; |
|
|
|
|
|
- UID
- 115233
- 性别
- 男
|
AD采样进程:
process(clk1) --AD采样进程,每次采样1024点
variable counter:integer range 0 to 1023; --直到pluse上身沿来再从新采样
begin
if clk1'event and clk1='1' and counter<=1023 then
counter:=counter+1;
oe<='0'; --输出使能赋低电平
data<=din; --采样数据输出
end if ;
if pluse'event and pluse='1' then
if counter>=1024 then
counter:=0;
oe<='1';
end if;
end if;
end process |
|
|
|
|
|
- UID
- 115233
- 性别
- 男
|
process(clk1,wren)--Êý¾ÝдÈËË«¿ÚramÖÐ,ÏÈдÔÙMCU¶Á
begin
wren<='1';
rden<='0';
if clk1'event and clk1='1' and wren='1' then
if waddress<="1111111110" then
waddress<=waddress+1;
data<=din;
end if;
end if;
if waddress="1111111110" then
wren<='0';
waddress<="0000000000";
end if;
end process;
ram port map(data=>data,wren=>wren,wraddress=>waddress,rdaddress=>raddress,rden=>rden,wrclock=>wrclock,rdclock=>rdclock,q=>dout);
process(raddress,rdclock)
rden<='1';
wren<='0';
begin
if rdclock'event and rdclock='1' then
dout<=data;
raddress<=raddress+1;
end if;
end process;
end behav;
AD采样速度和写入RAM 的速度是一样的,mcu的读速度是固定的. |
|
|
|
|
|
- UID
- 115233
- 性别
- 男
|
最后两个process是我随便写的.大家看上面的代码有什么问题,非常欢迎指出.
我感觉分频部分这样写问题很大,呵呵.
大家一起来讨论下啊,希望能在这里把双口ram的问题解决. |
|
|
|
|
|
- UID
- 115233
- 性别
- 男
|
有谁能给个控制dpram的例子给我参考一下吗?
写这个模块时有点困难. |
|
|
|
|
|
- UID
- 128442
- 性别
- 男
|
欢迎访问我的 BlogPage.
http://hi.baidu.com/mcu_spaces |
|
|
|
|
|