STM32自定义键盘(一)STM32单片机的USB-虚拟串口

时钟配置

本键盘用的主控芯片为STM32F103C8T6,12Mhz和32.768Khz的外部无源晶振。
在这里插入图片描述
系统主频72Mhz,USB时钟频率48Mhz。

USB接口配置

添加USB驱动代码
添加USB驱动代码。
在这里插入图片描述
USB_DEVICE配置为 Communication Device Class(虚拟串口)。

串口收发测试

串口发送

此时在“usbd_cdc_ic.c”文件的“static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)”函数中的“CDC_SET_LINE_CODING”和“CDC_GET_LINE_CODING”配置为空白,填写以下内容。

/**
  * @brief  Manage the CDC class requests
  * @param  cmd: Command code
  * @param  pbuf: Buffer containing command data (request parameters)
  * @param  length: Number of data to be sent (in bytes)
  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
{
  /* USER CODE BEGIN 5 */
  switch(cmd)
  {
    case CDC_SEND_ENCAPSULATED_COMMAND:

    break;

    case CDC_GET_ENCAPSULATED_RESPONSE:

    break;

    case CDC_SET_COMM_FEATURE:

    break;

    case CDC_GET_COMM_FEATURE:

    break;

    case CDC_CLEAR_COMM_FEATURE:

    break;

  /*******************************************************************************/
  /* Line Coding Structure                                                       */
  /*-----------------------------------------------------------------------------*/
  /* Offset | Field       | Size | Value  | Description                          */
  /* 0      | dwDTERate   |   4  | Number |Data terminal rate, in bits per second*/
  /* 4      | bCharFormat |   1  | Number | Stop bits                            */
  /*                                        0 - 1 Stop bit                       */
  /*                                        1 - 1.5 Stop bits                    */
  /*                                        2 - 2 Stop bits                      */
  /* 5      | bParityType |  1   | Number | Parity                               */
  /*                                        0 - None                             */
  /*                                        1 - Odd                              */
  /*                                        2 - Even                             */
  /*                                        3 - Mark                             */
  /*                                        4 - Space                            */
  /* 6      | bDataBits  |   1   | Number Data bits (5, 6, 7, 8 or 16).          */
  /*******************************************************************************/
    case CDC_SET_LINE_CODING:
			USBD_CDC_LineCoding.bitrate = (uint32_t)(pbuf[0] | pbuf[1]<<8 | pbuf[2]<<16 | pbuf[3]<<24);
			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] = USBD_CDC_LineCoding.bitrate & 0x000000ff;
			pbuf[1] = USBD_CDC_LineCoding.bitrate & 0x0000ff00;
			pbuf[2] = USBD_CDC_LineCoding.bitrate & 0x00ff0000;
			pbuf[3] = USBD_CDC_LineCoding.bitrate & 0xff000000;
			pbuf[4] = USBD_CDC_LineCoding.format;
			pbuf[5] = USBD_CDC_LineCoding.paritytype;
			pbuf[6] = USBD_CDC_LineCoding.datatype;
    break;

    case CDC_SET_CONTROL_LINE_STATE:

    break;

    case CDC_SEND_BREAK:

    break;

  default:
    break;
  }

  return (USBD_OK);
  /* USER CODE END 5 */
}

USBD_CDC_LineCoding变量类型为USBD_CDC_LineCodingTypeDef ,USBD_CDC_LineCodingTypeDef 的结构体类型定义在文件“usbd_cdc.h”中。
经过以上配置后,生成的keil工程中可以直接进行虚拟串口数据发送。

CDC_Transmit_FS((uint8_t *)"hello world\r\n",13);
HAL_Delay(100);

在电脑上的串口助手上,修改任意波特率都可以正常接收数据。

串口接收

void MX_USB_DEVICE_Init(void)函数在USB接收中断中调用static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)函数的USBD_Interface_fops_FS接收数据,可以在该函数中进行接收数据的转存。

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  usb_uart_rx_flag = 1;
  memset(usb_uart_rx_buf,0x00,64);
  memcpy(usb_uart_rx_buf,Buf,*Len);

  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  return (USBD_OK);
  /* USER CODE END 6 */
}

USB串口回声示例

  while (1)
  {
    
    if(usb_uart_rx_flag == 1)
    {
      usb_uart_rx_flag = 0;
      CDC_Transmit_FS(usb_uart_rx_buf,strlen(usb_uart_rx_buf));
    }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

USB重新枚举

以上程序,每次下载之后,需要重新插拔USB才能让电脑重新识别枚举单片机USB设备,将IO口PA12拉低一段时间可以实现重新枚举功能。

void usb_re_ennum()
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);

HAL_Delay(500);
HAL_GPIO_DeInit(GPIOA,GPIO_PIN_12);
return;
}
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰州_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值