zoukankan      html  css  js  c++  java
  • Cubieboard2裸机开发之(三)C语言操作LED

    前言

            前面通过汇编语言点亮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, cpsr
    13     and r1, r0, #0x1f
    14     teq r1, #0x1a
    15     bicne r0, r0, #0x1f
    16     orrne r0, r0, #0x13
    17     orr r0, r0, #0xc0
    18     msr cpsr, r0
    19     /* setup stack, so we can call C code */
    20     ldr sp, =(1024 * 10)
    21     /* call main function */
    22     bl main
    23 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同时闪烁。效果不好用图片展示,因此就不上图了。

  • 相关阅读:
    AdminLTE模板
    日历插件
    Jquery 拖拽表格宽度
    Java桌面程序打包成exe可执行文件
    使用Access-Control-Allow-Origin解决跨域
    Ubuntu默认root密码
    Lua的require和module小结
    nginx 安装
    chkconfig命令
    [转]fedora启动telnet服务
  • 原文地址:https://www.cnblogs.com/lknlfy/p/3594940.html
Copyright © 2011-2022 走看看