一、刷机和系统启动
1、TF 卡格式化:
可以使用SD Card Formatter软件格式化TF卡
2、镜像烧录:
使用win32diskimager软件将准备好的镜像烧录到TF卡中
镜像下载网址🔗点击这里 点击Orange Pi Zero2官方镜像的ubuntu镜像,跳转至百度网盘,下载3.0.6版本:

此镜像可能默认关闭uart5,需要使用uart5时配置一下串口uart5,打开配置文件:
sudo vi /boot/orangepiEnv.txt
加入以下字段,开启uart5和i2c3:
overlays=uart5 i2c3
如图所示:

3、登录系统:
利用
MobaXterm进行串口登录或SSH方式登录,初次登录应用串口登录或利用USB转HTML接入屏幕后登录,默认用户如下:
- 用户名:
orangepi,密码:orangepi- 用户名:
root,密码:orangepi
修改
orangepi用户密码:sudo passwd orangepi
① 串口登录:
使用TTL 转 USB模块连接开发板串口(电脑需要安装ch340驱动),如图所示,然后接入电脑,使用MobaXterm软件进行串口登录,波特率默认为115200,MobaXterm连接上串口后,插入开发板电源线,查看串口打印数据,检验刷机是否成功

② 重启及关机:
- 重启:
sudo reboot- 关机:
sudo poweroff
③ 网络配置:
- 扫描周围的
WIFI热点:nmcli dev wifi- 接入网络:
nmcli dev wifi connect user password xxxxxxxx// 比如接入用户名为user的wifi,密码为xxxxxxxx- 查看
IP地址:ip addr show wlan0或ifconfig
④ SSH 登录开发板:
镜像自带SSH服务器,只要通过MobaXterm登陆即可
二、基于官方外设开发
1、wiringPi 外设 SDK 安装:
git clone https://github.com/orangepi-xunlong/wiringOP -b master// 下载源码cd wiringOP// 进入文件夹sudo ./build clean// 清除编译信息sudo ./build// 编译
或者通过 windows 浏览器打开 https://github.com/orangepi-xunlong/wiringOP,下载压缩包,通过 MobaXterm 把压缩包传到开发板:- 解压:
unzip xxx.zip
cd xxx
sudo ./build- 验证是否安装成功:
gpio readall,如下图所示

上述1~26物理端口,以如图所示方向的引脚对应:

2、C 文件编译:
- 使用
wiringPi库,编译的时候需要链接:gcc xxx.c -o -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt- 可以制作简单的
shell脚本便于编译:vi bulid.sh// 编写 shell 文件- 加入以下代码:
gcc $1 -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt// $1 为参数- 保存文件后,为 shell 文件添加可执行权限:
chmod +x build.sh- 运行时 wiringPi 需要访问底层驱动程序,使用超级用户权限运行:
sudo ./a.out
3、基于官方外设的应用开发:
① GPIO 输入输出:
#include <stdio.h>
#include <wiringPi.h>
#include <unistd.h>
#define GPIO1 0
#define GPIO2 2
int main (void)
{
wiringPiSetup(); // 初始化 wiringPi 库
pinMode (GPIO1, OUTPUT); // 设置 IO 口为输出模式
pinMode (GPIO2, INPUT); // 设置 IO 口为输入模式
while(1){
sleep(1); // 延时 1 秒;
// usleep(); 延时微秒
digitalWrite (GPIO1, HIGH); // IO 口输出高电平
sleep(1);
digitalWrite (GPIO1, LOW); // IO 口输出低电平
if(digitalRead(GPIO2)){
// 检测 IO 口电平
printf("high level\n");
}else{
printf("low level\n");
}
}
return 0;
}
② 超声波测距:
时间函数:
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
struct timeval{
time_t tv_sec; /* seconds(秒)*/
suseconds_t tv_usec; /* microseconds(微秒)*/
};
struct timezone{
int tz_minuteswest; /* minutes west of Greenwich (格林威治时间往西方的时差) */
int tz_dsttime; /* type of DST correction (DST 时间的修正方式) */
};
- 获取自
1970-01-01 00:00:00到调用gettimeofday()函数所经历的秒数,存放在tv中,精确到微秒,在超声波测距应用中,我们只关心时间差值- 获取时区信息,存放到
tz中,不关心时置NULL
例程:
#include <stdio.h>
#include <sys/time.h>
#include <wiringPi.h>
#include <stdlib.h>
#include <unistd.h>
#define Trig 5
#define Echo 7
double getDistance()
{
double dis;
struct timeval start;
struct timeval end;
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
digitalWrite(Trig ,LOW);
usleep(5);
digitalWrite(Trig ,HIGH); /* 向 Trig 口发送 10 微秒 TTL 脉冲 */
usleep(10);
digitalWrite(Trig ,LOW);
while(!digitalRead(Echo)); // 等待 Echo 口高电平
gettimeofday(&start,NULL); // 获取时间
while(digitalRead(Echo)); // 等待 Echo 口低电平
gettimeofday(&end,NULL); // 获取时间
long diffTime = 1000000*(end.tv_sec-start.tv_sec)+(end.tv_usec - start.tv_usec); // 计算时间差值,单位:微秒
dis = (double)diffTime/1000000 * 34000 / 2; // 计算距离,音速为 340 m/s
/*
diffTime/1000000 转化为秒
340(m/s) * 100 转化为厘米每秒(cm/s)
往返为两段路程,需要 /2
*/
return dis;
}
int main()
{
double dis;
if(wiringPiSetup() == -1){
fprintf(stderr,"%s","initWringPi error");
exit(-1);
}
while(1){
dis = getDistance();
printf("dis = %lf\n",dis);
usleep(500000);
}
return 0;
}
③ Linux 定时器:
- 实现定时器,通过
itimerval结构体配置以及函数setitimer()产生的信号,系统随之使用signal信号处理函数来处理产生的定时信号,从而实现定时器
struct itimerval
{
/* Value to put into `it_value' when the timer expires. */
struct timeval it_interval;
/* Time to the next timer expiration. */
struct timeval it_value;
};
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
it_interval: |
计时器的初始值,一般基于这个初始值加或减,基于控制函数的参数配置 |
|---|---|
it_value: |
当程序运行到此,间隔多久启动定时器 |
tv_sec: |
秒 |
tv_usec |
微秒(μs)(10-6s) |
int setitimer (__itimer_which_t __which,
const struct itimerval *__restrict __new,
struct itimerval *__restrict __old);
| 返回值: | 成功返回 0,失败返回 -1 |
|---|---|
__which参数: |
ITIMER_REAL // 数值为 0,计时器的值实时递减,发送的信号是 SIGALRMITIMER_VIRTUAL // 数值为 1,进程执行时递减计时器的值,发送的信号是 SIGVTALRMITIMER_PROF // 数值为 2,进程和系统执行时都递减计时器的值,发送的信号是 SIGPROF |
__new参数: |
设定定时器相关设置 |
__old参数: |
保存先前__new的值,常设为NULL |
- 函数的第一个参数,我们使用
ITIMER_REAL,那么显然,我们需要捕获对应的信号进行逻辑相关处理,捕获SIGALRM信号:signal(SIGALRM, signal_handler);- 该方法一个进程只能创建一个定时器
例程:
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
static int i;
void signal_handler(int signum) // 每隔 2000 * 500 μs,即 1s 打印 "hello\n"
{
i++;
if(i == 2000){
printf("hello\n");
i = 0;
}
}
int main()
{
struct itimerval itv;
// 设定定时时间
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 500; // 500 微秒
// 定时时间设定完成后,间隔多久启动定时器
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
// 间隔 1 秒启动定时器
// 设定定时方式
if( -1 == setitimer(ITIMER_REAL, &itv, NULL)){
perror("error");
exit(-1);
}
//信号处理
signal(SIGALRM, signal_handler);
while(1);
return 0;
}
④ PWM 输出:
- 输出高电平持续时间为
1.0 ms,低电平持续时间为19 ms的PWM信号,即占空比为5%,周期为20 ms,频率为1 / 0.02s = 50 Hz
例程:
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
#include <wiringPi.h>
#define PWM 0
static int i = 0;
void signal_handler(int signum)
{
if(i <= 2){
digitalWrite(PWM, HIGH);
}else{
digitalWrite(PWM, LOW);
}
if(i == 40){
i = 0;
}
i++;
}
int main()
{
struct itimerval itv;
wiringPiSetup();
pinMode(PWM, OUTPUT);
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 500; // 定时时间 500 微秒
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
if( -1 == setitimer(ITIMER_REAL, &itv, NULL)){
perror("error");
exit(-1);
}
signal(SIGALRM, signal_handler);
while(1);
return 0;
}
⑤ OLED 显示屏应用——IIC协议:
- 由
Orange Pi Zero 2的26pin原理图可知,可用的i2c为i2c3- 启动
linux系统,确认/dev下存在i2c-3的设备节点,可以观察到系统支持I2C-3和I2C-5的驱动,而H616的外设只有一个IIC接口,用的是IIC-3- 开始测试
IIC,首先安装i2c-tools:
sudo apt-get install i2c-tools- 接好线后,终端输入指令
sudo i2cdetect -y 3,可以看到终端打印信息,如下图,表明已经通过i2c-3驱动扫描设备成功
下面基于wiringPi库中的例程进行开发,路径:.../wiringOP-next/examples/oled_demo.c,建议阅读熟悉例程代码
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#include "oled.h"
#include "font.h"
int oled_demo(struct display_info *disp) {
int i;
char buf[100]


最低0.47元/天 解锁文章
454

被折叠的 条评论
为什么被折叠?



