bayi1017 发表于 2011-5-12 09:51:53

各位大侠,有没有成功实现FPGA控制SJA1000实现CAN通信的Verilog例程,跪求指点!!!!!!

如题,本人最近的项目,在这里卡住了。希望有大侠指点,或者给点资料~~~谢跪谢大家~~~

fzfh1219 发表于 2011-5-12 09:58:38

SJA1000控制起来还挺麻烦的,要用个大状态机,或者用Nios II

bayi1017 发表于 2011-5-12 10:00:32

回复【1楼】fzfh1219
-----------------------------------------------------------------------

是啊~~所以比较头大啊~~
希望有做的这方面的大侠帮助~

bayi1017 发表于 2011-5-12 16:45:47

没有大侠做过吗?我看了SJA1000的数据手册,里面有个交流时序图?很奇怪时序图怎么还有交流的?是不是按这个时序控制SJA1000就行?

bayi1017 发表于 2011-5-13 11:50:28

板子加工中,这部分逻辑还没有搞定。。用那个时序图也太简单了吧。。不会用到2楼大侠说的那么大的状态机啊~还是我还没有搞清楚?

bayi1017 发表于 2011-5-13 11:53:20

回复【1楼】fzfh1219
-----------------------------------------------------------------------

请教大虾,SJA1000的数据手册,里面有个交流时序图,是不是按那个控制就可以?如果这样,不用您说的大状态机啊~应该是我还没有搞清楚吧?您说的控制的时序在哪里有呢?手册上我没见其他的时序图啊~

axel8888 发表于 2011-5-17 19:33:51

SJA1000?我只用ARM7做过,挺麻烦的东西

chenzhengxi 发表于 2011-5-20 02:21:08

不是很难,网上能找到例程,正搞中转板呢,ep1c6+7路sja1000,通信没问题。
先确认硬件ok再说。

bayi1017 发表于 2011-5-23 22:55:45

回复【7楼】chenzhengxi
-----------------------------------------------------------------------

大虾,我没找到有FPGA控制SJA1000的例程啊~全是用FPGA模拟SJA1000协议的~~~
能不能提供下您说的例程网址~十分感谢~~

chenzhengxi 发表于 2011-5-24 20:09:33

不好意思,还真没有,我记错了,控制sja1000的是自己写的。挺简单的,配置一下就能用,跟用单片机配置是一样的。
关键是硬件连接。你的怎么接的?
http://cache.amobbs.com/bbs_upload782111/files_39/ourdev_642565VN71FV.JPG
sja1000-245-FPGA (原文件名:1.JPG)

bayi1017 发表于 2011-5-25 14:03:32

回复【9楼】chenzhengxi
-----------------------------------------------------------------------

十分感谢您的回复,硬件上不是问题啊。
这个项目我们是测绘别人板子的,硬件连接又仔细对照了SJA1000的数据手册。
逻辑上首先要配置六个寄存器也清楚了,不过复位配置过后,由于SJA1000地址数据线复用,还需要写个比较复杂的状态机。
您的那个逻辑可以正常接受了吗?能否查考下您的逻辑,十分感谢~~

chenzhengxi 发表于 2011-5-25 22:35:26

ENTITY can_ctrl IS
port(
      clk   : in std_logic;
      reset : in std_logic;
      
          --15个io,还有一个中断io自己控制
      data                              :inout std_logic_vector(7 downto 0);
      ale                              :out std_logic:='0';
      nrd                              :out std_logic:='1';
      nwr                             :out std_logic:='1';
      ncs                             :out std_logic:='1';
      rst                            :out std_logic:='0';
      data_dir                         :out std_logic:='0';
          noe                           :out std_logic;
          --下面的是和你的控制逻辑交互的
      r_state_in                   :in std_logic;
      r_state_out                :out std_logic;
      w_state_in                   :in std_logic;
      w_state_out                :out std_logic;   
      rw_addr               :in std_logic_vector(7 downto 0);
      rw_data_in            :in std_logic_vector(7 downto 0);
      rw_data_out           :out std_logic_vector(7 downto 0);
      );
END ENTITY can_ctrl;

ARCHITECTURE active OF can_ctrl IS
signal data_out           :std_logic_vector(7 downto 0);
signal data_in                     :std_logic_vector(7 downto 0);
signal data_out_en        :std_logic;
signal data_temp            :std_logic_vector(7 downto 0);
signal av_r_state_out,av_w_state_out : std_logic;
signal av_addr          :std_logic_vector(7 downto 0);

type states is(idle,read,write);
signal current_state:states;
signal next_state : states;
signal count :std_logic_vector(3 downto 0);

BEGIN
        r_state_out <= av_r_state_out;
        w_state_out <= av_w_state_out;
        rst <= reset;
        data_in <= data;
        data <= data_out when data_out_en = '1' else (others => 'Z');
       
        process(clk,reset)
    begin
           if reset = '0' then
                       current_state <= idle;
           else
                       if rising_edge(clk) then
                         current_state <= next_state;
                       end if;
           end if;
    end process;
   
        process(r_state_in,w_state_in,count)
            begin
                      case current_state is
                              when idle =>
                                        if r_state_in = '1' then
                                next_state <= read;
                  elsif w_state_in = '1' then
                              next_state <= write;
                  else
                              next_state <= idle;
                  end if;
                              when read =>
                                        if count = "1111" then
                          next_state <= idle;
                  else
                      next_state <= read;
                  end if;
                              when write =>
                                        if count = "1111" then
                              next_state <= idle;
                  else
                              next_state <= write;
                  end if;
                              when others => next_state <= idle;
              end case;
        end process;
                  
        process(clk,reset)
        begin
            if rising_edge(clk) then
                      if reset = '0' then   
                      ale <= '0';
                      nrd <= '1';
                      nwr <= '1';
                               ncs <= '1';
                      data_dir <= '0';
                      noe <= '1';
                               data_out_en <= '0';
                      av_r_state_out <= '0';
                      av_w_state_out <= '0';
                      count <= "0000";
                       else
                      case current_state is
                              when idle =>
                                                ale <= '0';
                               nrd <= '1';
                               nwr <= '1';
                               ncs <= '1';
                               data_dir <= '0';
                               noe <= '1';
                               data_out_en <= '0';
                               count <= "0000";
                              when read =>
                                                noe <= '0';
                                  nwr <= '1';
                                  case count is
                                          when "0000" =>
                                                                data_out <= rw_addr;
                                                          data_out_en <= '1';
                                                                data_dir <= '1';
                                    nrd <= '1';
                                    ncs <= '0';
                                                                count <= count + "0001";
                                          when "0001" | "0010" | "0011" | "0100" =>
                                                                ale <= '1';
                                                                count <= count + "0001";
                                          when "0101" =>
                                                                ale <= '0';
                                                                count <= count + "0001";
                                    when "0110" =>
                                                                count <= count + "0001";
                                                                data_out_en <= '0';
                                                                data_dir <= '0';
                                                        when "0111"|"1000"|"1001"|"1010" =>
                                                                count <= count + "0001";
                                                                nrd <= '0';
                                          when "1011" =>
                                                                rw_data_out <= data_in;
                                                                count <= count + "0001";
                                          when "1100" =>
                                                                nrd <= '1';
                                                                count <= count + "0001";
                                                        when "1101"| "1110" =>
                                                                ncs <= '1';
                                                                count <= count + "0001";
                                                        when "1111"=>
                                                                av_r_state_out <= '1';
                                                        when others =>
                                                                null;
                                     end case;
                              when write =>                
                                                noe <= '0';
                                  nrd <= '1';
                                  case count is
                                          when "0000" =>
                                                                data_out <= rw_addr;
                                                                data_out_en <= '1';
                                    data_dir <= '1';
                                    nwr <= '1';
                                    ncs <= '0';
                                                                count <= count + "0001";
                                          when "0001" | "0010" | "0011" | "0100" =>
                                                                ale <= '1';
                                                                count <= count + "0001";
                                          when "0101" =>
                                                                ale <= '0';
                                                                count <= count + "0001";
                                          when "0110" =>
                                                                data_out_en <= '0';
                                    count <= count + "0001";
                                          when "0111"|"1000"|"1001"|"1010" =>
                                                                nwr <= '0';
                                                                data_out <= rw_data_in;
                                                                data_out_en <= '1';
                                                                count <= count + "0001";
                                          when "1011" =>
                                                                nwr <= '1';
                                                                count <= count + "0001";
                                          when "1100" =>
                                                                ncs <= '1';
                                                                count <= count + "0001";
                                          when "1101" =>
                                                                data_out_en <= '0';
                                                                count <= count + "0001";
                                                        when "1110" =>
                                                                count <= count + "0001";
                                          when "1111" =>
                                                                av_w_state_out <= '1';
                                          when others =>
                                                                null;
                                  end case;
                              when others =>
                                                null;
                      end case;
      
                      if av_r_state_out = '1' then                               
                                  av_r_state_out <= '0';
                      end if;
      
                      if av_w_state_out = '1' then
                                  av_w_state_out <= '0';
                      end if;
      
                      end if;--end reset
            end if;--end clk
        end process;
                        
END ARCHITECTURE active;

denike 发表于 2011-5-26 17:46:45

看看这个ourdev_643290H1GREK.rar(文件大小:60K) (原文件名:can.rar)

bayi1017 发表于 2011-5-26 21:37:07

回复【11楼】chenzhengxi
-----------------------------------------------------------------------

谢谢大侠~这个VHDL我不大会啊~不过可以参考下~
谢谢您的慷慨指点~~

bayi1017 发表于 2011-5-26 21:40:32

回复【12楼】denike
-----------------------------------------------------------------------

谢谢您的资料~这个程序用FPGAFPGA模拟了SJA1000协议的~~我想要的是对SJA1000的控制~
还是十分感谢您的热情帮助~

denike 发表于 2011-6-1 10:04:32

呵呵 ,那你按照SJA1000的寄存器进行配置一下就OK啦,不难

ye_song 发表于 2011-6-1 10:23:56

mark

dspsharc 发表于 2011-6-1 12:10:15

单片机能潇洒干的事可以累死FPGA开发人员

chenzhengxi 发表于 2011-6-1 22:25:07

回复【17楼】dspsharc
单片机能潇洒干的事可以累死fpga开发人员
-----------------------------------------------------------------------

同感,倒不是写不出来,就是烦,长长的面条代码。

windowsce 发表于 2011-10-6 18:58:04

用硬件实现和SJA1000的接口,用一个NIOS软核+一点RAM实现控制。似乎比纯状态机做出的要节省资源吧。
我用EP2C8做过,不过只做了初样就取消项目了。

xcreat 发表于 2011-10-9 22:16:00

好愚蠢的做法,让fpga干该干的事!!!!!!

xzf962 发表于 2011-11-12 17:42:59

为什么要用SJA1000?能不能直接控制前端的CAN收发器?

hzp080401234 发表于 2012-1-18 11:12:07

不知道楼主这个问题后续如何小弟最近在项目上也遇到这个问题了 。。求交流下 QQ317285318不胜感激

酥饼 发表于 2012-12-8 17:12:57

我也是用FPGA做SJA1000的控制,发出的波形只有一个起始,后面就全都是高,不知道为什么

nibia 发表于 2013-9-9 11:22:03

mark fpga can通信

SZSBS 发表于 2013-9-18 13:06:44

ACTEL的SMARTFUSION2的FPGA有带CAN跟CORTEX-M3的硬核
页: [1]
查看完整版本: 各位大侠,有没有成功实现FPGA控制SJA1000实现CAN通信的Verilog例程,跪求指点!!!!!!