AT32 USB_DEVICE — USB 键盘

AT32 AT32F403A_407_Firmware_Library V2.2.2 USB_DEVICE USB 键盘 示例教学

USB_DEVICE — USB 键盘

固件库: AT32F403A_407_Firmware_Library V2.2.2
芯片: AT32
源文件: AT32/AT32F403A_407_Firmware_Library_V2.2.2/project/at_start_f403a/examples/usb_device/keyboard/src/main.c


功能简介

本示例演示 USB 设备模式 — USB 键盘。MCU 作为 USB 设备连接到电脑,实现 HID 键盘/鼠标、虚拟串口(CDC)、大容量存储(MSC)等功能。

完整代码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
#include "usbd_core.h"
#include "keyboard_class.h"
#include "keyboard_desc.h"
#include "usbd_int.h"

int main(void)
{
  __IO uint32_t delay_index = 0;
  /* config nvic priority group */
  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

  system_clock_config();

  at32_board_init();

  /* select usb 48m clcok source */
  usb_clock48m_select(USB_CLK_HEXT);

#ifdef USB_LOW_POWER_WAKUP
  /* enable pwc and bpr clock */
  crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
  button_exint_init();
  usb_low_power_wakeup_config();
#endif

  /* enable usb clock */
  crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, TRUE);

  /* enable usb interrupt */
  nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn, 0, 0);

  /* usb core init */
  usbd_core_init(&usb_core_dev, USB, &keyboard_class_handler, &keyboard_desc_handler, 0);

  /* enable usb pull-up */
  usbd_connect(&usb_core_dev);

  while(1)
  {
    if(at32_button_press() == USER_BUTTON)
    {
      if(usbd_connect_state_get(&usb_core_dev) == USB_CONN_STATE_CONFIGURED)
      {
        keyboard_send_string(&usb_core_dev, (uint8_t *)" Keyboard Demo\r\n", 16);
      }
      /* remote wakeup */
      if(usbd_connect_state_get(&usb_core_dev) == USB_CONN_STATE_SUSPENDED
        &&(usb_core_dev.remote_wakup == 1))
      {
        usbd_remote_wakeup(&usb_core_dev);
      }
    }
#ifdef USB_LOW_POWER_WAKUP
     /* enter deep sleep */
    if(((keyboard_type *)(usb_core_dev.class_handler->pdata))->hid_suspend_flag == 1)
    {
      at32_led_off(LED2);
      at32_led_off(LED3);
      at32_led_off(LED4);
      /* congfig the voltage regulator mode */
      pwc_voltage_regulate_set(PWC_REGULATOR_LOW_POWER);

      /* enter deep sleep mode */
      pwc_deep_sleep_mode_enter(PWC_DEEP_SLEEP_ENTER_WFI);
      /* wait 3 LICK cycles to ensure clock stable, delay 120us*/
      /* when wakeup from deepsleep,system clock source changes to HICK */
      if((CRM->misc3_bit.hick_to_sclk == TRUE) && (CRM->misc1_bit.hickdiv == TRUE))
      {
        /* HICK is 48MHz */
        for(delay_index = 0; delay_index < 750; delay_index++)
        {
          __NOP();
        }
      }
      else
      {
        /* HICK is 8MHz */
        for(delay_index = 0; delay_index < 125; delay_index++)
        {
          __NOP();
        }
      }

      system_clock_recover();
      ((keyboard_type *)(usb_core_dev.class_handler->pdata))->hid_suspend_flag = 0;
      at32_led_on(LED2);
      at32_led_on(LED3);
      at32_led_on(LED4);
    }
#endif
  }
}

void button_exint_init(void)
{
  exint_init_type exint_init_struct;

  crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE0);

  exint_default_para_init(&exint_init_struct);
  exint_init_struct.line_enable = TRUE;
  exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
  exint_init_struct.line_select = EXINT_LINE_0;
  exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
  exint_init(&exint_init_struct);

  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  nvic_irq_enable(EXINT0_IRQn, 0, 0);
}

void usb_low_power_wakeup_config(void)
{
  exint_init_type exint_init_struct;

  exint_default_para_init(&exint_init_struct);

  exint_init_struct.line_enable = TRUE;
  exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
  exint_init_struct.line_select = EXINT_LINE_18;
  exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
  exint_init(&exint_init_struct);

  nvic_irq_enable(USBFSWakeUp_IRQn, 0, 0);
}

代码讲解

系统时钟初始化:配置 MCU 的主频和时钟树。不同芯片的时钟配置不同,一般由工具生成。

板级初始化:初始化开发板上的 LED、按键等基础外设。

中断优先级配置:NVIC 设置中断的抢占优先级和子优先级。数字越小优先级越高。

世界是你们
使用 Hugo 构建
主题 StackJimmy 设计