参考
香橙派zero3配个iic屏显示ip.csdn
orangepiwiki.site 用户手册
香橙派zero3资料下载
香橙派zero3 wifi配置
orangepi@orangepizero3:~$ gpio readall
+------+-----+----------+--------+---+ H616 +---+--------+----------+-----+------+
| GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO |
+------+-----+----------+--------+---+----++----+---+--------+----------+-----+------+
| | | 3.3V | | | 1 || 2 | | | 5V | | |
| 229 | 0 | SDA.3 | ALT5 | 0 | 3 || 4 | | | 5V | | |
| 228 | 1 | SCL.3 | ALT5 | 0 | 5 || 6 | | | GND | | |
| 73 | 2 | PC9 | OFF | 0 | 7 || 8 | 0 | ALT5 | TXD.5 | 3 | 226 |
| | | GND | | | 9 || 10 | 0 | ALT5 | RXD.5 | 4 | 227 |
| 70 | 5 | PC6 | ALT5 | 0 | 11 || 12 | 0 | OFF | PC11 | 6 | 75 |
| 69 | 7 | PC5 | ALT5 | 0 | 13 || 14 | | | GND | | |
| 72 | 8 | PC8 | OFF | 0 | 15 || 16 | 0 | OFF | PC15 | 9 | 79 |
| | | 3.3V | | | 17 || 18 | 0 | OFF | PC14 | 10 | 78 |
| 231 | 11 | MOSI.1 | OFF | 0 | 19 || 20 | | | GND | | |
| 232 | 12 | MISO.1 | OFF | 0 | 21 || 22 | 0 | OFF | PC7 | 13 | 71 |
| 230 | 14 | SCLK.1 | OFF | 0 | 23 || 24 | 0 | OFF | CE.1 | 15 | 233 |
| | | GND | | | 25 || 26 | 0 | OFF | PC10 | 16 | 74 |
| 65 | 17 | PC1 | OFF | 0 | 27 || 28 | 0 | ALT5 | PWM3 | 21 | 224 |
| 272 | 18 | PI16 | ALT2 | 0 | 29 || 30 | 0 | ALT5 | PWM4 | 22 | 225 |
| 262 | 19 | PI6 | OFF | 0 | 31 || 32 | | | | | |
| 234 | 20 | PH10 | ALT3 | 0 | 33 || 34 | | | | | |
+------+-----+----------+--------+---+----++----+---+--------+----------+-----+------+
| GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO |
+------+-----+----------+--------+---+ H616 +---+--------+----------+-----+------+
root@orangepizero3:~# ls /sys/class/gpio
export gpiochip0 gpiochip352 unexport
# 切换root
orangepi@orangepizero3:~$ sudo -i
# 操作PC9
# 导出引脚
root@orangepizero3:~# echo 73 > /sys/class/gpio/export
# 设置为输出模式
root@orangepizero3:~# echo out | sudo tee /sys/class/gpio/gpio73/direction
out
# 输出高电平
root@orangepizero3:~# echo 1 | sudo tee /sys/class/gpio/gpio73/value
1
# 输出低电平
root@orangepizero3:~# echo 0 | sudo tee /sys/class/gpio/gpio73/value
0
root@orangepizero3:~# ls /sys/class/gpio
export gpio73 gpiochip0 gpiochip352 unexport
# PC5输出高
orangepi@orangepizero3:~/gpio_demo_prj$ gpio write 7 1
# PC5输出低
orangepi@orangepizero3:~/gpio_demo_prj$ gpio write 7 0
代码
源码目录
orangepi@orangepizero3:~/gpio_demo_prj$ ls
build gpio.cpp gpio.h main.cpp Makefile
Makefile
CXX = g++
CXXFLAGS = -std=c++17 -Wall -O2 -pthread
TARGET = build/gpio_demo
SRCS := $(wildcard *.cpp)
OBJS := $(patsubst %.cpp,build/%.o,$(SRCS))
all: $(TARGET)
build:
mkdir -p build
$(TARGET): build $(OBJS)
$(CXX) $(CXXFLAGS) -o $@ $(OBJS)
build/%.o: %.cpp | build
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -rf build
.PHONY: all clean build
main.cpp
/**
GPIO69 (PC5):输出 1kHz 方波
GPIO70 (PC6):普通输出(先初始化,不使用)
GPIO73 (PC9):输入,检测电平变化并打印
**/
#include <chrono>
#include <iostream>
#include <thread>
#include "gpio.h"
using namespace std::chrono_literals;
static void OutputThread(GPIO &gpio)
{
while (true)
{
gpio.SetHigh();
std::this_thread::sleep_for(std::chrono::microseconds(500));
gpio.SetLow();
std::this_thread::sleep_for(std::chrono::microseconds(500));
}
}
static void InputThread(GPIO &gpio)
{
int last = gpio.Read();
std::cout << "GPIO73 = " << last << std::endl;
while (true)
{
int value = gpio.Read();
if (value != last)
{
last = value;
std::cout << "GPIO73 = " << value << std::endl;
}
// 防止CPU占满
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
int main()
{
GPIO gpio69(GPIO_PORT_69);
GPIO gpio70(GPIO_PORT_70);
GPIO gpio73(GPIO_PORT_73);
if (!gpio69.Open(GPIO::OUTPUT))
return -1;
if (!gpio70.Open(GPIO::OUTPUT))
return -1;
if (!gpio73.Open(GPIO::INPUT))
return -1;
// GPIO70 默认拉低
gpio70.SetLow();
std::thread outputThread(OutputThread, std::ref(gpio69));
std::thread inputThread(InputThread, std::ref(gpio73));
outputThread.join();
inputThread.join();
return 0;
}
gpio.h
#ifndef GPIO_H
#define GPIO_H
#include <string>
enum GPIO_PORT
{
GPIO_PORT_69 = 69, // PC5
GPIO_PORT_70 = 70, // PC6
GPIO_PORT_73 = 73 // PC9
};
class GPIO
{
public:
enum Direction
{
INPUT,
OUTPUT
};
public:
GPIO(GPIO_PORT port);
~GPIO();
bool Open(Direction dir);
void Close();
bool SetHigh();
bool SetLow();
bool Write(bool value);
int Read();
private:
bool Export();
bool SetDirection(Direction dir);
bool WriteFile(const std::string &file, const std::string &value);
private:
int m_gpio;
int m_fd;
};
#endif
gpio.cpp
#include "gpio.h"
#include <fcntl.h>
#include <unistd.h>
#include <chrono>
#include <cstring>
#include <iostream>
#include <thread>
GPIO::GPIO(GPIO_PORT port)
: m_gpio(static_cast<int>(port)),
m_fd(-1)
{
}
GPIO::~GPIO()
{
Close();
}
bool GPIO::WriteFile(const std::string &file,
const std::string &value)
{
int fd = open(file.c_str(), O_WRONLY);
if (fd < 0)
return false;
write(fd, value.c_str(), value.size());
close(fd);
return true;
}
bool GPIO::Export()
{
WriteFile("/sys/class/gpio/export",
std::to_string(m_gpio));
std::this_thread::sleep_for(
std::chrono::milliseconds(50));
return true;
}
bool GPIO::SetDirection(Direction dir)
{
std::string path =
"/sys/class/gpio/gpio" +
std::to_string(m_gpio) +
"/direction";
return WriteFile(path,
dir == OUTPUT ? "out" : "in");
}
bool GPIO::Open(Direction dir)
{
Export();
if (!SetDirection(dir))
{
std::cerr << "GPIO "
<< m_gpio
<< " set direction failed."
<< std::endl;
return false;
}
std::string path =
"/sys/class/gpio/gpio" +
std::to_string(m_gpio) +
"/value";
m_fd = open(path.c_str(), O_RDWR);
if (m_fd < 0)
{
std::cerr << "GPIO "
<< m_gpio
<< " open failed."
<< std::endl;
return false;
}
return true;
}
void GPIO::Close()
{
if (m_fd >= 0)
{
close(m_fd);
m_fd = -1;
}
}
bool GPIO::Write(bool value)
{
if (m_fd < 0)
return false;
lseek(m_fd, 0, SEEK_SET);
if (value)
return write(m_fd, "1", 1) == 1;
else
return write(m_fd, "0", 1) == 1;
}
bool GPIO::SetHigh()
{
return Write(true);
}
bool GPIO::SetLow()
{
return Write(false);
}
int GPIO::Read()
{
if (m_fd < 0)
return -1;
char value;
lseek(m_fd, 0, SEEK_SET);
if (read(m_fd, &value, 1) != 1)
return -1;
return value == '1';
}