Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页

    Neza-D1开发板学习之点灯篇

    MR Series
    1
    1
    1608
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • X
      xfdr0805 LV 5 last edited by

      1. 板子到手先来点个灯那是少不了的,先确定LED接在哪个引脚上,查看原理图,发现LED的座位号是U13,原来不是普通的LED,是一颗单总线的WS2812灯珠,这颗LED是接在PC0引脚上的,引脚标有LEDC-DO,是接在了LED控制器上,驱动官方已经做好了,我们直接用就可以

      2. 下边废话不多说,来看一下系统启动过程,系统已经把驱动给加载好了

         [    2.100847] sunxi_led_probe()1715 - start
         [    2.105375] sunxi_get_str_of_property()1560 - failed to get the string of propname led_regulator!
         [    2.115306] sunxi_register_led_classdev()1448 - led_classdev start
         [    2.126681] sunxi_led_probe()1820 - finish
        
      3. 来查看一下LED子系统下的灯

         # ls /sys/class/leds/
         blink         sunxi_led11g  sunxi_led3b   sunxi_led5r   sunxi_led8g
         sunxi_led0b   sunxi_led11r  sunxi_led3g   sunxi_led6b   sunxi_led8r
         sunxi_led0g   sunxi_led1b   sunxi_led3r   sunxi_led6g   sunxi_led9b
         sunxi_led0r   sunxi_led1g   sunxi_led4b   sunxi_led6r   sunxi_led9g
         sunxi_led10b  sunxi_led1r   sunxi_led4g   sunxi_led7b   sunxi_led9r
         sunxi_led10g  sunxi_led2b   sunxi_led4r   sunxi_led7g
         sunxi_led10r  sunxi_led2g   sunxi_led5b   sunxi_led7r
         sunxi_led11b  sunxi_led2r   sunxi_led5g   sunxi_led8b
        

        这里出现了很多LED,设备树默认是12个,这样子是不是很熟悉了,我们板子上的LED就是led0

         # ls /sys/class/leds/sunxi_led0b/
         brightness            power                 uevent
         device                subsystem             waiting_for_supplier
         max_brightness        trigger
        

        先来个红色的呼吸灯

         # echo heartbeat > /sys/class/leds/sunxi_led0r/trigger 
        

        再来个蓝色1秒闪烁一次

         # echo timer > /sys/class/leds/sunxi_led0b/trigger
        

        这灯真是亮瞎眼啊,查看亮度

         # cat  /sys/class/leds/sunxi_led0b/brightness 
         255
        

        调到50,这下好了

         # echo 50 > /sys/class/leds/sunxi_led0b/brightness
        

        把灯关掉

          # echo none > /sys/class/leds/sunxi_led0b/trigger
        

        查看支持哪些触发方式

         # cat  /sys/class/leds/sunxi_led0b/trigger 
         none rc-feedback rfkill-any rfkill-none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock mmc0 mmc1 timer oneshot [mtd] nand-disk heartbeat backlight gpio cpu cpu0 activity default-on transient netdev pattern audio-mute audio-micmute
        
      4. 当然以上的操作不是操作的GPIO,而是使用的LED子系统,下边是用GPIO操作LED,这里的LED是在扩展板上引出的,引脚是通过PCF8574扩展出来的,具体可以看看D1原理图

      5. 使用SYSFS方式操作GPIO,在操作前先查看一下系统里未使用的GPIO,这里以PD18 BL—PWM为例

        # ls /sys/class/gpio/
        export        gpiochip0     gpiochip2020  unexport
        # PD18 = 32*3+18=114
        # echo 114 > export 
        

        执行成功 目录下会出现gpio114,查看一下内容,可以看到里边有direction,value

        # ls gpio114 
        active_low            edge                  uevent
        device                power                 value
        direction             subsystem             waiting_for_supplier
        

        接下来设置方向

        # echo out > gpio114/direction 
        

        输出高电平

        # echo 1 > gpio114/value
        

        输出低电平

        # echo 0 > gpio114/value
        

        不用的话执行

        # echo 114 > unexport
        

        查看一下,已经没有那个引脚导出的目录了

        # ls
        export        gpiochip0     gpiochip2020  unexport
        
      6. 使用GPIOD操作GPIO,先查询一下系统GPIO情况

         # gpiodetect 
         gpiochip0 [2000000.pinctrl] (224 lines)
         gpiochip1 [pcf8574] (8 lines)
         # gpioinfo gpiochip0 | grep -v unused | grep -v kernel
         gpiochip0 - 224 lines:
                 line   0:      unnamed      "sysfs"   input  active-high [used]
                 line   1:      unnamed      "sysfs"   input  active-high [used]
                 line   5:      unnamed      "sysfs"   input  active-high [used]
                 line  34:      unnamed  "interrupt"   input  active-high [used]
                 line 110:      unnamed "soc@3000000:rotary" input active-low [used]
                 line 111:      unnamed "soc@3000000:rotary" input active-low [used]
                 line 115:      unnamed  "usb1-vbus"  output  active-high [used]
                 line 116:      unnamed    "otg_det"   input  active-high [used]
                 line 117:      unnamed     "otg_id"   input  active-high [used]
                 line 118:      unnamed "soc@3000000:ir_send" output active-high [used]
                 line 144:      unnamed    "phy-rst"  output  active-high [used]
                 line 166:      unnamed         "cd"   input  active-high [used]
         # gpioinfo gpiochip1
         gpiochip1 - 8 lines:
                 line   0:      unnamed "Key volume up" input active-low [used]
                 line   1:      unnamed "Key volume down" input active-low [used]
                 line   2:      unnamed   "Key back"   input   active-low [used]
                 line   3:      unnamed      "blink"  output   active-low [used]
                 line   4:      unnamed  "Key enter"   input   active-low [used]
                 line   5:      unnamed        "led"  output  active-high [used]
                 line   6:      unnamed      "reset"  output   active-low [used]
                 line   7:      unnamed         "dc"  output   active-low [used]
        

        同样使用上边那个未使用的引脚为例 PD18 BL-PWM
        输出高电平

         # gpioset gpiochip0 114=1
        

        输出低电平

         # gpioset gpiochip0 114=0
        

        读取引脚电平

         # gpioget gpiochip0 114
         1
        

        就这么简单

      7. 以上操作还都未涉及到代码,下边开始用代码操作GPIO,代码仅供参考

        SYSFS方式

         #include <stdio.h>
         #include <stdlib.h>
         #include <string.h>
         #include <unistd.h>
         int main(void)
         {
             FILE *p = NULL;
             int i = 0;
             p = fopen("/sys/class/gpio/export", "w");
             fprintf(p, "%d", 38);
             fclose(p);
             p = fopen("/sys/class/gpio/gpio38/direction", "w");
             fprintf(p, "out");
             fclose(p);
             for (i = 0; i < 100; i++)
             {
                 p = fopen("/sys/class/gpio/gpio38/value", "w");
                 fprintf(p, "%d", 1);
                 sleep(1);
                 fclose(p);
                 p = fopen("/sys/class/gpio/gpio38/value", "w");
                 fprintf(p, "%d", 0);
                 sleep(1);
                 fclose(p);
             }
             p = fopen("/sys/class/gpio/unexport", "w");
             fprintf(p, "%d", 38);
             fclose(p);
             return 0;
         }
        

        GPIOD方式

         #include "gpiod/gpiod.h"
         #include <linux/fcntl.h>
         #include <signal.h>
         #include <stdio.h> -std=c99  -std=gnu99
         #include <stdlib.h>
         #include <string.h>
         #include <sys/time.h>
         #include <unistd.h>
         #define LED_PIN 148     PD8 32*3+18
         #define msleep(t) usleep((t)*1000)
        
         struct gpiod_chip *chip;
         struct gpiod_line *line;
         
         void _timer_handler(int n)
         {
             num++;
             gpiod_line_set_value(line, num % 2);
         }
         int main(int argc, char const *argv[])
         {
             struct gpiod_line_request_config config;
             int req;
             /* 1.打开 GPIO 控制器 */
             chip = gpiod_chip_open("/dev/gpiochip0");
             if (!chip)
                 return -1;
             /* 2.获取指定引脚 */
             line = gpiod_chip_get_line(chip, LED_PIN);
             if (!line)
             {
                 gpiod_chip_close(chip);
                 return -1;
             }
             /* 3.配置引脚输出  */
              req = gpiod_line_request_output(line, "blink", 0);
              if (req)
              {
                  fprintf(stderr, "gpio line request error.\n");
                  return -1;
              }
             signal(SIGALRM, _timer_handler);
             struct itimerval itv;
             itv.it_value.tv_sec = 1;
             itv.it_value.tv_usec = 1000; 
             itv.it_interval.tv_sec = 1;
             itv.it_interval.tv_usec = 0;
             setitimer(ITIMER_REAL, &itv, NULL);
             while (1)
             {
                 
             }
        
             return 0;
         }
        
      8. 到此点灯结束,感谢观看!

      1 Reply Last reply Reply Quote Share 1
      • 1 / 1
      • First post
        Last post

      Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

      行为准则 | 用户协议 | 隐私权政策