完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
环境:
2、开启USB 3、开启USB设备:虚拟串口 4、生成工程 5、修改代码实现回环收发数据测试 在u***d_cdc_if.c文件中新定义一个结构体: USBD_CDC_LineCodingTypeDef USBD_CDC_LineCoding = { 115200, // 默认波特率 0X00, // 1位停止位 0X00, // 无奇偶校 0X08, // 无流控,8bit数据位 }; 找到CDC_Control_FS函数,找到CDC_SET_LINE_CODING和CDC_GET_LINE_CODING分支,添加以下代码: (CDC_SET_LINE_CODING:你在用串口助手选择波特率时候,STM32就会调用这个分支进行修改USB波特率) (CDC_GET_LINE_CODING:获取STM32的USB波特率) case CDC_SET_LINE_CODING: USBD_CDC_LineCoding.bitrate = (pbuf[3] << 24) | (pbuf[2] << 16) | (pbuf[1] << 8) | pbuf[0]; USBD_CDC_LineCoding.format = pbuf[4]; USBD_CDC_LineCoding.paritytype = pbuf[5]; USBD_CDC_LineCoding.datatype = pbuf[6]; break; case CDC_GET_LINE_CODING: pbuf[0] = (uint8_t)(USBD_CDC_LineCoding.bitrate); pbuf[1] = (uint8_t)(USBD_CDC_LineCoding.bitrate >> 8); pbuf[2] = (uint8_t)(USBD_CDC_LineCoding.bitrate >> 16); pbuf[3] = (uint8_t)(USBD_CDC_LineCoding.bitrate >> 24); pbuf[4] = USBD_CDC_LineCoding.format; pbuf[5] = USBD_CDC_LineCoding.paritytype; pbuf[6] = USBD_CDC_LineCoding.datatype; break; 如下图所示: 找到CDC_Receive_FS函数,这个函数如果USB虚拟串口数据收到就会被调用,我们在这个函数中将收到的数据在发回去,只需要添加CDC_Transmit_FS(Buf, *Len);这一句即可,如下图: 然后编译工程并下载,接上USB之后,设备管理器COM出现一个新的端口: 我们使用串口调试助手给它发数据: 6、实现USB转串口功能 发数据流程:串口调试助手发送数据->STM32的USB数据接收->STM32转发到串口3 收数据流程:STM32的串口3收到数据->转发到USB->STM32的USB发送到串口调试助手 第一步先在这里加入串口3的初始化操作: 贴一下串口3的初始化代码,这里我用到了队列,因为实际测试发现串口3接收数据量比较大的话,那么转发到USB虚拟串口的时候会丢数据,所以这里采用了缓存队列,当串口接收到的数据到达一定数据量之后才做一次转发到USB的操作,并且开启了空闲中断,作用是转发最后一包数据: 关于队列的使用可以查看我的另一篇博客:C/C++语言实现的一个缓存队列 /* * myusart.c * * Created on: Mar 22, 2021 * Author: hello */ #include "myusart.h" #include "myqueue.h" // 队列大小,定义为USB_CDC的发送包大小 #define QUEUE_SIZE APP_TX_DATA_SIZE // 队列数据空间。请使用宏QALIGN4,目的是为了根据队列大小计算实际需要的队列存储空间大小并对齐4字节 uint8_t QueueBuffer[QALIGN4(QUEUE_SIZE)]; // 队列句柄 Queue Uart3QueueHandle = {0}; #define UART3_QUEUE_Handle (&Uart3QueueHandle) // 串口转发到USB的缓冲,定义为USB包的一半大小 static uint8_t buffer[APP_RX_DATA_SIZE >> 1]; void UART3_Init(const USBD_CDC_LineCodingTypeDef *USBD_CDC_LineCoding) { __HAL_UART_DISABLE_IT(&huart3, UART_IT_RXNE); __HAL_UART_DISABLE_IT(&huart3, UART_IT_IDLE); HAL_UART_DeInit(&huart3); huart3.Instance = USART3; huart3.Init.BaudRate = USBD_CDC_LineCoding->bitrate; huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart3.Init.Mode = UART_MODE_TX_RX; huart3.Init.OverSampling = UART_OVERSAMPLING_16; switch (USBD_CDC_LineCoding->paritytype) { case 0: huart3.Init.Parity = UART_PARITY_NONE; break; case 1: huart3.Init.Parity = UART_PARITY_ODD; break; case 2: huart3.Init.Parity = UART_PARITY_EVEN; break; default: huart3.Init.Parity = UART_PARITY_NONE; break; } switch (USBD_CDC_LineCoding->datatype) { case 0x07: huart3.Init.WordLength = UART_WORDLENGTH_8B; break; case 0x08: if (huart3.Init.Parity == UART_PARITY_NONE) { huart3.Init.WordLength = UART_WORDLENGTH_8B; } else { huart3.Init.WordLength = UART_WORDLENGTH_9B; } break; default: huart3.Init.WordLength = UART_WORDLENGTH_8B; break; } switch (USBD_CDC_LineCoding->format) { case 0: huart3.Init.StopBits = UART_STOPBITS_1; break; case 2: huart3.Init.StopBits = UART_STOPBITS_2; break; default: huart3.Init.StopBits = UART_STOPBITS_1; break; } HAL_UART_Init(&huart3); Queue_Init(UART3_QUEUE_Handle, QUEUE_SIZE, QueueBuffer); __HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE); __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE); } void USART3_IRQHandler(void) { static uint32_t nsent = 0; static uint8_t dat = 0; if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE) != RESET) { __HAL_UART_CLEAR_FLAG(&huart3, UART_FLAG_RXNE); dat = huart3.Instance->DR & 0XFF; Queue_PutByte(UART3_QUEUE_Handle, dat); // 入队一个字节的数据 if (Queue_GetUsed(UART3_QUEUE_Handle) >= sizeof(buffer)) { Queue_Read(UART3_QUEUE_Handle, buffer, sizeof(buffer)); CDC_Transmit_FS(buffer, sizeof(buffer)); // 转发到USB } } if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE) != RESET) { nsent = Queue_GetUsed(UART3_QUEUE_Handle); if (nsent != 0) { Queue_Read(UART3_QUEUE_Handle, buffer, nsent); CDC_Transmit_FS(buffer, nsent); // 转发到USB } __HAL_UART_CLEAR_IDLEFLAG(&huart3); } } void UART3_SendData(const void *buf, uint32_t len) { const uint8_t *p = (const uint8_t*) buf; while (len--) { while (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_TXE) != SET); huart3.Instance->DR = (uint8_t) (*p++ & 0XFF); while (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_TC) != SET); } } //#ifdef __GNUC__ //#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) //#else //#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) //#endif //PUTCHAR_PROTOTYPE //{ // while (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_TXE) != SET); // huart3.Instance->DR = (uint8_t) (ch & 0XFF); // while (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_TC) != SET); // return ch; //} 然后在添加USB转发到串口的操作: 这样就实现了一个类似于USB转TTL模块的功能! ends… |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1621 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1546 浏览 1 评论
980 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
686 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1599 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
650浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
536浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 05:13 , Processed in 0.885015 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号