PS:要转载请注明出处,本人版权所有。

PS: 这个只是基于《我自己》的理解,

如果和你的原则及想法相冲突,请谅解,勿喷。

前置说明

  本文作为本人csdn blog的主站的备份。(BlogID=087)

  本文发布于 2019-08-24 11:48:24,现用MarkDown+图床做备份更新。blog原图已丢失,使用csdn所存的图进行更新。(BlogID=087)

环境说明

  无

起因


  我们有个项目,做了一个基于TX2核心板的硬件板卡,这个板卡除了做相关算法的检测之外,还得提供一些控制LED啊、通过拨码开关这些来设置一些内容的小功能,你说气不气,这些小功能还必须要实现。如果LED和拨码开关直接挂载到tx2的gpio上的话,就没有必要写本文了,没意义,因为只要学过嵌入式的人,给他一个板子,再差劲,读取和设置一个gpio的高低电平总会吧。如果不会,建议还多学学嵌入式基础知识(从单片机玩起来,先裸奔,再上OS)。

  这里我们知道,其实对于芯片来说,引脚是非常珍贵的,如果芯片所需要实现的功能复杂,那么通用的io管脚异常珍贵,这里就出现了一个种器件,叫做IO扩展器(所实话,我都不知道这样翻译对不对),从名字可知,就是较少的引脚扩展出更多的引脚,本文就是用两个引脚扩展出了16个引脚。

  TX2上,由于使用了Linux,读取和设置gpio也是非常简单的,直接打开相关的gpio设备,读写即可。不要问我为啥要用linux,不用其他os,或者直接裸机控制,我只能够回答曰:我是想啊,可是我实力不允许啊,什么caffe、opencv、ncnn、cuda等等堆到其他系统或者裸机下,我着实能力不够,弄不过去,关键还麻烦。

IO扩展器


IO扩展器原理简介

  其实本文的核心就是IO扩展器,这个器件由于我玩的板子少,见识少,我是第一次见到这种器件。下图就是这种器件在tx2手册里面的推荐使用方法。

  这种器件就是通过某种总线,然后扩展出尽可能多的io口。这里的这个器件通过I2C总线,扩展出16个io口。

  这里我们可以看到:SCL和SDA是I2C通信总线,A0和A1是可编程配置I2C从器件地址。(这里不懂也没关系,就是这个器件的地址可以编程设置,至于为啥要有这个地址,可以简单理解为一个总线挂载多个设备,某一时刻总线只能为其中一个设备提供服务,这些设备的区分就是通过地址来完成的。)

  P00-P17是扩展出来的IO口。

  知道以上足够了,没学过的也足够了。

  这个器件的特性是:通过I2C协议操作他的寄存器,他有8个8位寄存器,0-1寄存器是INPUT用,2-3寄存器是OUTPUT用,4-5好像是优先级裁决,6-7是配置寄存器,就是配置IO口是输出还是输入,如果接触过单片机、stm32这种的GPIO程序的话,是很好理解的。(手动滑稽,我出了校门就没接触过了)

  不要问下图的是什么器件(问就是不知道,手动滑稽),这只是举个例子,这个io扩展器的寄存器分配以及功能就是这样的。

IO扩展器编程操作---shell command

  首先这个器件是通过I2C协议操作的,不用关心I2C是什么,他们你可以类比为HTTP。

那么Linux上怎么通过I2C操作这个器件呢?

  首先,Linux上有一组工具:i2c-tool,它可以读取所有芯片的i2c bus上挂载的芯片,设置和读取寄存器等等,拿来做测试或者封装一个程序都是不错的。TX2的ubuntu16.04是自带这个工具的,他的详细用法大家去百度,我不造轮子了。

  在Ubuntu里面操作I2C是非常简单的,你不需要关心I2C的具体传输规定,不用管时序这些烦人的事情。

  首先我们先用工具来测试,美滋滋:

  还记得上文我提了这个IO扩展器的从地址的事情吗?由于我的A0和A1都是接的低电平,在这里我的器件地址是0x74,怎么来的,看下图。

  然后通过i2cdetect查看我们器件的位置(0x74)(注意,这个命令需要传入一个I2C总线序号,我这里是0,也就是说你要知道你这个IO扩展器挂载到哪个总线上的,这和SCL和SDL接线有关,有兴趣的可以去翻一翻手册就知道了,UU代表有人在占用这个设备)

  shell:>i2cdetect -y -r -a 0

  i2cdump可以通过标准i2c协议探测出所有的寄存器的值,下图8个寄存器的值就的出来了,分别对应上面的寄存器说明。XX代表没有这个寄存器。

  shell:>i2cdump -f -y 0 0x74

  然后:

  • i2cset -f -y i2c_bus_num slave_addr reg_num value 设置寄存器值
  • i2cget -f -y i2c_bus_num slave_addr reg_num 获取寄存器值

  其实通过上面的操作就可以完成整个io扩展器的操作,我们可以通过程序执行shell命令的方式设置和操作值。

IO扩展器编程操作---syscall

  实际上,linux做了很多东西,我们可以用标准的linux sys-api来完成以上内容,其实这些api就是i2ctool使用的部分。

  下面不墨迹,直接给出led操作的接口,有需要的参考吧。

int open_led_device(const char * i2c_bus_num, int slave_addr){

    int fd = 0; 

    if ( 0 > (fd = open(i2c_bus_num, O_RDWR)) ){//打开i2c总线

        perror("open i2c bus error:");
return -1;
} if(ioctl(fd, I2C_SLAVE_FORCE, DEVICE_I2C_ADDR) < 0) {//设置从器件地址,这里使用I2C_SLAVE_FORCE进行强行设置,那么这个设备忙 perror("set device slave addr error:");
return -1;
} if ( 0 > write_led_register(fd, LED_REG1_CFG_ADDR, LED_REG1_CFG_VAL) ){//设置写寄存器值,这两个宏和你的硬件连线有关。这里不给出。 printf("init pin for output-mode failed.\n");
close(fd);
return -1;
} return fd; } int read_led_register(int fd, char reg_addr, char *read_val){//读寄存器 if (write(fd, &reg_addr, 1) != 1){//write reg addr ,从器件地址通过open接口设置好后,先写入要读的reg地址 perror("set reg addr error:");
return -1;
} if ( read(fd, read_val, 1) != 1 ){//read data,等待i2c返回刚刚要查询的reg值 perror("read reg error:");
return -1;
}
return 0;
} int write_led_register(int fd, char reg_addr, char data){//写寄存器 char tmp_buf[2]; tmp_buf[0] = reg_addr;//reg 地址
tmp_buf[1] = data;//reg 值 if (write(fd, tmp_buf, 2) != 2){//write data perror("write data error:");
return -1;
} return 0;
} void close_led_device(int fd){//关闭 close(fd);
}

LED灯


  此处省略XXX字。

  相信每个人都知道,常规情况下,在LED灯的两边加电源正极和负极,灯就能亮。在电路设计上,一般来说,LED灯的一端都是和电源正极或者负极是连接好的,另一端和GPIO口接上。如果GPIO输出的电压和另一端电压逻辑一致(比如都是高电平、都是低电平),灯就不亮,反之就亮。

  注意:这段话是有毛病的,但是一般人这样理解就行了(不了解电子电路的就看到这就行了)。对于懂的人,这里多说一句,这里还有一个三极管做开关作用,也是就说LED灯两端都接在电源正负极,中间有个三极管开关。

拨码开关


  这种器件,又是另外一种新奇的东西了,感觉我这两年写的“祖传屎山“太多了,现在看到各种硬件器件都是眼前一亮的感觉。

  就是类似下图这种。

  其作用是:

  你可以人为的按这个+-号按钮,设置数字,这个数字会反应到电路上,从而芯片可以读取你设置的数字。

说白了,你的系统中有个数字参数,你可以通过这种器件进行手动设置,通过驱动程序,就可以更改这个系统参数,是不是 so 简单。

  这里简单说明一下电路是怎么反应出对应的数字的:

  我就举个栗子,下图是个例子拨码开关(手动滑稽,这里多说一句,上图的拨码开关,是4个拨码开关合在一起的,下图的这个输出编码是一个拨码开关的)

  这里可以简单理解为:

  一个拨码开关有5个引脚,一个引脚是C,接GND或者VCC,其他4个是编码引脚,是需要接GPIO,并去取编码的。

  其实很简单:

  例如:C端我接VCC,1248默认值为0,那么数字1,1号引脚接通,那么8421io口输出二进制就是0001,转换为10进制,就是1.

  然后写个程序读取这4个脚的值,转换一下,就OK。

后记


  无

参考文献


打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)

PS: 请尊重原创,不喜勿喷。

PS: 要转载请注明出处,本人版权所有。

PS: 有问题请留言,看到后我会第一时间回复。

TX2 核心板 GPIO、IO扩展器、拨码开关、LED灯 使用总结的更多相关文章

  1. 第一个FPGA工程----点亮开发板上的3个LED灯

    第一个FPGA工程----点亮开发板上的3个LED灯 1.新建FPGA工程 开启Quartus2的画面 File--New Project Wizard..指定工程的路径与工程名 指定所使用的FPGA ...

  2. 灵动微电子ARM Cortex M0 MM32F0010 GPIO 的配置驱动LED灯

    灵动微电子ARM Cortex M0 MM32F0010 GPIO的配置 目录: 1.前言 2.学习方法简要说明 3.要点提示 4.注意事项 5.MM32F0010系统时钟的配置 6.MM32F001 ...

  3. Beaglebone Black–GPIO 高低电平控制 LED 灯

    上一篇,运用 Linux 的 sysfs,控制本机上的 LED 灯,usr0 至 usr3,这次用 GPIO 控制外部的电路,点亮 LED 灯. 这次的全部材料: BBB 一台 购买 BBB 自带的 ...

  4. 树莓派GPIO控制RGB彩色LED灯

    树莓派GPIO通过PWM来控制RGB彩色LED灯,可以显示任何我们想要的颜色. RGB模块简介 这个RGB彩色LED里其实有3个灯,分别是红灯.绿灯和蓝灯.控制这三个灯分别发出不同强度的光,混合起来就 ...

  5. 在 S5PV210 的 开发板上 点亮 一个 LED 灯

    参考学习教程:周立功嵌入式Linux开发教程-(上册) 材料:首先 准备一个 安装好 Linux 的 开发板 使用  xshell 工具 连接 开发板  ,winscp 工具 连接 开发板  ,  准 ...

  6. NodeMCU手把手入门:配置NodeMCU ESP8266开发板环境及点亮LED灯

    之前一直在玩树莓派,最近实验室买了些NodeMCU就想着玩一玩,没想到挺有意思的.其实树莓派能实现的功能,它大部分也可以,价格比派也便宜不少,舍不得买派的同学可以先买这个开发板玩一玩. 本文主要介绍了 ...

  7. (一)stm32f103~~GPIO基本操作一(led灯)

    GPIO基本操作,如果更换IO口只需要更换端口设置即可 led.h文件 #ifndef __LED_H #ifndef __LED_H #define __LED_H #include "s ...

  8. [转] 基于TINY4412的Andorid开发-------简单的LED灯控制

    阅读目录 一.编写驱动程序 二.编写代码测试驱动程序 三.编写HAL代码 四.编写Framework代码 五.编写JNI代码 六.编写App 参考资料: <Andriod系统源代码情景分析> ...

  9. 基于TINY4412的Andorid开发-------简单的LED灯控制

    参考资料: <Andriod系统源代码情景分析> <嵌入式Linux系统开发完全手册_基于4412_上册> 作者:彭东林 邮箱:pengdonglin137@163.com 平 ...

  10. 【转载】基于TINY4412的Andorid开发-------简单的LED灯控制

    阅读目录(Content) 一.编写驱动程序 二.编写代码测试驱动程序 三.编写HAL代码 四.编写Framework代码 五.编写JNI代码 六.编写App 参考资料: <Andriod系统源 ...

随机推荐

  1. RabbitMQ初学

    RabbitMQ 消息队列在软件中的应用场景 异步处理上(优于原先的方式) 为什么优于呢? 首先,通常情况下,如上图我们其实不用消息队列的情况下,其实也可以不用100ms,不用allof即可 那么优势 ...

  2. 如何在 Mac 上配置 VirtualBox Host-Only 网络适配器

    默认Mac 上安装 VirtualBox 后,没有自动配置Host-Only 网络适配器,需要我们手工添加.方法如下: 打开VirtualBox软件, 依次点击 "管理 -> 工具 - ...

  3. 小知识:什么叫做workaround?

    技术人当遇到具体问题,能给出的各种解决方案,有一种类型叫做workaround,翻译过来通常为"应变方法"."变通方法": 其实这种方式通常是没有找到根本的解决 ...

  4. 使用VNC在Windows上远程访问Ubuntu服务器

    Step 0:事前准备 一台安装了ghome桌面的Ubuntu服务器(用作server) 一台Windows机器(用作client) Step 1:Linux服务器 在Ubuntu上安装一个VNC服务 ...

  5. Ubuntu下利用MWAN+LFTP解除单mac速度限制

    起因 公司网络限制了单个mac地址的速度, 而日常经常需要从线上环境下载几个G的数据到本地, 通过FileZilla每次需要一个多小时, 非常不方便 解决方案 WAN聚合 本地网口连接OpenWRT路 ...

  6. Oracle字符串行专列(字符串聚合技术)

    原文链接:http://oracle-base.com/articles/misc/string-aggregation-techniques.php 1     String Aggregation ...

  7. Layui项目实战干货总结(精品)

    写代码时遇到的知识点拿出来分享. 1.layer弹出层显示在top顶层 // 监听工具条 table.on('tool(tb-book)', function (obj) { var data = o ...

  8. 在python中发送自定义消息

    .py import win32api, win32con, win32gui import win32gui_struct import ctypes from ctypes import * GU ...

  9. ContentType组件表使用

    https://www.shuzhiduo.com/A/qVdepN2r5P/

  10. linux系统优化命令--day03

    用户管理与文件权限 给普通用户授权 root 用户 修改/etc/sudoers文件,文件非常重要, 不可以随意更改 vim /etc/sudoers 如果想要给用户赋予权限,我们要使用这个命令 vi ...