GPIO操作之C语言篇 分类: 嵌入式开发学习 2014-06-29 09:26 248人阅读 评论(0) 收藏
2014-06-29 09:26
453 查看
1:主要内容
在嵌入式开发中,一般使用汇编语言做一些芯片初始化工作,当对程序效率要求很高时,也有时会使用汇编语言,但汇编语言相对较难阅读和理解。因此,我们希望我们以后的实验在初始化完芯片相关功能后使用C语言进行编程,方便大家阅读及理解。这一篇的内容主要是讲解使用C语言来控制LED灯闪烁。2:相关要点
1,在通用PC机上写程序都有一个叫做main的函数,是程序的总入口。在嵌入式开发时,怎么从汇编语言跳转到C语言?在跳转之前需要设置哪些东西?2:,在ARM体系中,汇编和C语言之间相互调用时参数如何传递?
关于上面的两个疑问,我不在这里详细分析。我给出参考资料,大家自行参考,思索。
针对问题1: ucos在s3c2410上运行过程整体剖析之基础知识-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: <span style="white-space:pre"> </span>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<ms;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函数之前已经做了很多工作。相关文章推荐
- ARM处理器学习之--GPIO操作篇 分类: 嵌入式开发学习 2014-06-08 18:22 336人阅读 评论(0) 收藏
- 函数调用 堆栈 分类: 嵌入式开发学习 2011-04-08 23:56 4110人阅读 评论(0) 收藏
- arm 汇编 LDMFD 语句有关 分类: 嵌入式开发学习 2011-04-17 21:55 2444人阅读 评论(0) 收藏
- 关于c语言中的复杂原型声明 分类: 嵌入式开发学习 2011-07-18 23:04 534人阅读 评论(1) 收藏
- ARM芯片学习内容规划及ARM开发环境的搭建 分类: 嵌入式开发学习 2014-06-06 14:17 278人阅读 评论(0) 收藏
- 关于 arm的中断系统 分类: 嵌入式开发学习 2011-04-11 19:30 560人阅读 评论(0) 收藏
- configure 时的host build target问题 分类: 嵌入式开发学习 2011-07-20 22:46 3875人阅读 评论(0) 收藏
- c语言 中 # ##的使用方法 分类: 嵌入式开发学习 2014-05-23 17:16 141人阅读 评论(0) 收藏
- linux下的多线程调试(gdb) 分类: 嵌入式开发学习 2011-07-21 22:37 3337人阅读 评论(0) 收藏
- C语言中return与_exit的区别 分类: 嵌入式开发学习 2014-06-09 09:58 210人阅读 评论(0) 收藏
- linux环境搭建和arm开发板环境搭建 分类: 嵌入式开发学习 2011-03-17 22:59 1403人阅读 评论(1) 收藏
- linux 下c 编译和调试 分类: 嵌入式开发学习 2011-03-10 20:33 2433人阅读 评论(0) 收藏
- red hat 9.0 上安装qt4 分类: 嵌入式开发学习 2011-05-14 23:27 598人阅读 评论(0) 收藏
- 作为一个新人,怎样学习嵌入式Linux?(韦东山) 分类: 嵌入式开发学习 2014-06-03 08:12 316人阅读 评论(0) 收藏
- 关于 c语言的编译 和编译后程序的运行 分类: 嵌入式开发学习 2011-03-29 19:57 909人阅读 评论(0) 收藏
- 宏定义 do while(0)分析 分类: 嵌入式开发学习 2014-06-09 09:57 220人阅读 评论(0) 收藏
- qt 在linux环境下的搭建 (自己整理) 分类: 嵌入式开发学习 2011-04-29 20:54 6033人阅读 评论(0) 收藏
- Diff/Patch 工具的使用 分类: 嵌入式开发学习 2014-06-09 09:57 463人阅读 评论(0) 收藏
- 制作S3C6410 的交叉编译链(arm-linux-gcc 4.6.0) 分类: 嵌入式开发学习 2014-03-25 20:26 2398人阅读 评论(0) 收藏
- 对字节对齐的理解 分类: 嵌入式开发学习 2014-02-13 08:45 233人阅读 评论(0) 收藏