6.串口通信和传感器的使用 您所在的位置:网站首页 智能家居模块安装视频 6.串口通信和传感器的使用

6.串口通信和传感器的使用

2024-07-03 15:15| 来源: 网络整理| 查看: 265

一、串口通信及传感器数据采集 1.串口及初始化

串口是一种简单的通信接口,也是单片机中最常用,最简单的通信方式

通常传感器都是采用串口作为与上位机的通信接口

ARM板上提供了三个可以外接传感器的串口接口,位于开发板的右上角,

从上到下分别是:

​ 串口号 串口驱动设备文件名

​ CON2 “/dev/ttySAC1”

​ CON3 “/dev/ttySAC2”

​ CON4 “/dev/ttySAC3”

我们将传感器链接到对应的串口端口以后,在Linux中通过串口通信去获取该传感器的数据极其简单

只需要先打开串口设备文件,并将串口进行初始化配置,就可以调用write函数发送数据给传感器,调用read函数从传感器中获取数据

串口的初始化函数如下:

#include #include #include #include #include #include #include #include #include //串口配置需要的头文件 /* * init_serial:自定义的用来打开串口文件并对串口进行初始化的函数 * arg: * @fild:串口设备文件名,指定您要使用的串口 * @baudrate:整数,指定您要配置的串口的通信波特率 * 9600/115200/19200 * 配置的串口协议:数据位8,停止位1,不要校验,不要硬件控制流 * return: * 成功,返回打开 并初始化好的 串口的文件描述符,后期根据该返回值来与链接在该串口上的传感器进行通信 * 失败返回-1 **/ int init_serial(const char *file, int baudrate) { int fd; fd = open(file, O_RDWR); if (fd == -1) { perror("open device error:"); return -1; } struct termios myserial; //清空结构体 memset(&myserial, 0, sizeof (myserial)); //O_RDWR myserial.c_cflag |= (CLOCAL | CREAD); //设置控制模式状态,本地连接,接受使能 //设置 数据位 myserial.c_cflag &= ~CSIZE; //清空数据位 myserial.c_cflag &= ~CRTSCTS; //无硬件流控制 myserial.c_cflag |= CS8; //数据位:8 myserial.c_cflag &= ~CSTOPB;// //1位停止位 myserial.c_cflag &= ~PARENB; //不要校验 //myserial.c_iflag |= IGNPAR; //不要校验 //myserial.c_oflag = 0; //输入模式 //myserial.c_lflag = 0; //不激活终端模式 switch (baudrate) { case 9600: cfsetospeed(&myserial, B9600); //设置波特率 cfsetispeed(&myserial, B9600); break; case 115200: cfsetospeed(&myserial, B115200); //设置波特率 cfsetispeed(&myserial, B115200); break; case 19200: cfsetospeed(&myserial, B19200); //设置波特率 cfsetispeed(&myserial, B19200); break; } /* 刷新输出队列,清楚正接受的数据 */ tcflush(fd, TCIFLUSH); /* 改变配置 */ tcsetattr(fd, TCSANOW, &myserial); return fd; }

常见的串口传感器,通信方式一般有两种:

1 配置式通信:上位机只需要发送一次配置命令给传感器,传感器就会周期性采集并返回数据回复给上位机

比如:GY-39

2.询问式通信:上位机发送一次命令给传感器,传感器就会采集并返回一次数据给上位机,直到下一次上位机再发送命令,传感器彩虹再一次采集回复数据==》上位机每发送一次指令,才能获取一次数据 ==》烟雾传感器

int main(void) { int gy39_fd = 0; gy39_fd = init_serial("/dev/ttySAC1",9600); read(gy39_fd,...,...);//从gy39中读取数据存入到... write(gy39_fd,...,...);往gy_39里面写入... }

在使用串口与传感器通信,来获取传感器采集到的数据时,我们必须能够熟练地阅读传感器的使用手册

2.GY-39的使用

接线引脚

在这里插入图片描述

​ VCC:电源正极,接上位机的5v(vcc)

​ CT(UART_TX):串口数据发送端,接上位机的RX引脚

​ DR(UART_RX):串口数据接收端,接上位机的TX引脚

​ GND:电源接地,接上位机的GND

通信协议

命令

命令是由上位机发送给GY-39传感器的,用来告诉GY-39本次需要采集那些数据

GY-39的命令由三个字节组成:

指令格式:帧头+指令+校验和(8bit)

帧头:固定0xa5,表示一帧命令的开始

指令:表示命令码,8bit,不同的bit有不同的含义

校验和:前面两个字节的和,只取低8位

在这里插入图片描述

eg:

unsigned char cmd[3]={0xa5,0x81,0x26}; write(gy39_fd,cmd,3);//发送获取光强的命令给GY-39,之后GY-3会周期性给上位机回复光强数据

回复数据:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BOcFnHMQ-1686970317682)(pic/image-20230612104707196.png)]

在这里插入图片描述

在这里插入图片描述

读取GY-39的回复数据,有两种方式

1.简单粗暴

发送光强命令0x81,读取9字节

发送气象命令0x82,读取15字节

发送光强+气象数据0x83,读取15+9个字节

这种读取方式,前提是上位机与GY-39的通信必须一直稳定,不能出现误传

2.一个字节一个字节的读取,根据通信协议中数据帧的格式来边解析边读取数据

int gy39_getlux(void) { int gy39_fd = 0; int i = 0; ssize_t rsize = 0; unsigned char cmd[3]={0xa5,0x81,0x26}; unsigned char buf[25]={0}; gy39_fd = init_serial("/dev/ttySAC1",9600); write(gy39_fd,cmd,3);//发送获取光强的命令给GY-39,之后GY-3会周期性给上位机回复光强数据 while(1) { rsize = read(gy39_fd,buf,9); if (rsize == 9) { printf("GY-39 lux buffer:\n"); for ( i = 0; i gy39_getlux(); return 0; }

在这里插入图片描述

int gy39_lux(void) { int i = 0; int lux = 0; int gy39_fd = 0; ssize_t rsize = 0; unsigned char cmd[3]={0xa5,0x81,0x26};//命令数组帧头、指令、校验和(8bit) unsigned char buf[25]={0};//缓存数组保存从传感器返回的数据 gy39_fd =init_serial("/dev/ttySAC1",9600); write(gy39_fd,cmd,3);//发送读取光强的命令,GY-39开始周期性的回复光强数据 rsize=read(gy39_fd,buf,9); if (rsize = 9&&buf[2]=0x15)//数据帧9bit且byte2=0x15 { lux=(buf[4]&0xff) 不响 1 --->响 //[1]打开蜂鸣器的驱动设备文件 fd = open("/dev/pwm",O_RDWR); if(fd beep_ctrl[0] = 0; //不响 ret = write(fd,beep_ctrl,sizeof(beep_ctrl)); if( ret == -1) { perror("write"); } sleep(1); beep_ctrl[0] = 1; //响 ret = write(fd,beep_ctrl,sizeof(beep_ctrl)); if( ret == -1) { perror("write"); } sleep(1); } //[3] close(fd); return 0; } 案例:实现智能家居(光照气度,压强,海拔,湿度,温度达到临界值蜂鸣器自动警报等等)

在这里插入图片描述

** 关键代码:(需要源码私我)**

//智能家居文字显示 void word_view() { //标题(智能家居) for(int t=0;t show_word(guangqiang[t],sizeof(guangqiang[t]),16,0,200+80*t,190); } //温度 for(int t=0;t show_word(qiya[t],sizeof(qiya[t]),16,0,200+80*t,290); } //湿度 for(int t=0;t show_word(haiba[t],sizeof(haiba[t]),16,0,200+80*t,390); } //光强单位 for(int t=0;t show_word(wendudanwei[t],sizeof(wendudanwei[t]),8,0,355 + 7*t,240); } //气压单位 for(int t=0;t show_word(shidudanwei[t],sizeof(shidudanwei[t]),8,0,355 + 7*t,340); } //海拔单位 for(int t=0;t


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有