Neza-D1开发板学习之点灯篇
板子到手先来点个灯那是少不了的,先确定LED接在哪个引脚上,查看原理图,发现LED的座位号是U13,原来不是普通的LED,是一颗单总线的WS2812灯珠,这颗LED是接在PC0引脚上的,引脚标有LEDC-DO,是接在了LED控制器上,驱动官方已经做好了,我们直接用就可以
下边废话不多说,来看一下系统启动过程,系统已经把驱动给加载好了
[ 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来查看一下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当然以上的操作不是操作的GPIO,而是使用的LED子系统,下边是用GPIO操作LED,这里的LED是在扩展板上引出的,引脚是通过PCF8574扩展出来的,具体可以看看D1原理图
使用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使用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
就这么简单以上操作还都未涉及到代码,下边开始用代码操作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 323+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;
}到此点灯结束,感谢观看!