使用STM32 CUBEMX生成CAN,设置SYS


STM32F103c8t6的APB1时钟频率为36MHZ,
CAN的波特率=36/分频系数/(BS1+BS2+同步时间段)=36/9/8
=500KHZ


开启CAN中断

打开串口


生成代码

在生成的代码can.c中加入如下代码:
/* USER CODE BEGIN 1 */
/**
* @brief CAN过滤器配置函数
* @note 配置过滤器组0,接收所有标准ID报文
* @retval None
*/
void CANFilter_Config(void)
{
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0; // 过滤器组0(STM32F1xx过滤器组0-13)
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 掩码模式(接收符合ID掩码的报文)
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位过滤器
sFilterConfig.FilterIdHigh =(0x222 << 5) & 0xFFFF; // 32位标准ID高16位(无扩展ID时置0)
sFilterConfig.FilterIdLow = 0x0000; // 32位标准ID低16位(接收所有标准ID)
// 掩码配置:11位标准ID全匹配(0x7FF是11位全1),IDE位匹配(0)
sFilterConfig.FilterMaskIdHigh = (0x7FF << 5) & 0xFFFF;
sFilterConfig.FilterMaskIdLow = 0x0000; // 扩展ID掩码置0
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 匹配报文存入FIFO0
sFilterConfig.FilterActivation = ENABLE; // 启用过滤器
sFilterConfig.SlaveStartFilterBank = 14; // 从机过滤器起始组(F1xx无从机,填14即可)
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief CAN接收FIFO0中断回调函数
* @note 接收FIFO0有报文时触发,解析并打印报文
* @param hcan: CAN句柄
* @retval None
*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan_ptr) // 重命名形参,避免与全局hcan冲突
{
uint8_t data[8] = {0};
HAL_StatusTypeDef status;
// 确认是CAN1的中断(形参重命名为hcan_ptr,避免和全局hcan重复)
if (hcan_ptr->Instance == CAN1)
{
status = HAL_CAN_GetRxMessage(hcan_ptr, CAN_RX_FIFO0, &RxMessage, data);
if (HAL_OK == status)
{
printf("--->CAN Data Receive!\r\n");
printf("Std ID: 0x%03X\r\n", (uint16_t)RxMessage.StdId); // 标准ID打印(3位16进制)
printf("Data[0]: 0x%02X\r\n", data[0]);
printf("Data[1]: 0x%02X\r\n", data[1]);
printf("Data[2]: 0x%02X\r\n", data[2]);
printf("Data[3]: 0x%02X\r\n", data[3]);
printf("<---\r\n");
}
}
}
/**
* @brief CAN发送测试函数
* @note 发送标准ID=0x111,数据长度4字节的报文
* @retval None
*/
void CAN1_Send_Test(void)
{
uint32_t TxMailbox;
uint8_t data[4] = {0x01, 0x02, 0x03, 0x04};
TxMessage.IDE = CAN_ID_STD; // 标准ID格式
TxMessage.StdId = 0x111; // 标准ID=0x111
TxMessage.RTR = CAN_RTR_DATA; // 数据帧(非远程帧)
TxMessage.DLC = 4; // 数据长度4字节
TxMessage.TransmitGlobalTime = DISABLE; // 禁用时间戳
if (HAL_CAN_AddTxMessage(&hcan, &TxMessage, data, &TxMailbox) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief CAN启动初始化函数
* @note 启动CAN外设并使能接收中断
* @retval None
*/
void CAN_Start_Init(void)
{
// 启动CAN外设
if (HAL_CAN_Start(&hcan) != HAL_OK)
{
Error_Handler();
}
// 使能FIFO0接收中断
if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE END 1 */
单片机1中设置ID为0x222:

单片机1发送数据到ID设置为0x111:

单片机2中设置ID为0x111:

单片机2发送数据到ID设置为0x222:

掩码都统一改为0x7ff

如果需要本机调试(自收自发)掩码全改为0x0000,并且hcan.Init.Mode =CAN_MODE_LOOPBACK改为回环模式


调试正常后改回:

最后在main.c中加入:

5891

被折叠的 条评论
为什么被折叠?



