树莓派外设开发笔记
树莓派外设开发接口文档参考
WiringPi库(Linux动态库:.so 静态库:.a)
API printf(c标准库)
树莓派的接口: 驱动
IO口:input output 对主控来说
Input:人体,烟雾,火焰,震动等
Output:继电器,蜂鸣器
PWM:电机调速,灯光调明亮度
语音识别模块,液晶屏
串口uart
IIC
SPI
IIS
其他特定硬件的接口:flash
Nanopi:Linux
S3c2410,2440 6410
Tiny210 tiny4412
海思方案,瑞芯微方案,移远方案
C51,stm32,arduino,wemosD1:没有操作系统(Linux)
全双工:两个人可以同时交流,串口通信属于全双工
半双工:俩人交流,同一时间只有一人说话
打怪升级
- 树莓派初始化
#include<wiringPi.h>
int main()
{
wiringPiSetup();
}
- 1个继电器控制的小锁
#include <stdio.h>
#include <wiringPi.h>
#define SWITCHER 7
int main()
{
int cmd;
if(wiringPiSetup()==-1)
{
printf("初始化失败\n");
return -1;
}
pinMode(SWITCHER,OUTPUT);
digitalWrite(SWITCHER,HIGH);
while(1)
{
printf("请输入1/0,1---开启,0---关闭:\n");
scanf("%d",&cmd);
getchar();
if(cmd==1)
{
digitalWrite(SWITCHER,LOW);
}
else if(cmd==0)
{
digitalWrite(SWITCHER,HIGH);
}
cmd=10;
}
return 0;
}
- 4个继电器
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#define SWI1 26
#define SWI2 27
#define SWI3 28
#define SWI4 29
int main()
{
char cmd[12]={'\0'};
if(wiringPiSetup()==-1)
{
printf("初始化失败\n");
return -1;
}
pinMode(SWI1,OUTPUT);
pinMode(SWI2,OUTPUT);
pinMode(SWI3,OUTPUT);
pinMode(SWI4,OUTPUT);
digitalWrite(SWI1,HIGH);
digitalWrite(SWI2,HIGH);
digitalWrite(SWI3,HIGH);
digitalWrite(SWI4,HIGH);
while(1)
{
memset(cmd,'\0',sizeof(cmd));
printf("请输入1/2/3/4 on/off,数字是开关序号,on---开启,off---关闭\n");
gets(cmd);
// getchar();
if(strcmp(cmd,"1 on")==0)
{
digitalWrite(SWI1,LOW);
}
else if(strcmp(cmd,"1 off")==0)
{
digitalWrite(SWI1,HIGH);
}
if(strcmp(cmd,"2 on")==0)
{
digitalWrite(SWI2,LOW);
}
else if(strcmp(cmd,"2 off")==0)
{
digitalWrite(SWI2,HIGH);
}
if(strcmp(cmd,"3 on")==0)
{
digitalWrite(SWI3,LOW);
}
else if(strcmp(cmd,"3 off")==0)
{
digitalWrite(SWI3,HIGH);
}
if(strcmp(cmd,"4 on")==0)
{
digitalWrite(SWI4,LOW);
}
else if(strcmp(cmd,"4 off")==0)
{
digitalWrite(SWI4,HIGH);
}
if(strcmp(cmd,"all on")==0)
{
digitalWrite(SWI1,LOW);
digitalWrite(SWI2,LOW);
digitalWrite(SWI3,LOW);
digitalWrite(SWI4,LOW);
}
else if(strcmp(cmd,"all off")==0)
{
digitalWrite(SWI1,HIGH);
digitalWrite(SWI2,HIGH);
digitalWrite(SWI3,HIGH);
digitalWrite(SWI4,HIGH);
}
}
return 0;
}
- 超声波
timeval结构体在头文件为sys/time.h中,定义如下:
//头文件
#include <sys/time.h>
//结构
struct timeval
{
time_t tv_sec; //秒 [long int]
suseconds_t tv_usec; //微秒 [long int]
};
关联函数:gettimeofday()
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
第一个参数不用多说,第二个参数也是结构体,定义如下:
struct timezone
{
int tz_minuteswest; /* 和Greenwich 时间差了多少分钟 */
int tz_dsttime; /* 日光节约时间的状态 */
};
根据Linux的手册中关于函数gettimeofday的描述(man gettimeofday):
The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL
这种使用方式是过时的,该处通常提供NULL作为参数。
int digitalRead(int pin)函数
pin是引脚号:
作用:就是将当前引脚的电平返回HIGH/LOW,HIGH为1,LOW为0,如果当前引脚没有设置的话随机返回一个值
delayMicroseconds(us)函数:
在Arduino程序中
delay(1)是指延时1毫秒
delayMicroseconds(1)是指延时1微秒
#include <stdio.h>
#include <sys/time.h>
#include <wiringPi.h>
#define Trig 5
#define Echo 6
void chaoShengBoInit()
{
pinMode(Trig,OUTPUT);
pinMode(Echo,INPUT);
}
float disMeasure()
{
float dis;
long first;
long second;
struct timeval t1;
struct timeval t2;
digitalWrite(Trig,LOW);
delayMicroseconds(2);
digitalWrite(Trig,HIGH);
delayMicroseconds(10);
digitalWrite(Trig,LOW);
while(digitalRead(Echo)!=1)
{
gettimeofday(&t1,NULL);
}
while(digitalRead(Echo)!=0)
{
gettimeofday(&t2,NULL);
}
first=t1.tv_sec*1000000+t1.tv_usec;
second=t2.tv_sec*1000000+t2.tv_usec;
dis=(float)(second-first)/1000000*34300/2;
return dis;
}
int main()
{
float dis;
if(wiringPiSetup()==-1)
{
printf("初始化失败!\n");
return -1;
}
chaoShengBoInit();
while(1)
{
dis=disMeasure();
printf("get dis= %f cm\n",dis);
delay(1000);
}
return 0;
}
- 串口通信
初次使用树莓派串口编程,需要配置
进入 boot 文件夹
cd /boot/
修改 cmdline.txt文件
sudo vim cmdline.txt
删除【】之间的部分
dwc_otg.lpm_enable=0 【console=serial0,115200】 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
使用串口通信API时需要包含头文件:#include <wiringSerial.h>
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
int main()
{
int fd;
int cmd;
wiringPiSetup();
fd=serialOpen("/dev/ttyAMA0",9600);
if(fd==-1)
{
perror("why");
}
while(1)
{
while(serialDataAvail(fd)!=-1)
{
cmd=serialGetchar(fd);
if(cmd=='1')
{
serialPuts(fd,"chenlichen henshuai!\r\n");
// printf("cmd=%d\n",cmd);
}
if(cmd=='2')
{
serialPuts(fd,"chenlichen henbang!\r\n");
}
if(cmd=='3')
{
serialPuts(fd,"chenlichen henniu!\r\n");
}
}
// serialPutchar(fd,'c');
// serialPuts(fd,"chenlichen henshuai!\r\n");
// delayMicroseconds(1000000);
}
return 0;
}
- 语音模块的串口通信
#include <wiringSerial.h>
#include <wiringPi.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd;
int n_read;
char cmd[128]={'\0'};
wiringPiSetup();
fd=serialOpen("/dev/ttyAMA0",9600);
while(1)
{
n_read=read(fd,cmd,sizeof(cmd));
if(strlen(cmd)==0)
{
printf("超时!\n");
continue;
}
if(strstr(cmd,"open"))
{
printf("已打开!\n");
}
if(strstr(cmd,"close"))
{
printf("已关闭!\n");
}
memset(cmd,'\0',sizeof(cmd)/sizeof(char));
}
serialClose(fd);
return 0;
}
- 语音模块配合舵机实现智能垃圾桶
参考来源:[树莓派系列] 使用WiringPi库入门模拟舵机-SG90(C和Python)
#include <wiringSerial.h>
#include <wiringPi.h>
#include <softPwm.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define PWM_PIN 1
int main()
{
int fd;
int n_read;
char cmd[128]={'\0'};
wiringPiSetup();
fd=serialOpen("/dev/ttyAMA0",9600);
pinMode(PWM_PIN, PWM_OUTPUT);// 设置PWM输出
pwmSetMode(PWM_MODE_MS);// 设置传统模式
pwmSetClock(192);// 设置分频
pwmSetRange(2000);// 设置周期分为2000步
pwmWrite(PWM_PIN,250);
while(1)
{
n_read=read(fd,cmd,sizeof(cmd));
if(strlen(cmd)==0)
{
printf("超时!\n");
continue;
}
if(strstr(cmd,"open"))
{
printf("已打开!\n");
printf("当前方向: 0度\n");
pwmWrite(PWM_PIN,150);
}
if(strstr(cmd,"close"))
{
printf("已关闭!\n");
printf("当前方向: 90度\n");
pwmWrite(PWM_PIN,250);
}
memset(cmd,'\0',sizeof(cmd)/sizeof(char));
}
serialClose(fd);
return 0;
}