WiringPi

  • 安装
  • 使用 gpio readall查看所有引脚
  • 使用继电器
  • 配置引脚
  • 输出指定电平信号
  • 读取指定引脚电平信号
  • 继电器使用代码编程
  • 树莓派超声波测距
  • struct timeval 结构体
  • 时间控制函数
  • 1.void delay (unsigned int howLong)
  • 2.void delayMicroseconds (unsigned int howLong)
  • 3. unsigned int millis (void)
  • 4. unsigned int micros (void)
  • 串口通信
  • 打开并初始串口
  • 关闭串口
  • 发送一个字节
  • 获取串口缓存字节数
  • 读取一个串口缓存字符
  • 清空串口缓存的数据
  • 例子:
  • 语音模块控制灯的打开和关闭
  • 超声波测距 以及舵机的使用



精彩博文推荐



安装

进入 wiringPi的github (https://git.drogon.net/?p=wiringPi;a=summary) 下载安装包。点击页面的第一个链接的右边的snapshot,下载安装压缩包。

然后进入安装包所在的目录执行以下命令:

tar xfz wiringPi-98bcb20.tar.gz //98bcb20为版本标号,可能不同
 cd wiringPi-98bcb20
 ./build

验证wiringPi的是否安装成功,输入gpio -v,会在终端中输出相关wiringPi的信息。否则安装失败。

使用 gpio readall查看所有引脚

使用的时候要包含头文件

#include <wiringPi.h>

int main()
{
   int ret=wiringPiSetup();
   if(ret==-1){
         printf("失败\n");
         exit(-1);
   }
   return 0;
}

当使用这个函数初始化树莓派引脚时,程序使用的是wiringPi 引脚编号表
使用该库的时候首先要初始化该函数
wiringPiSetup();进行初始化操作

返回执行结果 如果为-1 表示返回失败

使用继电器

继电器一共三个开关控制 三个开关分别是 VCC GND 还有一个继电器控制引脚
介绍 GPIO控制函数

配置引脚

void pinMode(int pin ,int mode);
//mode:指定引脚的IO模式
//可取的值:INPUT、OUTPUT、PWM_OUTPUT,GPIO_CLOCK

注意:
只有wiringPi 引脚编号下的1脚(BCM下的18脚) 支持PWM输出
只有wiringPi编号下的7(BCM下的4号)支持GPIO_CLOCK输出

输出指定电平信号

void digitalWrite(int pin,int value)
value 引脚输出的电平值  LOW   HIGH

读取指定引脚电平信号

int digitalRead(int pin);

返回:引脚上的电平,可以是LOW HIGH 之一

继电器使用代码编程

继电器在低电平下面才会变亮

#include <wiringPi.h>
#include <stdio.h>

#define switch1 7  //指定连接的引脚是7
int main()
{ 
    int cmd;
    wiringPiSetup();
    pinMode(switch1,OUTPUT);
    digitalWrite(switch1,HIGH);//给他一个高电平   在最开始的时候不会变亮
            while(1){

                printf("请选择输入1/0 1表示高电平 0表示低电平\n");
                scanf("%d",&cmd);
                if(cmd==1){
                        digitalWrite(switch1,HIGH);
                }else if(cmd==0){
                        digitalWrite(switch1,LOW);
                }else{
                        cmd=10;
                }
        }
    return 0;
}

strlen表示的就取到/0计算/0前面的元素个数
sizeof表示的是这个字符串的个数包括/0

树莓派超声波测距

Trig 引脚用来接收树莓派的控制信号。接任意 GPIO 口。

Echo 引脚用来向树莓派返回测距信息。接任意 GPIO 口。

trig 表示的是触发信号 发送一个10us的高电平触发信号

Echo表示的是输出回响信号 当一个超声波信号发射后,ECHO引脚会输出高电平。当ECHO引脚直到检测到超声波信号回来的时,ECHO引脚输出低电平。 这个回响信号的时间表示的是来回经过的时间

树莓派gpio控制python 树莓派gpio库函数_树莓派gpio控制python

//
#include <wiringPi.h>  
#include <stdio.h>  
#include <sys/time.h>  
  
#define Trig    0  
#define Echo    1  
//初始化引脚  
void ultraInit(void)  
{  
    pinMode(Echo, INPUT);  
    pinMode(Trig, OUTPUT);  
    digitalWrite(Trig,LOW);
}  
  //测量距离函数
float disMeasure(void)  
{  
    struct timeval tv1;  
    struct timeval tv2;  
    long start, stop;  
    float dis;  
  
    //表示发送的10us的一个高电平脉冲
    digitalWrite(Trig, HIGH);  
    delayMicroseconds(10);      //发出超声波脉冲  
    digitalWrite(Trig, LOW);  
      
    while(digitalRead(Echo) != 1);  
    gettimeofday(&tv1, NULL);           //获取当前时间 gettimeofday 
  
    while(digitalRead(Echo) != 0);  
    gettimeofday(&tv2, NULL);           //获取当前时间  
    //计算出来的是微秒的时间
    start = tv1.tv_sec * 1000000 + tv1.tv_usec;   //微秒级的时间  
    stop  = tv2.tv_sec * 1000000 + tv2.tv_usec;  
    
    dis = (float)(stop - start) / 1000000 * 34000 / 2;  //求出距离  
  
    return dis;  
}  
  
int main(void)  
{  
    float dis;  
  
    if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen  
        printf("setup wiringPi failed !");  
        return -1;   
    }  
  
    ultraInit();  
      
    while(1){  
        dis = disMeasure();  
        printf("distance = %0.2f cm\n",dis);  //0.2f表示保留小数点后2位
        delay(1000);  
    }  
  
    return 0;  
}

struct timeval 结构体

结构体的头文件
#include <sys/time.h>

struct timeval
{
time_t tv_sec;        /* Seconds. */
suseconds_t tv_usec;  /* Microseconds. */
};

time_t类型,这本质上是一个长整数,表示从1970-01-01 00:00:00到目前计时时间的秒数,如果需要更精确一点的,可以使用timeval精确到毫秒。
tv_sec 表示的是秒
tv_usec 表示的是毫秒
在头文件#include <time.h>
数据类型前面有_ 例如_time_t

时间控制函数

1.void delay (unsigned int howLong)

这个是毫秒级的延时函数。

2.void delayMicroseconds (unsigned int howLong)

微秒级的延时函数

3. unsigned int millis (void)

这个函数返回 一个 从你的程序执行 wiringPiSetup 初始化函数(或者wiringPiSetupGpio ) 到 当前时间 经过的 毫秒数。
返回类型是unsigned int,最大可记录 大约49天的毫秒时长。

4. unsigned int micros (void)

这个函数返回 一个 从你的程序执行 wiringPiSetup 初始化函数(或者wiringPiSetupGpio ) 到 当前时间 经过的 微秒数。
返回类型是unsigned int,最大可记录 大约71分钟的时长。

串口通信

包含的头文件
#include <wiringSerial.h>

/* 修改 cmdline.txt文件 */
>cd /boot/
>sudo vim cmdline.txt


删除【】之间的部分
dwc_otg.lpm_enable=0 console=tty1【 console=serial0,115200】 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
dwc_otg.lpm_enable=0 【console=ttyAMA0,115200】 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait


/*修改 inittab文件 */
>cd /etc/
>sudo vim inittab

注释掉最后一行内容:,在前面加上 # 号
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100


sudo reboot 重启

打开并初始串口

int serialOpen (char *device, int baud)

device:串口的地址,在Linux中就是设备所在的目录。
串口文件存在于 /dev/ttyAMA0 里面
默认一般是"/dev/ttyAMA0",
baud:波特率
返回:正常返回文件描述符,否则返回-1失败

关闭串口

void serialClose (int fd)

发送一个字节

void serialPutchar (int fd, unsigned char c)
 void serialPuts (int fd, unsigned char c)

获取串口缓存字节数

int serialDataAvail (int fd)
返回:串口缓存中已经接收的,可读取的字节数,-1代表错误

读取一个串口缓存字符

int serialGetchar (int fd)
从串口读取一个字节数据返回。
如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1
所以,在读取前,做好通过serialDataAvail判断下。

清空串口缓存的数据

void serialFlush (int fd)
刷新,清空串口缓冲中的所有可用的数据。

例子:

int main()
{
   int fd;
   int cmd;
   fd=serialOpen("/dev/ttyAMA0",9600);  //打开设备所在文件   波特率设置9600
   if(fd==-1){
   printf("打开失败\n");
   exit(-1);
   }
   while(1){
          while(serialDataAvail(fd)!=-1){
           serialFlush(fd);//刷新缓冲区的值   
           cmd = serialGetchar(fd);
         // printf("cmd = %c\n",cmd);//使用串口打印小助手需要有printf stc=isp 则可有可无
           if(cmd == '2'){
                 serialPuts(fd,"fjsdflsdjfl\r\n");
           }
          }
//        serialPutchar(fd,'c');    //通过串口发射一个字符
//        delay(1);
   }
   return 0;
}

串口换行 \r\n 配合使用换行

语音模块控制灯的打开和关闭

当数据多的时候使用read write函数 和文件读取相同

while(1){
                nread = read(fd,cmd,sizeof(cmd));
                if(nread>0){
                        printf("cmd=%s\n",cmd);
                        if(!strcmp("shou",cmd)){
                                printf("收到\n");
                        }
                        if(!strncmp("open",cmd,4)){
                                digitalWrite(GPIO_27_B,HIGH);
                                delay(500);
                                digitalWrite(GPIO_28_G,HIGH);
                                delay(500);
                                digitalWrite(GPIO_29_R,HIGH);
                                delay(500);

                        }
                        if(!strncmp("close",cmd,5)){
                                digitalWrite(GPIO_27_B,LOW);
                                delay(500);
                                digitalWrite(GPIO_28_G,LOW);
                                delay(500);
                                digitalWrite(GPIO_29_R,LOW);
                                delay(500);
                        }
                }else{
                        printf("读取失败\n");
                        }
        }

超声波测距 以及舵机的使用

舵机的连线接口

舵机的接线  
红色是VCC    棕色是GND    橙色是信号线

舵机的使用方法 控制原理

舵机的控制一般需要一个20ms的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度舵机为例,那么对应的控制关系是这样的:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;

树莓派gpio控制python 树莓派gpio库函数_引脚_02


树莓派gpio控制python 树莓派gpio库函数_串口_03


这个代码一运行 就会执行到0°位置

while(1)//turn to 0
        {
                digitalWrite(15,HIGH); 
                delayMicroseconds(500);
                digitalWrite(15,LOW);
                delayMicroseconds(19500);
        }

使用舵机进行控制
控制舵机速度的代码
舵机向下移动

int i=180;//表示最大的while循环的次数
int k=0;//表示当前角度值
float x=0;//表示时间us
while(i--){
         x=11.11*k;
         digitalWrite(sign,HIGH);
         delayMicroseconds(500+x);
         degitalWrite(sign,LOW);
         delayMicroseconds(19500-x);
         if(k==angle){
                break;//当k执行等于要旋转到的角度后结束
         }
         k++;
}

舵机向上旋转多少度 要想上旋转90°
首先要确定是在什么角度进行旋转 比如当前的位置在90°的位置 需要把时间进行改变设置成1500

int i=180;//表示最大的while循环的次数
int k=0;//表示当前角度值
float x=0;//表示时间us
while(i--){
         x=11.11*k;
         digitalWrite(sign,HIGH);
         delayMicroseconds(1500-x);
         degitalWrite(sign,LOW);
         delayMicroseconds(18500+x);
         if(k==90){
                break;//当k执行等于要旋转到的角度后结束
         }
         k++;
}
while(1){

                dis=disMeasure();
                printf("测量的长度是%f\n",dis);
                printf("测量1\n");
                delayMicroseconds(1000000);//每隔一秒打印一次

                if(dis<20){
                //      使用上面舵机向上旋转的函数
                //再次进行判断  如果距离一直小于20 则进行延时  当距离大于20的时候 使用舵机向下旋转的函数
                        while(1){
                                dis=disMeasure();
                                printf("测量的长度是%f\n",dis);
                                printf("测量2\n");
                                if(dis<20){
                                        delayMicroseconds(1000000);

                                }else {
                                    //使用舵机向下旋转的函数进行关闭
                                        break;
                                }
                        }
                }else {
                        //使用舵机向下的函数
                        //检测长度
                        while(1){
                                dis=disMeasure();
                                printf("测量的长度是%f\n",dis);
                                printf("测量3\n");
                                if(dis>20){
                                        delayMicroseconds(1000000);
                                }else{
                                       //使用舵机向上的函数进行处理
                                        break;
                                }
                        }
                }
        }

使用代码 在最开始的位置进行距离的检测 当距离小于20cm 进入if 里面
执行开盖的指令 开盖完成后进入到