繁体   English   中英

c++中的STM32 uart回调

[英]STM32 uart callback in c++

也许这是一个愚蠢的问题,但我正在为 stm32 移植 c++ 中的 c 代码。 在 c 中,我使用此指令来检测 uart 通道上的中断:

HAL_UART_RegisterCallback(&huart1, HAL_UART_RX_COMPLETE_CB_ID, uart_callback);

现在,在 c++ 中,我想创建一个 class 来处理此信息并在 class 中声明uart_callback 我想知道这是否可能,因为我每次都会遇到错误,而且我不想在 main.js 中创建一个 rx_buffer。

编辑:这是 uart conf:

static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
  HAL_UART_RegisterCallback(&huart1, HAL_UART_RX_COMPLETE_CB_ID, Serial_com::uart_callback);
  /* USER CODE END USART1_Init 2 */

}

这是 hpp 文件:

class Serial_com {

    private:

        uint8_t end_of_packet;
        uint8_t led_time_sec;
        uint8_t led_time_csec;
        uint8_t address;
        uint16_t rx_length;
        uint16_t tx_bytes;

    public:

        uint8_t rx_serial_buffer[RX_BUFFER_LENGTH];
        uint8_t tx_serial_buffer[TX_BUFFER_LENGTH];
        uint16_t led_time;

        UART_HandleTypeDef* huart;

        Serial_com(UART_HandleTypeDef* huart);
        static void uart_callback();
        void send_data();
        void data_received();
        void reset();
};

和 function 不起作用:

static void Serial_com::uart_callback(){
    if(rx_serial_buffer[0] == 0){
        HAL_UART_Receive_IT(huart, &rx_serial_buffer[rx_length], 1);
    }
    else if(rx_serial_buffer[rx_length] == 35){
        end_of_packet = 1;
    }
    else if(rx_length < RX_BUFFER_LENGTH){
        rx_length++;
        HAL_UART_Receive_IT(huart, &rx_serial_buffer[rx_length], 1);
    }
}

A static method put very simply is very similar to a simple C function but it is inside the namespace of the class (of course there are other differences as well).

再次使用非 static 方法,简单地说就是“绑定”到在堆栈或堆上创建的 class 的特定实例。

您不能从 static 方法引用实例变量/方法,因为 static 方法不知道其 class 的实例。 它无法知道您指的是哪个“this”。

您将不可避免地不得不将串行设备本身的“全局”特性与您的 class 的一个或多个实例拼凑起来。

go 的一种方法是在 class 中制作几乎所有 static(缓冲区、长度等)。 然而,这有点违背了首先拥有带有实例的 class 的目的。

go 的另一种方法是将实例放在“全局范围”中的某个位置(它可以在命名空间中,但最终它必须可以从 static 上下文访问)并让您的 ZA81259CEF8E959C624DF1D456E 回调方法在该特定实例上工作。

这里的关键困难是您试图使用您不熟悉的语言机制来解决问题。

示例(对此有很多变化。这是许多可能性之一):

Serial_com* globalInstance = nullptr; //Set this in the constructor of Serial_com. eg globalInstance = this;

然后你可以像这样修改 static function :

void Serial_com::uart_callback(){
    if(globalInstance->rx_serial_buffer[0] == 0){
        HAL_UART_Receive_IT(huart, &(globalInstance->rx_serial_buffer[globalInstance->rx_length]), 1);
    }
    else if(globalInstance->rx_serial_buffer[globalInstance->rx_length] == 35){
        globalInstance->end_of_packet = 1;
    }
    else if(globalInstance->rx_length < RX_BUFFER_LENGTH){
        globalInstance->rx_length++;
        HAL_UART_Receive_IT(huart, &(globalInstance->rx_serial_buffer[globalInstance->rx_length]), 1);
    }
}

当然不会称之为优雅,但你可以从它开始。

但是,如果没有对 C++、实例、static 等的深入了解……这可能对您帮助不大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM