基于RISC-V CH32V103的鼠标键盘摇杆手柄Joystick学习开发板--实例Eg2_Mouse

基于RISC-V CH32V103的鼠标键盘摇杆手柄Joystick学习开发板–实例Eg2_Mouse

3.2 实例Eg2_Mouse

本节我们目标是实现模拟鼠标的功能,枚举一个具有XY,左右中键以及滚轮上下的功能;

3.2.1硬件设计

同上一章节

3.2.2 软件设计

在上一章节的基础上,我们在USB_DevTransProcess中找到报告描述符的获取,并修改为如下内容

case USB_DESCR_TYP_REPORT:
if(((pSetupReqPak->wIndex)&0xff) == 0)     //接口0报表描述符
{
    pDescr = MouseRepDesc;                      //数据准备上传
    len = sizeof(MouseRepDesc);
    Ready = 1;                                  //如果有更多接口,该标准位应该在最后一个接口配置完成后有效
}
else len = 0xff;                                //本程序只有2个接口,这句话正常不可能执行
break;

另外鼠标的报告描述符MouseRepDesc如下

const UINT8  MouseRepDesc[]=
{
            0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
            0x09, 0x02,                    // USAGE (Mouse)
            0xa1, 0x01,                    // COLLECTION (Application)
            0x09, 0x01,                    //   USAGE (Pointer)
            0xa1, 0x00,                    //   COLLECTION (Physical)
            0x05, 0x09,                    //     USAGE_PAGE (Button)
            0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
            0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
            0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
            0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
            0x95, 0x03,                    //     REPORT_COUNT (3)
            0x75, 0x01,                    //     REPORT_SIZE (1)
            0x81, 0x02,                    //     INPUT (Data,Var,Abs)
            0x95, 0x01,                    //     REPORT_COUNT (1)
            0x75, 0x05,                    //     REPORT_SIZE (5)
            0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
            0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
            0x09, 0x30,                    //     USAGE (X)
            0x09, 0x31,                    //     USAGE (Y)
            0x09, 0x38,                    //     USAGE (Wheel)
            0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
            0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
            0x75, 0x08,                    //     REPORT_SIZE (8)
            0x95, 0x03,                    //     REPORT_COUNT (3)
            0x81, 0x06,                    //     INPUT (Data,Var,Rel)
            0xc0,                          //     END_COLLECTION
            0xc0                           // END_COLLECTION
};

然后是报文数据的处理如下:

//处理并上报数据
void Gp_SendReport(void)
{	
	memset(Joystick_Buf,0,4);


	Ytemp=ADC_ConvertedValue[0];
	Xtemp=ADC_ConvertedValue[1];

	if(Xtemp>Xmax)
		Xtemp=Xmax;
	if(Xtemp<Xmin)
		Xtemp=Xmin;	

	if(Ytemp>=Ymax)
		Ytemp=Ymax;
	if(Ytemp<=Ymin)
		Ytemp=Ymin;
	
	printf("Xmax=%x,Xcen=%x,Xmin=%x\r\n",Xmax,Xtemp,Xmin);
	printf("Ymax=%x,Ycen=%x,Ymin=%x\r\n",Ymax,Ytemp,Ymin);
	//根据坐标极点确定坐标(两点直线方程)
	X=((Xtemp-Xmin)*255)/(Xmax-Xmin);
	Y=((Ytemp-Ymin)*255)/(Ymax-Ymin);

    if(X>(X_BASE+20))
    {
        Joystick_Buf[1]=((X-X_BASE)>>DIV)+1;
    }
    if(X<(X_BASE-20))
    {
        Joystick_Buf[1]=(u8)-(((X_BASE-X)>>DIV)+1);
    }
    if(Y>(Y_BASE+20))
    {
        Joystick_Buf[2]=((Y-Y_BASE)>>DIV)+1;;;
    }
    if(Y<(Y_BASE-20))
    {
        Joystick_Buf[2]=(u8)-(((Y_BASE-Y)>>DIV)+1);
    }
    Key_Handle(Joystick_Buf);

    Delay_Ms(5);

    while( Endp1Busy )
    {
        ;                                               //如果忙(上一包数据没有传上去),则等待。
    }
    Endp1Busy = 1;                                      //设置为忙状态
    memcpy(pEP1_IN_DataBuf, Joystick_Buf, 4);
    DevEP1_IN_Deal(4);

}	

其中X_BASE为摇杆中点, if(X>(X_BASE+20))就是摇杆左摇动;故而((X-X_BASE)>>DIV)+1计算赋值给我们我们X+坐标;
其他方向同理,
另外Key_Handle的代码如下,主要是为了处理按键与滚轮值

void Key_Handle(uint8_t* kv)
{
    if((LFKEY)==Bit_RESET)
    {
        kv[0]|=0x01;
    }
    if((RGKEY)==Bit_RESET)
    {
        kv[0]|=0x02;
    }
    if(SW1!=Bit_RESET)
    {
        kv[0]|=0x04;
    }
    if((UPKEY)==Bit_RESET)
    {
        if(c_tick++>5)
        {
            kv[3]=1;
            c_tick=0;
        }
    }
    if((DNKEY)==Bit_RESET)
    {
        if(c_tick++>5)
        {
            kv[3]=(u8)-1;
            c_tick=0;
        }
    }
}
3.2.3 下载验证

我们把固件程序下载进去可以,打开“设备与打印机”可以看到USB设备枚举成了一个“LD Mouse”,如下图。
image

我们打开一个网页,摇动摇杆鼠标指针跟着动;右边上下左右键,左右代表鼠标左右键,上下代表滚轮;然后摇杆中键代表鼠标中键;

视频教程:https://www.bilibili.com/video/BV17r4y1z758/

猜你喜欢

转载自blog.csdn.net/qq_36250901/article/details/123841362