STM32F091 CAN 不传输(另外,示例使用了不存在的功能???)

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

我有一块 STM32F091RCT 板,我试图将其强制用作临时 CAN 节点。为了有一个起点,我查找了一些代码示例。我从 this one 开始,但它引用了一些 typedef(例如

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 总线传输一条消息。不幸的是,情况似乎并非如此,因为连接到 CAN_TX 引脚的示波器(也尝试过 RX 进行了良好的测量)仅在执行

MX_CAN_Init()
时显示电压从 0 V 上升到 3.3 V。为了澄清起见,我正在测量直接从 MCU 发出的信号,收发器 (MCP2551) 之前。

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

can-bus stm32f0
1个回答
0
投票

虽然有点晚了,但我找到了 CAN_MCR->DBF 标志。默认情况下设置为 1,定义如下:

位 16 DBF:调试冻结 0:调试时CAN工作 1:调试期间 CAN 接收/发送冻结。接收 FIFO 仍然可以正常访问/控制。

因此,如果您运行调试器,则 CAN 总线将失效。当你不知道的时候很烦人...

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