数据通过spi自stm32发送到cpld,cpld处理后发回出现问题,详细如下

2019-03-25 07:29发布

我首先使用stm32通过spi发送数据到cpld,cpld处理数据后发回。问题的关键是,cpld中的程序的工作机制是这样的:我接受一切数据,甚至不区分什么帧头帧尾,什么位长。我cpld做的工作就是将收到的数据编码(收到的所有数据甚至空闲电平)都编码,经过低速光纤传输后在另一端把数据解码出来,包括什么空闲电平,帧头帧尾(当然,spi没用到帧头帧尾)。然后在通过spi传回给stm32。


可以看出,这种工作机制是很符合异步串行通信,但是spi是同步串行通信。所以stm32的spi预分频数只要超过了64,就无法接受到正确数据。通过示波器,我发现问题出在(看图)
搜狗截图20160922181734.png

从图上可以看出,在SCK(绿 {MOD}波形,黄 {MOD}波形是stm32的mosi发送数据)上升沿时,由于返回的数据和SCK不同步,导致SCK上升沿时不能每次都扫描到正确的电平。我认为解决的方法是:1、由于CPLD的时钟是50Mhz,而spi速度最高才是36/2=18M,只要将MISO(紫 {MOD}波形)左移半个SCK,就可以保证SCK每次都扫描到正确的电平。
2、或者将收到的mosi的黄 {MOD}波形数据收到后先不编码,左移半个SCK,然后再发送到编码。如图
搜狗截图20160922181803.png

但是,CPLD里的编码解码程序是别人写的,我不会改,我想单纯的在cpld的MoSi端,定义一个寄存器,然后在SCK的下降沿发送数据(stm32设置的是上升沿SCK检测电平)这样就能实现左移半个SCK。可是,写程序遇到了麻烦。
一个process中不能同时检测两个时钟沿。
可是我就是要在50Mhz的时钟下,检测spi的SCK的上升沿和下降沿啊。上升沿把数据存入寄存器。下降沿将数据发送到后面的编码器(别人的数据,我不会改,只能是保证它的不变,然后在前面加一个小模块,将小模块的输出当成它原来的输入给它)。


我写vhdl的思路是,第一个8bit数据,将数据存入a寄存器,第二个8bit数据传输周期,将数据存入b寄存器,同时在下降沿把a寄存器中数据发送到后面模块的输入,第三个8bit数据传输周期,将数据存入a寄存器,将b寄存器中数据发送到后面模块。这样不就同步了吗。

贴出来我写的那一些vhdl,帮忙告诉我怎么写,或者有解决上面问题的新思路。(我认为我上面的思路应该有逻辑错误,但我想了好久想不出来)谢谢了

signal TX:std_logic;
signal a:std_logic:='0';
signal b:std_logic:='0';
signal rx_shift_reg:std_logic_vector(7 downto 0):=(others=>'0');
signal rx_shift_reg_2:std_logic_vector(7 downto 0):=(others=>'0');
signal shift_cnt:std_logic_vector(3 downto 0):=(others=>'0');
signal shift_cnt_2:std_logic_vector(3 downto 0):=(others=>'0');
signal cnt:std_logic_vector(3 downto 0):=(others=>'0');
signal cnt_2:std_logic_vector(3 downto 0):=(others=>'0');


if rising_edge(spi_sck) then
        if(a='1')then
                rx_shift_reg<=rx_shift_reg(6 downto 0)& spi_din;
                shift_cnt<=shift_cnt+1;
                if(shift_cnt=x"07")then
                        b<='1';
                        a<=not a;
                end if;
        else
                rx_shift_reg_2<=rx_shift_reg_2(6 downto 0)& spi_din;
                shift_cnt_2<=shift_cnt_2+1;
                if(shift_cnt_2=x"07")then
                        b<='0';
                        a<=not a;
                end if;
        end if;
end if;
if(b='1')then
        if falling_edge(spi_sck) then
       
                cnt<=cnt+1;
                if(cnt=x"00")then
                        TX<=rx_shift_reg(7);
                else       
                        rx_shift_reg<=rx_shift_reg(6 downto 0)&'0';
                        TX<=rx_shift_reg(6);
                        if(cnt=x"07")then
                                cnt<=x"00";
                        end if;
                end if;
        end if;
else
        if falling_edge(spi_sck) then
                cnt_2<=cnt_2+1;
                if(cnt_2=x"00")then
                        TX<=rx_shift_reg_2(7);
                else       
                        rx_shift_reg_2<=rx_shift_reg_2(6 downto 0)&'0';
                        TX<=rx_shift_reg_2(6);
                        if(cnt_2=x"07")then
                                cnt_2<=x"00";
                        end if;
                end if;
        end if;
end if;



谢谢,头已炸
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
lcqzwnljx
2019-03-26 14:23
刚做完stm32通过SPI发送FPGA接收,预分频数从256到2都没问题。FPGA发送stm32接收暂时不用,还没测试,您说的“50M时钟实现18M的SPI通信是几乎不可能的”,我这用的25M时钟都没问题。

一周热门 更多>