#include "FreeRTOS.h"
#include "main.h"
#include "cmsis_os.h"
#include "can.h"
#include "can_filter.h"
#include "stdlib.h"
#include "string.h"
#ifdef USE_CAN_FILTER_IN_BOARD_XIANSHU
extern int g_device_id;
#endif
extern CAN_HandleTypeDef hcan;
/*******************************************************************************
* 函数名 : CANFilterConfig_AnyId
* 描 述 : 过滤器关闭,任何id数据都能接收
* 输 入 : 无
* 输 出 : 无
* 返回值 : 无
* 说 明 :
*******************************************************************************/
void CANFilterConfig_AnyId(void)
{
//CAN_FilterConfTypeDef sFilterConfig;
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterIdHigh = 0x0000;//32 位 ID 不使用过滤器
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;//32 位 MASK
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterBank = 0; //过滤器0
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //过滤器0关联到FIFO0
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterActivation = ENABLE; //激活过滤器0
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*******************************************************************************
* 函数名 : CANFilterConfig_Scale32_IdMask_StandardIdOnly
* 描 述 : 32bit掩码滤波 只过滤接收函数中设置的那几个标准帧id的数据
* 输 入 : 无
* 输 出 : 无
* 返回值 : 无
* 说 明 :
*******************************************************************************/
void CANFilterConfig_Scale32_IdMask_StandardIdOnly(void)
{
//CAN_FilterConfTypeDef sFilterConfig;
CAN_FilterTypeDef sFilterConfig;
uint16_t mask,num,tmp,i;
#ifdef USE_CAN_FILTER_IN_BOARD_XIANSHU
uint16_t StdIdArray[4] = {0}; //定义一组标准CAN ID
StdIdArray[0] = BASE_ID_RECV | (g_device_id << 4) | CAN_HEART_BEAT; //0x200,0x210...0x270
StdIdArray[1] = BASE_ID_RECV | (g_device_id << 4) | CAN_GPIO_SET; //0x201,0x211...0x271
StdIdArray[2] = BASE_ID_RECV | (g_device_id << 4) | CAN_GPIO_GET; //0x202,0x212...0x272
StdIdArray[3] = BASE_ID_RECV | (g_device_id << 4) | CAN_VOICE_SET; //0x203,0x213...0x273
#else
uint16_t StdIdArray[10] ={0x200,0x201,0x202,0x203,0x204,
0x205,0x206,0x207,0x208,0x209}; //定义一组标准CAN ID
#endif
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //配置为掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //设置为32位宽
sFilterConfig.FilterIdHigh =(StdIdArray[0]<<5); //验证码可以设置为StdIdArray[]数组中任意一个,这里使用StdIdArray[0]作为验证码
sFilterConfig.FilterIdLow =0;
mask =0x7ff; //下面开始计算屏蔽码
num =sizeof(StdIdArray)/sizeof(StdIdArray[0]);
for(i =0; i<num; i++) //屏蔽码位StdIdArray[]数组中所有成员的同或结果
{
tmp =StdIdArray[i] ^ (~StdIdArray[0]); //所有数组成员与第0个成员进行同或操作
mask &=tmp;
}
sFilterConfig.FilterMaskIdHigh =(mask<<5);
sFilterConfig.FilterMaskIdLow =0|0x02; //只接收数据帧
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //设置通过的数据帧进入到FIFO0中
sFilterConfig.FilterActivation = ENABLE; //激活过滤器
sFilterConfig.FilterBank = 0; //过滤器0 0~13 数字越小,优先级越高
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*******************************************************************************
* 函数名 : CANFilterConfig_Scale32_IdList
* 描 述 : 32bit列表滤波 精确识别id,可以同时识别出标准和扩展id号
* 输 入 : 无
* 输 出 : 无
* 返回值 : 无
* 说 明 :
*******************************************************************************/
void CANFilterConfig_Scale32_IdList(void)
{
CAN_FilterTypeDef sFilterConfig;
uint32_t StdId = 0x321; //这里写入两个CAN ID,一个位标准CAN ID
uint32_t ExtId = 0x1800f001; //一个位扩展CAN ID
sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST; //设为列表模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //配置为32位宽
sFilterConfig.FilterIdHigh = StdId<<5; //基本ID放入到STID中
sFilterConfig.FilterIdLow = 0|CAN_ID_STD; //设置IDE位为0
sFilterConfig.FilterMaskIdHigh = ((ExtId<<3)>>16)&0xffff;
sFilterConfig.FilterMaskIdLow = (ExtId<<3)&0xffff|CAN_ID_EXT; //设置IDE位为1
sFilterConfig.FilterFIFOAssignment = 0; //接收到的报文放入到FIFO0中
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterBank = 14; //过滤器14 0~13 数字越小,优先级越高
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*******************************************************************************
* 函数名 : CANFilterConfig_Scale16_IdList
* 描 述 : 16bit列表滤波 精确识别id(只能识别标准id),一个滤波器只能识别4个标准id
* 输 入 : 无
* 输 出 : 无
* 返回值 : 无
* 说 明 :
*******************************************************************************/
void CANFilterConfig_Scale16_IdList(void)
{
CAN_FilterTypeDef sFilterConfig;
uint32_t StdId1 =0x123; //这里采用4个标准CAN ID作为例子
uint32_t StdId2 =0x124;
uint32_t StdId3 =0x125;
uint32_t StdId4 =0x126;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST; //设为列表模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; //位宽设置为16位
sFilterConfig.FilterIdHigh = StdId1<<5; //4个标准CAN ID分别放入到4个存储中
sFilterConfig.FilterIdLow = StdId2<<5;
sFilterConfig.FilterMaskIdHigh = StdId3<<5;
sFilterConfig.FilterMaskIdLow = StdId4<<5;
sFilterConfig.FilterFIFOAssignment = 0; //接收到的报文放入到FIFO0中
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*******************************************************************************
* 函数名 : CANFilterConfig_Scale32_IdMask_ExtendIdOnly
* 描 述 : 32bit掩码滤波 只过滤接收函数中设置的那几个扩展帧数据
* 输 入 : 无
* 输 出 : 无
* 返回值 : 无
* 说 明 :
*******************************************************************************/
void CANFilterConfig_Scale32_IdMask_ExtendIdOnly(void)
{
CAN_FilterTypeDef sFilterConfig;
//定义一组扩展CAN ID用来测试
uint32_t ExtIdArray[10] ={0x1839f101,0x1835f102,0x1835f113,0x1835f124,0x1835f105,
0x1835f106,0x1835f107,0x1835f108,0x1835f109,0x1835f10A};
uint32_t mask,num,tmp,i;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //配置为掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //设为32位宽
sFilterConfig.FilterIdHigh =((ExtIdArray[0]<<3) >>16) &0xffff;//数组任意一个成员都可以作为验证码
sFilterConfig.FilterIdLow =((ExtIdArray[0]<<3)&0xffff) | CAN_ID_EXT;
mask =0x1fffffff;
num =sizeof(ExtIdArray)/sizeof(ExtIdArray[0]);
for(i =0; i<num; i++) //屏蔽码位数组各成员相互同或的结果
{
tmp =ExtIdArray[i] ^ (~ExtIdArray[0]); //都与第一个数据成员进行同或操作
mask &=tmp;
}
mask <<=3; //对齐寄存器
sFilterConfig.FilterMaskIdHigh = (mask>>16)&0xffff;
sFilterConfig.FilterMaskIdLow = (mask&0xffff)|0x02; //只接收数据帧
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*******************************************************************************
* 函数名 : CANFilterConfig_Scale32_IdMask_StandardId_ExtendId_Mix
* 描 述 : 32bit掩码滤波 只过滤接收函数中设置的那几个扩展帧和标准帧数据
* 输 入 : 无
* 输 出 : 无
* 返回值 : 无
* 说 明 :
*******************************************************************************/
void CANFilterConfig_Scale32_IdMask_StandardId_ExtendId_Mix(void)
{
CAN_FilterTypeDef sFilterConfig;
//定义一组标准CAN ID
uint32_t StdIdArray[10] ={0x711,0x712,0x713,0x714,0x715,
0x716,0x717,0x718,0x719,0x71a};
//定义另外一组扩展CAN ID
uint32_t ExtIdArray[10] ={0x1900fAB1,0x1900fAB2,0x1900fAB3,0x1900fAB4,0x1900fAB5,
0x1900fAB6,0x1900fAB7,0x1900fAB8,0x1900fAB9,0x1900fABA};
uint32_t mask,num,tmp,i,standard_mask,extend_mask,mix_mask;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //配置为掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //设为32位宽
sFilterConfig.FilterIdHigh =((ExtIdArray[0]<<3) >>16) &0xffff; //使用第一个扩展CAN ID作为验证码
sFilterConfig.FilterIdLow =((ExtIdArray[0]<<3)&0xffff);
standard_mask =0x7ff; //下面是计算屏蔽码
num =sizeof(StdIdArray)/sizeof(StdIdArray[0]);
for(i =0; i<num; i++) //首先计算出所有标准CAN ID的屏蔽码
{
tmp =StdIdArray[i] ^ (~StdIdArray[0]);
standard_mask &=tmp;
}
extend_mask =0x1fffffff;
num =sizeof(ExtIdArray)/sizeof(ExtIdArray[0]);
for(i =0; i<num; i++) //接着计算出所有扩展CAN ID的屏蔽码
{
tmp =ExtIdArray[i] ^ (~ExtIdArray[0]);
extend_mask &=tmp;
}
mix_mask =(StdIdArray[0]<<18)^ (~ExtIdArray[0]); //再计算标准CAN ID与扩展CAN ID混合的屏蔽码
mask =(standard_mask<<18)& extend_mask &mix_mask; //最后计算最终的屏蔽码
mask <<=3; //对齐寄存器
sFilterConfig.FilterMaskIdHigh = (mask>>16)&0xffff;
sFilterConfig.FilterMaskIdLow = (mask&0xffff);
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*******************************************************************************
* 函数名 : CANFilterConfig_Scale16_IdMask
* 描 述 : 16bit掩码滤波 可以识别两组标准帧
* 输 入 : 无
* 输 出 : 无
* 返回值 : 无
* 说 明 :
*******************************************************************************/
void CANFilterConfig_Scale16_IdMask(void)
{
CAN_FilterTypeDef sFilterConfig;
uint16_t StdIdArray1[10] ={0x7D1,0x7D2,0x7D3,0x7D4,0x7D5, //定义第一组标准CAN ID
0x7D6,0x7D7,0x7D8,0x7D9,0x7DA};
uint16_t StdIdArray2[10] ={0x751,0x752,0x753,0x754,0x755, //定义第二组标准CAN ID
0x756,0x757,0x758,0x759,0x75A};
uint16_t mask,tmp,i,num;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; //配置为掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; //设为16位宽
//配置第一个过滤对
sFilterConfig.FilterIdLow =StdIdArray1[0]<<5; //设置第一个验证码
mask =0x7ff;
num =sizeof(StdIdArray1)/sizeof(StdIdArray1[0]);
for(i =0; i<num; i++) //计算第一个屏蔽码
{
tmp =StdIdArray1[i] ^ (~StdIdArray1[0]);
mask &=tmp;
}
sFilterConfig.FilterMaskIdLow =(mask<<5)|0x10; //只接收数据帧
//配置第二个过滤对
sFilterConfig.FilterIdHigh = StdIdArray2[0]<<5; //设置第二个验证码
mask =0x7ff;
num =sizeof(StdIdArray2)/sizeof(StdIdArray2[0]);
for(i =0; i<num; i++) //计算第二个屏蔽码
{
tmp =StdIdArray2[i] ^ (~StdIdArray2[0]);
mask &=tmp;
}
sFilterConfig.FilterMaskIdHigh = (mask<<5)|0x10; //只接收数据帧
sFilterConfig.FilterFIFOAssignment = 0; //通过的CAN 消息放入到FIFO0中
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}