头文件:include
查看树莓派引脚情况:在显示终端输入命令gpio readall
宏定义引脚:例如#define JDQ 3
wiringPi库初始化:wiringPiSetup()
返回值等于-1 初始化失败
设置引脚为输出引脚:pinMode(JDQ, OUTPUT);
设置引脚为输入引脚:pinMode(JDQ, INPUT);
设置引脚为高电平:digitalWrite(JDQ, HIGH);
设置引脚为低电平:digitalWrite(JDQ, LOW);
读取引脚值:digitalRead(JDQ);
编译链库:-lwiringPi
#include
#include
#define JDQ 3
int handleCmd(int cmd)
{
switch(cmd)
{
case 0:
digitalWrite(JDQ, LOW);
break;
case 1:
digitalWrite(JDQ, HIGH);
break;
case 3:
printf("quit\n");
break;
}
return cmd;
}
int main()
{
int cmd;
if(wiringPiSetup() == -1)
{
printf("wiringPi init failure\n");
return -1;
}
pinMode(JDQ, OUTPUT);
digitalWrite(JDQ, HIGH);
while(1)
{
printf("input num(0-light,1-dark,3-quit):");
scanf("%d", &cmd);
if(handleCmd(cmd) == 3)
{
break;
}
}
return 0;
}
编译链接wiringPi库:
gcc JDQ_demo.c -lwiringPi -o JDQ_demo
HC-SR04超声波测距模块基本信息:
工作电压:5v
echo:回收声波,设置成输入引脚
trig:发射声波,设置成输出引脚
测距范围:最远4米左右
测距原理:当树莓派(trig引脚)持续10us的高电平,声波模块的trig端发送8个40Hz的方波,echo引脚从高电平到低电平的时间就是声波发出后遇到障碍物后反射回来的时间
获取系统函数原型:
int gettimeofday(struct timeval *tv, struct timezone *tz);
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
场景:通过判断声波模块到障碍物体的距离,可以做一个近距离感应提示灯
#include
#include
#include
#define TRIG 1
#define ECHO 2
#define JDQ 3
void devInit()
{
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(JDQ, OUTPUT);
digitalWrite(JDQ, HIGH);
}
float getDis()
{
long start;
long stop;
float dis;
struct timeval t1;
struct timeval t2;
digitalWrite(TRIG, LOW); //为了让数据更精准
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
while(digitalRead(ECHO) != HIGH);
gettimeofday(&t1, NULL);
while(digitalRead(ECHO) != LOW);
gettimeofday(&t2, NULL);
start = t1.tv_sec * 1000000 + t1.tv_usec; //s化us,10的6次方
stop = t2.tv_sec * 1000000 + t2.tv_usec;
dis = (float)(stop-start) / 1000000 * 34000 / 2; //空气中声音的传播速度340m/s
return dis;
}
int main()
{
float dis;
if(wiringPiSetup() == -1)
{
return -1;
}
devInit();
while(1)
{
delay(2000);
dis = getDis();
printf("%.2fcm\n", dis);
if(dis <= 15)
{
digitalWrite(JDQ, LOW);
delay(3000);
digitalWrite(JDQ, HIGH);
}
}
return 0;
}
在同一网段下传
官网开源下载:https://www.filezilla.cn/
使用:
使用:scp 文件名 目标主机名@目标主机ip地址:目录
例如:scp test.c [email protected]:/home/hhz/
如果目标主机在线,会提示输入目标主机密码
串口通信属于全双工,即两个人对骂,同时两个人是能听得见
半双工:一个人被另一个人骂地哑口无言,只能听
树莓派串口数据一次接收数据的量是8个字符,如果要使用串口通信完成某些任务时,可以先将要传的数据弄成容易区分和标记的,然后用字符串相关API处理。
vi /boot/cmdlinet.txt
编辑文件
方式一
备份好原内容
删除字符串:console=serial0,115200
方式二
备份好原内容或者注释掉,将原内容替换为:
dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
修改后sudo reboot
重启,如果重启不了,就重新上电
重启后查看是否有映射成功:ls -l /dev|grep serial
接线跟第一次用串口登录一样
头文件:#include
树莓打开串口:int serialOpen(char *device, int baud)
树莓发数据:void serialPutchar(int fd, unsigned char c)
树莓发数据:void serialPuts(int fd, char *s)
树莓接收数据:int serialDataAvail(int fd)
树莓接收数据:int serialGetchar(int fd)
树莓关闭串口:void serialClose(int fd)
还有vfs虚拟文件系统的API接口,下面的通用性强
vfs提供一个通用的接口,不仅适用于文件读写、网络信息收发、串口读写等等
#include
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
开关灯:
#include
#include
#include
#include
#include
#include
#define JDQ 3
void handleCmd(char *pBuf)
{
if(!strcmp(pBuf, "opendeng")) //字符串一样返回值为0
{
digitalWrite(JDQ, LOW);
}
else if(strstr("closelight", pBuf) != NULL) //搜索子串
{
digitalWrite(JDQ, HIGH);
}
else
{
printf("command error\n");
}
}
int main()
{
int fd;
char buf[16];
if(wiringPiSetup() == -1)
{
perror("why"); //打印错误信息
exit(0); //进程退出函数
}
pinMode(JDQ, OUTPUT);
digitalWrite(JDQ, HIGH);
fd = serialOpen("/dev/ttyAMA0", 9600); //第二个参数为波特率,返回值=-1打开串口失败
if(fd == -1)
{
printf("serialOpen failure\n");
exit(1);
}
while(1)
{
memset(buf, 0, sizeof(buf)); //memset初始化申请的内存,sizeof()计算数组、结构体等大小
read(fd, buf, sizeof(buf)); //fd:文件描述符,buf:将要写入的缓存区
if(strlen(buf)!= 0) //字符串长度
{
printf("receive:%s\n", buf);
handleCmd(buf);
}
}
return 0;
}