#申请原创# @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;
}
}
编译烧录查看效果
摇杆控制鼠标移动
左右按键,左键单击双击右键单击
|
赞,来学习一下!