发新帖本帖赏金 20.00元(功能说明)我要提问
123下一页
返回列表
打印
[活动]

【极海APM32F407IG Tiny Board开发板测评】6.基于官方USB鼠标例程和ADC实现用摇杆控制鼠标

[复制链接]
1897|47
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创# @21小跑堂  
6.基于官方USB鼠标例程和ADC实现用摇杆控制鼠标
官方的USB例程里有一个针对这个开发板模拟鼠标的的例程

用板子上的两个按键控制鼠标的左右移动,手里还有个这样的游戏手柄摇杆

打算结合一下实现类似一些笔记本上的小红点控制鼠标的功能
先实现ADC读取XY电平数据,用PC0 PC1分别做X Y的输入

ADC检测部分代码

uint16_t adcData1 = 2047,adcData2 = 2047;
void adc_init()
{
    GPIO_Config_T   gpioConfig;
    ADC_Config_T    adcConfig;
    ADC_CommonConfig_T  adcCommonConfig;

    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOC);

    GPIO_ConfigStructInit(&gpioConfig);
    gpioConfig.mode    = GPIO_MODE_AN;
    gpioConfig.pupd    = GPIO_PUPD_NOPULL;
    gpioConfig.pin     = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_Config(GPIOC, &gpioConfig);

    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC2);

    ADC_Reset();
    ADC_ConfigStructInit(&adcConfig);
    adcConfig.resolution          = ADC_RESOLUTION_12BIT;
    adcConfig.continuousConvMode  = ENABLE;
    adcConfig.dataAlign           = ADC_DATA_ALIGN_RIGHT;
    adcConfig.extTrigEdge         = ADC_EXT_TRIG_EDGE_NONE;
    adcConfig.scanConvMode        = DISABLE;
    ADC_Config(ADC1, &adcConfig);
    ADC_Config(ADC2, &adcConfig);
   
    /*Set ADC Clock Prescaler. ADC_Clock = APB2_Clock/4, 84/4=21MHz*/
    adcCommonConfig.prescaler = ADC_PRESCALER_DIV4;
    ADC_CommonConfig(&adcCommonConfig);

    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_10, 1, ADC_SAMPLETIME_112CYCLES);
    ADC_ConfigRegularChannel(ADC2, ADC_CHANNEL_11, 1, ADC_SAMPLETIME_112CYCLES);

    ADC_EnableInterrupt(ADC1, ADC_INT_EOC);
    ADC_EnableInterrupt(ADC2, ADC_INT_EOC);

    NVIC_EnableIRQRequest(ADC_IRQn, 1, 1);

    ADC_Enable(ADC1);
    ADC_Enable(ADC2);

    ADC_SoftwareStartConv(ADC1);
    ADC_SoftwareStartConv(ADC2);
}

void ADC_IRQHandler(void)
{

    if (ADC_ReadStatusFlag(ADC1, ADC_FLAG_EOC))
    {
        ADC_ClearStatusFlag(ADC1, ADC_FLAG_EOC);
        adcData1 = ADC_ReadConversionValue(ADC1);
    }
    if (ADC_ReadStatusFlag(ADC2, ADC_FLAG_EOC))
    {
        ADC_ClearStatusFlag(ADC2, ADC_FLAG_EOC);
        adcData2 = ADC_ReadConversionValue(ADC2);
    }
}
先通过串口printf打印出来看看,使用串口printf需要添加如下代码
#define DEBUG_USART TINY_COM1
#if defined (__CC_ARM) || defined (__ICCARM__) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
int fputc(int ch, FILE* f)
{
    USART_TxData(DEBUG_USART, (uint8_t)ch);
    while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
    return (ch);
}

#elif defined (__GNUC__)
int __io_putchar(int ch)
{
    USART_TxData(DEBUG_USART, ch);
    while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
    return ch;
}

int _write(int file, char* ptr, int len)
{
    int i;
    for (i = 0; i < len; i++)
    {
        __io_putchar(*ptr++);
    }
    return len;
}
#else
#warning Not supported compiler type
#endif
并勾选Use MicroLIB

如果勾选后编译出现这个错误,点击rebuild重新完整编译一下就行了

最后看看读取到的adc数据

接下来修改鼠标例程的代码,实现用摇杆控制鼠标移动,原来的2个按键用作鼠标的左右按键
先来了解一下原来代码中上报的report[4]中的4个字节都对应鼠标的哪些动作
report[0]:bit0为1左键按下0未按下,bit1为1右键按下0未按下,bit2为1中键按下0未按下
report[1]:鼠标X坐标变化量,8位有符号数正数右移负数左移
report[2]:鼠标Y坐标变化量,8位有符号数正数上移负数下移
report[3]:滚轮变化量,8位有符号数正数向前滚动负数向后滚动
了解了这些也就知道该怎么改了,修改后的鼠标代码

void USB_DevUserApplication(void)
{
    static uint8_t userAppState = USER_APP_INIT;
    static uint8_t interval = 0;
    static int8_t report[4] = { 0 };
    switch (userAppState)
    {
        case USER_APP_INIT:
            interval = USBD_HID_ReadInterval(&gUsbDeviceHS);

            report[0] = 0;
            report[1] = 0;
            report[2] = 0;
            report[3] = 0;
            userAppState = USER_APP_RUN;
            break;

        case USER_APP_RUN:
            if (!APM_TINY_PBGetState(BUTTON_KEY1))
            {
                APM_DelayMs(10);
                if (!APM_TINY_PBGetState(BUTTON_KEY1))
                {
                    report[0] |= 0x02;
                }
            }
            else
            {
                report[0] &= 0xFD;
            }

            if (!APM_TINY_PBGetState(BUTTON_KEY2))
            {
                APM_DelayMs(10);
                if (!APM_TINY_PBGetState(BUTTON_KEY2))
                {
                    report[0] |= 0x01;
                }
            }
            else
            {
                report[0] &= 0xFE;
            }
            report[1] = 0;
            report[2] = 0;
            if(adcData1 > 2197 || adcData1 < 1897)
            {
                report[1] = (2047 - adcData1)*15/2047;
            }
            if(adcData2 > 2197 || adcData2 < 1897)
            {
                report[2] = (adcData2 - 2047)*15/2047;
            }
            
            USBD_HID_TxReport(&gUsbDeviceHS, (uint8_t*)report, 4);
            APM_DelayMs(interval);
            break;
    }
}
编译烧录查看效果
摇杆控制鼠标移动

左右按键,左键单击双击右键单击




使用特权

评论回复

打赏榜单

Gfan 打赏了 20.00 元 2023-08-17
理由:APM32F407IG Tiny Board精选测评

评论
forgot 2023-10-12 11:49 回复TA
赞,来学习一下! 
沙发
guijial511| | 2023-7-12 08:33 | 只看该作者
可以做一个游戏模拟器了

使用特权

评论回复
板凳
tpgf| | 2023-8-5 08:56 | 只看该作者
摇杆控制鼠标需要多少个物理量呢

使用特权

评论回复
地板
chenjun89| | 2023-8-5 17:16 | 只看该作者
不错,有点好玩,做个模拟器啥的。

使用特权

评论回复
5
wiba| | 2023-8-5 19:02 | 只看该作者
这种摇杆模拟鼠标来检测的原理是什么呢

使用特权

评论回复
6
kxsi| | 2023-8-5 19:41 | 只看该作者
不太明白它的原理 为什么需要用adc进行检测呢 使用开关量不可以吗

使用特权

评论回复
7
coshi| | 2023-8-5 20:28 | 只看该作者
使用摇杆的原理和usb鼠标是不是不相同的啊

使用特权

评论回复
8
qcliu| | 2023-8-5 21:00 | 只看该作者
这种模拟操作的实时性怎么样 会不会有一定的延迟

使用特权

评论回复
9
drer| | 2023-8-5 21:32 | 只看该作者
像是这种类型的操作是不是必须就需要跑系统来实现了啊

使用特权

评论回复
评论
knk 2023-9-3 23:52 回复TA
有操作系统的话程序会简单很多 
10
weifeng90| | 2023-8-6 09:03 | 只看该作者
遥杆适合做个模拟器玩玩

使用特权

评论回复
11
yinxiangh| | 2023-8-26 23:56 | 只看该作者
这个摇杆好突兀

使用特权

评论回复
12
updownq| | 2023-9-5 10:02 | 只看该作者
需要确保鼠标驱动程序与操作系统兼容,并且可以被正确识别和配置。

使用特权

评论回复
13
alvpeg| | 2023-9-5 10:09 | 只看该作者
在编写代码时,需要注意时序控制、数据处理、中断处理等方面的问题。

使用特权

评论回复
14
lihuami| | 2023-9-5 10:17 | 只看该作者
摇杆通常由两个可动电阻、两个固定电阻和多个引脚组成,需要正确连接到单片机的ADC输入引脚上。

使用特权

评论回复
15
jimmhu| | 2023-9-5 10:32 | 只看该作者
摇杆模块和单片机都有稳定的电源供应,以防止不稳定的电压对系统的影响。

使用特权

评论回复
16
cemaj| | 2023-9-5 10:43 | 只看该作者
需要编写程序来处理摇杆的输入信号,以便将摇杆位置转换为鼠标的移动和点击信号

使用特权

评论回复
17
pentruman| | 2023-9-5 10:54 | 只看该作者
对采样得到的数字信号进行处理,将其转换为鼠标的移动控制信号。

使用特权

评论回复
18
deliahouse887| | 2023-9-5 11:05 | 只看该作者
深入理解USB协议, 正确地编写USB鼠标例程。

使用特权

评论回复
19
wwppd| | 2023-9-5 11:32 | 只看该作者
在进行数据处理时,需要注意数据的精度、数据的滤波、数据的校准等方面的问题。

使用特权

评论回复
20
eefas| | 2023-9-5 11:55 | 只看该作者
需要将ADC采集到的模拟电压转换为鼠标移动的相对坐标,并将其打包成USB协议报文发送给主机。需要注意鼠标加速度、速度和方向等特性,保证鼠标操作的流畅性和精确性。

使用特权

评论回复
发新帖 本帖赏金 20.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

500

帖子

4

粉丝