本帖最后由 muyichuan2012 于 2022-4-2 13:28 编辑
Joystick演示--AT_SURF案例12
视频效果: https://b23.tv/TJLnrce
简介
AT32-SUFR 板载了一个游戏手柄(五向摇杆按键),游戏手柄原理如下图所示,按键共有5 组不同
的导通路径,意味着按键可以输出5 个按键值。本章节描述了如何读取游戏手柄按键键值,并将键值
通过串口打印出来
在SUFR 板上游戏手柄没有直接连接MCU 的IO,而是连接到一个IO 扩展芯片PCA9555。
PCA9555 通过I2C 总线连接到MCU,当PCA9555 上的IO 电平发生变化时,在引脚INT 上会产生
一个下降沿。MCU 在检测到了下降沿了之后,通过I2C 总线读取PCA9555 的IO 状态寄存器得到当
前IO 的状态。
资源准备
硬件环境:
对应产品型号的AT-SURF-F437 Board
软件环境:
AT32F435_437_Firmware_Library_V2.x.x\project\at_sufr_f437\examples\joystick
硬件设计
本案例使用的硬件资源有游戏手柄按键、PCA9555,对应的引脚如下:
编号 PIN Name 外设功能 备注
1 PH2 I2C2 SCL PCA9555 SCL线
2 PH3 I2C2 SDA PCA9555 SDA线
3 PG3 GPIO PCA9555 INT线
编号 PIN Name 引脚功能 备注
1 IO1_0 上 五向摇杆按键
2 IO1_1 右 五向摇杆按键
3 IO1_2 下 五向摇杆按键
4 IO1_3 确认 五向摇杆按键
5 IO1_4 左 五向摇杆按键
软件设计
1) 游戏手柄测试
初始化I2C 接口
将游戏手柄按键所用到的PCA9555 IO 口配置成输入
读取PCA9555 IO 状态,判断是否有按键发生
2) 代码介绍
main 函数代码描述
int main(void) { uint16_t x = 0, i; joy_type key; /* 初始化系统时钟 */ system_clock_config(); /* 初始化中断优先级分组 */ nvic_priority_group_config(NVIC_PRIORITY_GROUP_4); /* 初始化延时函数 */ delay_init(); /* 初始化LCD */ lcd_init(LCD_DISPLAY_VERTICAL); /* 初始化五向摇杆按键 */ joystick_init(); lcd_clear(BLACK); /* 显示信息 */ lcd_string_show(80, 20, 200, 24, 24, (uint8_t*)"Joystick Test"); lcd_string_show(50, 400, 200, 24, 24, (uint8_t*)"key value:"); while(1) { /* 读取PCA9555 IO 状态 */ pca9555_io_scan(); /* 获取键值 */ key = joystick_press(); switch(key) { case JOY_LEFT: lcd_string_show(200, 400, 100, 24, 24, (uint8_t*)"left "); pitch = 10; roll= 0; yaw= 0; break; case JOY_RIGHT: lcd_string_show(200, 400, 100, 24, 24, (uint8_t*)"right"); pitch = -10; roll= 0; yaw= 0; break; case JOY_UP: lcd_string_show(200, 400, 100, 24, 24, (uint8_t*)"up "); pitch = 0; roll= -10; yaw=0; break; case JOY_DOWN: lcd_string_show(200, 400, 100, 24, 24, (uint8_t*)"down "); pitch = 0; roll= 10; yaw=0; break; case JOY_ENTER: lcd_string_show(200, 400, 100, 24, 24, (uint8_t*)"enter"); pitch = 0; roll= 0; yaw = 10; break; case JOY_NONE: break; default: break; } lcd_fill(80,80,230,220,BLACK); for(i=0; i<8; i++) rotate(cube, pitch/360, roll/360, yaw/360); for(i=0; i<28; i+=2) { lcd_draw_line(160+cube[lineid-1][0],150+cube[lineid-1][1], 160+cube[lineid[i+1]- 1][0], 150+cube[lineid[i+1]-1][1], WHITE); } delay_ms(10); } }
下载验证
如果有按键按下,被按下的按键值会通过LCD 屏显示出来。
|