STM32F407CAN中断接收

最近项目中用到CAN,想直接搬原子哥的代码,发现中断好像有些问题,另外网上的资源版本都很老,版本不同,本文采用最新版本()

注意事项:
CAN在配置接收得时候要配置滤波器,否则无法接收
频率配置:
由手册可知CAN挂载在APB1总线上,最高频率为42MHZ;
由此:

  • 预分频器值(hcan1.Init.Prescaler)设置为12
  • 时间段1(hcan1.Init.TimeSeg1)设置为7个时间单元。
  • 时间段2(hcan1.Init.TimeSeg2)设置为6个时间单元。

我们可以使用以下公式来计算CAN总线的波特率:

波特率 = CAN时钟频率 / ((时间段1 + 时间段2 + 1) × 预分频器)

假设STM32F407的CAN时钟频率为42 MHz,则波特率计算如下:

波特率 = 42 MHz / ((7 + 6 + 1) × 12) = 42 MHz / (14 × 12) = 42 MHz / 168 ≈ 250 kHz

因此,根据提供的参数,CAN总线的波特率约为250 kHz。请确保使用正确的CAN时钟频率进行准确的波特率计算。
以CAN1为例:
初始化并启动CAN:

void CAN1_Init(void)
{

      __HAL_RCC_CAN1_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
	CAN_FilterTypeDef sFilterConfig1;
	GPIO_InitTypeDef GPIO_InitStruct = {0};
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 12;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_7TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_6TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
	    /* 配置CAN过滤器 */
    sFilterConfig1.FilterBank = 0;                             /* 过滤器0 */
    sFilterConfig1.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig1.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig1.FilterIdHigh = 0x0000;                      /* 32位ID */
    sFilterConfig1.FilterIdLow = 0x0000;
    sFilterConfig1.FilterMaskIdHigh = 0x0000;                  /* 32位MASK */
    sFilterConfig1.FilterMaskIdLow = 0x0000;
    sFilterConfig1.FilterFIFOAssignment = CAN_FILTER_FIFO0;    /* 过滤器0关联到FIFO0 */
    sFilterConfig1.FilterActivation = CAN_FILTER_ENABLE;       /* 激活滤波器0 */
    sFilterConfig1.SlaveStartFilterBank = 14;
 /* 过滤器配置 */
    if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig1) != HAL_OK)
    {
        return ;
    }
        GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* USER CODE BEGIN CAN1_MspInit 1 */
	HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    	if(HAL_CAN_Start(&hcan1)!=HAL_OK)
	{
		Error_Handler();

	}
	if(HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接受邮箱0挂起中断
	{
		Error_Handler();
	}
}

中断函数:

extern uint8_t data[8];
extern CAN_RxHeaderTypeDef RXHeader; 	 // 接收消息的头部结构体
void CAN1_RX0_IRQHandler(void)
{
		HAL_CAN_GetRxMessage(&hcan1,CAN_FILTER_FIFO0,&RXHeader,data);//获取数据
		HAL_GPIO_TogglePin( GPIOG , GPIO_PIN_1);
	
}

封装发送函数:


// 发送CAN1标准数据帧
uint8_t CAN1_Send_Standard_Frame(uint32_t id, uint8_t *msg, uint8_t len)
{
    uint16_t t = 0;
    uint32_t TxMailbox;
    CAN_TxHeaderTypeDef can_tx_header;

    can_tx_header.StdId = id;          // 标准标识符
    can_tx_header.ExtId = 0;           // 扩展标识符(此处为标准帧,扩展标识符为0)
    can_tx_header.IDE = CAN_ID_STD;    // 使用标准帧
    can_tx_header.RTR = CAN_RTR_DATA;  // 数据帧
    can_tx_header.DLC = len;           // 数据长度

    if (HAL_CAN_AddTxMessage(&hcan1, &can_tx_header, msg, &TxMailbox) != HAL_OK)
    {
        // 发送失败,打印错误消息或采取其他适当的措施
        return 1;
    }

    // 等待发送完成,所有邮箱为空
    while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3)
    {
        t++;
        if (t > 0xFFF)
        {
            // 超时,直接中止邮箱的发送请求,采取适当的措施
            HAL_CAN_AbortTxRequest(&hcan1, TxMailbox);
            return 1;
        }
    }

    return 0; // 发送成功
}
// 发送CAN1扩展数据帧
uint8_t CAN1_Send_Extended_Frame(uint32_t id, uint8_t *msg, uint8_t len)
{
    uint16_t t = 0;
    uint32_t TxMailbox;
    CAN_TxHeaderTypeDef can_tx_header;

    can_tx_header.StdId = 0;           // 标准标识符(此处为扩展帧,标准标识符为0)
    can_tx_header.ExtId = id;          // 扩展标识符
    can_tx_header.IDE = CAN_ID_EXT;    // 使用扩展帧
    can_tx_header.RTR = CAN_RTR_DATA;  // 数据帧
    can_tx_header.DLC = len;           // 数据长度

    if (HAL_CAN_AddTxMessage(&hcan1, &can_tx_header, msg, &TxMailbox) != HAL_OK)
    {
        // 发送失败,打印错误消息或采取其他适当的措施
        return 1;
    }

    // 等待发送完成,所有邮箱为空
    while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3)
    {
        t++;
        if (t > 0xFFF)
        {
            // 超时,直接中止邮箱的发送请求,采取适当的措施
            HAL_CAN_AbortTxRequest(&hcan1, TxMailbox);
            return 1;
        }
    }

    return 0; // 发送成功
}

"如果你不去追逐自己的梦想,有一天你会被雇来帮助别人实现他们的梦想。" - 扖夫·乔布斯(Steve Jobs)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点灯大神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值