ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ARM裸机的知识总结(4) ------- 利用GPIO控制LED

2020-12-23 21:57:57  阅读:176  来源: 互联网

标签:------- LED 引脚 裸机 反汇编 寄存器 GPIO GPJ0


一、一步步点亮LED1_硬件工作原理及原理图查阅

1、LED物理特性介绍

LED本身有2个接线点,一个是LED的正极,一个是LED的负极。LED这个硬件的功能就是点亮或者不亮,物理上想要点亮一颗LED只需要给他的正负极上加正电压即可,要熄灭一颗LED只需要去掉电压即可。

2、查阅原理图了解板载LED硬件接法

在这里插入图片描述

查阅原理图,发现开发板上一共有5颗LED。其中一颗D26的接法是:正极接5V,负极接地。因此这颗LED只要上电就会常亮。因此我们分析这颗LED是电源指示灯。
剩下4颗LED的接法是:正极接3.3V,负极接了SoC上的一个引脚(GPIO),具体详细接法是:
D22:GPJ0_3
D23:GPJ0_4
D24:GPJ0_5
D25:PWMTOUT1(GPD0_1)

3、分析如何点亮及熄灭LED(GPIO)

分析:LED点亮的要求是:正极和负极之间有正向电压差。
思考:在开发板上如何为LED制造这个电压差让它点亮呢?
解答:因为正极已经定了(3.3V),而负极接在了SoC的引脚上,可以通过SoC中编程来控制负极的电压值,因此我们可以通过程序控制负极输出低电平(0V),这样在正负极上就有了压差,LED即可点亮。

4、一步步点亮LED2_数据手册查阅及相关寄存器浏览

1、GPIO概念的引入
GPIO : general purpose input output 通用输入输出
GPIO就是芯片的引脚(芯片上的引脚有些不是GPIO,只有一部分是),作为GPIO的这类引脚,他的功能和特点是可以被编程控制它的工作模式,也可以编程控制他的电压高低等。
通过之前的分析我们知道,我们设计电路时就把LED接在了一个GPIO上,这样我们就可以通过编程控制GPIO的模式和输入输出值来操控LED亮还是灭;如果你当时设计电路时把LED接在非GPIO上那就不可能了。

2、阅读数据手册中有关部分
当我们想要通过编程操控GPIO来操作LED时,我们首先需要通读一下S5PV210的数据手册中有关于GPIO的部分,这部分在数据手册的Section2.2中。

3、GPIO相关的寄存器介绍
回忆下之前说过的,软件操作硬件的接口是:寄存器。
我们当前要操作的硬件是LED,但是LED实际是通过GPIO来间接控制的,所以当前我们实际要操作的设备其实是SoC的GPIO。要操作这些GPIO,必须通过设置他们的寄存器。
查阅数据手册可知,GPJ0相关的寄存器有以下:
GPJ0CON, (GPJ0 control)GPJ0控制寄存器,用来配置各引脚的工作模式
GPJ0DAT, (GPJ0 data)当引脚配置为input/output模式时,寄存器的相应位和引脚的电平高低相对应。
(控制LED主要是前面两个寄存器)
GPJ0PUD, (pull up down)控制引脚内部弱上拉、下拉
GPJ0DRV, (driver)配置GPIO引脚的驱动能力
GPJ0CONPDN,(记得是低功耗模式下的控制寄存器)
GPJ0PUDPDN (记得是低功耗模式下的上下拉寄存器)
注:在驱动LED点亮时,应该将GPIO配置为output模式。
实际上真正操控LED的硬件,主要的有:GPJ0CON, GPJ0DAT 这么2个。

如何点亮LED,编程的步骤是:
1、操控GPJ0CON寄存器中,选中output模式
2、操控GPJ0DAT寄存器,相应的位设置为0(bit0~7)

5、一步步点亮LED3_从零开始手写汇编点亮LED

1、GPxCON、GPxDAT寄存器分析
GPJ0端口一共有8个引脚,分别记住:GPJ0_0 ~ GPJ0_7,相关重要寄存器就是GPJ0CON和GPJ0DAT
GPJ0CON寄存器中设置8个引脚的工作模式(32/8=4,每个引脚可以分到4位,譬如GPJ0_0对应的bit位为bit0 ~ bit3,GPJ0_3对应的位为bit12 ~ bit15。工作方法是:给相应的寄存器位写入相应的值,该引脚硬件就会按照相应的模式去工作。譬如给bit12~bit15写入0x0001,GPJ0_3引脚就成为输出模式了)

2、从零开始写代码操作寄存器
需要哪些先决条件才能写呢?
1. 硬件接法和引脚:GPJ0_3 GPJ0_4 GPJ0_5 低电平亮/高电平灭
2. GPJ0CON(0xE0200240)寄存器和GPJ0DAT(0xE0200244)寄存器
3. 工程管理:Makefile等
根据以上分析,我们就知道代码的写法了,代码所要完成的动作就是:
把相应的配置数据写入相应的寄存器即可。
用汇编控制GPIO实现LED的流水灯
代码演示:

/*
 * 文件名:	led.s	
 * 作者:	朱老师
 * 描述:	流水灯
 */
 
#define GPJ0CON	0xE0200240
#define GPJ0DAT	0xE0200244

.global _start					// 把_start链接属性改为外部,这样其他文件就可以看见_start了
_start:
	// 第一步:把所有引脚都设置为输出模式,代码不变
	ldr r0, =0x11111111			// 从后面的=可以看出用的是ldr伪指令,因为需要编译器来判断这个数
	ldr r1, =GPJ0CON			// 是合法立即数还是非法立即数。一般写代码都用ldr伪指令
	str r0, [r1]				// 寄存器间接寻址。功能是把r0中的数写入到r1中的数为地址的内存中去

	// 要实现流水灯,只要在主循环中实现1圈的流水显示效果即可
flash:
	// 第1步:点亮LED1,其他熄灭
	//ldr r0, =((0<<3) | (1<<4) | (1<<5))	// 清清楚楚的看到哪个灭,哪个是亮
	ldr r0, =~(1<<3)
	ldr r1, =GPJ0DAT
	str r0, [r1]				// 把0写入到GPJ0DAT寄存器中,引脚即输出低电平,LED点亮
	// 然后延时
	bl delay					// 使用bl进行函数调用
	
	// 第2步:点亮LED2,其他熄灭	
	ldr r0, =~(1<<4)
	ldr r1, =GPJ0DAT
	str r0, [r1]				// 把0写入到GPJ0DAT寄存器中,引脚即输出低电平,LED点亮
	// 然后延时
	bl delay					// 使用bl进行函数调用
	
	// 第3步:点亮LED3,其他熄灭	
	ldr r0, =~(1<<5)
	ldr r1, =GPJ0DAT
	str r0, [r1]				// 把0写入到GPJ0DAT寄存器中,引脚即输出低电平,LED点亮
	// 然后延时
	bl delay					// 使用bl进行函数调用
	
	b flash


// 延时函数:函数名:delay
delay:
	ldr r2, =9000000
	ldr r3, =0x0
delay_loop:	
	sub r2, r2, #1				//r2 = r2 -1
	cmp r2, r3					// cmp会影响Z标志位,如果r2等于r3则Z=1,下一句中eq就会成立
	bne delay_loop
	mov pc, lr					// lr寄存器的值放到PC寄存器里,进行函数调用返回

Makefile:

led.bin: led.o 
	arm-linux-ld -Ttext 0x0 -o led.elf $^
	arm-linux-objcopy -O binary led.elf led.bin
	arm-linux-objdump -D led.elf > led_elf.dis
	gcc mkv210_image.c -o mkx210
	./mkx210 led.bin 210.bin
	
%.o : %.S
	arm-linux-gcc -o $@ $< -c

%.o : %.c
	arm-linux-gcc -o $@ $< -c 

clean:
	rm *.o *.elf *.bin *.dis mkx210 -f

3、编译、下载、运行看结果
编译时用我们的工程管理,直接make编译得到led.bin和210.bin
下载运行可以用usb启动dnw下载;也可以用sd卡烧录下载,根据自己的情况用
一般都用usb下载,因为方便。如果电脑主板插上dnw会死机没法解决,那只有sd卡下载启动了。
注意:开发板上按下电源键之后4颗LED默认都是半亮的,当我们下载程序后其中3颗变的很亮,这说明我们的程序已经运行了。

4、总结和回顾(软件控制硬件思想、寄存器意义、原理图数据手册的作用)
软件到底是怎么控制硬件的?为什么程序一运行硬件就能跟着动?
软件编程控制硬件的接口就是:寄存器

6、反汇编工具objdump的使用简介

1、反汇编的原理&为什么要反汇编
arm-linux-objdump -D led.elf > led_elf.dis
objdump是gcc工具链中的反汇编工具,作用是由编译链接好的elf格式的可执行程序反过来得到汇编源代码
-D表示反汇编 > 左边的是elf的可执行程序(反汇编时的原材料),>右边的是反汇编生成的反汇编程序

反汇编的原因有以下:
(1)逆向破解。
(2)调试程序时,反汇编代码可以帮助我们理解程序(我们学习时使用objdump主要目的是这个),尤其是在理解链接脚本、链接地址等概念时。
(3)把C语言源代码编译链接生成的可执行程序反汇编后得到对应的汇编代码,可以帮助我们理解C语言和汇编语言之间的对应关系。非常有助于深入理解C语言。

2、反汇编文件的格式和看法
(汇编 assembly 反汇编 dissembly)
标号地址、标号名字、指令地址、指令机器码、指令机器码反汇编到的指令
扩展:ARM汇编中用地址池方式来实现非法立即数

3、初识指令地址
下载烧录执行的bin文件,内部其实是一条一条的指令机器码。这些指令每一条都有一个指令地址,这个地址是连接的时候ld给指定的(ld根据我们写的链接脚本来指定)

4、展望:反汇编工具帮助我们分析链接脚本
反汇编的时候得到的指令地址是链接器考虑了链接脚本之后得到的地址,而我们写代码时通过指定连接脚本来让链接器给我们链接合适的地址。
但是有时候我们写的链接脚本有误(或者我们不知道这个链接脚本会怎么样),这时候可以通过看反汇编文件来分析这个链接脚本的效果,看是不是我们想要的,如果不是可以改了再看。

本文是根据朱有鹏的《ARM裸机全集》的视频笔记整理而得。

标签:-------,LED,引脚,裸机,反汇编,寄存器,GPIO,GPJ0
来源: https://blog.csdn.net/Vincen___/article/details/111594933

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有