zoukankan      html  css  js  c++  java
  • CAN协议学习(二)MCAN控制器介绍

    更多细节请参看MCAN2文档mcan2_ps.pdf。

    一、MCAN2简介

    MCAN2Mentor公司开发的一个CAN2.0网络控制器的软核,初版2001年末版2006年。MCAN 2控制器实现了BOSCAN消息传输协议2.0a2.0b。规范2.0a(相当于can 1.2)涵盖标准消息格式(11位标识符);规范2.0b涵盖标准和扩展消息格式(11位和29位标识符)

    二、总体架构

    下图显示了MCAN2设计的主要功能块。

     

    CPUmcan 2的访问是通过独立的地址、输入数据和输出数据总线进行的。由主机设备将用于传输的消息放置到发送缓冲器中,以便由位处理器进行传输。设备接收到的消息首先由接收过滤器过滤,然后放入接收FIFO中。

    CPU通过称为接收缓冲区的13字节窗口访问接收FIFO.结合接收FIFO使用接收缓冲区允许CPU在接收其他消息时处理一条消息。接收FIFO的总长度为64个字节,并以循环方式使用,使其能够同时容纳最多5个扩展的帧格式消息。

    位定时逻辑块负责设备的波特率,并且是可编程的。所支持的波特率范围取决于主系统时钟XTAL1的频率,并且可以容易地跨越比BOSCH规范所选择的125kbud-1MBaud更宽的波特率范围。

    CAN总线的接口由发送信号tx0tx1和接收的rx 0提供。TX1通常与tx0相反,也可以编程为输出发送时钟,这对于测试非常有用。

    三、发送、接收过程

    要传输的数据以标准帧格式(SFF)或扩展帧格式(EFF)写入mcan 2的发送缓冲器(如下)。发送缓冲器包括CAN地址10h1ch之间的13个字节,一个帧最多可以发送8个字节的数据。注意:在将数据写入缓冲区之前,需要检查传输缓冲区状态(状态寄存器,位2),以确保缓冲区“释放”(SR.2=1)。当缓冲区被锁定时写入缓冲区的任何数据(SR.2=0)都会丢失而没有任何指示。

     

    发送缓冲器描述符字段的位布局如下所示.

     

    FF代表frame format0为标准帧,1为拓展帧。

    RTR代表REMOTE TRANSMISSION REQUEST1表示为远程帧。

    DLC代表DATA LENGTH CODE:范围0-8,大于8的数被自动解释为8

    ID代表IDENTIFIER:标识符充当消息的名称,用于接收过滤,并确定总线访问优先级。标识符的二进制值越低,优先级就越高。在标准帧格式(SFF)中,标识符由11(id.28id.18)组成。在扩展帧格式(Eff)消息中,标识符由29(id.28id.0)组成。id.28是最高位,首先在总线上传输。

    mcan 2接收的数据首先由接收滤波器过滤,然后传递给接收FIFO。接受过滤器只传递那些具有与接收过滤器寄存器中记录的消息相匹配的标识位的消息。

    接收FIFO64个字节深,允许最多5个完整扩展帧格式(EFF)消息的空间,并以循环方式使用。

    放置在接收FIFO中的数据通过一个称为接收缓冲区的13字节窗口读取。该窗口位于can地址10h-1ch,即它占用与发送缓冲器相同的地址空间。与传输缓冲区一样,它足够宽,可以容纳一条包含最多8个字节数据的消息。

    四、信号&寄存器描述

    信号描述:

     

    寄存器描述:

     

    五、接收过滤

    与过滤相关的寄存器:

    10h-13h ACR03 Acceptance Code Registers 0-3

    14h-17h AMR03 Acceptance Mask Registers 0-3

    MCAN2的接收过滤模块首先将接收到的数据帧的ID部分与ACR即接收码寄存器比较,如果一致则接收,如果不一致则丢弃;AMR是接收掩码寄存器,如果某位设为‘1’,则将ACR对应的位设为‘不关心’。根据MOD.3为0或1来设置单过滤或双过滤模式,具体如下图。

    六、时序图

     

    七、测试程序(流程图&代码)

      1 //test CAN 2019.03.22 by zhou
      2 
      3     assign  F_can_rx[0]=(F_can_tx[3]==1'b1)?F_can_tx[0]:((F_can_tx[0]==1'b1)?F_can_tx[3]:1'bZ);        //star
      4     assign  F_can_rx[3]=(F_can_tx[0]==1'b1)?F_can_tx[3]:((F_can_tx[3]==1'b1)?F_can_tx[0]:1'bZ);        //earth
      5 
      6     assign  F_can_rx[1]=(F_can_tx[2]==1'b1)?F_can_tx[1]:((F_can_tx[1]==1'b1)?F_can_tx[2]:1'bZ);        //star
      7     assign  F_can_rx[2]=(F_can_tx[1]==1'b1)?F_can_tx[2]:((F_can_tx[2]==1'b1)?F_can_tx[1]:1'bZ);        //earth
      8     
      9 
     10 
     11 task CPU_READ_NPT;        //just read data, no display
     12     input [17:2] addr;
     13     output [15:0] rddata;
     14 
     15        begin
     16         #120ns
     17     @(posedge S_cpu_clk) 
     18     F_nrd = 1'b1;
     19     F_nwr = 1'b1;
     20     F_ncs = 1'b1;
     21     F_addr =addr;
     22     @(posedge S_cpu_clk) 
     23     F_nrd = 1'b0;
     24     F_nwr = 1'b1;
     25     F_ncs = 1'b0;
     26     F_addr =addr;
     27     @(posedge S_cpu_clk) 
     28     wait (F_nrdy==0);
     29     rddata = F_data_o;
     30     //$display("the addr %h read result is %h",addr, rddata);
     31     @(posedge S_cpu_clk) 
     32     F_nrd = 1'b1;
     33     F_nwr = 1'b1;
     34     F_ncs = 1'b1;
     35     F_addr =0;
     36        end
     37 endtask
     38 
     39 
     40 task CAN_TEST_ALL;
     41     begin
     42     CAN_TEST(16'h0700,16'h1201,16'h0500,16'h1100,8'h03);
     43     //CAN_TEST(16'h0701,16'h1200,16'h0600,16'h1000,8'h12);
     44     end
     45 endtask
     46 
     47 
     48 task CAN_TEST;
     49     input [15:0] reset_reg_star;
     50     input [15:0] reset_reg_earth;
     51     input [15:0] base_reg_star;
     52     input [15:0] base_reg_earth;
     53     input [7:0] connect;
     54 
     55     int i_cnt;
     56     logic [15:0] can_rdata;
     57 
     58     begin
     59     $display("=============CAN %h TEST START=============",connect);
     60 
     61     CPU_WRITE(reset_reg_star,16'h0000);//CAN1A RST begin
     62     #170ns;
     63     CPU_WRITE(reset_reg_star,16'h0001);//CAN1A RST end
     64     CPU_WRITE(reset_reg_earth,16'h0000);//CAN2B RST begin
     65     #170ns;
     66     CPU_WRITE(reset_reg_earth,16'h0001);//CAN2B RST end
     67 
     68 
     69     //////////////////can init 1A&2B begin////////////////
     70     CPU_WRITE(base_reg_star,8'h09);    //CAN1A INIT [star]
     71     CPU_READ_NPT(base_reg_star,can_rdata);
     72     if(can_rdata != 8'h09)
     73     begin 
     74         $display("the addr base_reg_star read result is %h,wrong!(should be 8'h09)",can_rdata);
     75         $stop;
     76     end
     77     CPU_WRITE(base_reg_star+8'h1F,8'h08);
     78 
     79     CPU_WRITE(base_reg_star+8'h10,8'h00);
     80     CPU_WRITE(base_reg_star+8'h11,8'h00);
     81     CPU_WRITE(base_reg_star+8'h12,8'h00);
     82     CPU_WRITE(base_reg_star+8'h13,8'h00);
     83     CPU_WRITE(base_reg_star+8'h14,8'hFF);      // ////CARE ID:MUST 00                                                   
     84     CPU_WRITE(base_reg_star+8'h15,8'hFF);
     85     CPU_WRITE(base_reg_star+8'h16,8'hFF);
     86     CPU_WRITE(base_reg_star+8'h17,8'hFF);
     87 
     88     CPU_WRITE(base_reg_star+8'h04,8'h03);
     89     CPU_WRITE(base_reg_star+8'h06,8'h00);
     90     CPU_WRITE(base_reg_star+8'h07,8'h16);    
     91     CPU_WRITE(base_reg_star+8'h08,8'h00);
     92     CPU_WRITE(base_reg_star+8'h1E,8'h00);
     93     CPU_WRITE(base_reg_star+8'h00,8'h08);
     94 
     95     CPU_WRITE(base_reg_earth+8'h00,8'h09);    //CAN2B INIT [earth]
     96     CPU_READ_NPT(base_reg_earth+8'h00,can_rdata);
     97     if(can_rdata != 8'h09)
     98     begin 
     99         $display("the addr base_reg_earth+8'h00 read result is %h,wrong!(should be 8'h09)",can_rdata);
    100         $stop;
    101     end
    102     CPU_WRITE(base_reg_earth+8'h1F,8'h08);
    103 
    104     CPU_WRITE(base_reg_earth+8'h10,8'h12);         // //// ID:MUST 122X
    105     CPU_WRITE(base_reg_earth+8'h11,8'h24);        
    106     CPU_WRITE(base_reg_earth+8'h12,8'h00);
    107     CPU_WRITE(base_reg_earth+8'h13,8'h00);
    108     CPU_WRITE(base_reg_earth+8'h14,8'h00);                                                
    109     CPU_WRITE(base_reg_earth+8'h15,8'h00);
    110     CPU_WRITE(base_reg_earth+8'h16,8'hFF);
    111     CPU_WRITE(base_reg_earth+8'h17,8'hFF);
    112 
    113     CPU_WRITE(base_reg_earth+8'h04,8'h01);
    114     CPU_WRITE(base_reg_earth+8'h06,8'h00);
    115     CPU_WRITE(base_reg_earth+8'h07,8'h16);    
    116     CPU_WRITE(base_reg_earth+8'h08,8'h02);
    117     CPU_WRITE(base_reg_earth+8'h1E,8'h00);
    118     CPU_WRITE(base_reg_earth+8'h00,8'h08);
    119     //////////////////can init end///////////////////////////
    120 
    121 
    122     CPU_WRITE(base_reg_star+8'h01,8'h0C);    //CLR RX FIFO
    123 
    124     CPU_READ(base_reg_star+8'h02,can_rdata);    //SR[2]=?0
    125     while(can_rdata[2] == 0)
    126     begin
    127         #1us;
    128         CPU_READ_NPT(base_reg_star+8'h02,can_rdata);
    129     end
    130     
    131     
    132         CPU_WRITE(base_reg_star+8'h10,8'h08);    //Transmit Frame Information:standard,8 data
    133     CPU_WRITE(base_reg_star+8'h11,8'h56);    //identifier:ff0
    134     CPU_WRITE(base_reg_star+8'h12,8'h60);    
    135     for(i_cnt=3;i_cnt<11;i_cnt++)
    136     begin
    137         CPU_WRITE(base_reg_star+8'h10+i_cnt,i_cnt);//write data to transmit buffer,发送一帧标准帧数据
    138     end
    139     
    140 
    141     CPU_WRITE(base_reg_star+8'h01,8'h01);    //trans enable
    142     
    143     CPU_READ(base_reg_star+8'h03,can_rdata);
    144     CPU_READ(base_reg_star+8'h02,can_rdata);
    145     while(can_rdata[2] == 0)
    146     begin    
    147         #1us;
    148         CPU_READ_NPT(base_reg_star+8'h02,can_rdata);
    149         
    150     end
    151     CPU_READ(base_reg_star+8'h03,can_rdata);
    152     CPU_READ(base_reg_star+8'h02,can_rdata);
    153     
    154     #2ms;
    155     CPU_READ(base_reg_earth+8'h10,can_rdata);
    156     CPU_READ(base_reg_earth+8'h11,can_rdata);
    157     CPU_READ(base_reg_earth+8'h12,can_rdata);
    158     CPU_READ(base_reg_earth+8'h13,can_rdata);
    159     CPU_READ(base_reg_earth+8'h14,can_rdata);
    160     CPU_READ(base_reg_earth+8'h15,can_rdata);
    161     CPU_READ(base_reg_earth+8'h16,can_rdata);
    162     CPU_READ(base_reg_earth+8'h17,can_rdata);
    163     CPU_READ(base_reg_earth+8'h18,can_rdata);
    164     CPU_READ(base_reg_earth+8'h19,can_rdata);
    165     //CPU_READ(base_reg_star+8'h03,can_rdata);
    166     //CPU_READ(base_reg_star+8'h02,can_rdata);
    167     CPU_READ(base_reg_earth+8'h1a,can_rdata);
    168 
    169     
    170     ///////////////////////////////////second sending///////////////////////////////
    171     $display("####################################");
    172     CPU_WRITE(base_reg_star+8'h01,8'h0C);
    173     CPU_WRITE(base_reg_earth+8'h01,8'h0C);
    174 
    175     CPU_READ(base_reg_star+8'h02,can_rdata);    //SR[2]=?0
    176     while(can_rdata[2] == 0)
    177     begin
    178         #1us;
    179         CPU_READ_NPT(base_reg_star+8'h02,can_rdata);
    180     end
    181     CPU_READ(base_reg_star+8'h02,can_rdata);
    182 
    183     CPU_WRITE(base_reg_star+8'h10,8'h08);    //Transmit Frame Information:standard,8 data
    184     CPU_WRITE(base_reg_star+8'h11,8'h00);    //identifier:00
    185     CPU_WRITE(base_reg_star+8'h12,8'h00);    
    186     for(i_cnt=3;i_cnt<11;i_cnt++)
    187     begin
    188         CPU_WRITE(base_reg_star+8'h10+i_cnt,i_cnt);//write data to transmit buffer,发送一帧标准帧数据
    189     end        
    190 
    191 
    192     CPU_WRITE(base_reg_star+8'h01,8'h01);    //trans enable
    193     CPU_READ(base_reg_star+8'h02,can_rdata);    //SR[2]=?0
    194     #2ms
    195     CPU_READ(base_reg_earth+8'h10,can_rdata);
    196     CPU_READ(base_reg_earth+8'h11,can_rdata);
    197     CPU_READ(base_reg_earth+8'h12,can_rdata);
    198     CPU_READ(base_reg_earth+8'h13,can_rdata);
    199     CPU_READ(base_reg_earth+8'h14,can_rdata);
    200     CPU_READ(base_reg_earth+8'h15,can_rdata);
    201     CPU_READ(base_reg_earth+8'h16,can_rdata);
    202     CPU_READ(base_reg_earth+8'h17,can_rdata);
    203     CPU_READ(base_reg_earth+8'h18,can_rdata);
    204     CPU_READ(base_reg_earth+8'h19,can_rdata);
    205     //CPU_READ(base_reg_star+8'h03,can_rdata);
    206     //CPU_READ(base_reg_star+8'h02,can_rdata);
    207     CPU_READ(base_reg_earth+8'h1a,can_rdata);
    208     
    209     $display("CAN %h TEST Success!
    ",connect);
    210     end
    211 
    212 endtask
    MCAN2测试代码
  • 相关阅读:
    java 保留2位小数 转载
    android表格效果ListView隔行变色
    安卓学习之排版RelativeLayout表格布局
    安卓学习之如何关闭所有的activity
    安卓学习之android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)
    [转]Android 实现TextView中文字链接的方式
    OOP编程iBatis 学习笔记之二 单表增删改操作
    OOP编程iBatis 学习笔记之三 2个表或者多表关联查询
    安卓学习之排版TableLayout表格布局
    (原创)C#反射知识分享之二
  • 原文地址:https://www.cnblogs.com/zhouliyan/p/10612813.html
Copyright © 2011-2022 走看看