【嵌入式Linux+ARM】GPIO操作
1.GPIO介绍
GPIO(general purpose i/o ports)意思为通用输入/输出端口,通俗的说就是一些引脚。
我们可以通过它们输出高低电平 或 读入引脚的状态。
s3c2440中有130个I/O端口,分为A~J共9组,GPA、GPB、..... GPJ
2.GPIO寄存器
既然要操作GPIO,必须对相应的寄存器进行操作,2440中gpio寄存器有:
GPxCON——选择引脚功能(输入、输出、保留等)
GPxDAT——用来读写引脚
GPcUP ——某一位是1时,相应的引脚无内部上拉电阻;为0时,有内部上拉电阻
3.原理图
LED:
按键:
4.实验代码:
>>使用汇编语言实现点灯:
led_on.S
- .text
- .global _start
- _start:
- LDR R0, =0x56000050 //GPFCON寄存器地址
- MOV R1, #0x00001500 //见技术手册相应的配置,一般01为输出引脚
- STR R1, [R0] //设置为输出
- LDR R0, =0x56000054 //GPFDAT寄存器
- MOV R1, #0x00000000
- STR R1, [R0] //往GPFDAT寄存器写值
- 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 0x00000000 -g led_on.o -o led_on_elf //-Ttext表示设置连接地址
- arm-linux-objcopy -O binary -S led_on_elf led_on.bin //把elf文件转换为.bin文件
- clean:
- rm -rf *.bin *.o *elf
>>使用C语言实现点灯
使用c语言来写,需要一个启动文件,可以用来关闭看门口,设置堆栈等。
crt0.S
- .text
- .global _begin
- _begin:
- LDR R0, =0x53000000 //看门狗寄存器地址
- MOV R1, #0x00000000 //写0禁止看门狗
- STR R1, [R0]
- LDR SP, =1024*4 //设置堆栈,注意不能大于4K,因为现在可用的SRAM空间只有4K
- BL main //调用main函数,最后注意,汇编语言大小写无所谓的
- _LOOP:
- B _LOOP
led_on_c.c
- #define GPFCON *(volatile unsigned long *)0x56000050
- #define GPFDAT *(volatile unsigned long *)0x56000054
- int main()
- {
- GPFCON=0x00001500;//简单的配置为输出
- GPFDAT=0x00000000;//简单的输出0,通过上面的原理图可知,相应的led会亮
- return 0;
- }
Makefile
- led_on_c.bin : crt0.S led_on_c.c
- arm-linux-gcc -g -c -o crt0.o crt0.S
- 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 //把elf文件转换为反汇编文件
- clean:
- rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o
>>使用按键+c语言实现点灯
看上面的原理图,原理就是把按键的引脚配置为输入引脚,以读取引脚的状态;
但按键被按下时,引脚读到的是低电平;当按键松开时,读取到高电平;
crt0.S同上;
key_led.c
- /*
- GPF4 GPF5 GPF6 --led
- GPF0 GPF2 GPG3 --key
- */
- #define GPFCON (*(volatile unsigned long *)0x56000050)
- #define GPFDAT (*(volatile unsigned long *)0x56000054)
- #define GPGCON (*(volatile unsigned long *)0x56000060)
- #define GPGDAT (*(volatile unsigned long *)0x56000064)
- #define GPF4_out (1<<(4*2))
- #define GPF5_out (1<<(5*2))
- #define GPF6_out (1<<(6*2))
- #define GPF4_msk (3<<(4*2))
- #define GPF5_msk (3<<(5*2))
- #define GPF6_msk (3<<(6*2))
- #define GPF0_in (0<<(0*2))
- #define GPF2_in (0<<(2*2))
- #define GPG3_in (0<<(3*2))
- #define GPF0_msk (3<<(0*2))
- #define GPF2_msk (3<<(2*2))
- #define GPG3_msk (3<<(3*2))
- int main()
- {
- unsigned long dwDat;
- //1 output pin
- GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);
- GPFCON |= (GPF4_out | GPF5_out | GPF6_out);
- //input pin
- GPFCON &= ~(GPF0_msk | GPF2_msk);
- GPFCON |= (GPF0_in | GPF2_in);
- GPGCON &= ~GPG3_msk;
- GPGCON |= GPG3_in;
- while(1)
- {
- dwDat = GPFDAT;
- if(dwDat & (1<<0))
- GPFDAT |= (1<<4);
- else
- GPFDAT &= ~(1<<4);//light
- if(dwDat & (1<<2))
- GPFDAT |= (1<<5);
- else
- GPFDAT &= ~(1<<5);
- dwDat = GPGDAT;
- if(dwDat & (1<<3))
- GPFDAT |= (1<<6);
- else
- GPFDAT &= ~(1<<6);
- }
- return 0;
- }
Makefile相应的修改即可;
上面的程序编译都会得到bin文件,我们把它烧录进nand flash中即可,烧录可以使用工具,也可以通过固化在nor flash中的Uboot来烧录,方法很多,烧录后,上电,2440CPU会自动把nand flash前4k的内容,拷贝到2440片内4k的SRAM中运行,这块内存俗称stepping stone区。
注:原创文章,转载请注明出处:http://blog.csdn.net/scottly1/article/details/38960309
【嵌入式Linux+ARM】GPIO操作的更多相关文章
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之二
/** ****************************************************************************** * @author 暴走的小 ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之一
/** ****************************************************************************** * @author 暴走的小 ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之三
/** ****************************************************************************** * @author 暴走的小 ...
- linux 标准 GPIO 操作
Linux 提供了GPIO 操作的 API,具体初始化及注册函数在 driver/gpio/lib_gpio.c 中实现. #include int gpio_request(unsigne ...
- Linux内核 GPIO操作部分API
内核中关于GPIO的操作API主要集中在<linux/of_gpio.h>和<linux/gpio.h>中,前者主要是GPIO直接与设备树相关的操作,在Linux 设备树操作A ...
- [转载]嵌入式linux下操作GPIO
本文转自:http://blog.csdn.net/mirkerson/article/details/8464231 在嵌入式设备中对GPIO的操作是最基本的操作.一般的做法是写一个单独驱动程序,网 ...
- 嵌入式 Linux 如何操作 GPIO ?
作者:刘凯链接:https://www.zhihu.com/question/19704852/answer/19760467来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...
- 应聘linux/ARM嵌入式开发岗位
**************************************************************** 因为发在中华英才和智联招聘没有人采我所以我 在这里发布我的个人简历希望 ...
- 009-2010网络最热的 嵌入式学习|ARM|Linux|wince|ucos|经典资料与实例分析
前段时间做了一个关于ARM9 2440资料的汇总帖,很高兴看到21ic和CSDN等论坛朋友们的支持和鼓励.当年学单片机的时候datasheet和学习资料基本都是在论坛上找到的,也遇到很多好心的高手朋友 ...
随机推荐
- Tcp 三次握手 四次分手
看了 余晟以为的 “tcp没那么难吧”,算是对三次握手,四次分手有了一点点理解,记录下来以方便自己以后的查看. 原文链接:https://mp.weixin.qq.com/s?__biz=MzA3MD ...
- python计算机基础(一)
什么是编程语言? 跟计算机交流的语言 什么是编程? 编程就是写代码,让计算机能够听懂的语言 为什么要编程? 让计算机为我们做事,取代人 计算机5大组成分别有什么作用? CPU:控制,判断,配作用,内存 ...
- 数据结构( Pyhon 语言描述 ) — — 第6章:继承和抽象类
继承 新的类通过继承可以获得已有类的所有特性和行为 继承允许两个类(子类和超类)之间共享数据和方法 可以复用已有的代码,从而消除冗余性 使得软件系统的维护和验证变得简单 子类通过修改自己的方法或者添加 ...
- java中的equals与==的区别
equals是Object类的公共方法,方法内部是用==实现的.但是很多类都重写了equals方法,例如基本数据类型的封装类和String类,重写后比较的是对象的值或者内容是否相同.而==是比较地址, ...
- 深入浅出Oracle:DBA入门、进阶与诊断案例(读书笔记2)
第5章 Buffer Cache与Shared Pool原理 5.1 Buffer Cache原理 Buffer Cache是Oracle SGA中的一个重要部分,通常的数据访问和修改都需要通过Bu ...
- Linux cp复制
复制指定目录下的全部文件到另一个目录中文件及目录的复制是经常要用到的.linux下进行复制的命令为cp.假设复制源目录 为 dir1 ,目标目录为dir2.怎样才能将dir1下所有文件复制到dir2下 ...
- 【UML】UML图的发展和体系结构
导读:上次给徒弟验收UML的项目,在验收的时候提出了很多问题,徒弟也暴露了一些问题.说好我们一起总结成长的,由于最近的事儿,比较忙,所以现在进行总结.上次会议中说到要用门卫思维去总结这部分的知识点,用 ...
- 移动端没有session怎么处理
(转:https://my.oschina.net/wanglihui/blog/150726) 手机客户端与服务器端的通信,不同于浏览器与服务器端的通信.浏览器和服务器端的通信依靠session去维 ...
- Ubuntu安装 Docker CE,VNC访问docker图形界面并安装ROS
从包安装 如果您无法使用Docker的存储库来安装Docker CE,则可以下载.deb适用于您的发行版的 文件并手动安装.每次要升级Docker CE时都需要下载新文件. 安装Docker CE,将 ...
- POJ 2699 The Maximum Number of Strong Kings ——网络流
一定存在一种最优方案,使得分数前几个人是SK 所以我们可以二分答案或者枚举,然后就是经典的网络流建模. 另:输入很Excited #include <cstdio> #include &l ...