0

我有一块 STM32F091RCT 板,我正试图强迫它充当临时 CAN 节点。为了有个起点,我查阅了一些代码示例。我从这个开始,但它引用了一些类型定义(例如CanTxMsgTypeDef)和函数(HAL_CAN_Transmit例如),它们似乎不存在于stm32f0xx_hal_can.h标题中。因此,我选择了一个用于 F103 的示例,最后得到了这段代码(自动生成的注释和与 CAN 无关的东西被删除):

CAN_HandleTypeDef hcan;

// other peripheral configuration, etc.

static void MX_CAN_Init(void)
{

  hcan.Instance = CAN;
  hcan.Init.Prescaler = 16;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;      // also tried normal mode, same deal
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;


  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }

  CAN_FilterTypeDef sf;
    sf.FilterMaskIdHigh = 0x0000;
    sf.FilterMaskIdLow = 0x0000;
    sf.FilterFIFOAssignment = CAN_FILTER_FIFO0;
    sf.FilterBank = 0;
    sf.FilterMode = CAN_FILTERMODE_IDMASK;
    sf.FilterScale = CAN_FILTERSCALE_32BIT;
    sf.FilterActivation = CAN_FILTER_ENABLE;
    if (HAL_CAN_ConfigFilter(&hcan, &sf) != HAL_OK) {
      Error_Handler();

    }

    if (HAL_CAN_ConfigFilter(&hcan, &sf) != HAL_OK)
        Error_Handler();

//           this didn't want to work
//    if (HAL_CAN_RegisterCallback(&hcan, HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID, can_irq)) {
//      Error_Handler();
//    }

    if (HAL_CAN_Start(&hcan) != HAL_OK) {
      Error_Handler();
    }

    if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
      Error_Handler();
    }

}

void can_irq(CAN_HandleTypeDef *pcan) {
  CAN_RxHeaderTypeDef msg;
  uint8_t data[8];
  HAL_CAN_GetRxMessage(pcan, CAN_RX_FIFO0, &msg, data);
  // do something
}

// ...

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();
  MX_TIM1_Init();
  MX_CAN_Init();

  while (1)
  {
        uint32_t mb;
        CAN_TxHeaderTypeDef msg;
        uint8_t data[] = "Hello!";

        msg.StdId = 127;
        msg.IDE = CAN_ID_STD;
        msg.RTR = CAN_RTR_DATA;
        msg.DLC = 6;
        msg.TransmitGlobalTime = DISABLE;

        if (HAL_CAN_AddTxMessage(&hcan, &msg, data, &mb) != HAL_OK) {
          Error_Handler();
        }
  }
}

void send_CAN_test_message(void)
{
    uint32_t mb;
    CAN_TxHeaderTypeDef msg;
    uint8_t data[] = "Hello!";

    msg.StdId = 127;
    msg.IDE = CAN_ID_STD;
    msg.RTR = CAN_RTR_DATA;
    msg.DLC = 6;
    msg.TransmitGlobalTime = DISABLE;

    if (HAL_CAN_AddTxMessage(&hcan, &msg, data, &mb) != HAL_OK) {
      Error_Handler();
    }
}

所以我希望这会在主循环的每次迭代中通过 CAN 总线传输一条消息。MX_CAN_Init()不幸的是,情况似乎并非如此,因为连接到 CAN_TX 引脚的示波器(也尝试使用 RX 进行良好测量)仅显示执行时电压从 0 V 上升到 3.3 V。为了澄清起见,我在收发器 (MCP2551)之前直接测量来自 MCU 的信号。

我怀疑我在这里遗漏了一些非常明显的东西......有人会碰巧知道那个非常明显的东西是什么吗?也许是控制器引脚上的伪冲突(TX 和 RX 之间的差异),而控制器只是无限期地等待它?

4

0 回答 0