香橙派Pi5基于Qt5的GPIO操作
文章目录
前言
最近购买了一块香橙派Pi5的开发板,这款开发板不仅性能上较上一代的Pi4提升了很多,而且价格也非常亲民,属实是国货之光。
一、wiringOP是什么
wiringOP是适用于大部分瑞芯微处理器的GPIO控制模块,可以控制引脚的通断等操作。
二、wiringOP步骤
1.下载库
OrangePi的官方说明书中并没有找到Linux相关的GPIO列子,看来Pi5的说明书还不够完善啊,好在其他RK3588友商的帮助下我顺利地找到了兼容RK3588S的GPIO库,虽然也是Orangepi发布的源,下面是wiringOP下载方式:
git clone https://github.com/orangepi-xunlong/wiringOP.git
2.编译安装库
挂载到目录中:
cd ./wiringOP
清空库:
./build clean
编译库:
./build
编译完成后效果
3.编译安装devLib和wiringPi
经过此步可以把libwiringPiDev.so文件安装到我们的/usr目录下面去
cd ./devLib && sudo make -j4 && sudo make install && cd ..
这个操作和上一步操作一样,经过此步骤libwiringPi.so的依赖已经安装到了我们的/usr目录下
cd ./wiringPi && sudo make -j4 && sudo make install && cd ..
编译完成后的效果:
devLib完成效果
wiringOP完成后的效果
三、Qt配置wiringOP
PS:请务必在sudo模式下运行Qt否则无法使用到GPIO
1.配置Qt工程文件
下面是我的工程文件的目录
2.配置.pro
QT -= gui
#如果有GUI需要请把-改成+
CONFIG += c++11 console
CONFIG -= app_bundle
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
include(./pwm/pwm.pri)
include(./gpio/gpio.pri)
unix:!macx: LIBS += -L$$PWD/../../../usr/local/lib/ -lwiringPiDev
INCLUDEPATH += $$PWD/../../../usr/local/include
DEPENDPATH += $$PWD/../../../usr/local/include
unix:!macx: LIBS += -L$$PWD/../../../usr/local/lib/ -lwiringPi
INCLUDEPATH += $$PWD/../../../usr/local/include
DEPENDPATH += $$PWD/../../../usr/local/include
unix:!macx: LIBS += -L$$PWD/../../../usr/lib/aarch64-linux-gnu/ -lcrypt
INCLUDEPATH += $$PWD/../../../usr/lib/aarch64-linux-gnu
DEPENDPATH += $$PWD/../../../usr/lib/aarch64-linux-gnu
unix:!macx: PRE_TARGETDEPS += $$PWD/../../../usr/lib/aarch64-linux-gnu/libcrypt.a
3.配置.pri
gpio.pri
HEADERS += \
$$PWD/gpio.h
SOURCES += \
$$PWD/gpio.cpp
pwm.pri
HEADERS += \
$$PWD/pwm.h
SOURCES += \
$$PWD/pwm.cpp
四、程序代码
gpio.h
#ifndef GPIO_H
#define GPIO_H
#include <stdio.h>
#include <wiringPi.h>
#include <iostream>
class gpio
{
public:
gpio(int gpio_pin,int gpio_state);
~gpio();
int initGPIO();
void digitalPin(bool state);
private:
/*gpio_state
*
*INPUT 0
*OUTPUT 1
*PWM_OUTPUT 2
*GPIO_CLOCK 3
*SOFT_PWM_OUTPUT 4
*SOFT_TONE_OUTPUT 5
*PWM_TONE_OUTPUT 6
*
**/
int gpio_pin;
int gpio_num;
int gpio_state;
private:
int getGPIONum();
};
#endif // GPIO_H
gpio.cpp
#include "gpio.h"
/**
*
*The GPIO constructor function realized in here
*
*Description:The function will inital Gpio's pin,
*state and num that it can check this Gpio's num
*satisfied with your board or it will exit this
*function.
*
*Design by : shirakami
*Update date: 2023-2-25
**/
gpio::gpio(int gpio_pin,int gpio_state)
{
this->gpio_pin=gpio_pin;
this->gpio_state=gpio_state;
this->gpio_num=getGPIONum();
if(this->gpio_num==-1){
std::cout<<"Failed to get the number of GPIO"<<std::endl;
exit(-1);
}
}
/**
*
*The GPIO inital function realized in here
*
*Description:The function will inital Gpio's pinMode
*and then the wiringPiSetup() function return a type
*of bool.
*
*Example:if(initGPIO()==-1) {
* exit(-1);
*}
*
*Design by : shirakami
*Update date: 2023-2-25
**/
int gpio::initGPIO(){
pinMode(this->gpio_pin,this->gpio_state);
return wiringPiSetup();
}
/**
*
*The GPIO inital function realized in here
*
*Description:You shall set your GPIO's property
*in constructor function this function will call
*back these property in class.
*
*Example:digitalPin(state);
*
*Design by : shirakami
*Update date: 2023-2-25
**/
void gpio::digitalPin(bool state){
digitalWrite(this->gpio_pin,state);
}
int gpio::getGPIONum(){
int model=-1;
piBoardId(&model);
switch (model) {
case PI_MODEL_3:
case PI_MODEL_LTIE_2:
case PI_MODEL_ZERO:
case PI_MODEL_ZERO_PLUS_2:
case PI_MODEL_ZERO_PLUS:
case PI_MODEL_4_LTS:
case PI_MODEL_800:
case PI_MODEL_5:
return 17;
break;
case PI_MODEL_ZERO_2:
return 21;
break;
case PI_MODEL_WIN:
case PI_MODEL_PRIME:
case PI_MODEL_PC_2:
case PI_MODEL_H3:
case PI_MODEL_RK3399:
case PI_MODEL_4:
return 28;
break;
case PI_MODEL_R1_PLUS:
return 8;
break;
default:
std::cout<<"Oops - unable to determine board type... model;"<<model<<std::endl;
return -1;
break;
}
}
pwm.h
#ifndef PWM_H
#define PWM_H
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
class pwm
{
public:
pwm(int pwm_pin,int pwm_width,int pin_mode=SOFT_PWM_OUTPUT);
public:
int initPWM();
void startPWM();
private:
/**PIN_MODE
*INPUT 0
*OUTPUT 1
*PWM_OUTPUT 2
*GPIO_CLOCK 3
*SOFT_PWM_OUTPUT 4
*SOFT_TONE_OUTPUT 5
*PWM_TONE_OUTPUT 6
*
**/
int pwm_pin;
int pin_mode;
int pwm_width;
};
#endif // PWM_H
pwm.cpp
#include "pwm.h"
/**
*
*The PWM inital function realized in here
*
*Description:The function will inital PWM's
*pwm_pin,pwm_width,pin_mode that it can check
*this PWM's num satisfied with your board or
*it will exit this function.The pin_mode is
*default equal to 2.
*
*Design by : shirakami
*Update date: 2023-2-25
**/
pwm::pwm(int pwm_pin,int pwm_width,int pin_mode)
{
this->pwm_pin=pwm_pin;
this->pin_mode=pin_mode;
this->pwm_width=pwm_width;
}
int pwm::initPWM(){
return wiringPiSetup();
}
/**
*
*The PWM inital function realized in here
*
*Description:The function will inital Gpio's pinMode
*and then the wiringPiSetup() function return a type
*of bool.
*
*Example:startPWM()
*
*Design by : shirakami
*Update date: 2023-2-25
**/
void pwm::startPWM(){
pinMode (this->pwm_pin, this->pin_mode) ;
pwmWrite (this->pwm_pin, this->pwm_width) ;
}
main.cpp
#include <QCoreApplication>
#include <pwm/pwm.h>
#include <gpio/gpio.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
pwm* PWM=new pwm(16,500);
if(PWM->initPWM()==-1){
std::cout<<"Oops !!! exit pwm mode"<<std::endl;
exit(-1);
}
PWM->startPWM();
gpio* GPIO=new gpio(0,1);
if(GPIO->initGPIO()==-1){
std::cout<<"Oops !!! exit gpio mode"<<std::endl;
exit(-1);
}
GPIO->digitalPin(true);
std::cout<<"success start with pwm and gpio"<<std::endl;
return a.exec();
}
五、引脚图
输入命令就可以查看引脚图了:
gpio readall
需要注意的是我们使用对应的引脚标号的模式是默认wPi的模式,比如我们让0号引脚通入高电平,这时候就是对应到图片中左上角第二个电平被拉高了。
实物图对应:
六、运行程序
程序运行结果
设置pin0的引脚为高
设置pin0引脚为低
总结
wiringOP很多地方还是和wiringPi非常相似的,官方的例程下也有很多提供很多gpio硬件驱动的例子,但是比较遗憾的是香橙派Pi5并不支持硬件输出pwm所以只能使用SOFT_PWM_OUTPUT实现软件模拟PWM,因为我没有示波器没有办法测试到pwm波形,有能力的朋友请自行测试一下。在万用表测试下GPIO的高电平为3.3v,盲猜应该电流无法直接驱动继电器,可能需要外接一个7407N的芯片拉高引脚的电流。