首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

[求助]一个简单的16位计数器设计,出现奇怪问题,涉及到单片机和fpga读写时序

[求助]一个简单的16位计数器设计,出现奇怪问题,涉及到单片机和fpga读写时序

硬件平台:44b0+fpga.


44b0和fpga之间通过总线连接,把fpga映射至BANK4,现在在fpga中编写了一个简单的16位计数器,对外部8路输入脉冲计数。把八个计数器映射到了一个寄存器,并给它们分配地址。


现在出现奇怪的问题如下:


1、我现在测第三通道PUL3输入脉冲频率,第一次执行读操作,读出来的值是正确的,可是我第二次、第三次执行读操作(在44b0程序里,一次读操作的语句为:pulse = PULSE3;其中PULSE3是对计数器对应地址空间取值),即使改变了实际输入信号的频率,读出来的值也不改变,还是第一次的值。这时按下复位键后,第一次读数正确,后面又不改变数值,一直是第一次的读数。


2、更奇怪现象是:
比如我用JTAG下载VHDL程序或者按下复位键后,我先测第三通道的输入脉冲,这时会出现1所述现象。此时,如果我还不按复位键,而把信号发生器的输出脉冲接到第五通道上,然后再读第五通道的数值,这时发现读出来的数值是0。不论我怎么改变实际输入频率,读第五通道的数值总是0。这时如果复位,再读第五通道数值,第一次是正确的,后面又不正确。如果此时我把信号发生器输出接到第三通道,发现读第三通道数值又变为0了。


3、我开始怀疑原因是:读了一个通道数值后,数据总线上的值一直不变导致1所述现象。于是执行完脉冲测试子函数后,我去执行其它子函数,比如灯测试程序或者pwm输出程序,这时总得改变数据总线上的数据了吧?然后又返回去执行脉冲计数测试函数,发现这时的值还是没有变化。这是不是说明应该不是44b0程序的问题?


我觉得可能还是44b0和fpga读写的接口有问题。数据总线是不是得加三态门控制啊?从上面的现象来看,脉冲计数模块对外输出只是第一次有效,后面的对外输出一直是不变化的,除非来了复位信号


相应VHDL程序如下:


文件counter_control.vhd:


--使用测频法进行计数,该模块用于产生标准闸门信号,同时处理与单片机的接口时序
--闸门宽度可以是1s,也可是0.1s,0.01s,0.001s
--这里每隔1s输出一个脉冲(宽度为0.1us),由脉冲的上升沿触发开始计数


LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;


ENTITY counter_control IS
 ORT
 (   reset     :in std_logic;---active is low
  d    :in  std_logic_vector(15 downto 0);--闸门时间到时,锁存计数值
  clk     :in  std_logic;--外部输入时钟
  gate      ut std_logic;--标准闸门信号时钟,可以是1HZ,10HZ,100HZ,1000HZ等
  counter_cs:in  std_logic;--各个计数器的片选信号,实际上由各个计数器寄存器的地址译码所得
  data_out  ut std_logic_vector(15 downto 0)--计数器输出缓冲器
 ); 
END counter_control;


--*****************************************************
ARCHITECTURE rtl OF counter_control IS
signal  cnt  : INTEGER RANGE 0 TO 10000000;--std_logic_vector(24 downto 0);用于分频得到标准闸门信号
signal  temp1 : std_logic_vector(15 downto 0);
signal  temp2 : std_logic;
--*******************************************************
BEGIN
process(clk)
begin
if(reset = '0') then--复位计数器
   cnt <= 10000000;
   temp1 <= (OTHERS =>'0');  
elsif(clk'event and clk='1') then
 if(cnt = 0)then--满1秒
  cnt <= 10000000;
  temp1 <= d;
  temp2 <= '1';
 else  
     cnt <= cnt - 1;
  temp2 <= '0';
 end if;
end if;
end process;


data_out <= temp1 when counter_cs='0' else (OTHERS => 'Z');--counter_cs由fpga片选和计数器地址、读允许信号译码得到 
gate <= temp2;


END rtl; 



文件counter.vhd:



--16位加法计数器
--高电平脉冲清零计数器
--低电平开始计数


LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;


ENTITY counter IS
 ORT
 (
  pulse   :in std_logic;--被测信号
  clr  :in std_logic;--计数器清零信号
  counter_output ut std_logic_vector(15 downto 0)--计数值输出
 ); 
END counter;


--*****************************************************
ARCHITECTURE rtl OF counter IS
signal  temp0  : std_logic_vector(15 downto 0);
--*******************************************************
BEGIN
process(pulse,clr)
begin
if(clr = '1') then--在clr=‘1’的时候进行计数器清零
     temp0 <= (OTHERS =>'0');
elsif(pulse'event and pulse = '1') then
     temp0 <= temp0+1;
end if;
end process;


counter_output <= temp0;
END rtl;


还有一个顶层文件,用于把上面两个模块连接起来。发在另一个贴子里,这里发不下。


请各位朋友帮忙看看,这是毕业设计最重要的一部分,现在卡在这上面不能往下继续!


谢谢

文件:pulse.vhd
--脉冲检测顶层电路

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY pulse IS
PORT(
reset :in std_logic;---active is low
clk :in std_logic;--外部输入时钟
counter_cs :in std_logic;--各个计数器的片选信号,实际上由各个计数器寄存器的地址译码所得
pulse_in:in std_logic;--被测输入脉冲
data_outut std_logic_vector(15 downto 0)--计数器输出缓冲器
);
END pulse;

ARCHITECTURE rtl OF pulse IS
COMPONENT counter_control
PORT(
reset :in std_logic;---active is low
d :in std_logic_vector(15 downto 0);--闸门时间到时,锁存计数值
clk :in std_logic;--外部输入时钟
gate ut std_logic;--标准闸门信号时钟,可以是1HZ,10HZ,100HZ,1000HZ等
counter_cs:in std_logic;--各个计数器的片选信号,实际上由各个计数器寄存器的地址译码所得
data_out ut std_logic_vector(15 downto 0)--计数器输出缓冲器
);
END COMPONENT;

COMPONENT counter
PORT(
pulse :in std_logic;--被测信号
clr :in std_logic;--计数器清零信号
counter_output ut std_logic_vector(15 downto 0)--计数值输出
);
END COMPONENT;

SIGNAL d :std_logic_vector(15 downto 0);
SIGNAL gate:std_logic;

BEGIN
counter_control1:counter_control
PORT MAP( reset => reset,
d => d,
clk => clk,
gate => gate,
counter_cs => counter_cs,
data_out => data_out);
counter1:counter
PORT MAP(pulse => pulse_in,
clr => gate,
counter_output => d);
END rtl;

各位大侠,请帮帮忙吧,我卡在上面了,几天没有进展了

my mail: chenye_cau@163.com

如果不麻烦的话,也可给我发邮件指点

谢谢
返回列表