STM32 CAN回送模式

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

我正在开始将HAL驱动程序用于STM32F103xx MCU中CAN外设的环回模式的基本用法。根据MCU的用户手册,当完全完成传输并且数据在CAN总线中可用时,硬件会设置CAN_TSR寄存器的TME,RQCP和TXOK位,表明相应的邮箱已变空,并且传输成功完成。

当我调试以下程序时,CAN_TSR寄存器中未发生任何提及的更改。我只能看到TME位被置位,这意味着提供了一个邮箱用于发送,但从未发送过。

我的这段代码在程序中导致不定式循环:

while(HAL_CAN_IsTxMessagePending(&hcan, TxMailbox));

[能否请您解释一下我的问题和应该怎么做。感谢您的想法。

这是完整代码:

#include "main.h"
CAN_HandleTypeDef hcan;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);

/* USER CODE BEGIN PFP */
void Can_TX(void);
/* USER CODE END PFP */

int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();

  /* USER CODE BEGIN 2 */
  LCD1602_Begin4BIT(RS_GPIO_Port, RS_Pin, E_Pin, D4_GPIO_Port, D4_Pin, D5_Pin, D6_Pin, D7_Pin);
  LCD1602_print("Sending...");
  Can_TX();
  /* USER CODE END 2 */

  /* Infinite loop */
  while (1)
  {
    for (int i = 0; i <= 1000; i++);
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_CAN_Init(void)
{
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 1;
  hcan.Init.Mode = CAN_MODE_LOOPBACK;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  __HAL_RCC_GPIOA_CLK_ENABLE();
  HAL_GPIO_WritePin(GPIOA, RS_Pin|E_Pin|D4_Pin|D5_Pin|D6_Pin|D7_Pin, GPIO_PIN_RESET);
  GPIO_InitStruct.Pin = RS_Pin|E_Pin|D4_Pin|D5_Pin|D6_Pin|D7_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void Can_TX(void)
{
  CAN_TxHeaderTypeDef TxHeader;
  uint8_t our_message[5] = {'H','E','L','L','O'};
  uint32_t TxMailbox;
  TxHeader.DLC = 1;
  TxHeader.StdId = 0x65D;
  TxHeader.IDE = CAN_ID_STD;
  TxHeader.RTR = CAN_RTR_DATA;
  HAL_CAN_AddTxMessage(&hcan, &TxHeader, our_message, &TxMailbox);
  if(HAL_CAN_AddTxMessage(&hcan, &TxHeader, our_message, &TxMailbox) != HAL_OK)
  {
    Error_Handler();
  }
  while(HAL_CAN_IsTxMessagePending(&hcan, TxMailbox));
  LCD1602_print("Message is sent");
}

void Error_Handler(void) { }
c embedded stm32 can-bus hal
1个回答
0
投票
  • [...]当传输完全完成并且数据在CAN总线中可用时,硬件会设置CAN_TSR寄存器的TME,RQCP和TXOK位,表明相应的邮箱已空并且传输成功完成。

    当我调试以下程序时,CAN_TSR寄存器中没有发生任何提及的更改。

    STM32F103xx的CAN外设(“ bxCAN”)包含三个TX FIFO。因此,有( TMEx, RQCPx, TXOKx )的三个实例要检查-只是为了确保。

  • 我只能看到TME位置1,这意味着已提供一个邮箱用于发送,但从未发送过。

    在CAN_TSR中对TME位的解释中似乎有一个错误:正如您可以在几秒钟内完成验证。的24.9.2(第677-8页)STM32F103 reference manual,TME位<。因此,如果找到那些set位,则传输似乎已经结束。

  • 如果传输仍处于挂起状态,则可能是由于错误情况导致卡住。寄存器CAN_ESR中的错误计数器(REC / TEC)呢?

    如果没有接收器在监听,则CAN发射器将进入错误模式,因为接收器的确认位未到达发射器。该代码示例未显示CAN引脚的任何enable-GPIO指令。在环回模式下应该可以,但是我从来没有尝试过。

  • 传输可能正在等待中,因为bxCAN组件仍保持其

    初始化模式

  • ,请参见sec。参考手册中的24.4.1(第657页)。然后,软件必须触发转换为普通模式。我不确定HAL_CAN_Init()是否包含此内容。
  • 变量TxMailbox从未在用户代码中初始化。如果由功能HAL_CAN_AddTxMessage()分配,则可以。如果不是,HAL_CAN_IsTxMessagePending()将在错误的邮箱地址上轮询(也许永远)。
© www.soinside.com 2019 - 2024. All rights reserved.