stm32 cdc uart 透传程序
时间: 2023-12-22 21:03:02 浏览: 137
下面是基于STM32的CDC(USB虚拟串口)和UART的透传程序示例,供你参考:
```c
#include "main.h"
#include "usb_device.h"
UART_HandleTypeDef huart1;
uint8_t usbRxBuffer[64];
uint8_t uartRxBuffer[64];
uint8_t uartTxBuffer[64];
int uartRxIndex = 0;
int uartTxIndex = 0;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MX_USART1_UART_Init();
while (1)
{
// USB RX -> UART TX
if (cdc_rx_ready && uartTxIndex == 0)
{
cdc_rx_ready = 0;
memcpy(uartTxBuffer, usbRxBuffer, 64);
HAL_UART_Transmit_IT(&huart1, uartTxBuffer, 64);
uartTxIndex = 64;
}
// UART RX -> USB TX
if (uartRxIndex > 0)
{
CDC_Transmit_FS(uartRxBuffer, uartRxIndex);
uartRxIndex = 0;
HAL_UART_Receive_IT(&huart1, uartRxBuffer, 64);
}
// UART TX
if (uartTxIndex > 0)
{
HAL_UART_Transmit_IT(&huart1, uartTxBuffer, uartTxIndex);
uartTxIndex = 0;
}
HAL_Delay(1);
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
uartRxIndex = 64 - huart->RxXferCount;
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
uartTxIndex = 0;
}
}
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
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;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
HAL_UART_Receive_IT(&huart1, uartRxBuffer, 64);
}
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
void SysTick_Handler(void)
{
HAL_IncTick();
}
void USB_LP_CAN1_RX0_IRQHandler(void)
{
HAL_PCD_IRQHandler(&hpcd_USB_FS);
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
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_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
```
在上面的程序中,我们使用了STM32的HAL库来初始化USB和UART,并使用`HAL_Delay`函数在主循环中实现了简单的轮询,从而实现了USB和UART的透传。在每个UART接收中断中,我们将接收到的数据复制到缓冲区,以便稍后传输到USB。在每个UART发送中断中,我们将`uartTxIndex`设置为0,以便在下一次USB传输时将新的数据传输到UART。
请注意,在上面的示例中,我们使用了`HAL_UART_Transmit_IT`函数和`HAL_UART_Receive_IT`函数来启用UART的中断传输。您也可以使用阻塞传输(`HAL_UART_Transmit`和`HAL_UART_Receive`),但这可能会阻塞主线程,导致USB传输失败。
希望这个示例对你有帮助!
阅读全文