lovelessing 发表于 2024-5-16 11:21

【AT-START-F405测评】第三步:USB主机测试

前面测试了最基本的IO、串口、SPI等等,测多了开发板你就知道了,工程模板给你已经开了很多很多功能了,无外乎就是开关个配置复制复制修改修改代码。
所以直接一步到位测一下USB,用的是host-hid demo,可以识别USB鼠标和键盘设备

首先加上之前的OLED驱动
    nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

    system_clock_config();

    at32_board_init();
       
        /* get system clock */
        crm_clocks_freq_get(&crm_clocks_freq_struct);
       
        OLED_Init();
        OLED_SetDir(3);
        OLED_Clear(0);
        OLED_DrawRectangle(5,5,122,59,1);
        OLED_DrawRectangle(15,15,112,49,1);
        OLED_DrawRectangle(25,25,102,39,1);
        OLED_Refresh_Gram();

接着打开一个多少钱用来做定时刷新,因为host需要一直轮询,所以不能占用太多的刷新影响,而工程也没有开启滴答定时器做系统计数,因此不能获取到准确的时基,同于也不能通过循环次数做计时,因为每次循环时间并不一致
/* enable tmr1 clock */
        crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);

        /* tmr1 configuration */
        /* time base configuration */
        tmr_base_init(TMR1, 10-1, (crm_clocks_freq_struct.apb2_freq / 10000) - 1);
        tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);

        /* overflow interrupt enable */
        tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);

        /* tmr1 hall interrupt nvic init */
        nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
        nvic_irq_enable(TMR1_OVF_TMR10_IRQn, 1, 0);

        /* enable tmr1 */
        tmr_counter_enable(TMR1, TRUE);定时器中断中对变量进行计数,当作时基
uint32_t tmr_cnt = 0;

/**
* @briefthis function handles timer1 overflow handler.
* @paramnone
* @retval none
*/
void TMR1_OVF_TMR10_IRQHandler(void)
{
        if(tmr_interrupt_flag_get(TMR1, TMR_OVF_FLAG) == SET)
        {
                tmr_flag_clear(TMR1, TMR_OVF_FLAG);
                tmr_cnt += 10;
        }
}没100毫秒进行一次刷屏,尽量不占用USB轮询
    while(1)
    {
      usbh_loop_handler(&otg_core_struct.host);
                if(!(tmr_cnt % 100))
                {
                        OLED_Refresh_Gram();
                }
    }修改USB鼠标坐标回调函数,因为参数类型不适合,之后加上坐标限制以及OLED画点函数的调用
int16_t x_pos = 0, y_pos = 0;

uint8_t left_btn_flag = 0;

/**
* @briefusb host hid position
* @paramx: x position
* @paramy: y position
* @retval none
*/
void usbh_hid_mouse_position(int8_t x, int8_t y)
{
if((x != 0) || (y != 0))
{
    x_pos += x / 2;
    y_pos += y / 2;

    if(x_pos > MOUSE_WINDOW_WIDTH - 2)
    {
      x_pos = MOUSE_WINDOW_WIDTH - 2;
    }
    if(y_pos > MOUSE_WINDOW_HEIGHT - 2)
    {
      y_pos = MOUSE_WINDOW_HEIGHT - 2;
    }

    if(x_pos < 2)
    {
      x_pos = 2;
    }
    if(y_pos < 2)
    {
      y_pos = 2;
    }
    USBH_DEBUG("Moving Mouse");
        extern void OLED_DrawPoint(uint16_t x, uint16_t y, uint8_t p);
        if(left_btn_flag)
        {
                OLED_DrawPoint(x_pos,y_pos,1);
        }
}

}同样的对按键回调函数做出改动如下,当按住左键时使能画点,右键则用来清屏
/**
* @briefusb host hid button press
* @parambutton: button id
* @retval none
*/
void usbh_hid_mouse_button_press(uint8_t button)
{
switch(button)
{
    case MOUSE_BUTTON_LEFT:
      /* left button */
      USBH_DEBUG("Left Button Pressed ");
        left_btn_flag = 1;
      break;
    case MOUSE_BUTTON_RIGHT:
      USBH_DEBUG("Right Button Pressed ");
      /* left button */
        extern void OLED_Clear(uint8_t para);
        OLED_Clear(0);
      break;
    case MOUSE_BUTTON_MIDDLE:
      USBH_DEBUG("Middle Button Pressed ");
      /* middle button */
      break;
}
}

/**
* @briefusb host hid button release
* @parambutton: button id
* @retval none
*/
void usbh_hid_mouse_button_release(uint8_t button)
{
switch(button)
{
    case MOUSE_BUTTON_LEFT:
      /* left button */
      USBH_DEBUG("Left Button Released ");
        left_btn_flag = 0;
      break;
    case MOUSE_BUTTON_RIGHT:
      /* left button */
      USBH_DEBUG("Right Button Released ");
      break;
    case MOUSE_BUTTON_MIDDLE:
      /* middle button */
      USBH_DEBUG("Middle Button Released ");
      break;
}
}基本上就修改差不多了,下载代码跑一下

插上鼠标,画一个AT字符,USB驱动成功,画完了可以右键清除一下

呐咯密密 发表于 2024-5-21 13:20

实现的很棒

lovelessing 发表于 2024-5-21 19:09

呐咯密密 发表于 2024-5-21 13:20
实现的很棒

还有不少瑕疵呢,暂时没实现鼠标位置的动态显示,所以现在只能凭感觉感触位置画,都是测评要的比较急
页: [1]
查看完整版本: 【AT-START-F405测评】第三步:USB主机测试