STM32 CUBEMX生成CAN,双机互联

使用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中加入:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值