物联网技术
直播中

手托初梦

9年用户 849经验值
擅长:可编程逻辑 嵌入式技术
私信 关注
[问答]

怎样通过寄存器去操作GPIO?GPIO有哪些操作实例?

GPIO是什么?
怎样通过寄存器去操作GPIO?GPIO有哪些操作实例?

回帖(1)

刘婷

2021-6-28 15:48:03
  1、GPIO
  GPIO(General Purpose Input/Output Port),即通用输入输出端口,就是芯片的一些引脚。作为输入端口时,我们可以通过它们读入引脚的状态--高电平或低电平,作为输出端口时,我们可以通过它们输出高电平或低电平来控制连接的外围设备。
  S3C2440有130个GPIO引脚,分为A~J共9组:GPA、GPB、…、GPJ。通过设置相应的寄存器来设置某个引脚的功能(输入或输出或是其他特殊功能)。
  2、通过寄存器操作GPIO
  每个端口可以很容易的通过软件配置以满足各种系统配置和设计需求,在使用之前你必须定义每个引脚的功能,如果不是用于复用功能,则引脚可以配置为普通输入输出端口。
  1)端口配置寄存器GPxCON(x为A~J)
  GPxCON是用于选择引脚功能。
  PORT A的端口配置寄存器GPACON中每一位对应一个引脚(PORT A共23个引脚,bit0~bit22对应GPA0~GPA22)。当某位被设为0时,相应的引脚被设置成输出引脚,此时可以在GPADAT中相应位写入0或1让此引脚输出低电平或高电平。当某位被设为1时,相应的引脚被设为地址线或用于地址控制,此时GPADAT无用。(GPACON通常被设为全1,以便访问外部存储器件)
  PORT B~PORT J的端口配置寄存器操作完全相同:GPxCON中每两位控制一个引脚,00为输入、01为输出、10为特殊功能、11保留。
  2)端口数据寄存器GPxDAT(x为A~J)
  GPxDAT是用于读/写引脚数据。
  当引脚被设为输入时,读此寄存器可得到相应引脚的电平状态是高还是低;当引脚被设为输出时,通过写此寄存器的相应位可设置相应引脚输出高电平或低电平。
  3)端口上拉寄存器GPxUP(x为B~J,注意:PORT A端口没有这个寄存器)
  GPxUP是用于选择是否使用内部上拉电阻。
  此寄存器的某位被设置为1时,相应引脚不使用内部上拉电阻;设置为0时,相应引脚使用内部上拉电阻。
  3、使用软件来访问硬件
  对单个引脚的操作有3种:输出高低电平、检测引脚状态、中断,这些操作一般通过读、写寄存器完成。如图2所示威廉希尔官方网站 ,可以设置GPFCON寄存器将GPF4、GPF5、GPF6引脚设置4为输出功能,然后写GPFDAT寄存器的相应位使这3个引脚输出高电平或低电平来控制相应的LED。相应的引脚输出低电平时,LED点亮,输出高电平时,LED熄灭。
  S3C2440的GPFCON、GPFDAT寄存器地址分别是0x56000050、0x56000054,通过软件读写它们的地址可以访问这些寄存器。
  4、GPIO操作实例
  使用GPIO控制一个LED。例如,我们要想点亮LED1,就需要设置GPF4引脚为输出功能,然后设置该引脚输出低电平。
  板子上电后执行的第一条指令,并不是main函数,如果我们使用keil开发,启动文件会由编译器完成(会有一个S3C2440.S文件就是启动文件),它要做的工作主要是各种初始化然后跳转到C文件的main函数执行。但是我们在Linux系统下使用arm-linux-gcc编译裸机程序时,就需要自己编写一个这样的启动文件代码。(建一个目录led_on_c,把编写的代码文件和Makefile文件放在该目录下)
  自己编写的启动文件代码crt0.S内容:
  @******************************************************************************
  @ File:crt0.S
  @ 功能:通过它转入C程序
  @******************************************************************************
  .text
  .global _start
  _start:
  ldr r0, =0x53000000 @ WATCHDOG寄存器地址
  mov r1, #0x0
  str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启
  ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
  @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
  bl main @ 调用C程序中的main函数
  halt_loop:
  b halt_loop
  下面是LED1的控制程序led_on_c.c文件,内容如下:
  #define GPFCON (*(volatile unsigned long *)0x56000050)
  #define GPFDAT (*(volatile unsigned long *)0x56000054)
  int main()
  {
  GPFCON = 0x00000100; // 设置GPF4为输出口, 位[9:8]=0b01
  GPFDAT = 0x00000000; // GPF4输出0,LED1点亮
  return 0;
  }
  Makefile文件:
  led_on_c.bin : crt0.S led_on_c.c
  《span》 《/span》arm-linux-gcc -g -c -o crt0.o crt0.S
  《span》 《/span》arm-linux-gcc -g -c -o led_on_c.o led_on_c.c
  arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on_c.o -o led_on_c_elf
  arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin
  arm-linux-objdump -D -m arm led_on_c_elf 》 led_on_c.dis
  clean:
  rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o
  第2、3行分别编译源程序crt0.S、led_on_c.c
  第4行将编译得到的结果连接起来
  第5行把连接得到的ELF格式可执行文件led_on_c_elf转换成二进制格式文件led_on_c.bin
  第6行将结果转换为汇编码以供查看
  在led_on_c目录下执行make命令生成可执行文件led_on_c.bin,然后把该文件烧写到NAND Flash。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分