《嵌入式linux应用程序开发完全手册》LED裸板硬件编程(C语言) 学习笔记
2009-09-26 19:17
609 查看
《嵌入式linux应用程序开发完全手册》LED裸板硬件编程(C语言) 学习笔记
刚刚学习ARM的朋友,我建议先用汇编写一段时间的程序,对基本的ARM汇编有了一个基本的掌握后再改用C语言+汇编的方式进行程序设计,我们先来看一下C语言执行的过程,主要关注它的执行需要的条件和环境,然后根据这些环境在我们的裸板上搭建这些环境,让我们的C语言可以执行。
C语言执行的第一条指令其实并不是main函数,在生成一个C程序的可执行文件时,编译器通常会在我们的代码中加上几个称之为启动文件的的代码--- crt1.o,crti.o,crtend.o,crtn.o等,它们是标准的库文件,这些代码用来设置C程序运行所需的堆栈等,完成一些环境设置后,再调用main函数,生成的这些文件信赖于操作系统,在裸板上没有这些的编译器,这些代码根本无法运行,所以需要为我们真正的C语言写一代码环境配置的代码。以下代码都是简单的几行,就不作详细分析。
设置堆栈的程序如下:
点亮LED的C语言 代码如下:
上面实现了依次点亮一个LED1~LED4的功能,如果你感觉这一个灯一个一个地孤单的闪烁太寂寞,那现在我们将实现一个类似跑马灯的功能,让LED1~4按计数方式循环点亮,规律如下:
以下为1的位被点亮,由于LED1~4与I/O的连接如关系为led1~4连接GPB5~8,故规律如下示。
于是这样一个类似跑马灯的程序就自然而然的出来了:
Makefile文件如下:
调试程序的方法见前面所述。
刚刚学习ARM的朋友,我建议先用汇编写一段时间的程序,对基本的ARM汇编有了一个基本的掌握后再改用C语言+汇编的方式进行程序设计,我们先来看一下C语言执行的过程,主要关注它的执行需要的条件和环境,然后根据这些环境在我们的裸板上搭建这些环境,让我们的C语言可以执行。
C语言执行的第一条指令其实并不是main函数,在生成一个C程序的可执行文件时,编译器通常会在我们的代码中加上几个称之为启动文件的的代码--- crt1.o,crti.o,crtend.o,crtn.o等,它们是标准的库文件,这些代码用来设置C程序运行所需的堆栈等,完成一些环境设置后,再调用main函数,生成的这些文件信赖于操作系统,在裸板上没有这些的编译器,这些代码根本无法运行,所以需要为我们真正的C语言写一代码环境配置的代码。以下代码都是简单的几行,就不作详细分析。
设置堆栈的程序如下:
@****************************************************************************** @ File:crt0.S @ 功能:通过它转入C程序 @****************************************************************************** .text .global _start _start: ldr r0, =0x53000000 @ WATCHDOG寄存器地址 mov r1, #0x0 str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启 ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K bl main @ 调用C程序中的main函数 halt_loop: b halt_loop
点亮LED的C语言 代码如下:
#define GPBCON (*(volatile unsigned long *)0x56000010) #define GPBDAT (*(volatile unsigned long *)0x56000014) void delay(int t) { for(;t>0;t--); } int main() { while(1) { GPBCON = 0x00000400; // 设置GPB5为输出口, 位[11:10]=0b01 GPBDAT = 0x00000000; // GPB5输出0,LED1点亮 delay(30000); GPBCON = 0x00001000; // 设置GPB6为输出口, 位[13:12]=0b01 GPBDAT = 0x00000000; // GPB6输出0,LED2点亮 delay(30000); GPBCON = 0x00004000; // 设置GPB7为输出口, 位[15:14]=0b01 GPBDAT = 0x00000000; // GPB5输出0,LED3点亮 delay(30000); GPBCON = 0x00010000; // 设置GPB8为输出口, 位[17:16]=0b01 GPBDAT = 0x00000000; // GPB5输出0,LED4点亮 delay(30000); } return 0; }
上面实现了依次点亮一个LED1~LED4的功能,如果你感觉这一个灯一个一个地孤单的闪烁太寂寞,那现在我们将实现一个类似跑马灯的功能,让LED1~4按计数方式循环点亮,规律如下:
以下为1的位被点亮,由于LED1~4与I/O的连接如关系为led1~4连接GPB5~8,故规律如下示。
000000000 000100000 001000000 001100000 010000000 010100000 011000000 011100000 100000000 100100000 101000000 101100000 110000000 110100000 111000000 111100000
于是这样一个类似跑马灯的程序就自然而然的出来了:
#define GPBCON (*(volatile unsigned long *)0x56000010) #define GPBDAT (*(volatile unsigned long *)0x56000014) #define GPB5_out (1<<(5*2)) #define GPB6_out (1<<(6*2)) #define GPB7_out (1<<(7*2)) #define GPB8_out (1<<(8*2)) void wait(unsigned long dly) { for(; dly > 0; dly--); } int main(void) { unsigned long i = 0; GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出 while(1){ wait(30000); GPBDAT = (~(i<<5)); // 根据i的值,按计数方式循环点亮LED1-4 if(++i == 16) i = 0; } return 0; }
Makefile文件如下:
led_on_c.bin : crt0.S led_on_c.c arm-linux-gcc -g -c -o crt0.o crt0.S arm-linux-gcc -g -c -o led_on_c.o led_on_c.c arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on_c.o -o led_on_c_elf arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin arm-linux-objdump -D -m arm led_on_c_elf > led_on_c.dis clean: rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o
调试程序的方法见前面所述。
相关文章推荐
- 《嵌入式linux应用程序开发完全手册》KEY-LED裸板硬件编程(C语言) 学习笔记
- 《嵌入式linux应用程序开发完全手册》LED裸板硬件编程(汇编)学习笔记
- GNU/Linux应用程序开发学习笔记(三)套接字编程
- GNU/Linux应用程序开发学习笔记(二)管道编程
- 《嵌入式linux应用程序开发完全手册》系统时钟和定时器学习笔记
- Android(java)学习笔记218:开发一个多界面的应用程序之人品计算器的简单实现
- GTK+图形化应用程序开发学习笔记(四)—容器、构件
- Android(java)学习笔记221:开发一个多界面的应用程序之不同界面间互相传递数据(短信助手案例)
- GTK+图形化应用程序开发学习笔记(一)—概述
- Android开发学习笔记(九)Android应用界面编程 AutoCompleteTextView学习
- FFmpeg基础库编程开发学习笔记——音频常见格式及字幕格式
- C语言学习笔记之C语言编程
- ASP.NET 3.5核心编程学习笔记(57):针对AJAX应用程序的WCF服务
- GTK+图形化应用程序开发学习笔记(一)—概述
- 【GTK】GTK+图形化应用程序开发学习笔记(二)—Glib库
- 【GTk】GTK+图形化应用程序开发学习笔记(四)—容器、构件
- 【GTk】GTK+图形化应用程序开发学习笔记(六)—按钮
- GTK+图形化应用程序开发学习笔记(七)—标签构件.事件盒构件
- GTK+图形化应用程序开发学习笔记(一)—概述
- GTK+图形化应用程序开发学习笔记(二)—Glib库