正常创建一个工程之后对于can的配置
设置波特率为500k
打开中断,发送中断根据需求可用可不用,接收中断必须使能。
此处要添加使能can
can数据发送
参数分别是发送ID,长度和数据
void MyCAN_Transmit(uint32_t ID, uint8_t Length, uint8_t *Data)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailbox;
// 配置发送帧头
TxHeader.StdId = ID;
TxHeader.ExtId = ID;
TxHeader.IDE = CAN_ID_STD; // 标准帧
TxHeader.RTR = CAN_RTR_DATA; // 数据帧
TxHeader.DLC = Length;
TxHeader.TransmitGlobalTime = DISABLE;
// 发送数据并等待完成
if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, Data, &TxMailbox) != HAL_OK)
return;
// 等待发送完成或超时
uint32_t Timeout = 0;
while (HAL_CAN_IsTxMessagePending(&hcan1, TxMailbox))
{
if (++Timeout > 100000)
break;
}
}
在循环里进行发送
此时连接好线路之后 电脑上的can调试助手就可以接收到发送的数据了
接线示意图
can数据接收
中断回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{// 收到CAN数据会触发接收中断,进入该回调函数
uint32_t i;
uint8_t RxData[8];
CAN_RxHeaderTypeDef CAN_RxHeader;
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &CAN_RxHeader, RxData) == HAL_OK)
{
// 把接收的数据用CAN再发回去
MyCAN_Transmit(0x345,8,RxData);
}
}
并且要在主函数里打开接收中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
此时就可以使用电脑给STM32发送数据,STM32回将这个数据回发给电脑
过滤器
can的接收可以设置过滤器来进行筛选,根据参数的不同有不同的作用,需要详细了解可以查看相关的博客,这里只举例一种常用的方式
新建一个函数,设置过滤器的参数,并且在can初始化之后运行,即可进行过滤操作
目标id是你需要匹配的id 除了这个id以外其他id的数据不进行接收
我使用的STM32F407有两个can can1对应的过滤器有0-13 can对应的是14-27,每个can可以设置最多十四个过滤器
void CAN_Config(void)
{
CAN_FilterTypeDef filter0;
filter0.FilterBank = 0; // 使用第一个过滤器组
filter0.FilterMode = CAN_FILTERMODE_IDMASK; // 掩码模式
filter0.FilterScale = CAN_FILTERSCALE_32BIT;
filter0.FilterIdHigh = 0x123 << 5; // 目标ID(标准帧左移5位)
filter0.FilterMaskIdHigh = 0x7FF << 5; // 全匹配掩码
filter0.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filter0.FilterActivation = ENABLE;
CAN_FilterTypeDef filter1;
filter1.FilterBank = 1; // 使用第二个过滤器组
filter1.FilterMode = CAN_FILTERMODE_IDMASK;
filter1.FilterScale = CAN_FILTERSCALE_32BIT;
filter1.FilterIdHigh = 0x456 << 5; // 新ID配置
filter1.FilterMaskIdHigh = 0x7FF << 5;
filter1.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filter1.FilterActivation = ENABLE;
HAL_CAN_ConfigFilter(&hcan1, &filter0);
HAL_CAN_ConfigFilter(&hcan1, &filter1);
}
测试结果
首先使用id 111 122发送数据,都没有收到回复,id改为123发送之后,收到了STM32回复给我的数据,又使用id 345发送也是没有回复,再次使用id 456发送后收到了回复。与以上我设置的过滤器相匹配。