目录
1 简介
1.1 GPIO
2 LED实验步骤
2.1 通过电路原理图分析LED的控制逻辑
2.2 通过电路原理图查找LED与Exynos4412的连接关系
2.3 通过数据手册分析GPIO中哪些寄存器可以控制LED
2.4 通过程序去操控对应的寄存器完成对LED的控制
2.4.1 使用寄存器写入命令STR,把控制寄存器和数据寄存器内写入值
2.4.2 使用编译
2.4.3 烧录
3 实现led亮灭翻转
1 简介
SOC概念,芯片厂商在做芯片的时候出了CPU之外还会集成很多外设。如三星4412,处理cpu外,还集成了许多硬件控制器。
1.1 GPIO
GPIO(General-purpose input/output)即通用型输入输出,GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连,从而实现与外部硬件设备的通讯、控制及信号采集等功能
2 LED实验步骤
2.1 通过电路原理图分析LED的控制逻辑
2.2 通过电路原理图查找LED与Exynos4412的连接关系
2.3 通过数据手册分析GPIO中哪些寄存器可以控制LED
通过阅读4412芯片手册分析GPIO寄存器,搜索原理图中的GPX2_7
分别查看到与GPX2相关的控制寄存器、数据寄存器、上下拉寄存器、驱动强度寄存器(与LED有关的主要是控制寄存器)
控制寄存器
把32位寄存器分成了不同的位,每个位负责控制引脚配置为不同的功能。
也是32位寄存器,只用了[7:0]
- R(Read):表示将端口配置为输入(input)端口,可以读取(read)该端口的状态或值。
- W(Write):表示将端口配置为输出(output)端口,可以写入(write)一个特定的状态或值到该端口。
- X(Undefined):表示将端口配置为功能引脚(functional pin),并且读取(read)该端口时将会获得未定义(undefined)的值。
上拉下拉寄存器
在嵌入式系统中,上拉和下拉寄存器通常用于配置微控制器的引脚。当引脚被配置为输入模式时,上拉或下拉寄存器决定了引脚的默认电平状态。在输出模式下,上拉和下拉功能通常不会被使用。
- 上拉:当引脚被配置为输入模式并且没有外部连接时,上拉寄存器会使得引脚的电平保持高电平状态。
- 下拉:当引脚被配置为输入模式并且没有外部连接时,下拉寄存器会使得引脚的电平保持低电平状态。
一般而言,在将引脚配置为输入模式时,需要根据具体的硬件平台和需求来选择是否启用上拉或下拉。如果希望引脚在空闲时保持稳定的状态,可以启用上拉或下拉以确保引脚的默认状态。
驱动寄存器
通常,DRV寄存器的位数与系统中IO端口的数量相对应。每个位表示一个IO端口,可以设置为不同的驱动能力级别,例如低、中、高等级。
通过调整DRV寄存器中各个位的设置,可以控制每个IO端口的驱动能力,以满足特定的电流和电压要求。这样可以确保与外部设备或其他系统组件的连接质量和稳定性。
我们原理图中有三极管,这个寄存器也不需要使用到。
2.4 通过程序去操控对应的寄存器完成对LED的控制
2.4.1 使用寄存器写入命令STR,把控制寄存器和数据寄存器内写入值
led-asm.s
.text
_start:
LED_CONFIG:
LDR R2, =0x11000c40
LDR R1, =0x10000000
STR R1, [R2]
LED_OFF:
LDR R2, =0x11000c44
LDR R1, =0x00000000
STR R1, [R2]
STOP:
B STOP
.end
2.4.2 使用编译
直接编译会报错:
gcc编译过程分为四个步骤:
1.预处理(Pre-Processing) gcc -E
2.编译(Compiling) gcc -S
3.汇编(Assembling) gcc -c (我们只需要从这里开始就可以)
4.链接(Linking) gcc (生产可执行文件.elf)
写一个MakeFile
TARGET = led-asm
CROSS_COMPILE = arm-none-linux-gnueabi-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
all:
$(CC) -c $(TARGET).s -o $(TARGET).o
$(LD) $(TARGET).o -Ttext 0x40008000 -o $(TARGET).elf
$(OBJCOPY) -O binary -S $(TARGET).elf $(TARGET).bin
clean:
rm $(TARGET).o $(TARGET).elf $(TARGET).bin
Makefile详见
https://blog.csdn.net/m0_60718520/article/details/127218677
arm-none-linux-gnueabi-ld
常被用于交叉编译,即在一个系统上编译生成另一个不同体系结构的目标文件。由于 ARM 架构通常用于嵌入式设备和移动设备等场景,因此 arm-none-linux-gnueabi
工具链也经常被用于嵌入式和移动应用的开发。
需要注意的是,arm-none-linux-gnueabi-ld
并不直接编译源代码,而是用于链接目标文件。在 Linux 下进行 ARM 应用程序开发时,通常需要使用交叉编译器来编译和生成 ARM 架构的目标文件,然后再使用 arm-none-linux-gnueabi-ld
进行链接。
-Ttest
在 Linux 编译中,使用 -Ttext
选项可以指定链接器脚本中代码段(text segment)的起始地址。在你提到的例子中,-Ttext 0x40008000
将代码段的起始地址设置为 0x40008000。
这个选项通常用于嵌入式系统或者一些特定的应用场景,例如需要将程序加载到特定的内存地址上执行。如果你有这样的需求,可以在编译时通过 -Ttext
选项来指定代码段的起始地址。但是在一般的应用开发中,并不需要手动指定代码段的起始地址,因为链接器会为你处理好这些细节
arm-none-linux-gnueabi-objcopy
这个命令是使用 GNU objcopy 工具将目标文件转换为二进制文件
((TARGET).elf)转换为二进制文件((TARGET).bin)。这个命令的参数含义如下:
-O binary
:指定输出格式为二进制。-S
:在复制过程中去除调试符号,减小二进制文件的大小。$(TARGET).elf
:输入的目标文件。$(TARGET).bin
:输出的二进制文件。
使用 objcopy 工具可以将可执行文件或目标文件转换为不同的格式,包括二进制、Intel Hex、Motorola S-record 等。在这个命令中,选择了二进制格式作为输出。
这个命令通常用于在嵌入式系统中,将生成的可执行文件转换为可以直接加载到目标设备上运行的二进制文件。转换后的二进制文件可以通过各种方式进行烧录或传输到目标设备上。
请注意,在运行这个命令之前,先确保已经编译生成了目标文件($(TARGET).elf)作为输入。
把bin文件放到共享目录。
2.4.3 烧录
打开SecureCRT,连接串口115200
开发板上电3秒内按回车输入命令行
输入命令loadb 0x40008000
传输文件
输入命令 go 0x40008000跳转至内存其实位置执行程序,LED灯便会从亮变灭
3 实现led亮灭翻转
led-asm.s
.text
_start:
MAIN:
BL LED_CONFIG
LOOP: @循环
BL LED_ON
BL DELAY
BL LED_OFF
BL DELAY
B LOOP
LED_CONFIG: @配置控制寄存器
LDR R2, =0x11000c40
LDR R1, =0x10000000
STR R1, [R2]
MOV PC, LR
LED_ON: @数据寄存器输出高电平
LDR R2, =0x11000c44
LDR R1, =0x00000080
STR R1, [R2]
MOV PC, LR
LED_OFF: @数据寄存器输出低电平
LDR R2, =0x11000c44
LDR R1, =0x00000000
STR R1, [R2]
MOV PC, LR
DELAY:
LDR R1, =100000000 @主频1000Mhz,因为三级流水线及其他跳转因素相当于一秒钟闪烁2、3次
L:
SUB R1, R1, #1
CMP R1, #0
BNE L @ 不等于0一直循环
MOV PC, LR
STOP:
B STOP
.end
实现了led亮灭的功能
编译烧录参考2.4.2与2.4.3