STM32F446 的 CAN 传输完成中断未触发:(

问题描述 投票:0回答:1

我正在使用 STM32F446RE 板的 CAN 模块,该板具有标题中提到的 MCU。我正在尝试通过 Tera Term 终端在 UART 上传输一些数据,并获取该数据并通过环回模式发送并读回。对于初学者来说,我已经从 CubeMx 生成了配置,并编写了一些代码来传输用户输入到 can“网络”的数值,当发生这种情况时,我想进入一个可以完成的传输 ISR 并在 UART 上打印一些消息那里表明转移已完成。

在 CubeMx 中,我像这样配置了 CAN 中断:

CAN1 TX 中断使能

CAN1 RX 中断已启用(因为修复此问题后我也想触发接收中断)

这是代码的一部分(我无法全部复制粘贴,因为这篇文章会变得太长,只需询问我是否需要提供更多代码):

while (1)
  {
      /*keep getting what the user enters on the UART untill enter is pressed*/
      while(received_data != '\r')
      {
          HAL_UART_Receive(&huart2,&received_data,1,HAL_MAX_DELAY);
          recvd_buffer[buf_indx] = received_data;
          buf_indx++;
          if(buf_indx > 1)
          {
              buf_indx = 0;
          }
      }

      if( recvd_buffer[0] == '1' || recvd_buffer[0] == '0')
      {
          received_data = 0;
          buf_indx = 0;

          user_data = "\n\rOK. Starting CAN transmission in interrupt mode\n\r";
          len_of_data = strlen(user_data);
          HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
          //CAN will start sending data in non-blocking mode
          CAN_Tx(recvd_buffer[0]);
          recvd_buffer[0] = 0;
          recvd_buffer[1] = 1;
      }
      else
      {
          recvd_buffer[0] = 0;
          recvd_buffer[1] = 1;
          received_data = 0;
          user_data = "\n\rInvalid value. Please enter either 1 or 2\n\r";
          len_of_data = strlen(user_data);
          HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
      }
  }
}

下面我也实现了3个Tx邮箱发送完成回调函数:

void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
{
    uint16_t user_data = "\n\rTransmission completed mailbox_0\n\r";
    uint16_t len_of_data = strlen(user_data);
    HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
}

void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
{
    user_data = "\n\rTransmission completed mailbox_1\n\r";
    uint16_t len_of_data = strlen(user_data);
    HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
}

void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
{
    user_data = "\n\rTransmission completed mailbox_2\n\r";
    uint16_t len_of_data = strlen(user_data);
    HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
}

这是利用 CAN hal 驱动程序发送数据的 CAN_Tx 函数:

void CAN_Tx(uint8_t value)
{
  uint8_t mailbox_no;
  CAN_TxHeaderTypeDef can_header;
  can_header.StdId = 0;
  can_header.ExtId = 0;
  can_header.IDE = CAN_ID_STD;
  can_header.RTR = CAN_RTR_DATA;
  can_header.DLC = 1;
  can_header.TransmitGlobalTime = DISABLE;
  HAL_CAN_AddTxMessage(&hcan1, &can_header, value, &mailbox_no);
}

我已经调试了 main 中的代码,看起来工作正常。我在 Can_Tx 函数中没有收到错误,它成功返回。根据我对微控制器数据表(第 30.8 节 - bxCAN 中断)的理解,如果启用了定时器 1 传输中断,则应执行其中一个回调,具体取决于哪个邮箱用于传输。然而,这种情况不会发生,其中的代码将不会被执行。请帮助我理解我做错了什么。谢谢!

stm32 can-bus
1个回答
0
投票

我认为 Cube 在初始化 CAN 时存在错误。要激活 Tx 中断,必须在 CAN_IER 寄存器中设置 TMEIE 位,但尽管在 CUBE 中设置了中断,该位的值仍为 0。我在代码中的 CAN 初始化期间手动设置了它,然后 Tx 中断工作。

© www.soinside.com 2019 - 2024. All rights reserved.