目录
1.wiringPi外设SDK安装
方式一: git clone https : //github.com/orangepi-xunlong/wiringOP // 下载源码 cd wiringOP // 进入文件夹 sudo . / build clean // 清除编译信息 sudo . / build // 编译 方式二: 通过 windows 浏览器打开 https : //github.com/orangepi-xunlong/wiringOP // 下载压缩包 把压缩包通过 xterm 传到开发板 解压 unzip wiringOP-next.zip cd wiringOP-next sudo . / build // 编译 gpio readall 查看所有引脚的配置
如下图所示就是安装成功了
2.修改vim的默认缩进
sudo vim / etc / vim / vimrc set tabstop = 4 设置 tab 键缩进 4 个空格 set shiftwidth = 4 设置批量对齐时候的 tab 键空格数为 4
3.蜂鸣器的使用
基本io口的使用,蜂鸣器是低电平有效
#include <stdio.h>
#include <wiringPi.h>
#include <unistd.h>//延时函数的库文件
#define bba 0 //设置引脚0为蜂鸣器的控制引脚
int main()
{
wiringPiSetup();//初始化wiringpi库
pinMode(bba,OUTPUT);//设置IO口的输出模式,OUTPUT输出、INPUT输入
while(1){
usleep(500000);//微秒级延时
digitalWrite(bba,LOW);//设置引脚的电平 ,LOW低电平、HIGH高电平
usleep(500000);
digitalWrite(bba,HIGH);
}
}
sleep 秒延时
usleep 微秒延时
4.写一个简易的shell脚本来编译文件
1.先查看我们编译时需要链接的库
在wiringOP文件夹下面vi Makefile
这里就时我们编译时需要链接的库
创建一个shell.sh文件
echo $0 ----参数1
echo $1 ----参数2
gcc $1 -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt
添加完成之后给文件添加可执行权限 ----chmod -777 shell.sh 注意这里我设置的是最大权限
然后我们就可以直接使用了
、
5.超声波测距的使用
怎么让它发波 Trig ,给 Trig 端口至少 10us 的高电平 怎么知道开始发了 Echo 信号,由低电平跳转到高电平,表示开始发送波 怎么知道接收了返回波 Echo ,由高电平跳转回低电平,表示波回来了 怎么算时间 Echo 引脚维持高电平的时间! 波发出去的那一下,开始启动定时器 波回来的拿一下,我们开始停止定时器,计算出中间经过多少时间 怎么算距离 距离 = 速度( 340m/s ) * 时间 /2
5.1 Linux时间函数
Linux下可以使用gettimeofday()来查看当前时间,这个函数会计算从1970年1月1号00:00(UTC)到当前的时间跨度。
函数原型 #include<sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz (时区不关心可以设置为NULL)) gettimeofday() 会把目前的时间用 tv 结构体返回,当地时区的信息则放到 tz 所指的结构中
struct timeval
{
long tv_sec;/*秒*/
long tv_usec;/*微妙*/
};
可以看出算出来的时间跨度可以精确到微妙,time_t和suseconds_t的实际类型是long int。日常使用时,只需传第一个参数,第二个参数传NULL(因为linux内核不会使用这个参数)。
先简单举一个例子
计算程序在当前环境中数数10万次耗时多少#include <stdio.h>
#include <sys/time.h>
void time10w(){
int i,j;
for(i = 0;i<100;i++){
for(j = 0;j<1000;j++);
}
}
int main()
{
struct timeval tv;//开始的时间
struct timeval tvstop;//结束的时间
gettimeofday(&tv,NULL);
time10w();
gettimeofday(&tvstop,NULL);
long timeSum =1000000* (tvstop.tv_sec-tv.tv_sec)+(tvstop.tv_usec-tv.tv_usec)//时间间隔=运行时间
;
printf("time = %ld\n",timeSum);
}
程序运行结果
5.2 超声波代码的实现
#include <stdio.h>
#include <wiringPi.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#define bba 0 //蜂鸣器
#define trig 1
#define echo 2
double Distance ()
{
struct timeval startval;//开始时间
struct timeval stopval;//结束时间
//发送触发信号
digitalWrite(trig,LOW);
usleep(5);
digitalWrite(trig,HIGH);
usleep(10);
digitalWrite(trig,LOW);
//发送波
while(!digitalRead(echo));
gettimeofday(&startval,NULL);
//接收波
while(digitalRead(echo));
gettimeofday(&stopval,NULL);
long timeSum = 1000000*(stopval.tv_sec-startval.tv_sec)+(stopval.tv_usec-sta
rtval.tv_usec);//计算时间差
printf("timeSum = %ld\n",timeSum);
return timeSum*0.017;
}
int main()
{
if(wiringPiSetup() == -1 ){
fprintf(stderr,"%s","init wiringPiSettup error");
exit(-1);
}
double distance;
//初始化io口的输入输出模式
pinMode(bba,OUTPUT);
pinMode(trig,OUTPUT);
pinMode(echo,INPUT);
while(1){
sleep(1);//延时1秒
distance = 0;
distance = Distance();
printf("distance = %f\n",distance);
if(distance < 10){//当距离小于10cm时蜂鸣器响500ms
digitalWrite(bba,LOW);
usleep(500000);
digitalWrite(bba,HIGH);
}
}
return 0;
}
6. sg90舵机
使用Linux定时器来模拟pwm信号
分析:实现定时器,通过 itimerval 结构体 以及函数 setitimer 产生的信号,系统随之使用 signal 信号处理函数来处理产生的定时信号。从而实现定时器。 先看 itimerval 的结构体 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 ; }; it_interval :计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置 it_value :程序跑到这之后,多久启动定时器 struct timeval { __time_t tv_sec ; /* Seconds. */ __suseconds_t tv_usec ; /* Microseconds. */ }; int setitimer ( __itimer_which_t __which , const struct itimerval * __restrict __new , struct itimerval * __restrict __old )
setitimer() 将 value 指向的结构体设为计时器的当前值,如果 ovalue 不是 NULL ,将返回计时器原有值。 which: 三种类型很明显,这边需要捕获对应的信号进行逻辑相关处理 signal(SIGALRM,signal_handler); 返回说明: 成功执行时,返回0 。失败返回 -1
- ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是SIGALRM。
- ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM。
- ITIMER_PROF //数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF。
信号处理函数可以看这篇文章:Linux进程通信之信号-CSDN博客
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPi.h>
#include <signal.h>
#define sg90pin 3
int i = 0;
int jd;
void signal_handler(int signum)//信号处理函数
{
if(i<=jd){
digitalWrite(sg90pin,HIGH);
}else{
digitalWrite(sg90pin,LOW);
}
if(i == 40){
i = 0;
}
i++;
}
int main()
{
wiringPiSetup();
pinMode(sg90pin,OUTPUT);
struct itimerval timer;
jd = 0;
//计时时间
timer.it_interval.tv_sec=0;
timer.it_interval.tv_usec=500;//0.5ms
//运行到这计时器需要多久开始计时
timer.it_value.tv_sec=1;//1s
timer.it_value.tv_usec=0;
setitimer(ITIMER_REAL,&timer,NULL);
signal(SIGALRM,signal_handler);//时钟信号
while(1){
printf("1==0 2==45 3==90 4==135 5==180\n");//根据输入的数值进行角度的切换
scanf("%d",&jd);
sleep(2);
}
}
注意:一个进程只能创建一个定时器
标签:__,基于,struct,tv,bba,int,官方,include,外设 From: https://blog.csdn.net/weixin_58198422/article/details/136853101