移植篇:CAN配置
硬件:STM32F407开发板,CAN调试器,ST—LINK调试器
#
使用CUBEMX创建工程#
选用外部高速晶振
#
配置时钟树HCLK一般为默认最高,CAN使用的是APB1外设时钟。选择时钟源,输入需要的频率按回车即可自动调整其他参数
#
配置CAN使能后需要根据波特率对参数进行调整,当然也可以在程序中修改。
上图中可见APB1为42MHz,经过下图中预分频之后 42/3 = 14MHz。
如果我们希望得到1MHz波特率,那只需满足Jumpwidth+seg1+seg2= 14MHz / 1MHz = 14即可,其他波特率以此类推,也可以使用代码块实现波特率的配置。
#if defined (SOC_SERIES_STM32F1)/* APB1 36MHz(max) */static const struct stm32_baud_rate_tab can_baud_rate_tab[] ={ {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 3)}, {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_5TQ | CAN_BS2_3TQ | 5)}, {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 6)}, {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 12)}, {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 24)}, {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 30)}, {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 60)}, {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 150)}, {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_3TQ | 300)}};#elif defined (SOC_SERIES_STM32F4)/* APB1 42MHz(max) */static const struct stm32_baud_rate_tab can_baud_rate_tab[] ={ {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 3)}, {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_4TQ | 4)}, {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 6)}, {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 12)}, {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 24)}, {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 30)}, {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 60)}, {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 150)}, {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 300)}};#elif defined (SOC_SERIES_STM32F7)/* APB1 54MHz(max) */static const struct stm32_baud_rate_tab can_baud_rate_tab[] ={ {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 3)}, {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_7TQ | 4)}, {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 6)}, {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 12)}, {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 24)}, {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 30)}, {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 60)}, {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 150)}, {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_10TQ | CAN_BS2_7TQ | 300)}};#endif
#
生成代码并运行试车cubemx生成的默认代码只有初始化can的代码,开启can以及发送接收函数均需要自己编写,这部分可参照*_hal_can.c中提供的接口,也可以从网上直接copy,以下来自正点原子
void CAN_Config(void){ CAN_FilterTypeDef sFilterConfig;
/*##-2- Configure the CAN Filter ###########################################*/ sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK) { /* Filter configuration Error */ while(1) { } }
/*##-3- Start the CAN peripheral ###########################################*/ if (HAL_CAN_Start(&hcan1) != HAL_OK) { /* Start Error */ while(1) { } }
/*##-4- Activate CAN RX notification #######################################*/ if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) { /* Notification Error */ while(1) { } }
/*##-5- Configure Transmission process #####################################*/ TxHeader.StdId = 0x321; TxHeader.ExtId = 0x01; TxHeader.RTR = CAN_RTR_DATA; TxHeader.IDE = CAN_ID_STD; TxHeader.DLC = 2; TxHeader.TransmitGlobalTime = DISABLE;}
u8 CAN1_Send_Msg(u8* msg,u8 len){ u8 i=0; u32 TxMailbox=0; u8 message[8]; TxHeader.StdId=0X12; // TxHeader.ExtId=0x12; // TxHeader.IDE=CAN_ID_STD; //使用标准帧 TxHeader.RTR=CAN_RTR_DATA; // TxHeader.DLC=len; for(i=0;i<len;i++) { message[i]=msg[i]; } if(HAL_CAN_AddTxMessage(&hcan1, &TxHeader, message, &TxMailbox) != HAL_OK)//·¢ËÍ { return 1; } while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3) {} return 0;}