S5PV210 | 裸机汇编LED流水灯实验

发布者:SereneHarmony最新更新时间:2024-12-05 来源: cnblogs关键字:S5PV210  裸机汇编  LED流水灯 手机看文章 扫描二维码
随时随地手机看文章

开发板:

x210bv3s

1.原理图

上图中,当按下POWER键后,VDD_5V和VDD_IO会产生5V和3.3V的电压,其中D26无须GPIO控制,为常亮状态,即我们所说的电源指示灯,D[22:25]对应的GPIO口如下:

LED指示灯GPIO口编号动作
D22GPJ_3LED11:灭,0:亮
D23GPJ0_4LED21:灭,0:亮
D24GPJ0_5LED31:灭,0:亮
D25GPD0_1LED41:灭,0:亮
对应的GPIO口输出低电平,点亮LED;反之,熄灭LED灯;


2.Datasheet相关

1.S5PV210 RISC微处理器用户手册:

S5PV210_UM_REV1.1.pdf

获取方式:可在CSDN搜索下载,也可以@大飞歌获取

 

2.应用手册(内部ROM启动):

S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf 

获取方式:可网路搜索下载,也可以@大飞歌获取

中文文档地址:https://blog.csdn.net/I_feige/article/details/104848609

3.底板电路原理图:

x210bv3s.pdf

下载链接:https://download.csdn.net/download/i_feige/11877902

控制LED GPIO的寄存器设置详细参见以下章节(S5PV210_UM_REV1.1.pdf):


V210_ Book cover 

errata 

section 01_ overview 

section 02_ system 

section 03_ bus 

section 04_ interupt 

section 05_ memory 

section 06_ dma 

section 07_ timer 

section 08_ connectivity _ storage 

section 09_ mutimedia 

section 10_ audio _ etc 

section 11_ securty 

section 12_ etc

 

2.2.7 PORT GROUP GPD0 CONTROL REGISTER 

2.2.7.1 Port Group GPD0 Control Register ( GPD0CON , R / W , Address 0xE020_00A0)

2.2.7.2 Port Group GPD0 Control Register ( GPD0DAT , R / W , Address 0xE020_00A4)

2.2.7.3 Port Group GPD0 Control Register ( GPD0PUD , R / W , Address 0xE020_00A8)

2.2.7.4 Port Group GPD0 Control Register ( GPD0DRV , R / W , Address 0xE020_00AC)

2.2.7.5 Port Group GPD0 Control Register ( GPD0CONPDN , R / W , Address 0xE020_00B0)

2.2.7.6 Port Group GPD0 Control Register ( GPD0PUDPDN , R / W , Address 0xE020_00B4)

 

2.2.20 PORT GROUP GPJ0 CONTROL REGISTER 

2.2.20.1 Port Group GPJ0 Control Register ( GPJ0CON , R / W , Address 0xE020_0240)

2.2.20.2 Port Group GPJ0 Control Register ( GPJ0DAT , R / W , Address 0xE020_0244)

2.2.20.3 Port Group GPJ0 Control Register ( GPJ0PUD , R / W , Address 0xE020_0248)

2.2.20.4 Port Group GPJ0 Control Register ( GPJ0DRV , R / W , Address 0xE020_024C)

2.2.20.5 Port Group GPJ0 Control Register ( GPJ0CONPDN , R / W , Address 0xE020_0250)

2.2.20.6 Port Group GPJ0 Control Register ( GPJ0PUDPDN , R / W , Address 0xE020_0254)


GPD0控制寄存器组的相关信息(部分摘取如下):

2.2.7 PORT GROUP GPD0 CONTROL REGISTER
有六个控制寄存器,分别是 GPD0CON、GPD0DAT、GPD0PUD、GPD0DRV、GPD0CONPDN 和
端口组 GPD0 控制寄存器中的 GPD0PUDPDN。
2.2.7.1 端口组 GPD0 控制寄存器 (GPD0CON, R/W, Address = 0xE020_00A0)

GPD0CONBitDescriptionInitial State
GPD0CON[3][15:12]0000 = Input 0001 = Output 0010 = TOUT_3 0011 ~ 1110 = Reserved 1111 = GPD0_INT[3]0000
GPD0CON[2][11:8]0000 = Input 0001 = Output 0010 = TOUT_2 0011 ~ 1110 = Reserved 1111 = GPD0_INT[2]0000
GPD0CON[1][7:4]0000 = Input 0001 = Output 0010 = TOUT_1 0011 ~ 1110 = Reserved 1111 = GPD0_INT[1]0000
GPD0CON[0][3:0]0000 = Input 0001 = Output 0010 = TOUT_0 0011 ~ 1110 = Reserved 1111 = GPD0_INT[0]0000

2.2.7.2 端口组 GPD0 数据映射寄存器 (GPD0DAT, R/W, Address = 0xE020_00A4)

GPD0DATBitDescriptionInitial State
GPD0DAT[3:0][3:0]当端口被配置为输入端口时,对应的位是引脚状态。 当端口配置为输出端口时,引脚状态与对应位相同。 当端口被配置为功能引脚时,将读取未定义的值。0000

2.2.7.3 端口组 GPD0 上、下拉配置寄存器 (GPD0PUD, R/W, Address = 0xE020_00A8)

GPD0PUDBitDescriptionInitial State
GPD0PUD[n][2n+1:2n] n=0~300 = 上拉/下拉禁用 01 = 下拉启用 10 = 上拉启用 11 = 保留0x0055

2.2.7.4 端口组 GPD0 驱动强度配置寄存器 (GPD0DRV, R/W, Address = 0xE020_00AC)

GPD0DRVBitDescriptionInitial State
GPD0DRV[n][2n+1:2n] n=0~300 = 1x 10 = 2x 01 = 3x 11 = 4x0x0000

2.2.7.5 端口组 GPD0 低功耗模式配置寄存器 (GPD0CONPDN, R/W, Address = 0xE020_00B0)

GPD0CONPDNBitDescriptionInitial State
GPD0[n][2n+1:2n] n=0~300 = Output 0 01 = Output 1 10 = Input 11 = Previous state0x00

2.2.7.6 端口组 GPD0 低功耗模式上拉/下拉寄存器 (GPD0PUDPDN, R/W, Address = 0xE020_00B4)

GPD0PUDPDNBitDescriptionInitial State
GPD0[n][2n+1:2n] n=0~300 = 上拉/下拉禁用 01 = 下拉启用 10 = 上拉启用 11 = 保留0x00


例如设置GPD0_1 IO口为输出模式,拉高或者拉低(汇编语言实现):


#define GPD0CON         0xE02000A0

#define GPD0DAT         0xE02000A4

 

/* 初始化GPIO口(配置为输出模式),下面是比较规范的一种写法,也可参考代码实现(流水灯)相关部分 */    

ldr r0,=GPD0CON    //r0=0xE02000A0

ldr r1,[r0]            //将r0地址处的数据读出,保存到r1中(零偏移)

orr r1,r1,#0x0010      //设置r1的第4位(置1),其他位保持不变[7:4]->0001=Output

str r1,[r0]            //将r1中的内容传输到r0中数指定的地址内存中去

/* 点亮LED4,GPIO口输出低电平 */

ldr r0,=GPD0DAT //r0=0xE02000A4

ldr r1,[r0]            //将r0地址处的数据读出,保存到r1中(零偏移)

bic r1,r1,#0x0002 //清除r1的第1位(置0),其他位保持不变[1]

str r1,[r0]   //将r1中的内容传输到r0中数指定的地址内存中去

 

/* 熄灭LED4,GPIO口输出高电平 */

ldr r0,=GPD0DAT //r0=0xE02000A4

ldr r1,[r0]          //将r0地址处的数据读出,保存到r1中(零偏移)

orr r1,r1,#0x0002 //设置r1的第1位(置1),其他位保持不变[1]

str r1,[r0] //将r1中的内容传输到r0中数指定的地址内存中去

3.代码

3-1.代码实现(流水灯,仅作演示)

/*******************************************************

 *   > File Name: start.S

 *   > Author: fly

 *   > Create Time: 2020年07月17日 星期五 07时56分19秒

 ******************************************************/

/*=====================================================

 * 汇编点亮led灯:对应GPIO口输出低电平,点亮LED

 * D22->GPJ0_3

 * D23->GPJ0_4

 * D24->GPJ0_5

 * D25->PWMOUT1/GPD0_1

 *====================================================*/

#define GPD0CON         0xE02000A0

#define GPD0DAT         0xE02000A4

#define GPD0PUD         0xE02000A8

 

#define GPJ0CON         0xE0200240

#define GPJ0DAT         0xE0200244

#define GPJ0PUD         0xE0200248

 

#define PS_HOLD_CONTORL 0xE010E81C

#define WTCON           0xE2700000

#define SVC_STACK       0xD0037D80

 

//#define CONFIG_SYS_ICACHE_OFF   1

.global _start

_start:

    //给5v电源置锁

    //LDR指令:从内存中将1个32位的字读取到目标寄存器中

    //STR指令:将1个32位的字数据写入到指令中指定的内存单元中

    //ORR指令:逻辑或操作指令

    //BIC指令:位清除指令

    //MOV指令:数据传送

    ldr r0,=PS_HOLD_CONTORL     //r0=0xE010E81C

    ldr r1,[r0]                 //将r0地址处的数据读出,保存到r1中(零偏移)

    orr r1,r1,#0x300            //设置r1的第8、9位,其他位保持不变

    orr r1,r1,#0x1              //设置r1的第1位,其他位保持不变

    str r1,[r0]                 //将r1中的内容传输到r0中数指定的地址内存中去

 

    //关看门狗

    ldr r0, =WTCON

    mov r1, #0    //将立即数0传输到r1处

    str r1, [r0]

 

    //开/关iCache

    // MRC指令:从协处理器寄存器传数据到ARM寄存器

    // MCR指令:从ARM寄存器传数据到协处理器寄存器

    mrc p15, 0, r0, c1, c0, 0

    #ifdef CONFIG_SYS_ICACHE_OFF

    bic r0, r0, #0x00001000     @ clear bit 12 (I) I-Cache

    #else

    orr r0, r0, #0x00001000     @ set bit 12 (I) I-Cache

    #endif

    mcr p15, 0, r0, c1, c0, 0

 

    //设置栈,以便调用c函数

    ldr sp, =SVC_STACK

led_init:

    /* LED初始化 */

    //把GPIO设置输出模式

    ldr r0,=0x11111111

    ldr r1,=GPJ0CON

    str r0, [r1]                //把GPJ0所有的IO设置为输出模式

 

    ldr r0,=0x00000010

    ldr r1,=GPD0CON

    str r0,[r1]                 //把GPD0_1设置为输出模式

led_run:

    /* LED流水灯 */

    // 第1步:点亮LED1,其他熄灭

    ldr r0, =~(1<<3)            //r0=0xFFFFFFF7

    ldr r1, =GPJ0DAT            //r1=0xE0200244

    str r0, [r1]

    //熄灭LED4

    ldr r0, =~(0<<1)            //r0=0xFFFFFFFF

    ldr r1, = GPD0DAT

    str r0, [r1]

    bl delay

 

    // 第2步:点亮LED2,其他熄灭

    ldr r0, =~(1<<4)            //r0=0xFFFFFFEF

    ldr r1, =GPJ0DAT

    str r0, [r1]

    bl delay

 

    // 第3步:点亮LED3,其他熄灭

    ldr r0, =~(1<<5)            //r0=0xFFFFFFDF

    ldr r1, =GPJ0DAT

    str r0, [r1]

    bl delay

 

    //熄灭LED3/4/5,点亮LED4

    ldr r0, = ((1<<3)|(1<<4)|(1<<5))

    ldr r1, =GPJ0DAT

    str r0, [r1]

    ldr r0, =~(1<<1)            //r0=0xFFFFFFFD

    ldr r1, = GPD0DAT

    str r0, [r1]

    bl delay

 

    bl led_run

half:

    b half

 

    /* 延时函数:delay*/

delay:

    ldr r2,=9000000

    ldr r3,=0x0

delay_loop:

    //SUB指令:从寄存器Rn中减去shifter_operand表示的数值,

    //并将结果保存在目标寄存器Rd中,并根据指令的执行结果

    //设置CPSR中的相应标志位

    //SUB {} {s} ,,

    sub r2,r2,#1                //r2 = r2 - 1

    //CMP指令:使用寄存器Rn的值减去shifter_operand的值,

    //根据操作的结果更新CPSR中相应的条件标志位,以便后面

    //的指令根据相应的条件标志位来判断是否执行

    //CMP {} ,

    cmp r2, r3

    bne delay_loop

    mov pc,lr

配套编译Makefile文件:


# 将所有的.o文件链接成.elf文件,“-Ttext 0x0”

# 表示程序的运行地址是0x0,由于目前编写的是位置

# 无关码,可以在任一地址运行

# 将elf文件抽取为可在开发板上运行的bin文件

# 将elf文件反汇编保存在dis文件中,调试程序会用

# 添加文件头

# 编译器版本:arm-2009q3

.PHONY: all clean tools

 

CROSS ?= arm-linux-

NAME := LED

 

LD := $(CROSS)ld

OC := $(CROSS)objcopy

OD := $(CROSS)objdump

CC := $(CROSS)gcc

MK := ../../tools/mk_image/mkv210_image

 

all:$(NAME).bin

 

$(NAME).bin : start.o

$(LD) -Ttext 0x0 -o $(NAME).elf $^

$(OC) -O binary $(NAME).elf $(NAME).bin

$(OD) -D $(NAME).elf > $(NAME)_elf.dis

$(MK) $(NAME).bin

 

# 将当前目录下存在的汇编文件及C文件编译成.o文件

%.o : %.S

[1] [2]
关键字:S5PV210  裸机汇编  LED流水灯 引用地址:S5PV210 | 裸机汇编LED流水灯实验

上一篇:S5PV210 | 微处理器启动流程
下一篇:S5PV210 | 裸机汇编LED闪烁实验

推荐阅读最新更新时间:2026-03-22 11:47

S5PV210 | 裸机汇编LED闪烁实验
原理图 DATASHEET 2.2.7 PORT GROUP GPD0 CONTROL REGISTER There are six control registers, namely, GPD0CON, GPD0DAT, GPD0PUD, GPD0DRV, GPD0CONPDN and GPD0PUDPDN in the Port Group GPD0 Control Registers. 2.2.7.1 Port Group GPD0 Control Register (GPD0CON, R/W, Address = 0xE020_00A0) 2.2.7.2 Port Group GPD0 Control
[单片机]
<font color='red'>S5PV210</font> | <font color='red'>裸机</font><font color='red'>汇编</font><font color='red'>LED</font>闪烁实验
[ARM裸机程序][6]ARM GNU汇编程序示例
ARM GNU汇编程序框架 .section .data 初始化的数据 .section .bss 未初始化的数据 .section .text .global _start _start: 汇编代码 入口地址 汇编程序的示例 //start.s .bass .text .global _start _start: mov r1,#1 mov r2,#2 add r3,r1,r2 _loop: b _loop //Makefile all:start.o arm-linux-ld -Ttext 0x30000000 -o start.elf start.o start.o:star
[单片机]
Linux之ARM(IMX6U)裸机汇编LED驱动实验--驱动编写
1. I.MX6ULL的初始化 ①、使能时钟 使能时钟。CCGR0–CCGR6这七个寄存器控制着I.MX6ULL所有外设时钟的使能,为了简单,设置CCGR0–CCGR6这七个寄存器全部为0xFFFFFFFF,相当于使能所有的外设时钟 CCGR0: CCGR1: CCGR2: CCGR3: CCGR4: CCGR5: CCGR6: 汇编使能所有的外设时钟: ②、配置 GPIO_I003 PIN的复用为GPIO 将IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的bit3-0,设置为0101,这样GPIO_IO03就复用为GPIO 汇编实现: ③、配置 IOMUXC_SW_P
[单片机]
Linux之ARM(IMX6U)<font color='red'>裸机</font><font color='red'>汇编</font><font color='red'>LED</font>驱动实验--驱动编写
Linux之ARM(IMX6U)裸机汇编LED驱动实验--烧写bin文件到SD卡运行
代码烧写 I.MX6U 虽然内部有 96K 的 ROM,但是这 96K 的 ROM 是 NXP自己用的,不向用户开放。所以相当于说 I.MX6U 是没有内部 flash 的,但是我们的代码得有地方存放啊,为此,I.MX6U 支持从外置的 NOR Flash、NAND Flash、SD/EMMC、SPI NOR Flash和 QSPI Flash 这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中中。在这些存储介质中,除了 SD 卡以外,其他的一般都是焊接到了板子上的,我们没法直接烧写。但是 SD卡是活动的,是可以从板子上插拔的,我们可以将 SD 卡插到电脑上,在电脑上使用软件将.bin文件烧写到 SD 卡中,然后再插到板子
[单片机]
Linux之ARM(IMX6U)<font color='red'>裸机</font><font color='red'>汇编</font><font color='red'>LED</font>驱动实验--烧写bin文件到SD卡运行
2440裸机编程之二 C语言调用汇编语言编程
和C调用汇编一致,前四个参数用R0-R3传递,后面的用堆栈传递 测试这个程序: //****************************************************** //main.C extern int test(int, int, int); int n; int main(void) { n = test(2,4,6); while(1); } int add(int a, int b, int c) { return a+b+c; } //****************************************************** ;*********************
[单片机]
2440<font color='red'>裸机</font>编程之二 C语言调用<font color='red'>汇编</font>语言编程
2440裸机编程之一 C语言调用汇编语言编程
一、内嵌汇编的方式,使用关键字__asm{汇编指令……},这种方式操作简单,但是限制很多,比如:不能写PC、不支持标号表达式等等,许多正常的汇编指令和伪指令都不用。 下面是个例子: //****************************************** int x = 3; int y = 5; int z; int main(void) { __asm { MOV R0,x MOV R1,y ADD R0,R0,R1 MOV z,R0 } while(1); } //****************************************** 结果即z=x+y 如图 二、调用外部汇
[单片机]
2440<font color='red'>裸机</font>编程之一 C语言调用<font color='red'>汇编</font>语言编程
OK6410裸机学习之汇编调用C函数传参数
start.S汇编源码: .globl _start _start: // 硬件相关的设置 // Peri port setup ldr r0, =0x70000000 orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) // 关看门狗 // 往WTCON(0x7E004000)写0 ldr r0, =0x7E004000 mov r1, #0 str r1, // 设置栈 ldr sp, =6*1024 // int xxxxx(int start, int end, i
[单片机]
OK6410裸机学习之时钟设置-汇编
start.S源码: .globl _start _start: // 硬件相关的设置 // Peri port setup ldr r0, =0x70000000 orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) // 关看门狗 // 往WTCON(0x7E004000)写0 ldr r0, =0x7E004000 mov r1, #0 str r1, // 设置时钟 bl clock_init // 设置栈 ldr sp, =8*1024 bl main
[单片机]
OK6410<font color='red'>裸机</font>学习之时钟设置-<font color='red'>汇编</font>
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved