1.CAN引脚:
直接根据芯片和原理图在CubeMX设置就好了
2.设置CAN波特率:
// CAN波特率 = CAN时钟频率 / Prescaler / (TimeSeg1 + TimeSeg2 + 1)
// 例: 500kbps = 36MHz / 9 / (3 + 4 + 1) 36MHz为该例程APB1的总线时钟
3.时钟使能:
__HAL_RCC_CAN1_CLK_ENABLE();
(写两次两次忘记使能时钟)
4.中断使能:
不使能中断没有办法接收数据
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0); // CAN接收中断
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
__HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
5.过滤器设置:
这个是从别的博主那里找到的
void CAN_Config(void)
{
CAN_FilterTypeDef sFilterConfig;
/* Configure the CAN Filter */
sFilterConfig.FilterBank = 0; // 过滤器编号,使用一个CAN,则可选0-13;使用两个CAN可选0-27
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 过滤器模式,掩码模式或列表模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 过滤器位宽
sFilterConfig.FilterIdHigh = 0x0000; // 过滤器验证码ID高16位,0-0xFFFF
sFilterConfig.FilterIdLow = 0x0000; // 过滤器验证码ID低16位,0-0xFFFF
sFilterConfig.FilterMaskIdHigh = 0x0000; // 过滤器掩码ID高16位,0-0xFFFF
sFilterConfig.FilterMaskIdLow = 0x0000; // 过滤器掩码ID低16位,0-0xFFFF
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // FIFOx,0或1
sFilterConfig.FilterActivation = ENABLE; // 使能过滤器
sFilterConfig.SlaveStartFilterBank = 14; // 从过滤器编号,0-27,对于单CAN实例该参数没有意义
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
/* Start the CAN peripheral */
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
/* Start Error */
Error_Handler();
}
/* Activate CAN RX notification */
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
}
6.接收回调函数:
HAL_CAN_RxFifo0MsgPendingCallback(&hcan1);
HAL库自带的函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{// 收到CAN数据会触发接收中断,进入该回调函数
uint32_t i;
uint8_t RxData[8];
CAN_RxHeaderTypeDef CAN_RxHeader; //这个结构体也是HAL 库自带的
if(hcan == &hcan1)
{
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &CAN_RxHeader, RxData) == HAL_OK)
{//用串口打印接收到的数据
for(i = 0;i < CAN_RxHeader.DLC; i++)
{
printf("%02x ", RxData[i]);
}
}
}
}
自己记录自己学