树莓派外设开发接口文档参考
wringPi库(特定平台,特定功能的接口)树莓派wiringPi库详解 - lulipro - 博客园 (cnblogs.com)
一、树莓派的接口
IO口:input/output
Input传感器:人体红外,烟雾,火焰,震动等
Output设备:继电器,蜂鸣器
PWM:电机调速,灯光调节明暗
Uart:异步串口通信
IIC:集成电路总线(串行通信)
SPI:串行外设接口
IIS:音频通信总线
其他特定硬件的接口:flash
类树莓派的开发板:
Nanopi(linux);三星S3c2410、2440、6410;Tiny210、Tiny4412;海思方案;瑞芯微方案;移远方案。
单片机:C51,STM32,Arduino,WemosD1
单片机与开发板的区别:(没有OS)纯逻辑开发;树莓派:驱动。
二、树莓派的接口函数
1、验证wiringPi库是否安装成功,输入gpio -v,显示版本信息的为安装有该库的,否则需要安装库。
2、硬件初始化函数
函数 | 状态 | 介绍 |
---|---|---|
int wiringPiSetup(void) | 返回:执行状态,-1表示失败 | 当使用这个函数初始化树莓派引脚时,程序使用的是wiringPi 引脚编号表。引脚的编号为 0~16,需要root权限 |
int wiringPiSetupGpio (void) | 返回执行状态,-1表示失败 | 当使用这个函数初始化树莓派引脚时,程序中使用的是BCM GPIO 引脚编号表。需要root权限 |
wiringPiSetupPhys(void) | 不常用,不做介绍 | / |
wiringPiSetupSys (void) | 不常用,不做介绍 | / |
在使用wiringPi库时,你需要包含头文件 #include<wiringPi.h>。凡是写wiringPi的程序,都包含这个头文件。
①vi demo1.c(在这之前可以建一个文件夹)
②编写代码
③编译:gcc demo1.c
(报错:拼写错误wiringPi.h)
(仍然报错:这是别人做的库,要把库连上才行)
④连接库:gcc demo1.c -lwiringPi
3、通用GPIO控制函数
函数 | 参数 | 作用 |
---|---|---|
void pinMode(int pin, int mode) | pin:配置的引脚 mode:指定引脚的IO模式可取的值INPUT、OUTPUT、PWM_OUTPUT,GPIO_CLOCK | 作用:配置引脚的IO模式 注意:只有wiringPi 引脚编号下的1脚(BCM下的18脚) 支持PWM输出;只有wiringPi编号下的7(BCM下的4号)支持GPIO_CLOCK输出 |
void digitalWrite (int pin, int value) | pin:控制的引脚value:引脚输出的电平值。可取的值:HIGH,LOW分别代表高低电平 | 让对一个已近配置为输出模式的 引脚 输出指定的电平信号 |
int digitalRead (int pin) | pin:读取的引脚 返回:引脚上的电平,可以是LOW HIGH 之一 | 读取一个引脚的电平值 LOW HIGH ,返回 |
void analogWrite(int pin, int value) | pin:引脚 value:输出的模拟量 | 模拟量输出,树莓派的引脚本身是不支持AD转换的,也就是不能使用模拟量的API,需要增加另外的模块 |
int analogRead (int pin) | pin:引脚 返回:引脚上读取的模拟量 | 模拟量输入,树莓派的引脚本身是不支持AD转换的,也就是不能使用模拟量的API,需要增加另外的模块 |
void pwmWrite (int pin, int value) | pin:引脚 value:写入到PWM寄存器的值,范围在0~1024之间。 | 输出一个值到PWM寄存器,控制PWM输出。pin只能是wiringPi 引脚编号下的1脚(BCM下的18脚) |
void pullUpDnControl (int pin, int pud) | pin:引脚;pud:拉电阻模式;可取的值:PUD_OFF 启用任何拉电阻。关闭拉电阻。PUD_DOWN启用下拉电阻,引脚电平拉到GND;PUD_UP启用上拉电阻,引脚电平拉到3.3v | 对一个设置IO模式为 INPUT 的输入引脚设置拉电阻模式。与Arduino不同的是,树莓派支持的拉电阻模式更丰富。树莓派内部的拉电阻达50K欧姆 |
3、时间函数
函数 | 属性 |
---|---|
unsigned int millis (void) | 函数返回一个从你的程序执行 wiringPiSetup初始化函数(或者wiringPiSetupGpio) 到当前时间经过的毫秒数。返回类型是unsigned int,最大可记录大约49天的毫秒时长。 |
unsigned int micros (void) | 这个函数返回一个 从你的程序执行wiringPiSetup初始化函数(或者wiringPiSetupGpio )到当前时间经过的微秒数。返回类型是unsigned int,最大可记录大约71分钟的时长。 |
void delay (unsigned int howLong) | 将当前执行流暂停指定的毫秒数。因为Linux本身是多线程的,所以实际暂停时间可能会长一些。参数是unsigned int 类型,最大延时时间可达49天 |
void delayMicroseconds (unsigned int howLong) | 将执行流暂停指定的微秒数(1000微秒=1毫秒=0.001秒)。因为Linux本身是多线程的,所以实际暂停时间可能会长一些。参数是unsigned int 类型,最大延时时间可达71分钟 |
4、串口通信函数
包含头文件:#include <wiringSerial.h>
函数 | 属性 | 作用 |
---|---|---|
int serialOpen (char *device, int baud) | device:串口的地址,在Linux中就是设备所在的目录。默认一般是"/dev/ttyAMA0",我的是这样的。baud:波特率,返回:正常返回文件描述符,否则返回-1失败。 | 打开并初始串口 |
void serialClose (int fd) | fd:文件描述符 | 关闭fd关联的串口 |
void serialPutchar (int fd, unsigned char c) | fd:文件描述符,c:要发送的数据 | 发送一个字节的数据到串口 |
void serialPuts (int fd, char *s) | fd:文件描述符,s:发送的字符串,字符串要以’\0’结尾 | 发送一个字符串到串口 |
void serialPrintf (int fd, char *message, …) | fd:文件描述符,message:格式化的字符串 | 像使用C语言中的printf一样发送数据到串口 |
int serialDataAvail (int fd) | fd:文件描述符,返回:串口缓存中已经接收的,可读取的字节数,-1代表错误 | 获取串口缓存中可用的字节数。 |
int serialGetchar (int fd) | fd:文件描述符,返回:读取到的字符 | 从串口读取一个字节数据返回。如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1。所以,在读取前,做好通过serialDataAvail判断下。 |
void serialFlush (int fd) | fd:文件描述符 | 刷新,清空串口缓冲中的所有可用的数据。 |
*size_t write (int fd,const void * buf,size_t count) | fd:文件描述符,buf:需要发送的数据缓存数组,count:发送buf中的前count个字节数据,返回:实际写入的字符数,错误返回-1 | 这个是Linux下的标准IO库函数,需要包含头文件:#include <unistd.h>当要发送到的数据量过大时,wiringPi建议使用这个函数。 |
*size_t read(int fd,void * buf ,size_t count); | fd:文件描述符,buf:接受的数据缓存的数组,count:接收的字节数,返回:实际读取的字符数 | 这个是Linux下的标准IO库函数,需要包含头文件:#include <unistd.h>当要接收的数据量过大时,wiringPi建议使用这个函数。 |
eg1:树莓派控制继电器(gpio引脚输出高、低电平)
①gpio readall(两排io对称看)
②选择gpio.7控制继电器(3.3v)编写代码
③编译:gcc demo2.c -lwiringPi
④优化代码(加循环)(加宏定义方便移植、修改)
技巧:回到代码首行:Esc —— gg
自动缩进:回到首行后 —— =G
⑤运行:./a.out (Ctrl c退出运行)
eg2:超声波模块
HR-SC04超声波模块:
简介:超声波传感器模块上通常有两个超声波元器件,一个用于发射,一个用于接收。
引脚:VCC(正极)、GND(接地)、Trig(触发)、Echo(回应)
工作电压/电流:5V、15mA
感测距离:2~400cm
感测角度:<=15°
注意:被测物的面积不要小于50cm²并且尽力平整;具备温度补偿电路
使用方法:在超声波模块的触发脚位输入10微秒以上的高电位,即可发出超声波,发射超声波之后,与接收到传回的超声波之前,“响应”脚位呈现高电位。因此,程序可以从“响应”脚位的高电位脉冲持续时间,换算出被测物的距离。
源码:(编译:gcc chao.c -lwiringPi 运行:./a.out)
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#define Trig 4
#define Echo 5
void init()
{
if(wiringPiSetup()==-1)
{
printf("init wiringPi failed");//初始化失败进行反馈
exit(-1);
}
}
void ultraInit()
{
pinMode(Trig,OUTPUT);
pinMode(Echo,INPUT);
}
float disMeasure(void)
{
struct timeval tv1;
struct timeval tv2;
long start,stop;
float dis;
digitalWrite(Trig,LOW);
delayMicroseconds(2);//完成时序的低电平前趋
digitalWrite(Trig,HIGH);
delayMicroseconds(10);//发出超声波脉冲
digitalWrite(Trig,LOW);
while(!digitalRead(Echo)==1);
gettimeofday(&tv1,NULL);//获取当前的时间
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()
{
init();
ultraInit();
float dis;
while(1)
{
dis = disMeasure();
printf("distance is %0.2f cm\n",dis);
delay(1000);
}
return 0;
}
eg3:串口
树莓派首次使用串口通信需要配置:
1.修改cmdline.txt
sudo vi /boot/cmdline.txt
2.删除【】之间的部分
dwc_otg.lpm_enable=0 【console=ttyAMA0,115200】 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
3.修改 inittab文件(未找到——跳到5.)
sudo vi /etc/inittab
4.注释掉最后一行内容:,在前面加上 # 号
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
5.sudo reboot 重启
gpio readall //查看树莓派的io口
代码:
接线:GND接0V,TXD接RXD,RXD接TXD
#include <wiringSerial.h>
#include <wiringPi.h>
int main()
{
wiringPiSetup();
int fd;
fd = serialOpen("/dev/ttyAMA0",9600);
while(1)
{
serialPutchar(fd,'c');
delayMicroseconds(1000000);
}
return 0;
}
打开串口调试助手
运行代码
eg4:树莓派与语音模块通信
接线:TXD-RXD、RXD-TXD、GND-GND
语音模块:YS-LDV7
#include <wiringSerial.h>
#include <wiringPi.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
wiringPiSetup();
int fd;
int nread;
char cmd[128] = {'\0'};
fd = serialOpen("/dev/ttyAMA0",9600);
while(1){
nread = read(fd,cmd,sizeof(cmd));
if(strlen(cmd) == 0)
{
printf("over time\r\n");
continue;
}
printf("getData:%dbyte,context:%s\r\n",nread,cmd);
memset(cmd,'\0',sizeof(cmd)/sizeof(char));
}
return 0;
}