gpio接口编程实例

2023-05-16

一、GPIO
    gpio(general purpose ports)通用输入/输出端口
    gpio的操作是所有硬件操作的基础,这是底层开发人员必须掌握的
    
    以三星公司的s3c2410/s3c2440为例做一下简要说明
    s3c2410有117个i/o        分为A~H 8组
    s3c2440有130个i/o        分为A~J 9组
    
二、通过操作寄存器来控制gpio,说明如下
    寄存器类别            中文名称            功能描述
    GPxCON                配置寄存器            配置端口的功能,如作为输入口(input)、输出口(output)以及特殊功能口(如中断信号)
    GPxUP                上拉寄存器            上、下拉电阻的使能/失能(注:上拉电阻作用为当I/O PORTS被定义为input口时,为了避免信号干                                                    扰产生不正确的值,通常会使用上拉电阻。)
    GPxDAT                数据寄存器            只作为普通i/o时用于交互数据
    GPxDRV                驱动能级寄存器        配置引脚的推拉电流能力
    
    注:不同的处理器一般由不同的位数来控制一个pin,这需要查看数据手册才能正确配置,
    关于GPxDRV寄存器有的处理器是没有这组寄存器的,关于GPA一般用于接外部存储器而不作为
    普通的i/o,使用时应当注意这几点。
    
三、上、下拉电阻的作用
    1、钳位电平
    2、抗干扰
    3、提高引脚的推拉电流能力
    
四、引脚的操作步骤
    引脚的操作无外乎3种:输出高低电平,检测引脚状态,中断。
    操作步骤概括如下:
    1、查看引脚对应寄存器地址
    2、配置引脚的功能及上下拉电阻
    3、操作数据寄存器(只限用作普通i/o时)
    注:有的引脚会通过缓冲器与外设相连,缓冲器的作用主要是提高驱动能力,隔离前后级信号。
    
五、裸机程序的设计步骤
    编写源程序、生成可执行文件、烧写程序、运行测试
    
    这个过程中要注意一些问题:
    1、C语言程序在编译器编译生成可执行程序的时会在其中加入几个启动文件代码---ctrl.o、crti.o、
    crtend.o    crtn.o等,它们是标准库文件,用来设置堆栈,然后调用main函数,它们依赖于操作系
    统,在裸机中这些代码无法执行,所以需要自己写一个启动代码。
    2、在这个启动代码中需要做以下几件事
        @1   关看门狗,防止cpu一直自动重启
        @2     设置栈指针,设置sp时候注意其值不能大于内部RAM(IRAM)的空间大小
        @3     调用c程序中的main函数
    3、没有操作系统的裸板上运行程序,只能通过JTAG烧写
    
六、实验实例:实验平台mini2440单板

    1、汇编程序(led_on.S):点亮GPB5~8的四个led灯    
    
    .text                                    @代码段从此处开始
    .global _start                            @将_start标号定义为全局可见
    _start:                                 @程序入口
                LDR     R0,=0x56000010        @将GPBCON寄存器地址值装入R0 
                MOV     R1,#0x00015400        @配置5、6、7、8管脚为输出
                STR     R1,[R0]         
                LDR     R0,=0x56000014        @将GPBDAT寄存器地址值装入R0
                MOV     R1,#0x00000000        @让5、6、7、8管脚为输出低电平
                STR     R1,[R0]     
    MAIN_LOOP:
                B       MAIN_LOOP
    工程Makefile
    
    led_on.bin : led_on.S
        arm-linux-gcc -g -c  led_on.S -o led_on.o
        arm-linux-ld -Ttext 0x0000000 -g led_on.o -o led_on_elf
        arm-linux-objcopy -O binary -S led_on_elf led_on.bin
    clean:
        rm -f   led_on.bin led_on_elf *.o
    
    2、C语言程序(led_on.c)点亮GPB5、7、8的三个led灯
    
    #define GPBCON                (*(volatile unsigned long *)0x56000010)
    #define GPBDAT                (*(volatile unsigned long *)0x56000014)
    #define GPBCON_5678_OUTPUT  0x1<<5*2 | 0x1<<6*2 | 0x1<<7*2 | 0x1<<8*2
    #define GPBDAT_5678_LOW        0x0<<5*1 | 0x0<<6*1 | 0x0<<7*1 | 0x0<<8*1

    int main(int argc, char *argv[])
    {
        GPBCON &= ~(0x3<<5*2 | 0x3<<6*2 | 0x3<<7*2 | 0x3<<8*2);
        GPBCON |= GPBCON_5678_OUTPUT;

        GPBDAT &= ~(0x1<<5*1 | 0x1<<6*1 | 0x1<<7*1 | 0x1<<8*1);
        GPBDAT |= GPBDAT_5678_LOW;    

        GPBDAT |= 0x1<<6*1;

        return 0;
    }
    
    由于前面说过需要自己编写启动代码,若是没有启动代码,交叉编译器会报告缺少
    _start入口,所以必须自己编写一个启动代码
    
    .text
    .global _start
    _start:
            
    halt:
        b    halt
        
    ???这不是一个死循环吗?坑爹!这样led灯肯定不亮啊!!!
    好吧,先不管那么多,我们先用下面的Makefile编译,试试看灯到底亮不?
    
    led_on_test.bin:start.S led_on.c
        arm-linux-gcc -g -c start.S -o start.o
        arm-linux-gcc -g -c led_on.c -o led_on.o
        arm-linux-ld -Ttext 0x00000000 -g led_on.o start.o -o led_test_elf   #@要点1
        arm-linux-objcopy -O binary -S led_test_elf led_test.bin
        arm-linux-objdump -D -m arm led_test_elf > led_on.dis 
    clean:
        @rm *.o *.dis *elf *.bin
    
        二进制文件生成了,先不管把led_test.bin烧入板子,重启板子。看一看,我靠狗日的,
    竟然led灯神奇的亮了,更加坑爹了啊?!什么原因,且待后面继续探索。
        下面是另一个正确的启动代码,按部就班的操作吧!
        
    .text
    .global _start
    _start:
        ldr r0, =0x53000000
        ldr r1, =0x0
        str r1, [r0]

        ldr sp, =1024*4

        bl  main    

    halt:
        b    halt

    下面是Makefile
    led_on.bin:start.S led_on.c
        arm-linux-gcc -g -c start.S -o start.o
        arm-linux-gcc -g -c led_on.c -o led_on.o
        arm-linux-ld -Ttext 0x00000000 -g start.o led_on.o -o led_on_elf         #@要点2
        arm-linux-objcopy -O binary -S led_on_elf led_on.bin
        arm-linux-objdump -D -m arm led_on_elf > led_on.dis
            
    clean:
        @rm *.o *.dis *elf *.bin
        
        我们先使用make执行第一个目标生成led_on.bin ,烧入led_on.bin,然后重启板子,
    看看吧!发现可以正常点亮led灯。靠!当然这不用怀疑了,正确的东西怎能不行呢!
    可是为什么前面的那个坑爹的启动代码竟然可以点亮led灯呢???这的确有点让人费解
    仔细观察下:
    !!!请注意Makefile中的标注要点1 和 要点2  不同点在于链接时候顺序不一样呗!
    链接器在链接时候是以一种从左到右的顺序链接的。就算是这样又怎么了,不是说程序启动时候
    的入口应该都是_start吗???
    要不改下上面的链接顺序, 重新试一下吧!发现还真是这回上面的错误启动代码,不能将led点亮了
    ,虽然现象是正常了(与我们的理论推测结果一致),可是为什么呢?要不看看两次生成的反
    汇编代码吧!
    
    为交换链接顺序时错误的启动代码情况时反汇编如下(只看核心代码部分):
    00000000 <main>:
       0:    e52db004     push    {fp}        ; (str fp, [sp, #-4]!)
       4:    e28db000     add    fp, sp, #0    ; 0x0
       8:    e24dd00c     sub    sp, sp, #12    ; 0xc
       c:    e50b0008     str    r0, [fp, #-8]
      10:    e50b100c     str    r1, [fp, #-12]
      14:    e3a02456     mov    r2, #1442840576    ; 0x56000000
      18:    e2822010     add    r2, r2, #16    ; 0x10
      1c:    e3a03456     mov    r3, #1442840576    ; 0x56000000
      20:    e2833010     add    r3, r3, #16    ; 0x10
      24:    e5933000     ldr    r3, [r3]
      28:    e3c33bff     bic    r3, r3, #261120    ; 0x3fc00
      2c:    e5823000     str    r3, [r2]
      30:    e3a02456     mov    r2, #1442840576    ; 0x56000000
      34:    e2822010     add    r2, r2, #16    ; 0x10
            …………………………中间省略n行………………………………
      a0:    e1a00003     mov    r0, r3
      a4:    e28bd000     add    sp, fp, #0    ; 0x0
      a8:    e8bd0800     pop    {fp}
      ac:    e12fff1e     bx    lr

    000000b0 <_start>:
      b0:    eafffffe     b    b0 <_start>
    交换链接顺序后错误的启动代码情况时反汇编如下:
    00000000 <_start>:
       0:    eafffffe     b    0 <_start>

    00000004 <aa>:
       4:    e52db004     push    {fp}        ; (str fp, [sp, #-4]!)
       8:    e28db000     add    fp, sp, #0    ; 0x0
       c:    e24dd00c     sub    sp, sp, #12    ; 0xc
      10:    e50b0008     str    r0, [fp, #-8]
      14:    e50b100c     str    r1, [fp, #-12]
      18:    e3a02456     mov    r2, #1442840576    ; 0x56000000
      1c:    e2822010     add    r2, r2, #16    ; 0x10
      20:    e3a03456     mov    r3, #1442840576    ; 0x56000000
      24:    e2833010     add    r3, r3, #16    ; 0x10
      28:    e5933000     ldr    r3, [r3]
      2c:    e3c33bff     bic    r3, r3, #261120    ; 0x3fc00
      30:    e5823000     str    r3, [r2]
      34:    e3a02456     mov    r2, #1442840576    ; 0x56000000
            …………………………中间省略n行………………………………
      a0:    e3a03000     mov    r3, #0    ; 0x0
      a4:    e1a00003     mov    r0, r3
      a8:    e28bd000     add    sp, fp, #0    ; 0x0
      ac:    e8bd0800     pop    {fp}
      b0:    e12fff1e     bx    lr
      
    反汇编代码中依次含义如下
        0:        e52db004         push    {fp}
     地址         机器码            指令助记码
     
    其中地址指的是这条指令的存储位置,指令十六进制码(机器码)是这条指令在计算
    机中实际存储的数据形式, 指令助记码其实是指令十六进制码一种通俗一点的
    表达符号,目的是让程序员更容易看懂,试想一直让你看机器码,你是不是会疯掉啊。
    
    比较两者的反汇编代码不难知道,原来是“eafffffe     b    0 <_start>”这一条指令
    被存放在了不同的地址,才导致截然不同的结果,程序在运行时候依次由低地址往
    高地址依次取指令顺序顺序执行,所以前者在没有进入_start入口直接进入了main函数
    执行所以才出现了令人诧异的结果。
    
        总结后一定牢记:链接器在链接时候是以一种从左到右的顺序链接的,最好把启动代码
    作为第一个链接对象放在最左边,使其最先链接。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gpio接口编程实例 的相关文章

  • 树莓派4B gpio readall 出现Oops - unable to determine board type... model: 17

    树莓派使用GPIO接口是基于wiringPi的 官网链接 xff1a http wiringpi com 1 xff1a 出现问题的界面 pi 64 raspberrypi gpio v gpio version 2 50 Copyrigh
  • NVIDIA Jetson NX 控制GPIO

    目录 前言运行引脚图片 前言 看到一些博客说需要pip安装Jetson GPIO 以及通过下面命令设置用户权限 sudo groupadd span class token operator span f span class token
  • DSP中GPIO位域

    在TMS320F2812中 xff0c 对于程序中寄存器的名称是如何映射到物理地址的 xff0c 这里做一下详细的讲解 主要应用到三个文件 xff1a CMD h DSP28 GLobalVariableDefs c xff0c 其中CMD
  • STM32 GPIO模拟UART串口:最简延时方式

    STM32 GPIO模拟UART串口 xff1a 最简延时方式 在一些应用场景 xff0c MCU的硬件UART资源不足时 xff0c 或者可用于硬件UART配置的管脚优先配置给了其它功能使用 xff0c 就可以通过GPIO模拟UART功能
  • Jetson Xavier gpio编程 (8)

    GPIO lines are attached to gpiochips Look in sys class gpio and you should see gpiochip240 248 and 288 I haven t yet det
  • GPIO

    一 什么是GPIO xff1f 首先应该理解什么是GPIO GPIO xff0c 英文全称为General Purpose IO ports xff0c 也就是通用IO口 在嵌入式系统中常常有数量众多 xff0c 但是结构却比较简单的外部设
  • 28335之GPIO输入

    include 34 DSP2833x Device h 34 include 34 DSP2833x Examples h 34 define LED GpioDataRegs GPADAT bit GPIO0 GPIO配置函数 void
  • 【跟着江科大学Stm32】GPIO_LED_流水灯_蜂鸣器

    只要坚持下来了 xff0c 一定会有收获 xff01 一 LED闪烁 span class token macro property span class token directive hash span span class token
  • jetson nano GPIO控制说明

    文章目录 一 GPIO介绍二 安装GPIO库python库C 43 43 库 三 几种常用的通信协议UARTPWMI2CI2SSPI 四 控制函数说明python xff08 参考 https pypi org project Jetson
  • AIR103

    基础资料 基于Air103开发板 Air103 LuatOS 文档 上手 开发上手 LuatOS 文档 探讨重点 对官方社区库接口GPIO库使用及示例进行复现及分析 了解该的基本原理及操作方法 软件及工具版本 LuatOS AIR103 b
  • 新唐NUC980使用记录(5.10.y内核):在用户应用中使用GPIO

    文章目录 目的 使用参考与演示 使用参考 存在的问题 问题定位 修改设备树 使用测试 总结 设备树文件内容 目的 GPIO是最基础的外设 使用频率也非常高 这篇文章将简单体验在NUC980 Liunx用户应用中使用GPIO功能 这篇文章中内
  • 关于stm32的GPIO的操作

    首先先了解一下输出的模式 比较常用的是 推挽输出 1 GPIO Mode AIN 模拟输入 2 GPIO Mode IN FLOATING 浮空输入 3 GPIO Mode IPD 下拉输入 4 GPIO Mode IPU 上拉输入 5 G
  • MC9S12XEP100引脚的复用方式

    嵌入式码农小明最近在研发一个嵌入式产品 用的MC9S12XEP100芯片 其中三个需求需要通过几个使用SPI通讯的芯片实现 硬件开发人员小红照着芯片原理图布好了线 不知是否是没考虑到SPI通讯可以通过CS line来控制要通讯的从机从而实现
  • 学习笔记:STM32的ACD

    STM32f103系列有3个ADC ADC1 ADC2 ADC3 通道 ADC1和ADC2都有16个外部通道 2个内部通道 连接到温度传感器和内部参考电压 VREFINT 1 2V ADC3有8个外部通道 通道列表 通道顺序转换 使用多个通
  • ESP32C3解锁使用IO11

    目录 1 使用pip安装esptool 2 安装idf开发命令行环境 可参考 3 将开发板插入电脑 4 打开IDF CMD命令行 5 打开命令行窗口 源自官方wiki 本篇介绍如何给ESP32C3多释放一个io ESP32C3的GPIO11
  • 在 ARM 上的 Linux 中写入和读取内存映射设备寄存器

    我正在尝试按照以下步骤读取和写入 ARM9 SAM9X25 上的寄存器 http infocenter arm com help index jsp topic com arm doc faqs ka3750 html我以以下代码结束 in
  • Raspberry Pi RuntimeError:已为此 GPIO 通道启用冲突边缘检测

    我正在遵循此处找到的教程 https www linkedin com pulse prepare your raspberry pi work aws iot kay lerch I have not even begun the int
  • Raspberry Pi RPi.GPIO 错误并带有威胁回调

    我被 Python 包中的 wait for edge 函数困住了RPi http sourceforge net p raspberry gpio python wiki Inputs 我为 GPIO 下降添加了多个事件检测 只要回调函数
  • 如何检查您的内核是否支持硬件上的 GPIO?

    我的目标是控制 Intel 主板 带 C1037U 处理器的 NM70 芯片组 上 Peppermint 4 Linux 内核版本 3 8 0 中的 GPIO 引脚 如何检查您的内核是否支持硬件上的 GPIO 背景 主板 Intel NM7
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后

随机推荐

  • 7.Linux网络编程-UNIX域套接字

    一 xff1a UNIX套接字 用于同一台pc上运行的进程之间通信 xff0c 它仅仅复制数据 xff0c 不执行协议处理 xff0c 不需要增加删除网络报头 xff0c 无需计算校验和 xff0c 不产生顺序号 xff0c 无需发送确认报
  • 8.Linux网络编程-System V消息队列

    一 xff1a 消息队列 消息队列是进程间通信的一种手段 xff0c 进程产生的数据块以链表的形式存储在消息队列中 xff0c 每个数据块都被认为是有一个类型 xff0c 接收者进程接收的数据块可以有不同的类型 消息队列有以下的几个限制 x
  • 9.Linux网络编程-SYSTEM V共享内存

    一 xff1a 内存映射文件 1 基本原理 mmap是一种内存映射文件的方法 xff0c 即将一个文件或者其它对象映射到进程的地址空间 xff0c 实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系 实现这样的映射关系后 xff
  • ubuntu16.04安装openstack(ocata)

    一 系统和openstack信息 Liunx系统 xff1a ubuntu16 04 server 64位 openstack版本 xff1a stable ocata 二 VMware配置 1 处理器 xff1a 数量1 xff0c 核心
  • 代码注释规范

    一 背景 1 当我们第一次接触某段代码 xff0c 但又被要求在极短的时间内有效地分析这段代码 xff0c 我们需要什么样的注释信息 xff1f 2 怎么样避免我们的注释冗长而且凌乱不堪呢 xff1f 3 在多人协同开发 维护的今天 xff
  • 1.Linux网络编程-字节序和地址转换函数

    1 IPv4套接口地址结构 IPv4套接口地址结构通常称为 网际套接字地址结构 xff0c 它以 sockaddr in 命名 xff0c 定义在头文件 lt netinet in h gt 中 struct sockaddr in uin
  • 2.Linux网络编程-socket函数和C2S实现

    1 TCP客户 服务器模型 TCP服务器 xff1a socket gt bind gt listen gt accept gt block直至客户连接到达 gt read gt 处理请求 gt write gt read gt close
  • form表单通过request取不到值multipart/form-data 文件上传表单中传 递参数无法获取的原因!

    1 什么是multipart form data 首先我们需要明白在html中的enctype属性 xff0c enctype xff1a 规定了form表单在发送到服务器时候编码方式 他有如下的三个值 application x www
  • 3.Linux网络编程-粘包处理

    visiopacket h Created on 2019年5月8日 Author hfeng liu 粘包处理 xff1a 由于TCP是基于流传输的机制 xff0c 当发送多个间隔较小的小报文时 xff0c 它会在缓冲区中缓存成一个报文发
  • linux shell脚本执行sql语句建表建库

    linux shell脚本执行sql语句建表建库 1 创建sql脚本2 创建shll脚本 1 创建sql脚本 创建contract ddl sql span class token comment 创建数据库contract user sp
  • 【Windows版】VScode配置C++开发环境

    博客已更新 xff1a Windows版 VScode配置C 43 43 开发环境 花花少年的博客 CSDN博客
  • Windows+COLMAP三维重建教程【exe安装】

    一 步骤 1 下载COLMAP COLMAP COLMAP 2 解压并运行COLMAP 3 稀疏三维重建 xff0c 生成稀疏图 4 稠密图三维重建 xff0c 生成稠密图 二 可能出现的问题 1 Dense stereo reconstr
  • FFmpeg教程(超级详细版)

    一 参考资料 通过ffmpeg把图片转换成视频 FFmpeg命令 一 使用filter complex命令拼接视频 FFmpeg 视频处理入门教程给新手的 20 多个 FFmpeg 命令示例 FFmpeg命令行转码 ffmpeg 翻译文档
  • yolov5+Deepsort实现目标跟踪

    一 参考资料 项目源码 pytorch yolo5 43 Deepsort实现目标检测和跟踪 工程落地 YoloV5 43 deepsort 43 Fast ReID 完整行人重识别系统 xff08 三 xff09 yolov5 deeps
  • 华为Ascend昇腾适配PyTorch框架

    一 参考资料 PyTorch用户文档 PyTorch网络模型移植 amp 训练指南 AscendPyTorch 第三方框架适配 二 重要说明 CPU架构为ARM架构时 xff0c 由于社区未提供ARM架构CPU版本的torch包 xff0c
  • 提高工作效率的宝藏网站和宝藏工具

    一 好用的网站 面包多 面包多 创作者在面包多 xff0c 通过出售课程 xff0c 文章 xff0c 绘画 xff0c 创意作品 xff0c 软件 xff0c 电子书 xff0c 音乐 xff0c 游戏 xff0c 咨询服务 xff0c
  • ubuntu服务器相关教程

    二 常用操作 1 ssh相关 span class token comment 安装ssh服务 span span class token function sudo span span class token function apt g
  • 超级实用的C++学习网站

    重要说明 xff1a 该博客长期更新 xff0c 方便读者查阅 xff01 一 参考资料 学习C 43 43 这几个网站足矣 二 C 43 43 学习网站 C 43 43 中文网 cppreference 当之无愧的C 43 43 学习第一
  • Vue 安装 Element Plus

    Element UI 是一款基于 Vue 的桌面端组件库 xff0c 提供了丰富的PC端组件 xff0c 简化了常用组件的封装 xff0c 大大降低了开发难度 随着 Vue 版本的更新 xff0c Element UI 2 x 升级到了El
  • gpio接口编程实例

    一 GPIO gpio general purpose ports 通用输入 输出端口 gpio的操作是所有硬件操作的基础 xff0c 这是底层开发人员必须掌握的 以三星公司的s3c2410 s3c2440为例做一下简要说明 s3c2410