04 点亮LED C

发布者:皮球最新更新时间:2021-10-18 来源: eefocus关键字:点亮LED  S3C2440 手机看文章 扫描二维码
随时随地手机看文章

1 C语言控制LED

前述汇编中,写地址0x56000050(GPFCON)和0x56000054(GPFDAT),相当于C中的指针操作。


void main(void)

{

unsigned int * pGPFCON = 0x56000050;

unsigned int * pGPFDAT = 0x56000054;

 

/* 配置GPF4为输出引脚 */

*pGPFCON = 0x100;

 

/* 设置GPF4输出0 */

*pGPFDAT = 0;

}


问题来了。1 我们写出了main函数,谁来调用它?  2  main函数中的变量,保存在内存中,内存地址是多少?


解决办法:我们还需要写一个汇编代码,给main函数设置内存,调用main函数


代码如下:


led.c


int main(void)

{

unsigned int * pGPFCON = (unsigned int *)(0x56000050);

unsigned int * pGPFDAT = (unsigned int *)(0x56000054);

 

/* 配置GPF4为输出引脚 */

*pGPFCON = 0x100;

 

/* 设置GPF4输出0 */

*pGPFDAT = 0;

 

return 0;

}


start.S


.text

.global _start

 

_start:

 

/* 设置内存: sp栈 */

ldr sp, =4096 /* nand启动 */

// ldr sp, =0x40000000 + 4096 /* nor启动 */

 

/* 调用main */

bl main

 

halt:

b halt

Makefile


all:

arm-linux-gcc -c -o led.o led.c

arm-linux-gcc -c -o start.o start.S

arm-linux-ld -Ttext 0 start.o led.o -o led.elf

arm-linux-objcopy -O binary -S led.elf led.bin

arm-linux-objdump -D led.elf > led.dis

 

clean:

rm *.bin *.o *.elf *.dis

汇编指令中,bl跳转和b的区别(bl会在lr寄存器中,保存当前pc - 4,就是当前指令的下一条指令):

2 C语言分析

几条汇编指令:


2.1  add r0, r1, r2  或 add r0, r1, #4 

2.2  sub r0, r1, r2 或 sub r0, r1, #4

3 ldm  stm  传送多个数据

按照图示,堆栈操作中,常使用的是ldmia(先读取栈数据,再增加栈地址)和stmdb(先减少栈地址,然后保存到栈中)。


如图所示,stmdb sp!, {fp, ip, lr, pc},大括号里面的寄存器顺序可以随便写,无所谓。


假设sp = 4096:(1)sp=sp-4  pc寄存器的值,被保存在4092~4095内存中;(2)sp=sp-4;lr寄存器的值被保存在4088~4091内存中。。。


到这里,说白了,stmdb就是把寄存器的值保存到内存(栈)中。


最后这个感叹号sp!,表示sp为修改后的值4080;如果不加!,则sp为原始值4096。


ldmia指令

C语言内部机制分析

Start.S做了哪些事情?


1 设置栈;2 调用main函数,把返回地址保存在lr中;

led.c main函数做了什么?


1 定义两个局部变量;2 设置变量; 3 return 0;


问题来了。为什么要设置栈?因为C函数要用。怎么使用?


栈的作用:1 保存局部变量;2 保存lr等寄存器(子函数调用);


调用者如何串参数给被调用者?被调用者如何传返回值给调用者?


怎么从栈中恢复寄存器?


1 ATPCS规则

2 汇编代码与bin文件

可以看到,bin文件完全就是汇编代码。


再次说明:关于BL跳转与LR返回地址的解释:

内存布局:

汇编代码操作寄存器如下:

通过r0寄存器传递参数


led.c


void delay(int cnt)

{

while (cnt--);

}

 

int led_on(int which)

{

unsigned int * pGPFCON = (unsigned int *)(0x56000050);

unsigned int * pGPFDAT = (unsigned int *)(0x56000054);

 

if (4 == which)

{

/* 配置GPF4为输出引脚 */

*pGPFCON = 0x100;

}

else if (5 == which)

{

/* 配置GPF5为输出引脚 */

*pGPFCON = 0x400;

}

/* 设置GPF4/5输出0 */

*pGPFDAT = 0;

 

return 0;

}

 

start.S


 

.text

.global _start

 

_start:

 

/* 设置内存: sp栈 */

ldr sp, =4096 /* nand启动 */

// ldr sp, =0x40000000 + 4096 /* nor启动 */

 

// 使用r0传递参数

mov r0, #4

bl led_on

 

ldr r0, =100000

bl delay

 

mov r0, #5

bl led_on

 

halt:

b halt


编译得到的汇编文件如下:

关键字:点亮LED  S3C2440 引用地址:04 点亮LED C

上一篇:S3C2440 UART串口驱动(裸机)
下一篇:04 点亮LED 汇编

推荐阅读最新更新时间:2024-11-23 05:00

80C152单片机上HDLC通信规程中的应用
80C152是一种基于MCS-51的高集成度8位微控制器,也是一种通用通信控制器。它既适用于外围系统或器件的智能管理,也适用于低成本,高速串行通信场合。80C152是80C51的派生产品,保留了80C51的所有功能;增加了新的功能和外围电路,包括:一种叫做全局串行通道(GSC)的高速多协议串行通讯接口,两个直接存储器存取(DMA)通道,HOLD/HLDA总线控制,第5、6、7个I/O口。较大的片内RAM容量。因而特别适用于综合业务数字网(ISDN)、局域网和用户定义的串行多机系统。 600)this.style.width='600px';" border=0> 1 80C152的主要特性与结构 80C152的主要特性如下
[单片机]
80<font color='red'>C</font>152单片机上HDLC通信规程中的应用
矩阵式键盘扫描c程序
把每个键都分成水平和垂直的两端接入,比如说扫描码是从垂直的入,那就代表那一行所接收到的扫描码是同一个bit,而读入扫描码的则是水平,扫描的动作是先输入扫描码,再去读取输入的值,经过比对之后就可知道是哪个键被按下。 比如说扫描码送入01111111,前面的0111是代表此时扫描第一行P1.0列,而后面的1111是让读取的4行接脚先设為VDD,若此时第一行的第三列按键被按下,那读取的结果就会变成01111101(注意1111变成1101),其中LSB的第三个bit会由1变成0,这是因為这个按键被按下之后,会被垂直的扫描码电位short,而把读取的LSB的bit电位拉到0,此即為扫描原理。 * 描述:
[单片机]
实时操作系统μC/OS-II在51单片机上的移植
μC/OS-II是一种公开源代码、结构小巧、具有可剥夺实时内核的嵌入式开发系统,代码简短、条理清晰、实时性及安全性能很高,绝大部分代码用C编写,现已被移植到多种处理器的构架中。随着51单片机片内资源的日益丰富,在51单片机上移植μC/OS-II已成为可能,植入系统后,由系统来管理软件与硬件资源,简化应用程序的设计,并且使应用系统功能更加完善。因此在51单片机上移植μC/OS-II具有十分重要的意义。 1 μC/OS实时操作系统概述 μC/OS-II实时操作系统是一种可移植、可固化、可裁剪即可剥夺型的多任务实时内核,适用于各种 微处理器 和微控制器。μC/OS-II主要包括任务调度、时间管理、内存管理、事件管理(信号量、邮箱
[单片机]
实时操作系统μ<font color='red'>C</font>/OS-II在51单片机上的移植
单片机C语言 串口传输 结构体
串口传输 结构体 就是 把结构体 转换为 数组 ,然后传输 数组中的 char。 即 struct - - - - - - - char ; 然后 char - - - -- - - - -- struct . 给出一下简单实例代码 : #include stdio.h #include stdlib.h /*--------------------------start file---------------------------------*/ typedef struct { int id; char name ; int score; }student; int struct_ar
[单片机]
更强劲更轻薄,搭载骁龙850的Yoga C630 WOS
联想Yoga C630 WOS(Windows on Snapdragon)是首款搭载全新 高通骁龙850移动计算平台 的始终在线、始终连接的PC。这款二合一笔记本融合了Windows 10操作系统、增强的性能、精巧轻薄的设计、超过25小时的电池续航以及集成的千兆级LTE连接,这也使它成为一款可以满足极致移动生产力与娱乐的设备。 Yoga C630 WOS旨在满足用户对生产力与娱乐的全部需求,从创作大文件演示文稿到追剧,再到其他更多事情。接下来,让我们一起来看看这款始终在线、始终连接的PC如何支持用户忙碌的一天。 随时随地 保持连接 在离开室内环境或家庭Wi-Fi之前,你通常会查看日历,同时也意识到即将迎来漫长的
[家用电子]
更强劲更轻薄,搭载骁龙850的Yoga <font color='red'>C</font>630 WOS
s3c2440 mmu.c的分析
/************************************************ NAME : MMU.C DESC : Revision : 1.0 ************************************************/ #include def.h #include option.h #include 2440addr.h #include 2440lib.h #include 2440slib.h #include mmu.h // 1) Only the section table is used. // 2) The cachable/non-cach
[单片机]
对<font color='red'>s3c</font>2440 mmu.<font color='red'>c</font>的分析
将基于AT89C2051的解码器应用于安防系统
1 引 言      目前,我国应用极广的编解码器是Princeton公司生产的具有531441(3 12 )种状态的PT2262编码芯片和与之配套的PT2272解码芯片。但一片PT2272只能对一种地址的PT2262的15种状态进行解码,对于较大的编解码保安防盗控制系统,常使用多片PT2272组合解码,但仍远远满足不了大中型安防系统的设计要求。因此,采用AT89C2051单片机,实现了PT2262的大容量解码功能。 2 PT2262的编码原理      PT2262(可参阅http://www.princeton.com.tw)的工作原理如图1所示,图中K0~K7为地址端,应该预置其状态;K8~K11为数据端,按下按钮开
[单片机]
μC/OS-II在LPC213X上的多种移植方案
μC/OS-II是可移植、适用于对安全性要求苛刻的剥夺型实时多任务嵌入式系统,简单易学,在工程应用和嵌入式系统教学中很受欢迎。LPC213X是Philips公司推出的基于ARM7TDMI-S核的32位RISC微处理器,也适合于ARM学习开发平台和工程应用。 1 与μC/OS-II移植工作相关的主要特性 ARM体系结构分为7种运行模式,ARM和Thumb两种工作状态。LPC213X的编程模型就是标准的ARM7体系结构;同时LPC213X也具备ARM的标准异常模式IRQ和FIQ。稍具特色的是其VIC向量中断控制器。分别对IRQ、FIQ、非向量中断和软件中断进行了分类,具有对32个中断输入的可编程分配机制。这对于μC/OS-II的移植
[应用]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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