目录
环境搭建及产品介绍
刷机和系统启动
1 SDFormatter傻瓜式安装-----格式化内存卡,
2 Win32Diskimager傻瓜式安装------ 刷机课程使用的镜像是 Orangepizero2_2.2.0_ubuntu_bionic_desktop_linux4.9.170.img
3 登录 使用USB转TTL模块,使用MobaXterm免费好用,类似的工具还有Putty-相对太简陋,SecurityCRT老牌 工具-需要付费或者破解
4 SSH登陆开发板 这是企业开发调试必用方式,比串口来说不用接线,前提是接入网络并获得板子IP地址,且系统做了 SSH的服务器,本镜像自带SSH服务器,所以通过mobaXterm登陆就行
命令接入网络 nmcli dev wifi connect wifixxxxx password 密码xxxx
5 wiringPi外设SDK安装 git clone https://github.com/orangepi-xunlong/wiringOP //下载源码 cd wiringOP //进入文件夹 sudo ./build clean //清除编译信息 sudo ./build //编译 验证指令: gpio readall 下载i2c sudo apt-get install i2c-tools
快捷指令
1 sudo vim /etc/vim/vimrc set tabstop=4 设置tab键缩进4个空格 set shiftwidth=4 设置批量对齐时候的tab键空格数为4
2 简易编译的shell脚本: gcc $1 -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt
基础外设--蜂鸣器、定时器、舵机、oled、超声波等
蜂鸣器
1 #include <stdio.h>
2 #include <wiringPi.h>
3 #include <unistd.h>
4
5 #define BEEP 0
6 int main()
7 {
8 wiringPiSetup();//外设库初始化
9 pinMode(BEEP,OUTPUT);//第0角配置成出
10 while(1){
11 digitalWrite(BEEP,LOW);//往该角配置低电平
12 usleep(300000);
13 digitalWrite(BEEP,HIGH);//往该角配置低电平
14 usleep(300000);
15 }
16 return 0;
17 }
定时器
1 #include <stdio.h>
2 #include <sys/time.h>
3 #include <stdlib.h>
4 #include <signal.h>
5
6 void signal_handler(int signum)//信号处理函数 --- 类似中断处理函数
7 {
8 static int i = 0;
9 i++;
10 if(i == 2000){
11 printf("cloct\n");
12 i = 0;
13 }
14 }
15
16 int main()
17 {
18 struct itimerval itv;
19 //计时多久 秒毫秒
20 itv.it_interval.tv_sec = 0;
21 itv.it_interval.tv_usec = 500;
22
23 //程序到这之后开始计时 2秒后
24 itv.it_value.tv_sec = 2;
25 itv.it_value.tv_usec = 0;
26
27 //定时器属性(实时、虚拟等)、通过信号把结构体传参数、NULL
28 if(-1 == setitimer(ITIMER_REAL,&itv,NULL)){//定时器 结构体
29 perror("sertitimer error");
30 exit(-1);
31
32 }
33 //注册信号捕获函数----定时器到时间则发送一个信号
34 signal(SIGALRM,signal_handler);
35 while(1);
36
37 return 0;
38 }
超声波
1 #include <stdio.h> 2 #include <sys/time.h> 3 #include <unistd.h> 4 #include <wiringPi.h> 5 #include <stdlib.h> 6 #define trig 0 7 #define echo 1 8 9 double getDistance() 10 { 11 double dis;//定义距离 12 struct timeval start;//开始时间 13 struct timeval stop;//结束时间 14 15 pinMode(trig,OUTPUT);//配置引脚模式 16 pinMode(echo,INPUT); 17 18 digitalWrite(trig,LOW);//触发信号 19 usleep(5); 20 digitalWrite(trig,HIGH); 21 usleep(10); 22 23 while(!digitalRead(echo));//低电平取反卡住 echo 为高电平退出等待开始计时 24 gettimeofday(&start,NULL);//开始计时 25 while(digitalRead(echo));//echo 为低电平低退出 26 gettimeofday(&stop,NULL);//退出计时 27 28 long liffTime = 1000000*(stop.tv_sec - start.tv_sec) + (stop.tv_usec - start.tv_usec); 29 // printf("liffTime = %ld\n",liffTime); 30 31 dis = (double)liffTime*0.000001*34000/2;//距离=时间*速度 32 33 return dis; 34 } 35 36 int main(){ 37 38 double dis; 39 40 if(wiringPiSetup() == -1){ //外设库初始化 41 printf("wiringpiSetup error!!\n"); 42 exit(-1); 43 } 44 printf("init succeed!!\n"); 45 46 while(1){ 47 dis = getDistance(); 48 printf("dis:%lf\n",dis); 49 sleep(1); 50 } 51 return 0; 52 }
舵机
1 #include <stdio.h>
2 #include <sys/time.h>
3 #include <stdlib.h>
4 #include <signal.h>
5 #include <wiringPi.h>
6
7 #define sg90pin 5
8
9 static int i = 0;
10 static int jd = 0;
11 void signal_handler(int signum)
12 {
13 if(i <= jd){
14 digitalWrite(sg90pin,HIGH);
15 }
16 else{
17 digitalWrite(sg90pin,LOW);
18 }
19
20 if(i == 40){
21 // printf("---------\n");
22 i = 0;
23 }
24
25 i++;
26 }
28 int main()
29 {
30 //外设初始化及配置
31 wiringPiSetup();
32 pinMode(sg90pin,OUTPUT);
33
34 struct itimerval itv;
35
36 //计时多久 秒毫秒
37 itv.it_interval.tv_sec = 0;
38 itv.it_interval.tv_usec = 500;
39
40 //程序到这之后开始计时 2秒后
41 itv.it_value.tv_sec = 2;
42 itv.it_value.tv_usec = 0;
43
44 //定时器属性(实时、虚拟等)、传参数、NULL
45 if(-1 == setitimer(ITIMER_REAL,&itv,NULL)){
46 perror("sertitimer error");
47 exit(-1);
48
49 }
50
51 signal(SIGALRM,signal_handler);
52 while(1){
53 printf("input jd:1-0 2-45 3-90 4-135 5 180\n");
54 scanf("%d",&jd);
55 }
56
57 return 0;
58 }
OLED-I2C
#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_show(struct display_info *disp) {
int i;
char buf[100];
oled_putstrto(disp, 0, 9+1, "Welcome to my world");//-- 3 -- 显示、宽、高、内容
disp->font = font1;//字体
oled_putstrto(disp, 0, 20, "---prppr good luckey---");//-- 3 -- 显示、宽、高、内容
disp->font = font1;//字体
oled_putstrto(disp, 0, 30, "--time 2023.7.16--");//-- 3 -- 显示、宽、高、内容
disp->font = font1;//字体
oled_send_buffer(disp);//strcpy从数组放到结构体中 --4--把结构体通过内核发送给硬件
return 0;
}
void show_error(int err, int add) {
//const gchar* errmsg;
//errmsg = g_strerror(errno);
printf("\nERROR: %i, %i\n\n", err, add);
//printf("\nERROR\n");
}
void show_usage(char *progname) {
printf("\nUsage:\n%s <I2C bus device node >\n", progname);
}
int main(int argc, char **argv) {
int e;
char filename[32];
struct display_info disp;//结构体中有地址、文件名、字体 数组
if (argc < 2) {//判断传入参数是否正确
show_usage(argv[0]);
return -1;
}
memset(&disp, 0, sizeof(disp));//清空结构体
sprintf(filename, "%s", argv[1]);//把传入的第二个参数以字符串放到数组中
disp.address = OLED_I2C_ADDR;//i2c硬件地址 0x3c
disp.font = font2;//字体
e = oled_open(&disp, filename);//--1--打开文件
e = oled_init(&disp);//--2--初始化
oled_show(&disp); //--3--显示
return 0;
}
串口
封装一个serialTool.c --->serialTool.h文件
在串口中 打开 #include "serialTool.h"
编译 gcc uartTest1.c serialTool.c -lpthread 执行:sudo ./a.out /dev/ttyS5
//把serialTool.c 创建serialTool.h头文件 在uartdemo.c中调用头文件""
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "wiringSerial.h"
int myserialOpen (const char *device, const int baud)
{
struct termios options ;
speed_t myBaud ;
int status, fd ;
switch (baud){
case 4800: myBaud = B4800 ; break ;
case 9600: myBaud = B9600 ; break ;
case 115200: myBaud = B115200 ; break ;
}
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
return -1 ;
fcntl (fd, F_SETFL, O_RDWR) ;
// Get and modify current options:
tcgetattr (fd, &options) ;
cfmakeraw (&options) ;
cfsetispeed (&options, myBaud) ;
cfsetospeed (&options, myBaud) ;
options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
tcsetattr (fd, TCSANOW, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS
return fd ;
}
void serialSendstring (const int fd, const char *s)
{
int ret;
ret = write (fd, s, strlen (s));
if (ret < 0)
printf("Serial Puts Error\n");
}
int serialGetstring (const int fd,char *buffer)
{
int n_read;
n_read = read(fd,buffer,32);
return n_read;
}
//需传入参数 ./a.out /dev/ttyS5
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "wiringSerial.h"
#include <pthread.h>
#include <unistd.h>
#include "serialTool.h"//-----“”先找该目录下三个函数 open write read
int fd;
void* readSerial()
{
char buff[32];
while(1){
memset(buff,'\0',sizeof(buff));//清空
serialGetstring(fd,buff);
printf("Get-->%s\n",buff);//创建线程1 调用seriaTool.h中的接收函数 并打印
}
}
void* sendSerial()
{
char buff[32];
while(1){
memset(buff,'\0',sizeof(buff));//清空
scanf("%s",buff);
serialSendstring(fd,buff);//创建线程2 输入内容放到buff中 调用serialTool.h中的发送函数 把buff传过去
}
}
int main(int argc,char **argv)//--1--通过主函数 传入串口硬件地址argv[1] ---/dev/ttyS5
{
char deviceName[32] = {'\0'};
pthread_t readt;//线程读 接收
pthread_t sendt;//线程写 发送
if(argc < 2){
printf("uage:%s /dev/ttyS?\n",argv[0]);
}
strcpy(deviceName,argv[1]);//--2--把硬件物理地址传进来 放在deviceName里面 再open打开
if((fd = myserialOpen(deviceName,115200)) == -1){//--3--调用serialTool.h中的函数 打开并判断是否正确
printf("myserialOpen error!!");
exit(-1);
}
pthread_create(&readt,NULL,(void*)readSerial,NULL);//--4--读取线程 调用readSerial函数读取
pthread_create(&sendt,NULL,(void*)sendSerial,NULL);//--5--发送线程 调用sendSerial函数发送
pthread_join(readt,NULL);
pthread_join(sendt,NULL);
return 0;
}