测试单片机是STM32F427ZGT6,CAN外设的主频是45MHz
Can外设配置
- TTCM(Time triggered communication mode)时间触发模式,用于生成时间戳,可以实现分时同步功能
- ABOM(Automatic bus-off management) 自动离线管理,当节点检测到它发送错误或接收错误超过一定值时,会自动进入离线状态
- AWUM(Automatic bus-off management),自动唤醒功能,CAN 外设可以使用软件进入低功耗的睡眠模式,如果使能了这个自动唤醒功能,当 CAN 检测到总线活动的时候,会自动唤醒
- NART(No automatic retransmission)报文自动重传功能,设置这个功能后,当报文发送失败时会自动重传至成功为止
- RFLM(Receive FIFO locked mode)FIFO 锁定模式,该功能用于锁定接收 FIFO。锁定后,当接收 FIFO 溢出时,会丢弃下一个接收的报文。若不锁定,则下一个接收到的报文会覆盖原报文
- TXFP(Transmit FIFO priority)报文发送优先级的判定方法,ID 优先级还是报文存进邮箱的顺序来发送
使能接收中断
CAN外设使用步骤: 1. 配置CAN总线设备(以上2步,配置分频,配置QS1,QS2) 2. 在主程序内打开CAN设备, 3. 配置过滤器 4. 使能中断 5. 实现中断回调函数
CAN_RxHeaderTypeDef rxheadr;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
if(hcan==&hcan1)
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rxheadr, rx_can_data);
else
HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO0, &rxheadr, rx_can_data);
}
static void LEDTaskFunction( void * param)
{
CAN_TxHeaderTypeDef header={
.StdId = 1,
.ExtId=0,
.IDE = CAN_ID_STD,
.RTR = CAN_RTR_DATA,
.DLC=8
};
xsem = xSemaphoreCreateBinary();
if(xsem!=NULL)
{
hb_printf("create sem binary ok\r\n");
}
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
uint32_t id1=1;
uint32_t tmp = (id1<<21)|CAN_ID_STD|CAN_RTR_DATA;
sFilterConfig.FilterIdHigh = (tmp&0xffff0000)>>16;
sFilterConfig.FilterIdLow = tmp&0xffff;
uint32_t id2=2;
tmp = (id2<<21)|CAN_ID_STD|CAN_RTR_DATA;
sFilterConfig.FilterMaskIdHigh =(tmp&0xffff0000)>>16;
sFilterConfig.FilterMaskIdLow =tmp&0xffff;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0 ;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 0;
HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig);
HAL_CAN_Start(&hcan1);
HAL_CAN_Start(&hcan2);
HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO0_MSG_PENDING);
数据发送的方法
- 配置好cubemx参数主要是波特率
- 打开CAN外设
- 构建一个发送结构体
- 使用发送
CAN_TxHeaderTypeDef header={
.StdId = 1,
.ExtId=0,
.IDE = CAN_ID_STD,
.RTR = CAN_RTR_DATA,
.DLC=8
};
HAL_CAN_Start(&hcan1);
HAL_CAN_AddTxMessage(&hcan1, &header, "12345678", (uint32_t *) CAN_TX_MAILBOX0);
数据过滤器的设置方式
每组筛选器包含 2 个 32 位的寄存器,分别为 CAN_FxR1 和 CAN_FxR2,它们用来存储要筛选的 ID 或掩码 下面以32位筛选器标准帧为例: CAN_FxR1[31-22]位是标准数据帧的id设置位合计11bit CAN_FxR1[1] 是设置遥控帧还是数据帧 CAN_FxR1[2] 是设置标准帧还是扩展ID帧,此处设置为标准帧
示例代码设置标识符模式的标注帧 的ID 设置方法(32位列表模式)
uint32_t id1=1;
uint32_t tmp = (id1<<21)|CAN_ID_STD|CAN_RTR_DATA;
sFilterConfig.FilterIdHigh = (tmp&0xffff0000)>>16;
sFilterConfig.FilterIdLow = tmp&0xffff;
uint32_t id2=2;
tmp = (id2<<21)|CAN_ID_STD|CAN_RTR_DATA;
sFilterConfig.FilterMaskIdHigh =(tmp&0xffff0000)>>16;
sFilterConfig.FilterMaskIdLow =tmp&0xffff;
示例2: 仅仅接收ID是奇数的数据(32位掩码模式)
接收所有数据
4种过滤模式的详细描述图
|