STM32 HAL库的CAN总线滤波器设置

STM32 HAL库的CAN总线滤波器设置

stm32cubemx生成的can初始化代码

#include "can.h"

#include "gpio.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;

/* CAN1 init function */
void MX_CAN1_Init(void)
{
    
    

  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 3;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SJW = CAN_SJW_1TQ;
  hcan1.Init.BS1 = CAN_BS1_9TQ;
  hcan1.Init.BS2 = CAN_BS2_4TQ;
  hcan1.Init.TTCM = DISABLE;
  hcan1.Init.ABOM = ENABLE;
  hcan1.Init.AWUM = DISABLE;
  hcan1.Init.NART = DISABLE;
  hcan1.Init.RFLM = DISABLE;
  hcan1.Init.TXFP = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    
    
    _Error_Handler(__FILE__, __LINE__);
  }

}
/* CAN2 init function */
void MX_CAN2_Init(void)
{
    
    

  hcan2.Instance = CAN2;
  hcan2.Init.Prescaler = 3;
  hcan2.Init.Mode = CAN_MODE_NORMAL;
  hcan2.Init.SJW = CAN_SJW_1TQ;
  hcan2.Init.BS1 = CAN_BS1_9TQ;
  hcan2.Init.BS2 = CAN_BS2_4TQ;
  hcan2.Init.TTCM = DISABLE;
  hcan2.Init.ABOM = ENABLE;
  hcan2.Init.AWUM = DISABLE;
  hcan2.Init.NART = DISABLE;
  hcan2.Init.RFLM = DISABLE;
  hcan2.Init.TXFP = DISABLE;
  if (HAL_CAN_Init(&hcan2) != HAL_OK)
  {
    
    
    _Error_Handler(__FILE__, __LINE__);
  }

}

针对滤波器的设置

#include "my_can.h"
//改变成中文字符模式,现在一个中文字符占一个空格
uint16_t data[4]={
    
    0};
void My_CAN_FilterConfig(CAN_HandleTypeDef* _hcan)   
{
    
    
	//can1 &can2 use same filter config
	CAN_FilterConfTypeDef		CAN_FilterConfigStructure;
	static CanTxMsgTypeDef		Tx1Message;
	static CanRxMsgTypeDef 		Rx1Message;
	static CanTxMsgTypeDef		Tx2Message;
	static CanRxMsgTypeDef 		Rx2Message;
    
	CAN_FilterConfigStructure.FilterNumber = 0;//指定初始化第0组的过滤器
	CAN_FilterConfigStructure.FilterFIFOAssignment = CAN_FilterFIFO0;  // Filter FIFO 0 assignment for filter x
	CAN_FilterConfigStructure.BankNumber = 14;//can1(0-13) can2(14-27)//这个是can2可以使用过滤器组的起点
	CAN_FilterConfigStructure.FilterActivation = ENABLE;//使能过滤器组

	if(_hcan == &hcan1){
    
    
        CAN_FilterConfigStructure.FilterMode = CAN_FILTERMODE_IDLIST;//标志符列表模式
        CAN_FilterConfigStructure.FilterScale = CAN_FILTERSCALE_16BIT;//设置成16位,这样每组过滤器就有4个过滤器
        CAN_FilterConfigStructure.FilterIdHigh = (0x201 << 5);//因为每个标准ID都是11位的,在过滤的时候要左对齐,而过滤器是16位,所以要左移5位
        CAN_FilterConfigStructure.FilterIdLow = (0x202 << 5);
        CAN_FilterConfigStructure.FilterMaskIdHigh = (0x203 << 5);
        CAN_FilterConfigStructure.FilterMaskIdLow = (0x204 << 5);
        
				if(HAL_CAN_ConfigFilter(_hcan, &CAN_FilterConfigStructure) != HAL_OK)
					{
    
    
						while(1);//show error!
					}
					_hcan->pTxMsg = &Tx1Message;
					_hcan->pRxMsg = &Rx1Message;
	}
    
	if(_hcan == &hcan2){
    
    
        CAN_FilterConfigStructure.FilterMode = CAN_FILTERMODE_IDLIST;
        CAN_FilterConfigStructure.FilterScale = CAN_FILTERSCALE_16BIT;
        CAN_FilterConfigStructure.FilterIdHigh = (0x301 << 5);
        CAN_FilterConfigStructure.FilterIdLow = (0x302<< 5);
        CAN_FilterConfigStructure.FilterMaskIdHigh = (0x303<< 5);
        CAN_FilterConfigStructure.FilterMaskIdLow = (0x304<<5);
        
        CAN_FilterConfigStructure.FilterNumber = 14;//这个是选择can2的过滤器,因为之前设置的为0,所以这里针对can2还要初始化一下
		//14也是can2使用的过滤器,也是要初始化的过滤器组,也就是说,can1使用第0组,can2使用第14组
        if(HAL_CAN_ConfigFilter(_hcan, &CAN_FilterConfigStructure) != HAL_OK)
        {
    
    
            while(1);//show error!
        }
					_hcan->pTxMsg = &Tx2Message;
					_hcan->pRxMsg = &Rx2Message;
	}	
}

通过can发送数据

HAL_StatusTypeDef  CAN2_SEND_Data(uint16_t *p)
{
    
    
		HCAN_2.pTxMsg->RTR = CAN_RTR_DATA;//数据帧
		HCAN_2.pTxMsg->IDE = CAN_ID_STD; //标准帧
		HCAN_2.pTxMsg->DLC = 8;      
    HCAN_2.pTxMsg->StdId = 0x123; //ID 
    HCAN_2.pTxMsg->Data[0] = (uint8_t)(((int16_t)p[0])>>8);
    HCAN_2.pTxMsg->Data[1] = (uint8_t)(p[0]);      
    HCAN_2.pTxMsg->Data[2] = (uint8_t)(p[1]>>8);   
    HCAN_2.pTxMsg->Data[3] = (uint8_t)(p[1]); 
    HCAN_2.pTxMsg->Data[4] = (uint8_t)((p[2])>>8);
    HCAN_2.pTxMsg->Data[5] = (uint8_t)(p[2]);
    HCAN_2.pTxMsg->Data[6] = (uint8_t)(((int16_t)p[3])>>8);
    HCAN_2.pTxMsg->Data[7] = (uint8_t)(p[3]);  

    return(HAL_CAN_Transmit(&HCAN_2, 100));    
}

can总线中断服务函数以及数据处理函数

void Receive_DATA(CAN_HandleTypeDef* hcan)
{
    
    
	data[0] = (uint16_t)(hcan->pRxMsg->Data[0]<<8 | hcan->pRxMsg->Data[1]);    //角度值
	data[1] =  (int16_t)(hcan->pRxMsg->Data[2]<<8 | hcan->pRxMsg->Data[3]);    //速度值
 
  data[2]  =  (int16_t)(hcan->pRxMsg->Data[4]<<8 | hcan->pRxMsg->Data[5]);
	data[3]  = (int16_t)(hcan->pRxMsg->Data[6]<<8 | hcan->pRxMsg->Data[7]);
   
    
}
/*****************************************************
@ Brief: Callback函数,can接收的软中断,要事先在main中开启接收中断
@ Param: can的结构体指针
*****************************************************/
//这个函数只能中断一次,所以在离开中断处理函数之前要再次使能
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* _hcan)
{
    
    
	if(_hcan==&HCAN)
	{
    
    
		switch (_hcan->pRxMsg->StdId)
		{
    
    
            case 0x201:
							Receive_DATA(_hcan);
               //处理代码
                 break;               
		}
		//_hcan->Instance->IER|=0x00008F02;//这一行的作用也是消息挂起中断使能,和下面的作用一样
		__HAL_CAN_ENABLE_IT(_hcan, CAN_IT_FMP0);//消息挂起中断使能
	}
    
  else if(_hcan==&HCAN_2)
    {
    
    
        switch (_hcan->pRxMsg->StdId)
        {
    
    
            case 0x301:
           //处理代码
                 break;
                           
        }
        //_hcan->Instance->IER|=0x00008F02; 
		__HAL_CAN_ENABLE_IT(_hcan, CAN_IT_FMP0);//消息挂起中断使能,必须要有这一句,不然只中断一次就不能进入中断了
    }
    
}

猜你喜欢

转载自blog.csdn.net/sharpzhen/article/details/108763966