搜索
bottom↓
回复: 27

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

[复制链接]

出0入0汤圆

发表于 2011-5-12 09:51:53 | 显示全部楼层 |阅读模式
如题,本人最近的项目,在这里卡住了。希望有大侠指点,或者给点资料~~~谢跪谢大家~~~

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-5-12 09:58:38 | 显示全部楼层
SJA1000控制起来还挺麻烦的,要用个大状态机,或者用Nios II

出0入0汤圆

 楼主| 发表于 2011-5-12 10:00:32 | 显示全部楼层
回复【1楼】fzfh1219
-----------------------------------------------------------------------

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

出0入0汤圆

 楼主| 发表于 2011-5-12 16:45:47 | 显示全部楼层
没有大侠做过吗?我看了SJA1000的数据手册,里面有个交流时序图?很奇怪时序图怎么还有交流的?是不是按这个时序控制SJA1000就行?

出0入0汤圆

 楼主| 发表于 2011-5-13 11:50:28 | 显示全部楼层
板子加工中,这部分逻辑还没有搞定。。用那个时序图也太简单了吧。。不会用到2楼大侠说的那么大的状态机啊~还是我还没有搞清楚?

出0入0汤圆

 楼主| 发表于 2011-5-13 11:53:20 | 显示全部楼层
回复【1楼】fzfh1219
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-5-17 19:33:51 | 显示全部楼层
SJA1000?我只用ARM7做过,挺麻烦的东西

出0入0汤圆

发表于 2011-5-20 02:21:08 | 显示全部楼层
不是很难,网上能找到例程,正搞中转板呢,ep1c6+7路sja1000,通信没问题。
先确认硬件ok再说。

出0入0汤圆

 楼主| 发表于 2011-5-23 22:55:45 | 显示全部楼层
回复【7楼】chenzhengxi
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-5-24 20:09:33 | 显示全部楼层
不好意思,还真没有,我记错了,控制sja1000的是自己写的。挺简单的,配置一下就能用,跟用单片机配置是一样的。
关键是硬件连接。你的怎么接的?

sja1000-245-FPGA (原文件名:1.JPG)

出0入0汤圆

 楼主| 发表于 2011-5-25 14:03:32 | 显示全部楼层
回复【9楼】chenzhengxi
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 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;

出0入0汤圆

发表于 2011-5-26 17:46:45 | 显示全部楼层
看看这个ourdev_643290H1GREK.rar(文件大小:60K) (原文件名:can.rar)

出0入0汤圆

 楼主| 发表于 2011-5-26 21:37:07 | 显示全部楼层
回复【11楼】chenzhengxi
-----------------------------------------------------------------------

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

出0入0汤圆

 楼主| 发表于 2011-5-26 21:40:32 | 显示全部楼层
回复【12楼】denike
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-6-1 10:04:32 | 显示全部楼层
呵呵 ,那你按照SJA1000的寄存器进行配置一下就OK啦,不难

出0入0汤圆

发表于 2011-6-1 10:23:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-1 12:10:15 | 显示全部楼层
单片机能潇洒干的事可以累死FPGA开发人员

出0入0汤圆

发表于 2011-6-1 22:25:07 | 显示全部楼层
回复【17楼】dspsharc  
单片机能潇洒干的事可以累死fpga开发人员
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-10-6 18:58:04 | 显示全部楼层
用硬件实现和SJA1000的接口,用一个NIOS软核+一点RAM实现控制。似乎比纯状态机做出的要节省资源吧。
我用EP2C8做过,不过只做了初样就取消项目了。

出0入0汤圆

发表于 2011-10-9 22:16:00 | 显示全部楼层
好愚蠢的做法,让fpga干该干的事!!!!!!

出0入0汤圆

发表于 2011-11-12 17:42:59 | 显示全部楼层
为什么要用SJA1000?能不能直接控制前端的CAN收发器?

出0入0汤圆

发表于 2012-1-18 11:12:07 | 显示全部楼层
不知道楼主这个问题后续如何  小弟最近在项目上也遇到这个问题了 。。求交流下 QQ317285318  不胜感激

出0入0汤圆

发表于 2012-12-8 17:12:57 | 显示全部楼层
我也是用FPGA做SJA1000的控制,发出的波形只有一个起始,后面就全都是高,不知道为什么

出0入0汤圆

发表于 2013-9-9 11:22:03 | 显示全部楼层
mark fpga can通信

出0入0汤圆

发表于 2013-9-18 13:06:44 | 显示全部楼层
ACTEL的SMARTFUSION2的FPGA有带CAN跟CORTEX-M3的硬核
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表