ARM处理器学习之--GPIO操作篇

发布者:忠正最新更新时间:2018-07-22 来源: eefocus关键字:ARM处理器  GPIO操作 手机看文章 扫描二维码
随时随地手机看文章

在上一篇文章中我们详细讲解了ARM开发环境的搭建,我们选择了X86-linux平台交叉编译ARM程序,交叉编译链选用arm-linux-系列。另外,我们还说明了一些开发需要的基础知识。关于以上这些内容,请参见ARM芯片学习内容规划及ARM开发环境的搭建

我们学习高层应用程序开发的时候,一般第一个程序是经典的”hello world”程序。我们学习嵌入式的开发,主要是根据应用需求,选用合理的电子器件设计硬件电路,然后使用主控芯片控制外设。所以,我们GPIO操作篇的内容选为让电路板上的一个LED灯闪烁。

在讲解实验之前,我还是说明一下。这些基础实验,都是在特定硬件平台上运行的,且现象也是在特定电路板上才能产生的。所以实验中的程序并没有通用的移植性。拿到程序之间编译后下载到您的开发板上不一定能正常执行。需要简单修改。而且,我写这一系列的教程是让大家了解使用一款32bit处理器的基本方法和思路。并不是针对某一硬件平台。之所以所有程序都在一个固定的硬件平台上运行是因为要保证程序及想法的正确性。

 

相信,有些朋友以前就学习过单片机。学习单片机时有一些应该知道的基本问题。同样,学习ARM等其他芯片的使用方法时也一样。下面,我已疑问的形式写在下面:

1.        我通过交叉编译链编译、链接好的程序怎么放到芯片里去?放在什么位置?

2.        芯片加电后从哪里读取第一条指令运行?

3.        交叉编译链编译出的程序地址、下载到芯片里的地址、真正运行时的地址之间到底是什么关系?

4.        ARM芯片有没有中断向量表?在什么位置?

上面这些问题在开发普通PC机程序的时候,你不用考虑,因为这些编译器、操作系统、函数库都帮你做好了,所以你只需要把精力主要放到应用需求上就行了。但现在只有一个ARM芯片,没有任何其他支持,所以,这些问题你就需要理解并掌握。

 

针对第一个问题:LPC2220这款芯片支持在线编程功能,也就是可以通过串口下载你编译好的程序。(其实现方式是芯片内部有固化的loader,这个loader给你提供一些通过串口交互的简单命令。在PC机上一般都有其下载程序的上位机软件)下载到什么位置,要看这款芯片加电后的启动方式。不论从哪个地读取指令并启动,这个地址上应该连接着一种非易失性存储芯片,并且芯片要支持随机读。一般ARM类芯片,支持很多种启动方式,像 norflash启动、nandflash 启动、SD卡启动等等。而且启动方式是可以配置的。我选择的启动方式是norflash启动,这款norflash连接在0X80000000开始的地方。

所以,我们应该把编译、链接好的程序下载到0x8000000开始的地址中去。

 

针对第二个和第四个问题,我们选择了norflash启动方式,那么这款芯片会从物理地址0x8000000地址处开始取出第一条指令并执行。同时,ARM的中断向量表也会指向从0x8000000开始的32字节。见下面的表格:

0x00000000    Reset

0x00000004    Undefined Instruction

0x00000008    Software Interrupt

0x0000000C   Prefetch Abort (instruction fetch memory fault)

0x00000010    Data Abort (data access memory fault)

0x00000014    Reserved *

0x00000018    IRQ

0x0000001C   FIQ

也就是说,当有中断产生时,cpu还是会从上面列出的地址去取指令,只不过这些地址被重新映射到了0x8000000。也即,中断向量表对cpu来说是不变的,但是根据不同的启动方式,将这些逻辑地址重新映射到不同的物理地址上。选择norflash启动模式,就是将中断向量表映射到了物理地址0x8000000。在这种模式下,cpu一上电,还是从0x00000000地址取第一条指令,但是这只是针对cpu来说是逻辑上的0x00000000,其实的真正物理地址是0x80000000。

针对第三个疑问,经过上面的分析我们知道了芯片的启动方式、从哪里取第一条指令。也知道了怎么下载到指定的地址。在说明,下载地址、链接地址、运行地址之间的关系之前,我们先要理解一个问题:Cpu的工作方式。 cpu的工作方式是从指定的地址里取出一条指令进行解析,然后根据解析结果做相应的操作。像前面分析的启动方式,就是从物理地址0x8000000地址开始取指令并执行。我们编译出、链接出来的映像是具有一定格式的,具体格式请参考gnu链接器的说明,这里不做详细说明。我们要知道这样一个事实,我们程序里的code段是顺序存放的,而且我们程序里的跳转指令都要依据我们把第一条指令放在什么地址处。这样说比较晦涩难懂,我们举例说明。如果,我们指定第一条指令的地址为0x8000000,那第二条指令就会接着往后存放。

假设我们有一小段汇编指令。(假设编译出来的是ARM指令,每条指令32bit)

Start:LDR R0, =0xE0028028      @IO2DIR             

                                       LDR R1,= 0x10000000 

                                       STR R1,[R0]                             @设置P2.28为输出

                                       LDR PC, Start

若我们编译、连接好的程序如下表:

 


链接好的地址

指令内容(编译出的是二进制指令编码,我们使用汇编表示)

0x8000000

LDR R0, =0xE0028028

0x8000004

LDR R1,= 0x10000000

0x8000008

STR R1,[R0]              

0x800000c

LDR PC, Start

 

连接好的映像地址其实并不存储在我们编译、链接出的映像里。这些地址在存储器的地址线上体现,这里这样做表格只是为了好理解。假设,我们把上面的映像文件下载到0x8000000开始的地址处。那么,当执行LDR PC, Start这条指令时,其实这条指令相当于LDR PC, 0x8000000,就是把0x8000000这个地址赋给PC,接着cpu就从PC值指向的地址处开始取指令并执行。这样程序又从头开始执行了。实现了我们的想法。但是,如果我们链接时指定的代码段开始地址是0x8000000,但是我们将这段映像转载到了0x8100000开始的地方,并设置cpu从0x8100000开始取指执行。那么,当我们同样执行到LDR PC, Start指令时,还是把0x8000000这个地址赋值给PC,cpu还会从0x8000000取指令执行,这个时候0x8000000地址处并不是我们想要的内容,导致程序不能正常运行。

通过,上面的例子我们知道了,实际上链接器链接时要求地址是这段映像代码段各个指令位置的一个说明。你要保证程序真正运行的地址和编译器链接要求的地址保持一致,要不然一些绝对跳转指令将不能正常执行。从而导致程序出错。

关于,下载地址,当然可以和真正运行时的地址不同,但你要保证当程序真正运行时所在的地址和链接器要求的地址相一致。实现方法是利用一些和地址无关的指令,将代码在真正运行之前复制到链接器所要求的地址。

好了,这些基本问题搞明白了,我们就可以通过向ARM芯片控制外设了。这里当然是要控制led灯了。

 

 

用主控芯片控制外设的一般方法:

1.         看电路原理图,弄明白主控芯片和外设是怎么连接的。

2.         根据电路连接和需求对主控芯片进行设置。

3.         书写相应代码,实现功能。

 

我的ARM芯片和led灯的连接方式,如下图:

 


我们只控制LED1,通过看电路原理图,我们发现LED1和ARM芯片的P2.28引脚相连。

那下面我们看看怎么设置ARM芯片的P2.28引脚就可以了。很显然,我们让P2.28管脚输出0,LED灯会亮,输出1,LED灯会灭。

使用一个ARM芯片的管脚一般分以下两步:

1.         设置这个管脚的功能。(这个管脚可能有好多功能,根据需要设置)

2.         操作这个管脚

关于配置和操作这个管脚的寄存器地址和方法请参见LPC2220的datasheet。

接着就是写程序、makefile文件,然后在linux主机上编译链接,最后下载到norflash运行。

你看到的现象就是LED1会闪烁。

程序内容如下:

 

 

 

@******************************************************************************

@ 文件名 :control_led.s

@ 功   能:利用P2.28控制led灯闪烁

@

@ 作者    :张连聘

@ 创建时间:2014-06-08

@******************************************************************************

.text

.global _start

 

                            @定义程序中使用到的常量                  

                            .equ   IO2DIR  ,0xE0028028       @控制IO0的输入、输出属性寄存器

                            .equ   IO2SET  ,0xE0028024  @IO2输出1控制寄存器

                            .equ   IO2CLR  ,0xE002802C  @IO2输出0控制寄存器

                            .equ   LEDCON  ,0x10000000  @(1<<28)

                           

                           

_start:

 

                             LDR PC,  ResetAddr

                    

ResetAddr:

.word ResetInit

ResetInit:

                            LDR R0,=IO2DIR      @IO2DIR             

                            LDR R1,=LEDCON 

                            STR R1,[R0]                         @设置P2.28为输出

 

MaiLoop:

                            LDR R0,=IO2CLR 

                            LDR R1,=LEDCON

                            STR R1,[R0]        @P2.28为输出0,熄灭led

                            BL DELAYS                     @调用延时程序

                           

                            LDR R0,=IO2SET

                            LDR R1,=LEDCON                      

                            STR R1,[R0]        @P2.28为输出1,点亮led

                            BL DELAYS                     @调用延时程序

                  

                           

                            B MaiLoop

                           

                           

@******************************************************************************

@ 名   称:DELAYS

@ 功   能:软件延时

@ 入口参数:无

@ 出口参数:无

@ 占用资源:R7

@******************************************************************************

DELAYS:  

                            MOV                  R7,#0x00002000               @延时参数

DELAYS_L1:      SUBS         R7,R7,#1                                  @ R7 = R7-1

                            BNE           DELAYS_L1             @判断R7-1结果是否为0,若不为0则跳转

                            MOV                  PC,LR                                    @返回               

                           

程序里需要说明的:

关于gnu arm汇编请参考相关书籍。这里只说明一些和这里相关的内容。

.text 定义一个代码段的开始。.global _start定义一个全局的标号,一般供链接器链接多个.o文件时使用。

.equ定义一个常量。@后面的内容为注释内容。

                             LDR PC,  ResetAddr

ResetAddr:

.word ResetInit

ResetInit:

这段代码需要说明一下,有些朋友可能有这样的疑问,为什么第一条指针需要跳转指令,还有为什么不能用LDR PC,  ResetInit。

关于这个问题,我们上面分析了,从0x8000000开始的32byte都是中断(异常)向量表,每个中断向量只有四个字节的空间,肯定不能放下中断处理程序,所以放置一条跳转指令。上电后,默认执行Reset,这时候对CPU来说,它认为PC地址为0x00000000,只不过这个地址被其他硬件设备重新映射到了0X80000000地址上了,但cpu并不知道这个硬件设备的存在。而直接LDR PC,  ResetInit只能实现前后32       M空间的跳转,显然不能满足我们的意愿。通过上面的方法定义的ResetAddr,然后再用LDR PC,  ResetAddr可以实现4G范围内跳转。

其他内容都很简单了,那条指令不明白可以查阅ARM指令集。

下面看makefile文件:

control_led.bin:control_led.s

         arm-linux-gcc -g -c -o control_led.o control_led.s

         arm-linux-ld -Ttext  0x80000000 -g  control_led.o -o control_led_elf

         arm-linux-objcopy -O binary -S control_led_elf  control_led.bin

clean:

         rm -f control_led.bin control_led_elf *.o

 

makefile的基本语法和格式,我就不多说了。

嵌入式linux下的arm-linux系列工具,默认链接出来的是在linux内核支持下的映像文件,是ELF格式的映像文件。而我们没有操作系统的支持,所以,我们要利用二进制工具将ELF格式的映像文件转换成纯二进制指令格式映像文件。

我们上面说的链接器链接地址的概念,在arm-linux-ld 的体现就是 arm-linux-ld -Ttext  0x80000000 -g  control_led.o -o control_led_elf,其中-Ttext选项就是指代码段的起始链接地址。这里将地址连接到0x80000000开始的地方。

好了,关于ARM芯片的启动,链接地址,下载地址,执行地址以及第一个点亮LED灯的程序,makefile讲解就到这里吧。

我把这个试验中所涉及到的源码和word文档都打包上传到csdn的下载频道:

下载地址:ARM芯片基础实验之GPIO操作


关键字:ARM处理器  GPIO操作 引用地址:ARM处理器学习之--GPIO操作篇

上一篇:嵌入式之IO口总结
下一篇:ARM GPIO接口置位方法

推荐阅读最新更新时间:2024-03-16 16:09

三星ARM处理器S3C4510B的HDLC通道使用及编程
摘要 三星16/32位ARM处理器S3C4510B是目前在国内应用非常广泛的一种性价比很高的ARM处理器,本文在介绍S3C4510B中HDLC通道结构特点的基础上,详细说明了4510中HDLC通道在DMA收发方式下的工作过程,使用方法和编程中的一些注意事项。 1:S3C4510B简介 S3C4510B(以下简称4510)是韩国三星公司开发的一款基于ARM7TDMI架构的16/32位高性能微处理器。具用丰富的外围接口,如以太网,HDLC等,可灵活配置,适用于多种应用。4510具有以下性能特点: ◆ 8K字节的内部CACHE,也可用作内部SRAM ◆ 两线IIC接口,作为IIC主器件使用 ◆ 以太网控制
[嵌入式]
μCOSII在基于Cortex-M3核的ARM处理器上的移植
目前,嵌入式技术已被广泛应用到汽车电子、无线通信、数码产品等各个领域。嵌入式操作系统及嵌入式处理器技术发展迅猛,嵌入式操作系统典型代表有μCOS—II、μClinux、Winclow CE、VxWorks等;嵌入式处理器包括ARM、MIPS、PowerPC等。随着软硬件技术的发展,人们开始意识到基于嵌入式操作系统的程序开发模式的便利性及可靠性,并且在程序开发过程中开始倾向于从传统超循环开发模式转向基于嵌入式操作系统的开发模式。 1 软硬件开发环境及处理器介绍 1.1 软件硬开发环境 本移植过程使用的软件环境是RealView MDK开发套件,此产品是ARM公司最新推出的针对各种嵌入式处理器的软件开发工具,该开发套件功能强
[单片机]
μCOSII在基于Cortex-M3核的<font color='red'>ARM处理器</font>上的移植
STM8L探索套件学习笔记-GPIO端口操作(一)
STM8与STM32一样提供了固件库函数,方便用户快速开发,不需要花费很多时间去查寄存器。不过没有STM32的库完善,给的说明文档是chm格式的,名字是stm8l15x_stdperiph_lib_um.chm,这个官网有下载,今天按照官方给的模板自己做个模板文件夹,方便后期的移植,这样就不要再重复设置了。首先我们看看GPIO模块,在用固件库之前先了解下GPIO里面的大体的寄存器,方便后期使用固件库。缺点是你所以输入的参数都会检测是否符合规范,必须得按照库函数里面定义的参数写。 GPIO寄存器有:输出寄存器(ODR),输入寄存器(IDR),方向寄存器(DDR),控制寄存器1(CR1)和控制寄存器2(CR2).后面三个寄存器组和可
[单片机]
STM8L探索套件学习笔记-<font color='red'>GPIO</font>端口<font color='red'>操作</font>(一)
基于ARM处理器的便携式心电血压检测仪
    近年来,心脏病和高血压的患病率逐年增高,动态心电图和血压监测为心血管疾病的预测、诊断和评估提供了极有价值的信息。随着嵌入式系统在医用仪表中的广泛应用,本文介绍了一种以Samsung公司的S3C44B0X为核心的集血压和心电检测功能于一体的便携式家庭健康监护系统,该系统充分利用ARM的片内资源,实现了人体心电、血压信号的采集、显示、打印和传输。仪器硬件主要由S3C44B0X主控芯片、心电放大电路、血压检测模块、存储系统及外围接口电路组成,系统结构框图如图1所示。S3C44B0X内置的A/D转换器用于采集心电信号和血压信号,LCD用于显示数据,微型打印机用于输出心电图波形,用户可通过外接PS2键盘控制系统的工作状态,包括选择检
[单片机]
ARM处理器选型指南:选ARM7还是选Cortex-M3
要使用低成本的 32位处理器,开发人员面临两种选择,基于Cortex-M3内核或者ARM7TDMI内核的处理器。如何做出选择?选择标准又是什么?本文主要介绍了ARM Cortex-M3内核微控制器区别于ARM7的一些特点,帮助您快速选择。 1.ARM实现方法 ARM Cortex-M3是一种基于ARM V7架构的最新ARM嵌入式内核,它采用哈佛结构,使用分离的指令和数据总线( 冯诺伊曼结构下,数据和指令共用一条总线 )。从本质上来说,哈佛结构在物理上更为复杂,但是处理速度明显加快。根据摩尔定理,复杂性并不是一件非常重要的事,而吞吐量的增加却极具价值。 ARM公司对Cortex-M3的定位是:向专业嵌入式市场提供低成本、低功耗的芯
[单片机]
诺基亚双管齐下 同时推上网本和智能本
    8月27日消息,据中国台湾媒体报道,来自台湾手机厂商的消息称,除了推出上网本Nokia Booklet 3G,诺基亚还将推出一款基于ARM处理器的智能本。     诺基亚周一宣布,将推出Nokia Booklet 3G上网本。该款产品基于英特尔Atom处理器和微软Windows操作系统,电池续航时间可达到12小时。在下周召开的诺基亚全球大会上,诺基亚将公布该款上网本的价格和上市日期等信息。     与此同时,来自台湾手机厂商的消息称,诺基亚还计划于2010年年中推出一款基于ARM处理器的智能本。目前,诺基亚目前正与ODM(原始设计商)商讨代工事宜,合作对象有可能是仁宝或富士康。     此前也有报道称,诺基亚将
[嵌入式]
arm LPC210X GPIO操作有关的寄存器
通常的名称 描述 属性 复位值 PORT0的地址和名称 IOPIN GPIO的管脚值。不管当前管脚的方向如何,都能从此寄存器读取GPIO的状态。 读/写 NA 0xE002 8000 IO0PIN IOSET GPIO置高电平寄存器。写1则相应的管脚输出高电平。 读/写 0x0000 0000 0xE002 8004 IO0SET IODIR GPIO方向设置寄存器。控制各个引脚的方向。 读/写 0x0000 0000 0xE002 8008 IO0DIR IOCLR GPIO置低电平寄存器。写1则相应的管脚输出低电平。 只写 0x0000 0000 0xE002 800C IO0CLR GPIO有两种工作方式
[单片机]
Cadence 和ARM发布创新“锦囊”以加速基于ARM处理器设计的验证闭合
基于 ARM 处理器的“锦囊”充分利用 C adence Plan-to-Closure 的 方法 学 和 经过 ARM 技术认证的 AMBA 验证 IP 【 2006 年 7 月 3 日法国尼斯, CDN Live! EMEA 大会】 Cadence 设计系统有限公司( Nasdaq 股票代码: CDNS )和 ARM ( LSE 股票代码: ARM; Nasdaq 股票代码: ARMHY )今天发布了面向 ARM 技术 的 Cadence? Functional Verification Kit ( 功能验证锦囊 ) , 为设计团队在验证基于 ARM 处理器的设计过程中提供低风险的验证闭
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved