本帖最后由 Demon 于 2019-4-8 17:58 编辑

最近本人又调试了一款比较有趣的传感器模块--PS2  Joystick摇杆模块。下面将本人的测试方法分享于大家,下文仅个人见解,若有不足之处,望指出,不胜感激。

一、模块介绍

PS2双轴游戏摇杆模块采用了PS2游戏手柄上优质金属按键摇杆电位器,模块集成电源指示灯,可以显示工作状态;坐标标识符清晰简明、定位准确。

模块外观.png (94.31 KB, 下载次数: 24)

2019-4-8 15:51 上传

我们先来看下它的工作原理吧,那样我们也知道它里面到底是怎么回事,这对我们对它的使用很有帮助,下面是模块的功能示意图:

功能示意图.png (100.63 KB, 下载次数: 22)

2019-4-8 15:53 上传

由上图可见的,模块设有二路模拟输出和一路数字输出接口,输出值分别对应(X,Y)双轴偏移量,其类型为模拟量;另一数字表示用户是否在Z轴按下,其类型为数字开关量。通过控制器编程,传感器扩展板插接,完成具有创意性的互动作品或者游戏。

game.jpeg (34.75 KB, 下载次数: 25)

2019-4-8 16:07 上传

game1.jpeg (48.97 KB, 下载次数: 29)

2019-4-8 17:52 上传

二、代码简述

按照惯例,在了解模块后,先在kernel/arch/arm64/boot/dts/rockchip/rk3308-firefly.dtsi设备树中添加设备的节点信息。

PS2_test@ff1e0000{

compatible = "ps2 joystick";

clocks = ;

lock-names = "saradc";

Z-axis = ;

io-channels = , ;

io-channel-names = "X-axis" , "Y-axis";

status = "okay";

};复制代码   代码中使用了ADC通道0与ADC通道2,还有一个GPIO口。所使用的ADC时钟为saradc。下面将进行驱动代码的编写:首先在kernel/drivers/adc/下创建一个对应的文件夹,加入Kconfig、Makefile、ps2.c其中。

static struct file_operations ps2_fops = {

.owner = THIS_MODULE,

.open  = ps2_open,

.release = ps2_release,

.read  = ps2_read,

};

static struct miscdevice ps2_miscdev = {

.minor = MISC_DYNAMIC_MINOR,

.name  = "PS2",

.fops  = &ps2_fops,

};

static const struct of_device_id ps2_match[] = {

{ .compatible = "ps2 joystick" },

{},

};

static struct platform_driver ps2_driver = {

.probe = ps2_probe,

.remove = ps2_remove,

.driver = {

.owner = THIS_MODULE,

.name = "PS2 Game joystick module",

.of_match_table = ps2_match,

}

};

static int ps2_init(void)

{

adc_clock = clk_get(NULL, "saradc");

if(!adc_clock) {

return -ENOENT;

}

clk_enable(adc_clock);

platform_driver_register(&ps2_driver);

return misc_register(&ps2_miscdev);

}复制代码    在此就不对驱动的框架进行赘述,在初始化函数中将驱动申请为杂项设备,还有相关的设备信息。下面将对probe函数进行解析:

static int ps2_probe(struct platform_device *pdev)

{

enum of_gpio_flags z_flag;

devs = pdev;

ps2 = kmalloc(sizeof(struct PS2), GFP_KERNEL);

if(!ps2){

printk("ps2 kmalloc memory err!!!\n");

return -ENODEV;

}

z_axis_gpio = of_get_named_gpio_flags(pdev->dev.of_node, "Z-axis", 0, &z_flag);

if(!gpio_is_valid(z_axis_gpio)) {

printk("z-axis is invalid!\n");

return -ENODEV;

}

gpio_direction_input(z_axis_gpio);

chan0 = iio_channel_get(&(pdev->dev), "X-axis");

if(IS_ERR(chan0)){

return -1;

}

chan2 = iio_channel_get(&(pdev->dev), "Y-axis");

if(IS_ERR(chan2)){

return -1;

}

return 0;

}复制代码   其中需要一提的是iio_channel_get()函数,功能作用为:获取 iio 通道描述。参数为:设备描述指针、所用通道描述指针。of_get_named_gpio_flags()功能为:获取GPIO信息。gpio_is_valid()功能为:判断GPIO是否合法。下面为ps2_read()函数:

ssize_t ps2_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos)

{

int ret;

char data[20] = {0};

ps2_get_value();

sprintf(data, "%d,%d,%d",ps2->x_axis,ps2->y_axis,ps2->z_axis);

ret = copy_to_user(buf, data, sizeof(data));

return ret;

}复制代码   在read()函数中调用的ps2_get_value()是获取所需值的函数。具体如下:

int ps2_get_value(void)

{

int ret;

ret = iio_read_channel_raw(chan0, &(ps2->x_axis));

if(ret < 0 || ret > 4) {

printk("read channel() erro!!!");

return ret;

}

ps2->x_axis = (STANDARD_VOL * ps2->x_axis) / CONVERSION_NUM;

ret = iio_read_channel_raw(chan2, &(ps2->y_axis));

if(ret < 0 || ret > 4){

printk("read channel() erro!!!");

return ret;

}

ps2->y_axis = (STANDARD_VOL * ps2->y_axis) / CONVERSION_NUM;

ps2->z_axis = gpio_get_value(z_axis_gpio);

return 0;

}复制代码   其中iio_read_channel_raw()函数的功能为:读取 chan 通道 AD 采集的原始数据。参数为:通道指针、数据存放指针。此处的STANDARD_VOL与CONVERSION_NUM分别表示标准电压、转换位数。关于ADC的使用方法,可以参照firefly官方wikADC使用

gpio_get_value()函数的功能为:获取GPIO的IO值。代码写到此处,驱动算是基本已经完成,对其进行编译,生成固件,烧入开发板。以下为应用层测试程序的编写:

int main(int argc, char argv[])

{

char data[20] = {0};

int fd,ret;

int ps2[3];

char tmp = ',';

char *flag[5] = {0};

fd = open("/dev/PS2", O_RDONLY);

if(fd < 0){

printf("open /dec/PS2 faild!!\n");

return -1;

}

while(1)

{

ret = read(fd, buff, sizeof(data));

if(ret < 0){

printf("read fd faild!!\n");

return -1;

}

flag = strtok(data, &tmp);

if(flag)

ps2[0] = atoi(flag);

flag = strtok(NULL, &tmp);

if(flag)

ps2[1] = atoi(flag);

flag = strtok(NULL, &tmp);

if(flag)

ps2[2] = atoi(flag);

printf("x: %d, y: %d, z:%d", ps2[0], ps2[1], ps2[2]);

bzero(data, 20);

sleep(1);

}

return 0;

}复制代码   测试程序较为简单,访问读取/dev/PS2数据即可。再使用strtok()函数分割data,得到每个轴的数据。完成之后,使用指定的交叉编译链进行编译,将可执行文件传输至开发板中。

三、效果展示

一切准备工作处理完成之后,即可执行程序,查看代码效果!!

效果.png (94.25 KB, 下载次数: 26)

2019-4-8 17:33 上传

(此文仅个人见解,若有不足之处,望指出,不胜感激)

ps2摇杆android图形编程,ROC-RK3308-CC开发实例总结--PS2 Joystick摇杆模块相关推荐

  1. android图形编程,Android图形编程基础

    Color //方法1 int color1 = Color.BLUE; //方法2 int color2 = Color.argb(177, 255,255,255); //方法3:在xm l里面定 ...

  2. Android多工程(project)开发实例

    开发过程中,我遇到过这样一种需求,多个App并行开发,但是基础库(网络.图片.自定义view之类)完全可以用同一套,基础库一般不会频繁修改,但是如果修改了某一些代码,又希望对所有引用基础库的工程生效, ...

  3. 使用WC“.NET研究”F实现SOA面向服务编程——简单的WCF开发实例

    前面为大家介绍过WCF的特点,现在再讲解一下WCF基础概念. 在WCF里,各个Application之间的通信是由EndPoint来实现的,EndPoint是WCF实现通信的核心要素.一个WCF Se ...

  4. Android开发——图形编程(一)简单介绍与使用绘图类Paint、Canvas

    Android图形编程基础 文章目录 Android图形编程基础 画笔Paint的 画布Canvas 自定义View的基本实现方法 实例代码 绘图绘图,首先要有的就是颜色Color Android系统 ...

  5. 「雕爷学编程」Arduino动手做(38)——joystick双轴摇杆模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  6. 《Android游戏编程之从零开始》书评之基础的魅力

    拜读完<Android游戏编程之从零开始>的试读章节之后,感受颇深,对于游戏开发过程中用到的知识,有了初步的了解,此书就一些基本图形为例,展开对游戏开发的基本原理的阐述.本人感觉,介绍一种 ...

  7. android开发重要控件,Android界面编程——Android基本控件

    Android界面编程 Android应用开发的一项重要内容就是界面开发.对于用户来说,不管APP包含的逻辑多么复杂,功能多么强大,如果没有提供友好的图形交互界面,将很难吸引最终用户. 作为一个程序员 ...

  8. 用Xlib库进行基本图形编程

    用Xlib库进行基本图形编程 用Xlib库进行基本图形编程 目录 1.前言 2.X Window系统的客户服务器模式 3.GUI编程-同步化的编程模型 4.基本的Xlib概念         1.X ...

  9. android gpu 编程,Android设备上的GPU编程

    1)Programming Smartphone's GPU and programming other GPU (Nvidia GeForce 9 for example) are equal? 不 ...

最新文章

  1. 在Linux下gcc缺省编译,在Linux下GCC将文件合起来编译
  2. 使用ImageMagick 在图片上绘制粗斜体的中文也许是一个错误。
  3. Redis中的I/O 多路复用(I/O Multiplexing)
  4. android自定义布局中的平滑移动
  5. matlab中的矩阵元素错位,matlab – 如何将矩阵中较弱元素附近的弱元素归零?
  6. Layabox 实现 PageView 翻页
  7. 线程状态的区别 blocked waitting ,join 详解
  8. iOS16.0:屏幕旋转
  9. 腾讯云图 数据源 api
  10. 联想Lephone与Apple iPAD的完美组合
  11. 【vscode】常用快捷键
  12. 雾锁FCoin:局中局套住了谁?
  13. android 手机型号占有量,2021年安卓手机性能排行及手机品牌占有率
  14. AD9361、AD9613高速AD采集处理开发案例,基于C6678+Kintex-7
  15. Python小项目—照片马赛克
  16. 青云霍秉杰:一文读懂Prometheus长期存储主流方案
  17. 攻守一体,酣畅淋漓——分析《只狼》的战斗系统
  18. mpls通过BGP实现互通
  19. 在cmd中安装MySQL,MySQL(桌面图标版)
  20. 百度网盘网页版如何对文件按照文件名进行排序

热门文章

  1. 10个优秀设计网站盘点
  2. Guitar Pro8.0.1吉他制谱打谱软件
  3. java-php-python-ssmX钢材商贸公司网络购销管理系统计算机毕业设计
  4. 西门子s7—200smart型PLC和昆仑通泰触摸屏程序
  5. 十.四轮车驱动开发之三: 巧用编码器获取电机转速信息
  6. tensorflow人工智能-卫星图像识别
  7. 错误:-[UIKBBlurredKeyView candidateList]: unrecognized selector sent to instance
  8. 国内机器视觉行业中工业相机的发展现状及其面临的技术挑战
  9. oracle列分区,Oracle数据库分区--实例
  10. Win11中Unity商店资源无法在PackageManager中下载