前言
前面通過匯編語言點亮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同時閃爍。效果不好用圖片展示,因此就不上圖了。
新聞熱點
疑難解答