tag 标签: can_ip

相关博文
  • 热度 11
    2016-4-8 16:46
    1569 次阅读|
    0 个评论
    前言:因为目前研究的是如何使用CAN_IP,而CAN_CONTROLLER第一步就是对各个寄存器进行初始化。因此在此先看tb中是如何进行初始化的。并且对各个重要的task进行解读。   /************************************************************************************* task send_bit;//rx线的测试task,单位输入   input bit;   integer cnt;   begin     #1 rx=bit;  //延迟一个时间单位  进行赋值     repeat ( (`CAN_TIMING1_TSEG1 + `CAN_TIMING1_TSEG2 + 3)*BRP) @ (posedge clk);//  等待( (`CAN_TIMING1_TSEG1 + `CAN_TIMING1_TSEG2 + 3)*BRP) 多个时钟上升沿   end endtask     /**************************************************************************************** task write_register;//对can1 的寄存器进行操作的task   input reg_addr;   input reg_data;     `ifdef CAN_WISHBONE_IF  //一种总线,在can中使用的是这个结构     begin       wait (wb_free);       wb_free = 0;       @ (posedge wb_clk_i);       #1;        cs_can = 1;       wb_adr_i = reg_addr;       wb_dat_i = reg_data;       wb_cyc_i = 1;       wb_stb_i = 1;       wb_we_i = 1;       wait (wb_ack_o);       @ (posedge wb_clk_i);       #1;        wb_adr_i = 'hz;       wb_dat_i = 'hz;       wb_cyc_i = 0;       wb_stb_i = 0;       wb_we_i = 'hz;       cs_can = 0;       wb_free = 1;     end   `else     begin       $display("(%0t) Writing register with 0x%0x", $time, reg_addr, reg_data);       wait (port_free);       port_free = 0;       @ (posedge clk);       #1;       cs_can = 1;       @ (negedge clk);       #1;       ale_i = 1;       port_0_en = 1;       port_0_o = reg_addr;       @ (negedge clk);       #1;       ale_i = 0;       #90;            // 73 - 103 ns       port_0_o = reg_data;       wr_i = 1;       #158;       wr_i = 0;       port_0_en = 0;       cs_can = 0;       port_free = 1;     end   `endif endtask  
  • 热度 15
    2016-4-7 09:34
    1510 次阅读|
    1 个评论
    本节内容提要: 根据SJA1000的初始化程序,了解CAN的初始化过程以及对象。本来是想整理的,后来发现一整篇都很有用就直接转载了。 不过我在想,如果是直接用verilog实现can 是否有另外的方法来对can进行初始化,比如在fpga对can进行赋值。 参考网址:http://www.360doc.com/content/16/0119/13/29617669_529065812.shtml -----------------------------------------我是正文分界线------------------------------------------------------ CAN 的初始化配置步骤,CAN 相关的固件库函数和定义分布在文件 stm32f10x_can.c 和头文件 stm32f10x_can.h 文件中。 1)配置相关引脚的复用功能,使能 CAN 时钟。 我们要用 CAN,第一步就要使能 CAN 的时钟。其次要设置 CAN 的相关引脚为复用输出,这里我们需要设置 PA11 为上拉输入(CAN_RX 引脚)PA12 为复用输出(CAN_TX 引脚),并使能 PA 口的时钟。使能 CAN1 时钟的函数是: RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能 CAN1 时钟 2)设置 CAN 工作模式及波特率等。 这一步通过先设置 CAN_MCR 寄存器的 INRQ 位,让 CAN 进入初始化模式,然后设置CAN_MCR 的其他相关控制位。再通过 CAN_BTR 设置波特率和工作模式(正常模式/环回模式)等信息。  最后设置 INRQ 为 0,退出初始化模式。 在库函数中,提供了函数 CAN_Init()用来初始化 CAN 的工作模式以及波特率,CAN_Init()函数体中,在初始化之前,会设置 CAN_MCR 寄存器的 INRQ 为 1 让其进入初始化模式,然后初始化 CAN_MCR 寄存器和 CRN_BTR 寄存器之后,会设置 CAN_MCR 寄存器的 INRQ 为 0让其退出初始化模式。所以我们在调用这个函数的前后不需要再进行初始化模式设置。下面我们来看看 CAN_Init()函数的定义: uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct); 第一个参数就是 CAN 标号,这里我们的芯片只有一个 CAN,所以就是 CAN1。 第二个参数是 CAN 初始化结构体指针,结构体类型是 CAN_InitTypeDef,下面我们来看看这个结构体的定义: typedef struct { uint16_t CAN_Prescaler;   uint8_t CAN_Mode;      uint8_t CAN_SJW;       uint8_t CAN_BS1;          uint8_t CAN_BS2;        FunctionalState CAN_TTCM;  FunctionalState CAN_ABOM;   FunctionalState CAN_AWUM;   FunctionalState CAN_NART;  FunctionalState CAN_RFLM;  FunctionalState CAN_TXFP;   } CAN_InitTypeDef; 这个结构体看起来成员变量比较多,实际上参数可以分为两类。前面 5 个参数是用来设置寄存器 CAN_BTR,用来设置模式以及波特率相关的参数,设置模式的参数是CAN_Mode, 我们实验中用到回环模式 CAN_Mode_LoopBack 和常规模式 CAN_Mode_Normal,大家还可以选择静默模式以及静默回环模式测试。其他设置波特率相关的参数 CAN_Prescaler,CAN_SJW,CAN_BS1 和 CAN_BS2 分别用来设置波特率分频器,重新同步跳跃宽度以及时间段 1 和时间段 2 占用的时间单元数。后面 6 个成员变量用来设置寄存器 CAN_MCR,也就是设置 CAN 通信相关的控制位。 初始化实例为: CAN_InitStructure.CAN_TTCM=DISABLE;      //非时间触发通信模式  CAN_InitStructure.CAN_ABOM=DISABLE;      //软件自动离线管理    CAN_InitStructure.CAN_AWUM=DISABLE;          //睡眠模式通过软件唤醒 CAN_InitStructure.CAN_NART=ENABLE;    //禁止报文自动传送  CAN_InitStructure.CAN_RFLM=DISABLE;      //报文不锁定,新的覆盖旧的  CAN_InitStructure.CAN_TXFP=DISABLE;      //优先级由报文标识符决定  CAN_InitStructure.CAN_Mode= CAN_Mode_LoopBack; //模式设置:  1,回环模式; //设置波特率 CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度为个时间单位  CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //时间段 1 占用 8 个时间单位 CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//时间段 2 占用 7 个时间单位 CAN_InitStructure.CAN_Prescaler=5;   //分频系数(Fdiv)  CAN_Init(CAN1, CAN_InitStructure);             //  初始化 CAN 3)设置滤波器。 我们将使用滤波器组 0,并工作在 32 位标识符屏蔽位模式下。先设置 CAN_FMR的 FINIT 位,让过滤器组工作在初始化模式下,然后设置滤波器组 0 的工作模式以及标识符 ID和屏蔽位。最后激活滤波器,并退出滤波器初始化模式。 在库函数中,提供了函数 CAN_FilterInit ()用来初始化 CAN 的滤波器相关参数, CAN_Init()函数体中,在初始化之前,会设置 CAN_FMR 寄存器的 INRQ 为 INIT 让其进入初始化模式,然后初始化 CAN 滤波器相关的寄存器之后,会设置 CAN_FMR 寄存器的 FINIT 为 0 让其退出初始化模式。所以我们在调用这个函数的前后不需要再进行初始化模式设置。下面我们来看看CAN_FilterInit ()函数的定义: void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct); 这 个 函 数 只 有 一 个 入 口 参 数 就 是 CAN 滤 波 器 初 始 化 结 构 体 指 针 , 结 构 体 类 型 为CAN_FilterInitTypeDef,下面我们看看类型定义: typedef struct { uint16_t CAN_FilterIdHigh;  uint16_t CAN_FilterIdLow;    uint16_t CAN_FilterMaskIdHigh;  uint16_t CAN_FilterMaskIdLow;  uint16_t CAN_FilterFIFOAssignment;  uint8_t CAN_FilterNumber;      uint8_t CAN_FilterMode;      uint8_t CAN_FilterScale;         FunctionalState CAN_FilterActivation;  } CAN_FilterInitTypeDef; 结构体一共有 9 个成员变量,第 1 个至第 4 个是用来设置过滤器的 32 位 id 以及 32 位 mask id,分别通过 2 个 16 位来组合的 第 5 个成员变量 CAN_FilterFIFOAssignment 用来设置 FIFO 和过滤器的关联关系,我们的实验是关联的过滤器 0 到 FIFO0,值为 CAN_Filter_FIFO0。 第 6 个成员变量 CAN_FilterNumber 用来设置初始化的过滤器组,取值范围为 0~13。 第 7 个成员变量 FilterMode 用来设置过滤器组的模式,取值为标识符列表模式CAN_FilterMode_IdList 和标识符屏蔽位模式 CAN_FilterMode_IdMask。 第 8 个成员变量 FilterScale 用来设置过滤器的位宽为 2 个 16 位 CAN_FilterScale_16bit 还是 1 个32 位 CAN_FilterScale_32bit。 第 9 个成员变量 CAN_FilterActivation 就很明了了,用来激活该过滤器。 过滤器初始化参考实例代码: CAN_FilterInitStructure.CAN_FilterNumber=0;    //过滤器 0 CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32 位  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32 位 ID CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32 位 MASK CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;// FIFO0 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器 0 CAN_FilterInit(CAN_FilterInitStructure);//滤波器初始化 至此,CAN 就可以开始正常工作了。如果用到中断,就还需要进行中断相关的配置 4)发送接受消息 在初始化 CAN 相关参数以及过滤器之后,接下来就是发送和接收消息了。库函数中提供了发送和接受消息的函数。发送消息的函数是: uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage); 这个函数比较好理解,第一个参数是 CAN 标号,我们使用 CAN1。第二个参数是相关消息结构体 CanTxMsg 指针类型,CanTxMsg 结构体的成员变量用来设置标准标识符,扩展标示符,消息类型和消息帧长度等信息。 接受消息的函数是: void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage); 前面两个参数也比较好理解,CAN 标号和 FIFO 号。第二个参数 RxMessage 是用来存放接受到的消息信息。 结构体 CanRxMsg 和结构体 CanTxMsg 比较接近,分别用来定义发送消息和描述接受消息, 5)CAN 状态获取 对于 CAN 发送消息的状态,挂起消息数目等等之类的传输状态信息,库函数提供了一些列的函数,包括 CAN_TransmitStatus()函数,CAN_MessagePending()函数,CAN_GetFlagStatus()函数等等,大家可以根据需要来调用。 点击( 此处 )折叠或打开 //CAN初始化 //tsjw:重新同步跳跃时间单元.范围:1~3; CAN_SJW_1tq     CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq //tbs2:时间段2的时间单元.范围:1~8; //tbs1:时间段1的时间单元.范围:1~16;     CAN_BS1_1tq ~CAN_BS1_16tq //brp :波特率分频器.范围:1~1024;(实际要加1,也就是1~1024) tq=(brp)*tpclk1 //注意以上参数任何一个都不能设为0,否则会乱. //波特率=Fpclk1/((tsjw+tbs1+tbs2)*brp); //mode:0,普通模式;1,回环模式; //Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Normal_Init(1,8,7,5,1); //则波特率为:36M/((1+8+7)*5)=450Kbps //返回值:0,初始化OK; // 其他,初始化失败; u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode) {       GPIO_InitTypeDef GPIO_InitStructure;     CAN_InitTypeDef CAN_InitStructure;      CAN_FilterInitTypeDef CAN_FilterInitStructure; #if CAN_RX0_INT_ENABLE        NVIC_InitTypeDef NVIC_InitStructure; #endif       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA时钟                                                          RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽     GPIO_Init(GPIOA, GPIO_InitStructure);        //初始化IO                //CAN单元设置      CAN_InitStructure.CAN_TTCM=DISABLE;                         //非时间触发通信模式 //      CAN_InitStructure.CAN_ABOM=DISABLE;                         //软件自动离线管理     //       CAN_InitStructure.CAN_AWUM=DISABLE;                         //睡眠模式通过软件唤醒(清除CAN-MCR的SLEEP位)//       CAN_InitStructure.CAN_NART=ENABLE;                             //禁止报文自动传送 //       CAN_InitStructure.CAN_RFLM=DISABLE;                         //报文不锁定,新的覆盖旧的 //       CAN_InitStructure.CAN_TXFP=DISABLE;                         //优先级由报文标识符决定 //       CAN_InitStructure.CAN_Mode= mode;     //模式设置: mode:0,普通模式;1,回环模式; //       //设置波特率       CAN_InitStructure.CAN_SJW=tsjw;                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq     CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq       CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq       CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~    CAN_BS2_8tq       CAN_InitStructure.CAN_Prescaler=brp; //分频系数(Fdiv)为brp+1    //       CAN_Init(CAN1, CAN_InitStructure); // 初始化CAN1       CAN_FilterInitStructure.CAN_FilterNumber=0;     //过滤器0      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;       CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位       CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32位ID       CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;       CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK       CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;       CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0      CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0         CAN_FilterInit(CAN_FilterInitStructure);//滤波器初始化      #if CAN_RX0_INT_ENABLE          CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       NVIC_Init(NVIC_InitStructure); #endif     return 0;      }   #if CAN_RX0_INT_ENABLE    //使能RX0中断 //中断服务函数             void USB_LP_CAN1_RX0_IRQHandler(void) {       CanRxMsg RxMessage;     int i=0;     CAN_Receive(CAN1, 0, RxMessage);     for(i=0;i8;i++)     printf('rxbuf :%d\r\n',i,RxMessage.Data ); } #endif     //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)     //len:数据长度(最大为8)                 //msg:数据指针,最大为8个字节. //返回值:0,成功; //         其他,失败; u8 Can_Send_Msg(u8* msg,u8 len) {       u8 mbox;   u16 i=0;   CanTxMsg TxMessage;   TxMessage.StdId=0x12;                     // 标准标识符为0   TxMessage.ExtId=0x12;                 // 设置扩展标示符(29位)   TxMessage.IDE=0;             // 使用扩展标识符   TxMessage.RTR=0;         // 消息类型为数据帧,一帧8位   TxMessage.DLC=len;                             // 发送两帧信息   for(i=0;i;i++)   TxMessage.Data =msg ;                 // 第一帧信息   mbox= CAN_Transmit(CAN1, TxMessage);   i=0;   while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)(i0XFFF))i++;    //等待发送结束   if(i=0XFFF)return 1;   return 0;           }     //can口接收数据查询 //buf:数据缓存区;     //返回值:0,无数据被收到; //         其他,接收的数据长度; u8 Can_Receive_Msg(u8 *buf) {                       u32 i;     CanRxMsg RxMessage;     if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0;        //没有接收到数据,直接退出     CAN_Receive(CAN1, CAN_FIFO0, RxMessage);//读取数据         for(i=0;i8;i++)     buf =RxMessage.Data ;     return RxMessage.DLC;     }
  • 热度 13
    2016-4-6 14:14
    1372 次阅读|
    0 个评论
    前言:在看如何用FPGA实现can_controller ,本来想把代码上传上来的,结果没成功。如果有意向研究的,可以自己去下载  pudn就有。can tb有点问题,我也只是在刚刚研究,如果有意向可以和我交流, 欢迎大家讨论呐。【PS:坚决抵制伸手党】 本文为整理总结,参考文档如下: 《STM32中文参考手册2010》 ----------------------------------------------------我是正文分界线----------------------------------------- 1 CAN IP有提到  Wishbone, 是总线的一种。 它通过在IP核之间建立一个通用接口完成互连。可以用于在 软核 、固核以及硬核之间进行互联。 2 CAN_IP 需要初始化的寄存器, 或者初始化方式可以参考百度文库700多页的手册,22章就是关于can的初始化。我看完了也会整理一下。 3 CAN的工作模式: 初始化模式、正常模式、睡眠模式。分别对应不同的寄存器配置。   4 bxCAN(基本扩展CAN)功能描述 1 发送处理 设置标识符,数据长度和待发送数据; 然后对CAN_TIxR寄存器的TXRQ位置’1’,来请求发送。TXRQ位置’1’后,邮箱就不再是空邮箱;而一旦邮箱不再为 空置,软件对邮箱寄存器就不再有写的权限。TXRQ位置1后,邮箱马上进入 挂号状态,并等待成为最高优先级的邮箱,参见 发送优先级 。一旦邮箱成为最高优先级的邮箱,其状态就变为 预定发送状态。一旦CAN总线进入空闲状态,预定发送邮箱中的报文就马上被发送(进入 发送状态)。一旦邮箱中的报文被成功发送后,它马上变为 空置邮箱;硬件相应地对CAN_TSR寄存器的RQCP和TXOK位置1,来表明一次成功发送。如果发送失败,由于仲裁引起的就对CAN_TSR寄存器的ALST位置’1’,由于发送错误引起的就对TERR位置’1’。 --------------------------------------------------我是16.4.6更新分界线--------------- 3 接收管理   根据CAN协议, 当报文被 正确接收 (直到EOF域的最后一位都没有错误), 且通过了 标识符过滤 ,那么该报文被认为是 有效 报文。   4 标识符过滤 在CAN协议里,报文的 标识符 不代表节点的地址,而是跟 报文的内容 相关的。因此,发送者以 广播 的形式把报文发送给所有的接收者。节点在接收报文时-根据标识符的值-决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。 过滤器可配置为, 屏蔽位模式 和 标识符列表模式 。 bxCAN的过滤器规则: 在接收一个报文时,其标识符首先与配置 在标识符列 表模式下的过滤器相比较 ;如果匹配上,报文就被存放到相关联的FIFO中,并且所匹配的过滤 器的序号被存入过滤器匹配序号中。如同例子中所显示,报文标识符跟#4标识符匹配,因此报 文内容和FMI4被存入FIFO。 如果没有匹配,报文标识符 接着与配置在屏蔽位模式下的过滤器 进行比较。 如果报文标识符没有跟过滤器中的任何标识符相匹配,那么硬件就丢弃该报文,且不会对软件有任何打扰。   5 报文存储 邮箱是软件和硬件之间传递报文的接口。邮箱包含了所有跟报文有关的信息 :标识符 、 数据 、 控制 、 状态 和 时间戳信息 。   发送邮箱:    接收邮箱(FIFO):在接收到一个报文后,软件就可以访问接收FIFO的输出邮箱来读取它。一旦软件处理了报文(如把它读出来),软件就应该对CAN_RFxR寄存器的RFOM位进行置’1’,来释放该报文,以便为后面收到的报文留出存储空间。过滤器匹配序号存放在CAN_RDTxR寄存器的FMI域中。16位的时间戳存放在CAN_RDTxR寄存器的TIME 域中。 6 出错管理 7 位时间特性(重要)  (1 )位时间特性逻辑通过采样来监视串行的CAN总线,并且通过与帧起始位的边沿进行同步,及通过与后面的边沿进行重新同步,来调整其采样点。  (2)名义上的每位时间分为3段: ●  同步段(SYNC_SEG):通常期望位的变化发生在该时间段内。其值固定为1个时间单元(1 xt CAN )。 ●  时间段1(BS1): 定义采样点的位置。 它包含CAN标准里的PROP_SEG和PHASE_SEG1。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的 正向 漂移。 ●  时间段2(BS2): 定义发送点的位置 。它代表CAN标准里的PHASE_SEG2。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的 负向 漂移。   重新同步跳跃宽度 (SJW) 定义了,在每位中可以延长或缩短多少个时间单元的上限。其值可以编 程为 1到4个 时间单元。   有效跳变被定义为,当bxCAN自己没有发送隐性位时,从显性位到隐性位的第1次转变。 如果在时间段1(BS1)而不是在同步段(SYNC_SEG)检测到有效跳变,那么BS1的时间就被延长最多SJW那么长,从而 采样点被延迟 了。 相反如果在时间段2(BS2)而不是在SYNC_SEG检测到有效跳变,那么BS2的时间就被缩短最多SJW那么长,从而 采样点被提前 了。 为了避免软件的编程错误,对位时间特性寄存器(CAN_BTR)的设置,只能在bxCAN处于初始化状态下进行。   8 bxCAN中断 9 CAN寄存器描述 9   9.1寄存器访问保护             软件只能在CAN处于 初始化模式 时修改CAN_BTR寄存器。             软件只能在发送邮箱为 空 的状态改变它。            过滤器的数值只能在关闭对应过滤器组的状态下,或设置FINIT位为’1’后才能改。此外,只有在设置整个过滤器为初始化模式下( 即FINIT=1) ,才能修改过滤器的设置,即修改CAN_FMxR,CAN_FSxR和CAN_FFAR寄存器。   9.2 CAN控制和状态寄存器    CAN 主控制寄存器 (CAN_MCR)    CAN 主状态寄存器 (CAN_MSR)    CAN 发送状态寄存器 (CAN_TSR)    CAN 接收FIFO 0 寄存器 (CAN_RF0R)    CAN 接收FIFO 1 寄存器(CAN_RF1R)     CAN 中断使能寄存器 (CAN_IER)    CAN 错误状态寄存器 (CAN_ESR)     CAN 位时序寄存器 (CAN_BTR) 9.3CAN邮箱寄存器 9.4CAN过滤器寄存器   CAN  过滤器主控寄存器 (CAN_FMR)   CAN  过滤器模式寄存器 (CAN_FM1R)   CAN  过滤器位宽寄存器 (CAN_FS1R)   CAN  过滤器FIFO 关联寄存器 (CAN_FFA1R)   CAN  过滤器激活寄存器 (CAN_FA1R)   CAN  过滤器组i 的寄存器x (CAN_FiRx)