配置波特率
CAN总线通信的各节点通信时会产生相位差,所以要进行位同步,两个节点保持步调一致。
CAN_SJW:重新同步跳跃宽度(SJW) 。定义了在每位中可以延长或缩短多少个时间单元的上限。其值可以编程为1到4个时间单元。
CAN_BS1:时间段1(BS1):定义采样点的位置。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。
CAN_BS2:时间段2(BS2):定义发送点的位置。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。
CAN_Prescaler:分频率。
CAN总线的波特率是取自于总线APB1(PCLK1)
CAN总线的波特率=PCLK1/((CAN_SJW + CAN_BS1 + CAN_BS2)*CAN_Prescaler)
如上图所示,将参数配置为PCLK1=36MHz、CAN_SJW=1、CAN_BS1=5、CAN_BS2=6、CAN_Prescaler=6
则CAN总线的波特率=PCLK1/((1 + 5 + 6) * 6) = 36MHz / 12 / 6 = 500K bits
Can过滤器配置
void Can_Configure_Filter()
{
sFilterConfig.FilterNumber = 0;//过滤器组0
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//工作在标识符屏蔽位模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//滤波器位宽为单个32位
sFilterConfig.FilterIdHigh = 0x0000;//要过滤的ID高位
sFilterConfig.FilterIdLow = 0x0000;//要过滤的ID低位
sFilterConfig.FilterMaskIdHigh = 0x0000;//过滤器高16位每位无须匹配
sFilterConfig.FilterMaskIdLow = 0x0000;//过滤器低16位每无必须匹配
sFilterConfig.FilterFIFOAssignment = CAN_FIFO0;//过滤器被关联到FIFO0
sFilterConfig.FilterActivation = ENABLE; //使能过滤器
//sFilterConfig.BankNumber = 14;
if (HAL_OK != HAL_CAN_ConfigFilter(&hcan, &sFilterConfig))
{
Error_Handler();
}
}
标准帧过滤器配置
//过滤器为LIST掩码模式,其过滤ID为需跟过滤器严格匹配。只有相同的ID才能引起CAN中断。
VOID Dev_Can_Chip_Filt_Std_List(BUS_CAN_E bus,UCHAR idx,ULONG id0,ULONG id1,ULONG id2,ULONG id3)
{
CAN_FilterConfTypeDef Filter;
CAN_HandleTypeDef* hwal_can_handler = NULL;
hwal_can_handler = &HWAL_CAN_0;
Filter.FilterMode = CAN_FILTERMODE_IDLIST;
Filter.FilterScale = CAN_FILTERSCALE_16BIT;
Filter.FilterIdHigh = (id0<<5)|CAN_ID_STD;
Filter.FilterIdLow = (id1<<5)|CAN_ID_STD;
Filter.FilterMaskIdHigh = (id2<<5)|CAN_ID_STD;
Filter.FilterMaskIdLow = (id3<<5)|CAN_ID_STD;
Filter.FilterFIFOAssignment = CAN_FIFO0;
if(BUS_CAN_0 == bus) {Filter.FilterNumber = idx;}
#ifdef SYS_USE_CAN_1
else {Filter.FilterNumber = idx + DEV_CAN_BANK_NUMBER;}
#endif
Filter.FilterActivation = ENABLE;
Filter.BankNumber = DEV_CAN_BANK_NUMBER;
HAL_CAN_ConfigFilter(hwal_can_handler,&Filter);
return;
}
//过滤器为MASK掩码模式,其过滤ID为mask与ID相与,为部分位匹配模式。当设置为0时,设定为全部ID通过过滤器。
VOID Dev_Can_Chip_Filt_Std_Mask(BUS_CAN_E bus,UCHAR idx,USHORT id0,USHORT mask0,USHORT id1,USHORT mask1)
{
CAN_FilterConfTypeDef Filter;
CAN_HandleTypeDef* hwal_can_handler = NULL;
hwal_can_handler = &HWAL_CAN_0;
Filter.FilterMode = CAN_FILTERMODE_IDMASK;
Filter.FilterScale = CAN_FILTERSCALE_16BIT;
Filter.FilterIdHigh = (id0<<5)|CAN_ID_STD;
Filter.FilterIdLow = (id1<<5)|CAN_ID_STD;
Filter.FilterMaskIdHigh = (mask0<<5)|CAN_ID_STD;
Filter.FilterMaskIdLow = (mask1<<5)|CAN_ID_STD;
Filter.FilterFIFOAssignment = CAN_FIFO0;
if(BUS_CAN_0 == bus) {Filter.FilterNumber = idx;}
#ifdef SYS_USE_CAN_1
else {Filter.FilterNumber = idx + DEV_CAN_BANK_NUMBER;}
#endif
Filter.FilterActivation = ENABLE;
Filter.BankNumber = DEV_CAN_BANK_NUMBER;
HAL_CAN_ConfigFilter(hwal_can_handler,&Filter);
return;
}
拓展帧过滤器配置
VOID Dev_Can_Chip_Filt_Ext_List(BUS_CAN_E bus,UCHAR idx,ULONG id0,ULONG id1)
{
CAN_FilterConfTypeDef Filter;
CAN_HandleTypeDef* hwal_can_handler = NULL;
hwal_can_handler = &HWAL_CAN_0;
Filter.FilterMode = CAN_FILTERMODE_IDLIST;
Filter.FilterScale = CAN_FILTERSCALE_32BIT;
Filter.FilterIdHigh = ((id0<<3)>>16)&0xffff;
Filter.FilterIdLow = ((id0<<3)&0xffff)|CAN_ID_EXT;
Filter.FilterMaskIdHigh = ((id1<<3)>>16)&0xffff;
Filter.FilterMaskIdLow = ((id1<<3)&0xffff)|CAN_ID_EXT;
Filter.FilterFIFOAssignment = CAN_FIFO0;
if(BUS_CAN_0 == bus) {Filter.FilterNumber = idx;}
#ifdef SYS_USE_CAN_1
else {Filter.FilterNumber = idx + DEV_CAN_BANK_NUMBER;}
#endif
Filter.FilterActivation = ENABLE;
Filter.BankNumber = DEV_CAN_BANK_NUMBER;
HAL_CAN_ConfigFilter(hwal_can_handler,&Filter);
return;
}
VOID Dev_Can_Chip_Filt_Ext_Mask(BUS_CAN_E bus,UCHAR idx,ULONG id0,ULONG mask0)
{
CAN_FilterConfTypeDef Filter;
CAN_HandleTypeDef* hwal_can_handler = NULL;
hwal_can_handler = &HWAL_CAN_0;
Filter.FilterMode = CAN_FILTERMODE_IDMASK;
Filter.FilterScale = CAN_FILTERSCALE_32BIT;
Filter.FilterIdHigh = ((id0<<3)>>16)&0xffff;
Filter.FilterIdLow = ((id0<<3)&0xffff)|CAN_ID_EXT;
Filter.FilterMaskIdHigh = ((mask0<<3)>>16)&0xffff;
Filter.FilterMaskIdLow = ((mask0<<3)&0xffff)|CAN_ID_EXT;
Filter.FilterFIFOAssignment = CAN_FIFO0;
if(BUS_CAN_0 == bus) {Filter.FilterNumber = idx;}
#ifdef SYS_USE_CAN_1
else {Filter.FilterNumber = idx + DEV_CAN_BANK_NUMBER;}
#endif
Filter.FilterActivation = ENABLE;
Filter.BankNumber = DEV_CAN_BANK_NUMBER;
HAL_CAN_ConfigFilter(hwal_can_handler,&Filter);
return;
}