Created
April 1, 2020 11:26
-
-
Save heiher/a594849f1a3241fede48ebaf013a21fb to your computer and use it in GitHub Desktop.
外置硬盘盒电源开关伺服电机控制程序(树莓派开机自动触发,配合继电器)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <poll.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <sched.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <sys/mount.h> | |
static const char *led_prefix = "/sys/class/leds"; | |
static const char *gpio_prefix = "/sys/class/gpio"; | |
static int | |
mount_sysfs (void) | |
{ | |
struct stat s; | |
int ret; | |
if (stat ("/sys/class", &s) == 0) { | |
return 0; | |
} | |
ret = mkdir ("/sys", 0755); | |
if (ret < 0 && errno != EEXIST) { | |
return -1; | |
} | |
return mount ("none", "/sys", "sysfs", 0, NULL); | |
} | |
static int | |
set_scheduler_rt (void) | |
{ | |
struct sched_param sp = { .sched_priority = 1 }; | |
return sched_setscheduler (0, SCHED_RR, &sp); | |
} | |
static int | |
set_led (int led, int brightness) | |
{ | |
char path[256]; | |
char buf[16]; | |
int ret = -1; | |
int len; | |
int fd; | |
snprintf (path, sizeof (path), "%s/led%d/brightness", led_prefix, led); | |
fd = open (path, O_WRONLY); | |
if (fd < 0) { | |
goto exit; | |
} | |
len = snprintf (buf, sizeof (buf), "%d\n", brightness); | |
ret = write (fd, buf, len); | |
close (fd); | |
exit: | |
return ret; | |
} | |
static int | |
gpio_set_export (int gpio, int unexport) | |
{ | |
char path[256]; | |
char pin[16]; | |
int ret = -1; | |
int len; | |
int fd; | |
if (unexport) { | |
snprintf (path, sizeof (path), "%s/unexport", gpio_prefix); | |
} else { | |
snprintf (path, sizeof (path), "%s/export", gpio_prefix); | |
} | |
fd = open (path, O_WRONLY); | |
if (fd < 0) { | |
goto exit; | |
} | |
len = snprintf (pin, sizeof (pin), "%d", gpio); | |
ret = write (fd, pin, len); | |
if (ret <= 0) { | |
goto exit_close; | |
} | |
usleep (10 * 1000); | |
exit_close: | |
close (fd); | |
exit: | |
return ret; | |
} | |
static int | |
gpio_set_direction (int gpio, int direction) | |
{ | |
char path[256]; | |
int ret = -1; | |
int fd; | |
snprintf (path, sizeof (path), "%s/gpio%d/direction", gpio_prefix, gpio); | |
fd = open (path, O_WRONLY); | |
if (fd < 0) { | |
goto exit; | |
} | |
if (direction) { | |
ret = write (fd, "out", 3); | |
} else { | |
ret = write (fd, "in", 2); | |
} | |
close (fd); | |
exit: | |
return ret; | |
} | |
static int | |
gpio_write (int fd, int value) | |
{ | |
if (value) { | |
return write (fd, "1", 1); | |
} | |
return write (fd, "0", 1); | |
} | |
static int | |
gpio_open (int gpio, int direction) | |
{ | |
char path[256]; | |
int fd; | |
gpio_set_export (gpio, 1); | |
if (gpio_set_export (gpio, 0) < 0) { | |
fprintf (stderr, "ERR: Export gpio%d failed!\n", gpio); | |
return -1; | |
} | |
if (gpio_set_direction (gpio, direction) < 0) { | |
fprintf (stderr, "ERR: Set direction of gpio%d failed!\n", gpio); | |
return -1; | |
} | |
snprintf (path, sizeof (path), "%s/gpio%d/value", gpio_prefix, gpio); | |
fd = open (path, O_RDWR); | |
if (fd < 0) { | |
fprintf (stderr, "ERR: Open value of gpio%d failed!\n", gpio); | |
return -1; | |
} | |
return fd; | |
} | |
static void | |
gpio_close (int gpio, int fd) | |
{ | |
close (fd); | |
gpio_set_export (gpio, 1); | |
} | |
static void | |
click_button (int fd) | |
{ | |
const double duty_up = 2.0; | |
const double duty_down = 4.0; | |
int i; | |
set_led (0, 255); | |
for (i = 0; i < 10; i++) { | |
gpio_write (fd, 1); | |
usleep (duty_down * 200); | |
gpio_write (fd, 0); | |
usleep ((100.0 - duty_down) * 200); | |
} | |
for (i = 0; i < 10; i++) { | |
gpio_write (fd, 1); | |
usleep (duty_up * 200); | |
gpio_write (fd, 0); | |
usleep ((100.0 - duty_up) * 200); | |
} | |
set_led (0, 0); | |
} | |
static void | |
led_blink (int led) | |
{ | |
for (;;) { | |
set_led (led, 255); | |
usleep (100 * 1000); | |
set_led (led, 0); | |
usleep (100 * 1000); | |
} | |
} | |
int | |
main (int argc, char *argv[]) | |
{ | |
int fd; | |
if (mount_sysfs () < 0) { | |
fprintf (stderr, "ERR: Mount sysfs failed!\n"); | |
goto exit; | |
} | |
if (set_scheduler_rt () < 0) { | |
fprintf (stderr, "WARN: Set realtime scheduler failed!\n"); | |
} | |
fd = gpio_open (18, 1); | |
if (fd < 0) { | |
goto exit; | |
} | |
click_button (fd); | |
gpio_close (18, fd); | |
led_blink (0); | |
return 0; | |
exit: | |
led_blink (1); | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment