购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第9章
让游戏操纵杆正常工作起来

由于JoyStickMouse例程是与官方评估板配套的,与我们设计的开发板引脚的定义有可能不一样,所以才会导致PC鼠标无法正常受开发板按键的控制。如果你想将厂家发布的例程应用到自己的开发平台上,必须 按照引脚的定义进行相应修改 。那么具体应该修改哪些地方呢?我们先进入main主函数,初步了解一下JoyStickMouse例程的代码执行流程,相应的源代码如清单9.1所示。

清单9.1 main主函数

main主函数一开始调用了几个初始化函数(暂时不用理会,后续会详细讲解)后,就进入了while死循环。其中,Joystick_Send函数实现给主机发送数据的功能,而是否发送数据则取决于JoyState函数的返回值以及PreXferComplete变量(后述)。JoyState函数用来获取轻触按键的状态,它的具体实现在hw_config.c源文件中,相应的源代码如清单9.2所示,相应的hw_config.h头文件如清单9.3所示。

清单9.2 JoyState函数

清单9.3 hw_config.h头文件

从清单9.2中可以看到,JoyState函数内部使用预编译指令定义了不同平台对应的按键读取代码,如果你定义了USE_STM32373C_EVAL或USE_STM32303C_EVAL宏,编译器会编译所有#else分支后面的语句,相反则编译if分支后面的语句。前面已经提过,JoyStickMouse例程只定义了宏USE_STM3210B_EVAL,因此编译器会编译所有#if分支语句。为方便读者更轻松地进行源代码阅读,本书后续均删除源代码中不会被执行的预处理指令,整理后的JoyState函数如清单9.4所示(为节省篇幅,代码需要修改的地方会提示在注释部分,后续会详述具体的修改方法)。

清单9.4 整理后的JoyState函数

Button_RIGHT、Button_LEFT、Button_UP、Button_DOWN分别用来唯一标识某个按键,它们被定义在stm32_eval_legacy.h头文件(所有适配层都会包含该头文件),如清单9.5所示。

清单9.5 stm32_eval_legacy.h头文件(部分)

从清单9.5中可以看到,前述4个按键标识符又分别被定义为BUTTON_RIGHT、BUTTON_LEFT、BUTTON_UP、BUTTON_DOWN,它们被声明在适配层stm3210b_eval.h头文件中,相应的源代码如清单9.6所示。

清单9.6 stm3210b_eval.h头文件(部分)

从清单9.6中可以看到,上、下、左、右4个按键分别被赋予了唯一的数字进行标记,并且以枚举常量的方式被定义,清单9.4中的STM_EVAL_PBGetState函数则根据传入的唯一数字进行相应按键状态的读取与返回操作,该函数被定义在stm3210b_eval.c源文件中,相应的源代码如清单9.7所示。

清单9.7 stm3210b_eval.c源文件(部分)

从清单9.7中可以看到,STM_EVAL_PBGetState函数中调用了读取引脚位状态的GPIO_ReadInputDataBit函数,需要传入后者的“GPIO外设基地址与引脚位信息”被统一保存在数组BUTTON_PORT与BUTTON_PIN中。也就是说,适配层将所有使用到的GPIO外设基地址、引脚位、总线时钟、中断线等信息都定义为宏,然后用数组将这些信息分类存储(例如,数组BUTTON_PORT用于保存GPIO外设基地址。数组BUTTON_PIN用于保存引脚位,数组BUTTON_CLK用于保存总线时钟控制位,数组BUTTON_EXTI_LINE用于保存引脚对应的中断线,其他以此类推),这样就可以使用唯一标识符从不同数组中获得某个引脚的所有信息。我们以Button_Right为例给出了相应按键引脚信息的获取流程,如图9.1所示。

图9.1 Button_Right对应的引脚获取流程

也就是说,官方例程中实现右移功能的按键对应单片机的引脚PE0。相应地,我们也可以查到上、下、左移按键对应的引脚分别为PD8、PD14、PE1。由于这4个引脚都不在我们规划的IO引脚中(见表4.2),所以目前开发板控制PC鼠标的功能是不正常的。

我们自己的开发板上有7个按键可供使用,假设现在决定使用K1~K4分别实现下、右、左、上移的功能,相应的引脚规划如图9.2所示。在源代码方面,首先需要将清单9.6中4个按键相关信息的宏定义 按注释后面的语句修改 。当然,有些宏定义并没有使用到(如中断线、中断源等),但为了源代码的完整性,我们仍然给出了所有的修改语句。

还有什么地方需要修改呢?我们再次回到JoyState函数中,第一条if语句是读取“右移”按键的状态,并且加了一个“非”逻辑运算符,这意味着: 官方评估板配套的游戏杆按键是低有效的(空闲状态下为高电平) 。那么理论上,官方例程应该会将按键相关的引脚初始化为“上拉输入”模式(如果评估板已经外接了上拉电阻,也可以初始化为“悬空输入”模式),这一点我们可以通过分析main主函数中的Set_System函数来验证,相应的源代码如清单9.8所示。

图9.2 引脚规划

清单9.8 Set_System函数

我们只需要关注其中调用的STM_EVAL_PBInit函数(其定义见清单9.7),它根据指定的按键唯一标识符与配置模式(Mode_GPIO代表普通引脚,Mode_EXTI代表外部中断输入,其定义见清单9.5)进行初始化。具体来讲,从函数一开始就通过前述数组查找的方式,使能了指定引脚对应GPIO外设的总线时钟,并且将它们设置为“悬空输入”模式,这也就意味着: 官方评估板上的按键均有额外的上拉电阻 (其他语句只有在将GPIO设置初始化为外部中断输入时使用到,暂时可不予理会)。

由于我们开发板上的按键采用高有效的方式连接(默认为低电平),而且没有外接下拉电阻,所以还需要做两件事。其一,应该在清单9.7的STM_EVAL_PBInit函数中将引脚模式初始化为下拉输入模式(GPIO_Mode_IPD),这样才能够使所有按键在初始化后就维持低电平(空闲状态)。其二,应该将JoyState函数(清单9.4)中所有if语句中的非逻辑运算符“!”去掉。这也就意味着在空闲状态(低电平)下,JoyState函数将返回状态0,也就相当于通知应用程序: 此时没有按键被按下 。如果不修改判断逻辑,就会出现前述体验游戏操纵杆设备时“PC鼠标总会不受控地往右移”的现象,因为在原来的逻辑下,空闲状态(低电平)是有效电平,而JoyState函数读取到第一个右移按键有效后就直接返回(不再执行剩下的代码),所以PC鼠标才会一直右移。

总体上,如果使用自己的STM32单片机开发板实现JoyStickMouse例程,则需要确认以下三点。其一, 更改数组BUTTON_PORT与BUTTON_PIN中各引脚信息的具体定义 (其他是可选的);其二, 对按键的输入引脚进行初始化,使它们默认处于无效状态 (也就是更改STM_EVAL_PBInit函数中引脚的初始化模式),具体取决于开发板上的按键连接方式;其三, 更改JoyState函数中判断读取状态的逻辑 (高电平还是低电平有效)。当然,即使使用的开发平台并不是基于STM32单片机,这三点同样也是成功实现官方例程的修改思路。

当按照前述三点更改之后,再重新编译项目并将STM3210B-EVAL.hex文件下载到开发板中,你就可以通过按键K1~K4正常控制PC鼠标移动方向了,是不是很简单。恭喜!你人生中的第一个USB设备已经开发完成了! C6mTZ5hP9KRT+6oN/zUG8M051pwB30s8B9cdD0F+adZV5LCIw+vrMQX/LNT1HgZS

点击中间区域
呼出菜单
上一章
目录
下一章
×