打印
[应用相关]

STM32 CAN滤波器配置总结

[复制链接]
1679|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
过期的塔头|  楼主 | 2021-7-23 23:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这里采用分别介绍查询发送、中断接收和中断发送、中断接收两种方式。
第一步,初始化各端口与寄存器,这里只介绍CAN_Configuration代码如下:
CAN_InitTypeDef        CAN_InitStructure;
CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  /* CAN register init */
CAN_DeInit();
CAN_StructInit(&CAN_InitStructure);
  /* CAN cell init */
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;// 正常模式
CAN_InitStructure.CAN_SJW=CAN_SJW_2tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler=8; //36MHz/(1+8+7)*9 =250Kb/s
CAN_Init(&CAN_InitStructure);
  /* CAN filter init */初始化滤波器
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 =tempid ;//接收板的CAN地址
CAN_FilterInitStructure.CAN_FilterIdLow =0x0004;//选择扩展标识符(见手册CAN_RIxR)
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xffff;//接收板的地址要和tempid一致
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0004;//下面有介绍
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //选择FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure); //进入初始化函数
       /* CAN FIFO0 message pending interrupt enable */
CAN_ITConfig(CAN_IT_FMP0, ENABLE);  //FIFO0 消息挂号中断屏蔽
CAN_ITConfig(CAN_IT_TME, ENABLE);      //发送邮箱空中断屏蔽
CAN_ITConfig(CAN_IT_BOF, ENABLE);   //离线中断允许

使用特权

评论回复
沙发
过期的塔头|  楼主 | 2021-7-23 23:25 | 只看该作者
第二步,在嵌套向量中断控制中设置下,代码如下:

NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM

  /* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else  /* VECT_TAB_FLASH  */

  /* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  

#endif

  /* Enable CAN RX0 interrupt IRQ channel */ //接收中断

NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//发送中断,如果是查询方式发送的话,下面代码不要

NVIC_InitStructure.NVIC_IRQChannel=USB_HP_CAN_TX_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢先中断优先

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应中断优先

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

使用特权

评论回复
板凳
过期的塔头|  楼主 | 2021-7-23 23:26 | 只看该作者
第三步,编写发送子函数

CanTxMsg TxMessage; //定义数据结构类型变量

u8 TransmitMailbox = 0;

u16 i = 0;

TxMessage.ExtId=(tempid << 13);     //tempId 为接受板地址,应用过程中要左移13位

TxMessage.IDE=CAN_ID_EXT;//使用扩展帧

TxMessage.RTR=CAN_RTR_DATA;//发送数据帧

TxMessage.DLC= 1; //设置发送数据的长度

TxMessage.Data[0] = SendData;//赋值待发送

TransmitMailbox = CAN_Transmit(&TxMessage);//开始发送数据

i = 0;

//通过检查CANTXOK位来确认发送是否成功

while((CAN_TransmitStatus(TransmitMailbox) != CANTXOK) && (i != 0xFF))

  {

    i++;

   }

使用特权

评论回复
地板
过期的塔头|  楼主 | 2021-7-23 23:27 | 只看该作者
第四步,编写中断接收函数,注:下面代码在stm32f10x_it.c中编写

Void  USB_LP_CAN_RX0_IRQHandler(void)

{

  CanRxMsg  can_rx_one_frame; //定义接收数据变量

CAN_Receive(CAN_FIFO0,&can_rx_one_frame);//接收数据函数

  Receive_data = can_rx_one_frame.Data[0];//接收到的数据转存给变量Receive_data

CAN_FIFORelease(CAN_FIFO0);// 释放一 FIFO0

}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

81

主题

955

帖子

0

粉丝