tag 标签: GPIO

相关帖子
相关博文
  • 热度 9
    2021-10-25 18:16
    1100 次阅读|
    0 个评论
    【灵动微电子MM32 eMiniBoard】+6路PWM输出测试
    灵动微电子MM32 eMiniBoard 036的MCU为:MM32F3277G7P 主要参数如下: 成品做工不错,布局整体合理,如下: 我只测试了一下6路PWM输出,步骤如下: 用TIME1的六路PWM输出,找到相应GPIO口并配置为PWM输出。 六步换相对应代码如下: 下载程序,输出波形如下: 从输出波形可以看出,未输出PWM的通到有轻微扰动,我这是未驱动后级电路的情况下测试的,所以相关GPIO的带载能力和相互影响如用到实际项目时,应重点测试评估。 后面有时间测试再更新内容,感谢面包板提供的测试样板。
  • 热度 2
    2021-6-29 16:03
    1851 次阅读|
    1 个评论
    灵活使用单片机GPIO各种输入输出模式
    单片机的 GPIO 一般会有: 输入 输出 模式,输入模式有输入上拉,下拉或高阻 输出模式有推挽,开漏。 51 单片机还有准双向模式。 输入模式 上拉,下拉都比较好理解。比如按键输入时,将口线设置为输入上拉,这样就按键可以不上拉。输入上拉模式一般上拉电流很小,通常情况为数百微安,如果上拉电流不合适,外围电路就得单独考虑上拉问题。 输出模式常用推挽输出,当输出高电平时,可以源出电流,输出低电平时,可以源入电流。 比如点亮一个 LED 灯,使用低电平点亮,使用推挽输出,如果 LED 灯被上拉到 5V , 3.3V 系统上,为高时, LED 有可能仍然会亮。只是比为低时亮度小一点。这种情况下,如果将输出改为 OD , LED 就可以正常亮灭。 另一个例子, GPIO 模拟 I ² C 总线。 SCL 线可以设置为推挽输出,没问题。但 SDA 是双向的,读取数据时或读 ACK 时,需要改变端口方向。比如 SDA 输出为 PP 高,从器件异步 ACK 拉低,端口会输出大电流。如果 SDA 线改成 OD 输出,则无此问题。当需要输入时,不需要改变端口方向,只需要将端口输出置高即可。总线上不会有异常电流。 51 单片机的准双向模式就更神奇了,可以与 OD 输出类比,但不需要外接上拉电阻(加了也无妨)。 输出为高时,在开始的 2 个 CPU 时钟为强上拉,保证动态特性,随后变成弱上拉。此时如果外部输入为高,则保持弱上拉,可以读入稳定的高。如果外部输入为低,端口变成极弱上拉,能读入低。当输出为低的时候,强下拉到低。需要注意的是,外部输入的电流不要过大,不然端口电流过大,可能会 latch up 。
  • 热度 9
    2020-7-1 11:40
    2262 次阅读|
    0 个评论
    By Toradex 秦海 1). 简介 NXP iMX8 是 NXP 去年底发布的基于 Cortex-A72/A53 和 Coretex-M4 异构多核架构的 ARM 处理器,本文就基于嵌入式 Linux 演示 GPIO 相关应用示例。 本文所演示的 ARM 平台来自于 Toradex 基于 NXP iMX8QM ARM 处理器的 Apalis iMX8QM ARM 嵌入式平台。 2). 准备 a). Apalis iMX8QM ARM 核心版配合 Apalis Evaluation Board 载板 ,连接调试串口 UART1 (载板 X29 )到开发主机方便调试。 b). Apalis iMX8 Cortex-A 核心安装 Toradex Ycoto Linux Console image V3.04 版本,详细信息请参考 这里 。 d). Apalis Evaluation Board GPIO 相关硬件连接 X2 MXM_3 X34 LED1 X2 MXM_5 X34 SW5 X2 MXM_11 X34 SW1 3). GPIO 命令行测试 a). 嵌入式 Linux 系统下之前呗广泛应用的 GPIO 工具为 sysfs GPIO 接口( /sys/class/gpio ),但是目前这个项目已经处于 deprecated 状态,经 Linux Kernel Community 确定其替代者就是 GPIO 字符设备 API Libgpiod 。因此,尽管本文测试使用的 Toradex Ycoto Linux Console image V3.04 版本依然支持 sysfs GPIO 接口,但是已经不建议使用,如果需要相关说明,可以参考 这里 。本文接下来的测试都是基于 Libgpiod 来进行。 b). GPIO 数字编码 ./ ARM SOC 定义 GPIO 管脚通常为一串字母数字的组合,之前 sysfs API 操作时候需要将不同 SOC GPIO 的字母数字命名转换为纯数字编码,对于不同的 SOC 转换规则的详细说明请见 这里 ,而本文使用的 libgpiod API 则直接可以按照 GPIO 命名进行操作,更为直观和便利。 ./ 首先根据 Apalis iMX8 datasheet 4.4 章节的表格,找出所需要 GPIO 管脚的字母数字组合命名,比如本文涉及的三个 GPIO 管脚;在接下来的 Libgpiod API 中都需要使用对应的 GPIO 命名中的 和 这两个参数来操作对应的 GPIO 管脚 ### GPIO 字符数次串命名规则: LSIO.GPIO .IO LSIO.GPIO0.IO09 LSIO.GPIO0.IO12 LSIO.GPIO4.IO01 c). 在具体调试 GPIO 之前,还需要确认在 Linux kernel device tree 中,这个管脚被定义为 GPIO 且并没有被其他驱动功能占用,否则在具体操作 GPIO 的时候会出现冲突导致异常,关于 device tree 的说明本文不赘述,可以参考 这里 。本文所涉及的三个 GPIO 管脚默认即配置为 GPIO ,因此无需修改。 d). 调用 Libgpiod API 在命令行下进行 GPIO 测试 ./ Apalis iMX8 上电开机进入嵌入式 Linux 系统,下面操作在调试串口下进行 ./ 罗列 GPIO banks ,也就是对应的上面提到的 controller 。可以看到有 8 个 banks ,每个 banks 包含 32 lines ,也就是 32 gpio 。当然,实际上结合具体的 SOC 和模块定义,不一定每个 banks 和 lines 都有对应的 GPIO 管脚,有效的肯呢个只是一部分。 ----------------------------------- root@apalis-imx8:~# gpiodetect gpiochip0 (32 lines) gpiochip1 (32 lines) gpiochip2 (32 lines) gpiochip3 (32 lines) gpiochip4 (32 lines) gpiochip5 (32 lines) gpiochip6 (32 lines) gpiochip7 (32 lines) ----------------------------------- ./ 查看某个 bank 具体 GPIO lines 的情况,可以查看系统中当前哪些 GPIO 被占用了。 ----------------------------------- root@apalis-imx8:~# gpioinfo 0 gpiochip0 - 32 lines: line 0: unnamed unused input active-high line 1: unnamed unused input active-high line 2: unnamed unused input active-high line 3: unnamed unused input active-high line 4: unnamed unused input active-high line 5: unnamed unused input active-high line 6: unnamed unused input active-high line 7: unnamed unused input active-high line 8: unnamed unused output active-high line 9: unnamed unused output active-high line 10: unnamed unused input active-high line 11: unnamed unused input active-high line 12: unnamed unused input active-high line 13: unnamed unused input active-high line 14: unnamed unused input active-high line 15: unnamed unused input active-high line 16: unnamed unused input active-high line 17: unnamed unused input active-high line 18: unnamed unused input active-high line 19: unnamed unused input active-high line 20: unnamed unused input active-high line 21: unnamed unused input active-high line 22: unnamed unused input active-high line 23: unnamed unused input active-high line 24: unnamed unused input active-high line 25: unnamed unused input active-high line 26: unnamed unused input active-high line 27: unnamed unused input active-high line 28: unnamed unused input active-high line 29: unnamed unused input active-high line 30: unnamed "reset" output active-low line 31: unnamed "usb3503 connect" output active-high ----------------------------------- ./ 测试 X2 MXM_3 管脚 GPIO output 操作, gpioset 命令的作用就是设置对应 GPIO 管脚为输出状态,并输出为设置的高或者低电平。 ----------------------------------- # 设置 GPIO 输出为高电平驱动 LED 点亮 root@apalis-imx8:~# gpioset 0 9=1 # 设置 GPIO 输出为低电平驱动 LED 熄灭 root@apalis-imx8:~# gpioset 0 9=0 # 通过 gpioinfo 查看 bank0 可以发现 line 9 是 output 状态 root@apalis-imx8:~# gpioinfo 0 gpiochip0 - 32 lines: …… line 9: unnamed unused output active-high …… ----------------------------------- ./ 测试 X2 MXM_11 管脚 GPIO input 操作, gpioget 命令的作用就是设置对应 GPIO 管脚为输入状态,并读取当前的 GPIO 电平。 ----------------------------------- # SW1 拨至低电平位置(靠近载板边缘),读取连接的 X2 MXM_11GPIO 电平 root@apalis-imx8:~# gpioget 4 1 0 # SW1 拨至高电平位置(远离载板边缘),读取连接的 X2 MXM_11GPIO 电平 root@apalis-imx8:~# gpioget 4 1 1 # 通过 gpioinfo 查看 bank4 可以发现 line 1 是 input 状态 root@apalis-imx8:~# gpioinfo 4 gpiochip4 - 32 lines: …… line 1: unnamed unused input active-high …… ----------------------------------- ./ 测试 X2 MXM_5 管脚 GPIO 中断操作, gpiomon 命令的作用就是设置对应的 GPIO 为输入状态,并监测对应 GPIO 管脚的事件(。 ----------------------------------- # 设置 X2 MXM_5 管脚中断监测 root@apalis-imx8:~# gpiomon 0 12 # 按下 SW5 按键 event: RISING EDGE offset: 12 timestamp: # 松开 SW5 按键 event: FALLING EDGE offset: 12 timestamp: # 通过 gpioinfo 查看 bank0 可以发现 line 12 是 input 状态 root@apalis-imx8:~# gpioinfo 0 gpiochip0 - 32 lines: …… line 12: unnamed unused input active-high …… ----------------------------------- 4). GPIO C 代码示例程序测试 a). 首先先在开发 Linux 主机安装 SDK , SDK 为按照这里说明通过 Ycoto project/OpenEmbedded 环境编译得到,安装过程中根据提示可以自行更改 SDK 安装目录 ----------------------------------- $ chmod +x tdx-xwayland-glibc-x86_64-Qt5-Wayland-Image-aarch64-toolchain-2.6.4.sh $ ./tdx-xwayland-glibc-x86_64-Qt5-Wayland-Image-aarch64-toolchain-2.6.4.sh TDX Wayland with XWayland SDK installer version 2.6.4 ===================================================== Enter target directory for SDK (default: /opt/tdx-xwayland/2.6.4): You are about to install the SDK to " ". Proceed ? Y … ----------------------------------- b). c 代码示例 1 - 测试 X2 MXM_3 管脚输出循环驱动 LED 亮和灭,时间间隔为 1s ./ 源代码参考如下 https://github.com/simonqin09/Apalis_iMX8_Libgpiod/blob/master/gpio-toggle/gpio-toggle.c ./ 主要说明如下 ----------------------------------- ### include libgpiod 头文件 #include ### 定义 GPIO chip 和 line 结构体 struct gpiod_chip *output_chip; struct gpiod_line *output_line; ### 配置 GPIO 为输出 output_chip = gpiod_chip_open_by_name(chip); output_line = gpiod_chip_get_line(output_chip, offset); gpiod_line_request_output(output_line, "gpio-toggle", GPIOD_LINE_ACTIVE_STATE_HIGH); ### 切换 GPIO 输出状态 int line_value = 0; OR ine_value = 1; gpiod_line_set_value(output_line, line_value); ----------------------------------- ./ 编译,本示例使用通过命令行编译方式,详细说明请参考 这里 ----------------------------------- ### export SDK 环境变量 $ source /environment-setup-aarch64-tdx-linux ### 编译,因为需要 gpiod 库,因此要再 link 选项加入 -lgpiod 选项,否则会出现 ”undefined reference to …” 错误 $ cd $ ${CC} -Wall -lgpiod -lpthread gpio-toggle.c -o gpio-toggle ### 部署 $ scp gpio-toggle root@ :/home/root ----------------------------------- ./ 测试,在 Apalis iMX8 上面运行刚编译部署好的 gpio-toggle 二进制程序,载板上面的 LED1 LED 灯会 1s 间隔亮和灭 ----------------------------------- root@apalis-imx8:~# cd /home/root/ root@apalis-imx8:~# ./gpio-toggle Usage by bank/pin number: gpio-toggle OUTPUT-BANK-NUMBER OUTPUT-GPIO-NUMBER root@apalis-imx8:~# ./gpio-toggle 0 9 LED turns ON LED turns OFF LED turns ON LED turns OFF …… ----------------------------------- c). c 代码示例 2 - 测试 X2 MXM_5 管脚通过按键输入,捕获上升沿事件后切换 X2 MXM_3 输出状态驱动 LED 亮和灭 ./ 源代码参考如下 https://github.com/simonqin09/Apalis_iMX8_Libgpiod/blob/master/gpiotest/gpiotest.c ./ 主要说明如下 ----------------------------------- ### include libgpiod 头文件 #include ### 定义 GPIO chip 和 line 以及 event 结构体 struct gpiod_chip *input_chip; struct gpiod_line *input_line; struct gpiod_line_event event; ### 配置 GPIO 为输入,中断事件为上升沿 input_chip = gpiod_chip_open_by_name(chip); input_line = gpiod_chip_get_line(input_chip, offset); gpiod_line_request_rising_edge_events(input_line, "gpiotest"); ### GPIO 输入事件响应 while (1) { gpiod_line_event_wait(input_line, NULL); if (gpiod_line_event_read(input_line, &event) != 0) continue; /* this should always be a rising event in our example */ if (event.event_type != GPIOD_LINE_EVENT_RISING_EDGE) continue; …… } ----------------------------------- ./ 编译,本示例使用通过 Eclipse IDE 工具进行编译,详细 Eclipse IDE 下载安装以及 SDK 配置说明请参考 这里 ----------------------------------- ### export SDK 环境变量 $ source /environment-setup-aarch64-tdx-linux ### 在同一个终端中启动 Eclopse IDE $ cd $ ./eclipse ### 在 Eclipse IDE 下参考上面的说明文档创建新的 C/cross compile 工程,并按照说明文档配置好 SDK 。同样因为 linker 需要 gpiod 相关库,因此要在下面位置增加相关库 菜单: Properties 选项卡 : Settings 选项 : Libraries Libraries (-l) 栏目下面增加: gpiod ### Eclipse 点击 build 进行编译,根据选择是 Debug 还是 Release ,编译后的二进制文件会在对应的目录,本文使用 Debug ### 部署 $ cd /gpiotest/Debug $ scp gpiotest root@ :/home/root ----------------------------------- ./ 测试,在 Apalis iMX8 上面运行刚编译部署好的 gpiotest 二进制程序,载板上面的 LED1 LED 灯初始状态为灭,随着按下 SW5 按键交替亮和灭 ----------------------------------- root@apalis-imx8:~# cd /home/root/ root@apalis-imx8:~# ./gpiotest Usage by bank/pin number: gpio-test INPUT-BANK-NUMBER INPUT-GPIO-NUMBER OUTPUT-BANK-NUMBER OUTPUT-GPIO-NUMBER root@apalis-imx8:~# ./gpiotest 0 12 0 9 LED initial status is OFF button pressed 1 times LED turns ON button pressed 2 times LED turns OFF button pressed 3 times LED turns ON …… ----------------------------------- 5). 总结 本文基于 NXP iMX8 示例了嵌入式 Linux 使用 Libgpiod API 来驱动 GPIO ,通过示例可见其直观性和便利性均大大优于传统的 sysfs API ,因此会被 Linux Kernel Community 确定为 sysfs API 的替代者。
  • 热度 15
    2013-8-13 09:56
    991 次阅读|
    0 个评论
      KL25系列和其它的单片机一样为了实现在有限的引脚封装内实现更多的功能每个引脚基本上都是多路复用,当然有些引脚例外,如VDD,VSS,RESET等等。它和有些单片机有所区别,有的单片机多路复用的引脚只要你使能相关的功能,此引脚便自动的成为了该功能相关引脚,而KL25不仅需要使能将用到的功能模块并且还要配置I/O口引脚,而与这个功能设置相关的模块便是MCU内部的Signal Multiplexing and Signal Descriptions Module和Port Control and interrupts Module(PORT)。KL25的端口中不是所有的端口都具有外部中断能力只有PortA和PortD具有中断能力。同样KL25独特的时钟模式即如要想要使用某一功能模块必须要先使能其时钟源,同样在使用PORT模块时首先就是要使能其时钟源。在进行端口引脚分配时注意不要为一个引脚分配多个功能还有具有相同功能的引脚分配的相互之间应尽量靠近如分配I2C功能引脚时CLK和DATA引脚应尽量靠近KL25 PORT模块具有以下特点:1.引脚中断选择。2.端口控制。PORT模块具有以下四种工作模式:1.运行模式。PORT运行正常。2.等待模式。PORT运行正常,如果使能了中断检测能让MCU从低功耗下唤醒,DMA请求仍然可以但不能让MCU从低功耗下唤醒。3.停止模式。在停止模式下PORT能配置为如果中断使能检测的情况下能通过异步的唤醒信号将MCU进行唤醒。4.调试模式。PORT运行正常。PORT模块的相关寄存器不多,主要为PORTx_PCRn,PORTx_GPCLR,PORTx_GPCHR,PORTx_ISFR。设置起来相对较简单。PORTx_PCRn主要是端口相关功能设置,PORTx_GPCLR,PORTx_GPCHR主要是为了同时让几个端口具有相同的设置而不用单独的去进行设置,减小了麻烦。PORTx_ISFR为端口中断状态寄存器主要是相关位的中断标志,如果该位置1后需通过软件对相关位进行重写1,便可清除中断标志位,如果电平检测,当中断产生后如果电平有效状态依旧存在则马上又产生中断。总的来说,KL25的端口操作较为简单。以配置外部中断为例简单说说步骤:1.使能PORTx时钟源。2.为I/O口选择功能。3.配置中断发生模式(电平,边沿,DMA)。
  • 热度 10
    2013-6-26 20:24
    1437 次阅读|
    1 个评论
     先说说我对STM32 IO口的认识吧。 刚开始学习一款单片机的时候一般都是从操作IO口开始的,所以我也一样,先是弄个流水灯。 刚开始我对STM32的认识不够,以为是跟51单片机类似,可以直接操作端口,可是LED灯却没反应,于是乎,仔细查看资料发现,原来对于ARM,不管你要操作哪个IO口,都要先配置IO口。 不过对于普通的IO口的应用,配置会比较简单,主要就以下几个步骤: 1.打开相应IO口的时钟; 2.打开IO口相应引脚位; 3.配置IO口的模式; 4.初始化IO端口。   对于STM32的IO口可以根据需要由软件配置成8种模式: 1.输入浮空; 2.输入上拉; 3.输入下拉; 4.模拟输入; 5.开漏输出; 6.推挽输出; 7.推挽式复用功能; 8.开漏复用功能   那么我就把IO初始化端口的部分程序贴出来大家共享。 /*************************************************************************************** **************************************************************************************** * FILE : LED.c * Description : LED flash *   * Study STM32 record. *  * History:           LED0            PA.0  LED1            PA.1  LED2          PA.12  LED3            PA.13  LED4            PA.14  LED5            PA.15 * Version Name       Date Description    1.0    Penny   2013.05.31         **************************************************************************************** ****************************************************************************************/    #include "ms5.h"   void LED_Init(void) {   GPIO_InitTypeDef  GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; //LED0--PB.0 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); //初始化PB口 GPIO_SetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);//PB.0 输出高   delay_ms(10);   GPIO_ResetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); }    
相关资源