gpio mysql_GPIO操作之C语言篇

1:主要内容

在嵌入式开发中,一般使用汇编语言做一些芯片初始化工作,当对程序效率要求很高时,也有时会使用汇编语言,但汇编语言相对较难阅读和理解。因此,我们希望我们以后的实验在初始化完芯片相关功能后使用C语言进行编程,方便大家阅读及理解。这一篇的内容主要是讲解使用C语言来控制LED灯闪烁。

2:相关要点

1,在通用PC机上写程序都有一个叫做main的函数,是程序的总入口。在嵌入式开发时,怎么从汇编语言跳转到C语言?在跳转之前需要设置哪些东西?

2:,在ARM体系中,汇编和C语言之间相互调用时参数如何传递?

关于上面的两个疑问,我不在这里详细分析。我给出参考资料,大家自行参考,思索。

针对问题2:参见资料 ATPCS.pdf

3:实验源码

initsystem.s

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

@ 文件名 :initsystem.s

@ 功 能:初始化系统并copy代码

@

@ 作者 :张连聘

@ 创建时间:2014-06-22

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

.text

.global _start

@声明常量

.equ DATA_DST,0x40000000 @目的地址

.equ DATA_SRC,0x80000000 @源地址

@引入外部标号

.extern main

.extern start_copy_addr

_start:

LDR PC, ResetAddr

ResetAddr: .word ResetInit

ResetInit:

LDR R0,=DATA_DST @RO 指向目的地址

LDR R1,=start_copy_addr @R1 指向源地址

MOV R10,#128 @复制的个数为128*8*4=4K

CopyLoop: LDMIA R1!,{R2-R9}@从R1指定的内存地址处装载数据到R2--R9中

STMIA R0!,{R2-R9}@把R2--R9的数据复制到R0指定的内存中

SUBS R10,R10,#1

BNE CopyLoop

LDR SP,=0X40000000+1024*64 @设置堆栈指针,LPC2220内部有64KRAM,设置SP指针指向最高地址

LDR PC,=main @调用C语言的main函数

HaltLoop:

B HaltLoop

.end

main.c

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

* 文件名 :main.c

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

*

* 作者 :张连聘

* 创建时间:2014-06-25

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

//定义一些控制寄存器地址

#define IO2DIR (*(volatile unsigned long *)0xE0028028) //IO2输入、输出配置寄存器

#define IO2SET (*(volatile unsigned long *)0xE0028024) //IO2输出1控制寄存器

#define IO2CLR (*(volatile unsigned long *)0xE002802C) //IO2输出0控制寄存器

#define LEDCON (1<<28)

void Delay(int ms);

void main(void)

{

IO2DIR = LEDCON; //配置P2.28为输出口

while (1)

{

IO2SET = LEDCON; //点亮LED灯

Delay(6666);

IO2CLR = LEDCON; //熄灭LED灯

Delay(6666);

}

}

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

* 名 称:Delay

* 功 能:软件延时

* 入口参数:ms

* 出口参数:无

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

void Delay(int ms)

{

int i,j;

for(i=0;i<10;i++)

for(j=0;j

;

}

led_control.lds

/*

* led_control 的链接脚本。

*

*

*/

MEMORY

{

rom (rx) : ORIGIN = 0x80000000, LENGTH = 2M

ram (!rx) : ORIGIN = 0x40000000, LENGTH = 2M

}

ENTRY(_start)

SECTIONS

{

. = 0x80000000 ;

.init :

{

initsystem.o(.text)

start_copy_addr = . ;

} >rom

. = 0x40000000 ;

.main :

AT (ADDR(.init)+SIZEOF(.init))

{

main.o(.text)

} >ram

}

makefile

control_led.bin:main.c initsystem.s

arm-linux-gcc -g -c -o main.o main.c

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

arm-linux-ld -Tled_control.lds -nostdlib -g main.o initsystem.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

4:源码重点分析

我们在main.c里定义了一个main函数,那我们在汇编代码里怎么引用呐?

.extern  main        声明在另一个文件中定义了main函数。然后LDR PC,=main  跳转到main函数。这里说明一下,之所以不能使用BL指令跳转,是因为启动代码执行的地址在0X80000000 ,而启动代码将main函数代码copy到0X40000000。Bl的跳转范围没有这么大。还有,这个main函数完全可以更改为其他函数,只是一个普通的函数名称。

LDR   SP,=0X40000000+1024*64       使用这条指令,是设置SP堆栈指针的位置。这里讲堆栈指针设置在了LPC2220这款芯片的内部RAM的最顶端。默认的ARM处理器是递减堆栈。

5:总结

由上面的实验可见,PC机编程时的main函数只是一个普通的函数名称,只不过他们底层设置好了,调用main函数,所以我们一般说普通PC机程序总入口是main函数。其实,在main函数之前已经做了很多工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值