前面测试了最基本的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;
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] this function handles timer1 overflow handler.
* @param none
* @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;
/**
* @brief usb host hid position
* @param x: x position
* @param y: 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);
}
}
}
同样的对按键回调函数做出改动如下,当按住左键时使能画点,右键则用来清屏
/**
* @brief usb host hid button press
* @param button: 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;
}
}
/**
* @brief usb host hid button release
* @param button: 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驱动成功,画完了可以右键清除一下
|