前言
前面通过汇编语言点亮LED,代码虽然简单,但并不是很直观。这次使用熟悉的C语言来控制LED,但是需要注意的地方有两点,第一,要想使用C语言,首先需要在调用C语言代码之前设置好堆栈;第二,调用C语言函数时,是需要相对跳转还是绝对地址跳转,还是两者都可以,这就需要知道代码是否运行在链接地址处,是位置无关的还是位置有关的。从前面分析可以知道,我们的代码是运行在链接地址处的,因此可以用直接进行函数的调用。
一、目的
使用C语言的方式操作板载LED。
二、源代码说明
start.S文件。首先禁止CPU的IRQ和FIQ,设置为管理模式,然后设置堆栈指针,最后调用C语言的main函数。
1 /* 2 * (C) Copyright 2014 conan liang <lknlfy@163.com> 3 * 4 */ 5 6 /* global entry point */ 7 .globl _start 8 _start: b reset 9 10 reset:11 /* disable IRQ & FIQ, set the cpu to SVC32 mode */12 mrs r0, cpsr13 and r1, r0, #0x1f14 teq r1, #0x1a15 bicne r0, r0, #0x1f16 orrne r0, r0, #0x1317 orr r0, r0, #0xc018 msr cpsr, r019 /* setup stack, so we can call C code */20 ldr sp, =(1024 * 10)21 /* call main function */22 bl main23 loop:24 b loop
main.c文件。首先初始化LED所在IO管脚,设置为输出功能,并且输出低电平,即一开始两个LED是熄灭的。
1 #include "led.h" 2 3 /* just for test */ 4 static void delay(void) 5 { 6 unsigned int i; 7 8 for (i = 0; i < 50000; i++); 9 }10 11 /* C code entry point */12 int main(void)13 {14 /* init PIO */15 led_init();16 17 while (1) {18 /* two LEDs on */19 set_led_on();20 delay();21 /* two LEDs off */22 set_led_off();23 delay();24 }25 26 return 0;27 }
led.c文件。LED驱动程序,一个初始化函数,一个使两个LED同时点亮函数,一个同时使两个LED同时熄灭函数。
1 #include "led.h" 2 #include "io.h" 3 4 /* set two LEDs on */ 5 void set_led_on(void) 6 { 7 unsigned int tmp; 8 9 /* PH20 and PH21 output 1 */10 tmp = readl(PH_DAT);11 tmp |= (0x1 << 20);12 tmp |= (0x1 << 21);13 writel(tmp, PH_DAT);14 }15 16 /* set two LEDs off */17 void set_led_off(void)18 {19 unsigned int tmp;20 21 /* PH20 and PH21 output 0 */22 tmp = readl(PH_DAT);23 tmp &= ~(0x1 << 20);24 tmp &= ~(0x1 << 21);25 writel(tmp, PH_DAT);26 }27 28 /* init PIO */29 void led_init(void)30 {31 unsigned int tmp;32 33 /* set PH20 and PH21 output */34 tmp = readl(PH_CFG2);35 tmp &= ~(0x7 << 16);36 tmp &= ~(0x7 << 20);37 tmp |= (0x1 << 16);38 tmp |= (0x1 << 20);39 writel(tmp, PH_CFG2);40 /* set PH20 and PH21 output 0 */41 tmp = readl(PH_DAT);42 tmp &= ~(0x1 << 20);43 tmp &= ~(0x1 << 21);44 writel(tmp, PH_DAT);45 }
三、验证
使用arm-linux-gnueabihf工具编译后生成led_c.b文件,再使用mksunxiboot工具在led_c.b文件前面加上一个头部,最终生成led_c.bin文件,使用以下命令将led_c.bin文件烧写到TF中:
#sudo dd if=./led_c.bin of=/dev/sdb bs=1024 seek=8
将TF卡插入Cubieboard2,上电即可看到两个LED同时闪烁。效果不好用图片展示,因此就不上图了。
新闻热点
疑难解答