通信原理课设(gec6818) 008:LED+蜂鸣器+串口+MQ01+GY39+RFID

目录

1、LED和蜂鸣器

a. 安装驱动

b. 代码

2、串口

3、MQ01烟雾传感器

4、GY39


1、LED和蜂鸣器

a. 安装驱动

在开发板上要使用led和蜂鸣器需要安装对应的驱动

链接:https://pan.baidu.com/s/15I1kGKhT1kENqplu5Dmg5Q?pwd=lebe 
提取码:lebe

将上面的两个文件放到开发板上面去

使用insmod命令加载驱动:

insmod led_drv.ko

insmod pwm.ko

去/dev文件夹,如果看到led_drv和pwm,就是驱动加载成功

如果在加载驱动的过程中,提示文件繁忙,那就先卸载驱动,再重新下载:

rmmod gec6818_beep.ko
再insmod pwm.ko

b. 代码

led大家都很熟悉了,概念和原理啥的就跳过

为了在后面的gy39和mq01使用中,当数值超过一定阈值时,能调用led,所以我定义了变量state,num,直接调led函数,并传相应的值就能实现led灯的亮灭,蜂鸣器也是如此。

led.c :

#include "led.h"
//state:灯的状态,是开还是关  1:开 0:关  
//num:灯的编号,亮哪个灯
int state = 0; //灯默认为关
int num;
void led(int state,int num)
{
	int fd,ret;
	char led_ctrl[2]; //0 --> 灯的状态  1 --->灯编号
	//[1]
	fd = open("/dev/led_drv",O_RDWR);
	if(fd < 0)
	{
		printf("open led_drv failed\n");
	}

	led_ctrl[1] = num;  //
	led_ctrl[0] = state; //on
	ret = write(fd,led_ctrl,sizeof(led_ctrl));
	  
	if( ret != 2)
	{
		perror("write");
	}

	close(fd);
}

led.h :

#ifndef _LED_H_
#define _LED_H_

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void led(int state,int num);

#endif

beep.c :

#include "beep.h"
int sound = 0; //默认不响
void beep(int sound)
{
	int fd,ret;
	char beep_ctrl[1]; //0 --> 不响  1 --->响
	//[1]
	fd = open("/dev/pwm",O_RDWR);
	if(fd < 0)
	{
		printf("open /dev/pwm failed\n");
	}

	beep_ctrl[0] = sound; 	//响
    ret = write(fd,beep_ctrl,sizeof(beep_ctrl));
    if( ret == -1)
	{
	    perror("write");
	}	

	close(fd);	

}

beep.h :

#ifndef __BEEP_H__
#define __BEEP_H__

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void beep(int sound);

#endif

2、串口

在linux里面串口也是一个文件
    "/dev/ttySAC1" -> 串口1
    "/dev/ttySAC2" -> 串口2
    "/dev/ttySAC3" -> 串口3

我们在使用串口之前要设置这个串口的波特率以及其他的属性,调用int init_serial(const char *file, int baudrate)这个函数。

serial_init.c :

#include "serial_init.h"

//初始化串口,把 open 和 初始化 结合在一起了
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;
}

serial_init.h :

#ifndef __SERIAL_INIT__
#define __SERIAL_INIT__

#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>



//初始化串口,把 open 和 初始化 结合在一起了
int init_serial(const char *file, int baudrate);


#endif

3、MQ01烟雾传感器

基本流程:

1、初始化串口

2、发送命令:FF 01 86 00 00 00 00 00 79

3、MQ采集数据

4、处理数据,将返回值第2个字节左移8位并于第3个字节相或

注意,烟雾传感器MQ是发送一次命令,返回一次信息。

MQ01.c :

#include "MQ01.h"

extern int state; //灯默认为关
extern int num;

void Z_MQ(void)
{
    int Z_MQ_fd = 0;
    unsigned char yanwucmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
    unsigned char yanwu_buf[100]={0};
    int yanwu;
    Z_MQ_fd = init_serial("/dev/ttySAC2",9600);
    while(1)
    {
        write(Z_MQ_fd,yanwucmd,9);
        read(Z_MQ_fd,yanwu_buf,9);
        yanwu = yanwu_buf[2]<<8 | yanwu_buf[3];
        printf("烟雾值:%d\n",yanwu);
        if(yanwu>=300)
        {
            led(1,9);  //led9 亮
            beep(1);   //蜂鸣器响
            sleep(5);//持续5s
            beep(0);   //蜂鸣器关
        }
        else{
            led(0,9);  //led9 灭
            beep(0);   //蜂鸣器关
        }
        sleep(1);
    }
    close(Z_MQ_fd);
}


MQ01.h :

#ifndef __MQ01_H__
#define __MQ01_H__

//#include <stdio.h>
#include "serial_init.h"
#include <unistd.h>
#include "led.h"
#include "beep.h"


void Z_MQ(void);

#endif

4、GY39

基本流程:

1、初始化串口

2、发送命令

      当发送命令为:0xA5+0x81+0x26时,只输出光照
      当发送命令为:0xA5+0x82+0x27时,只输出温度、气压、湿度、海拔
      当发送命令为:0xA5+0x83+0x28时,输出全部:光照、温度、气压、湿度、海拔

3、采集数据

4、处理数据

光照强度计算方法(当 Byte2=0x15 , 数据 :Byte4~Byte7 ) :
Lux=( 前高 8 <<24) | ( 前低 8 <<16) | ( 后高 8 <<8) | 后低 8 位 单位 lux
例:一帧数据
<5A- 5A- 15 -04- 00 -00- FE- 40 - 0B >
Lux=(0x00<<24)|(0x00<<16)|(0xFE<<8)|0x40
Lux=Lux/100 =650.88 (lux)
温度、气压、湿度、海拔,计算方法(当 Byte2=0x45 时):
温度: Byte4~Byte5
T=( 8 <<8)| 8
T=T/100 单位℃
气压: Byte6~Byte9
P=( 前高 8 <<24) | ( 前低 8 <<16) | ( 后高 8 <<8) | 后低 8
P=P/100 单位 pa
湿度: Byte10~Byte11
Hum=( 8 <<8)| 8
Hum=Hum/100 百分制
海拔: Byte12~Byte13

H=(高 8 <<8)|8 单位 m

例:一帧数据
< 5A -5A -45 -0A - 0B -2D -00 -97 -C4 -3F -12- 77 -00- 9C - FA >
T=(0x0B<<8)|0x2D=2861
温度 T=2861/100=28.61 ( )
P=(0x00<<24)|(0x97<<16)|(C4<<8)|3F=9946175
气压 P=9946175/100=99461.75 (pa)
Hum=(0x12<<8)| 77=4727
湿度 Hum=4727/100=47.27 (%)
海拔 H=(0x00<<8)|0x9c=156 (m)

   

GY39.c :

#include "GY39.h"

extern int state; //灯默认为关
extern int num;

void printGy39Data(unsigned char *recvdata,int n)
{
	int i;
	for(i = 0;i < n;i++)
	{
		printf("%x ",recvdata[i]);
	}
	printf("\n");
	int LUX,T,P,HUM,H;//光照,气温,气压,湿度,海拔
	LUX = (recvdata[4]<<24 | recvdata[5]<<16 | recvdata[6]<<8 | recvdata[7]) / 100; 
	T = (recvdata[13]<<8 | recvdata[14]) / 100; 
	P = (recvdata[15]<<24 | recvdata[16]<<16 | recvdata[17]<<8 | recvdata[18]) / 100; 
	HUM = (recvdata[19]<<8 | recvdata[20]) / 100; 
	H = recvdata[21]<<8 | recvdata[22];
	printf("LUX:%d T:%d P:%d HUM:%d H:%d\n",LUX,T,P,HUM,H);

	if(T>28)
	{
		led(1,8);  //led9 亮
        beep(1);   //蜂鸣器响
        sleep(5);//持续5s
        beep(0);   //蜂鸣器关
	}
	else{
		led(0,8);  //led8灭
		led(0,9);
	}
}

void Gy39GetData()
{
	int fd = init_serial("/dev/ttySAC1",9600);
	unsigned char cmd[3] = {0xA5,0x83,0x28};
	
	int r = write(fd,cmd,3);
	printf("write r = %d\n",r);
	usleep(500000);
	int gy39_i = 0;
	unsigned char recvdata[24] = {0};
	int timeout = 0;
	while(1)
	{
		r = read(fd,recvdata + gy39_i,1);
		if(0 == r)
		{
			timeout++;
			usleep(1000);
			if(timeout > 1000)//连续两秒没有回应
			{
				printf("超时\n");
				timeout = 0;
				break;
			}
			continue;
		}
		timeout = 0;
		gy39_i++;
		switch(gy39_i)
		{
			case 1:if(recvdata[0] != 0x5a){gy39_i = 0;}break;
			case 2:if(recvdata[1] != 0x5a){gy39_i = 0;}break;
			case 3:if(recvdata[2] != 0x15){gy39_i = 0;}break;			
			case 4:if(recvdata[3] != 0x04){gy39_i = 0;}break;
			case 24:printGy39Data(recvdata,24);gy39_i = 0;break;//接收完毕
			default:
				if(gy39_i > 24 || gy39_i < 0)
				{
					gy39_i = 0;
					sleep(1);
				}
				break;			
		}		
	}
}

GY39.h :

#ifndef __GY39_H__
#define __GY39_H__

//#include <stdio.h>
#include <unistd.h>
#include "serial_init.h"
#include "beep.h"
#include "led.h"
void printGy39Data(unsigned char *recvdata,int n);
void Gy39GetData();
//int gy39_getlux(void);

#endif

---------------------------------------------------补充-----------------------------------------------------------------------

5、RFID识别

#include "rifd.h"

//获取校验和
char get_BCC(char *cmd)
{
	char BCC = 0;
	int i;
	for(i = 0;i < cmd[0] - 2;i++)
	{
		//BCC = BCC ^ cmd[i];
		BCC ^= cmd[i];
	}
	
	return ~BCC;
}


/*
	防碰撞
	
*/
void CascAnticollRfidCmd(int fd)
{
	char cmd[8] = {0};
	cmd[0] = 0x08;
	cmd[1] = 0x02;
	cmd[2] = 0x42;
	cmd[3] = 0x02;
	cmd[4] = 0x93;//使用ALL模式
	cmd[5] = 0x00;
	cmd[6] = get_BCC(cmd);
	cmd[7] = 0x03;
	//将这个命令发送给rfid 
	write(fd,cmd,cmd[0]);
	
	//稍微延时一会 0.1s
	usleep(100000);
	
	//收rfid的回应
	unsigned char buf[10] = {0};
	int r = read(fd,buf,10);
	if(r == 10)
	{		
		if(buf[2] == 0)
		{
			int getUID  = buf[4] | buf[5] << 8 | buf[6] << 16 | buf[7] << 24;
			printf("getUID = %x\n",getUID);//卡序列号
		}
	}
	else
	{
		perror("read CascAnticollRfidCmd error");
	}
	
	
}


/*
	这个函数是对rfid进行请求的
	成功返回0  失败返回-1
*/
int RequestRfidCmd(int fd)
{
	unsigned char cmd[7] = {0};
	cmd[0] = 0x07;
	cmd[1] = 0x02;
	cmd[2] = 0x41;
	cmd[3] = 0x01;
	cmd[4] = 0x52;//使用ALL模式
	cmd[5] = get_BCC(cmd);
	cmd[6] = 0x03;
	//将这个命令发送给rfid 
	write(fd,cmd,cmd[0]);
	
	//稍微延时一会 0.1s
	usleep(1000000);
	
	//等待rfid的回应
	char buf[8] = {0};
	int r = read(fd,buf,8);
	if(r == 8)
	{
		if(buf[2] == 0)//请求成功
		{	
			switch(buf[4])
			{
				case 0x04:
					printf("S50\n");  //卡片类型
					break;
				case 0x02:
					printf("S70\n");
					break;
			}
			
			return 0;
		}
		return -1;
		
	}
	else
	{
		perror("请求失败\n");
		//将蜂鸣器弄的不响
		
		return -1;
	}
}



/*
	这个函数的功能是为了给rfid发送使能命令 
	并且专注这个rfid的返回信息
	fd:是你的初始化好了的串口
	成功返回0 失败返回-1
*/
int SendEnableCmd(int fd)
{
	unsigned char cmd[6] = {0};
	cmd[0] = 0x06;
	cmd[1] = 0x01;
	cmd[2] = 0x41;
	cmd[3] = 0x00;
	cmd[4] = get_BCC(cmd);
	cmd[5] = 0x03;
	
	//将这个命令发送给rfid 
	write(fd,cmd,cmd[0]);
	
	//稍微延时一会 0.1s
	usleep(100000);
	
	
	//等你的rfid回你的信息
	char buf[18] = {0};
	int r = read(fd,buf,18);
	//printf("%d %d\n",r,buf[2]);
	if(18 == r)//这样你才叫得到了完整信息
	{
		if(buf[2] == 0)//这样才叫准备好了
		{
			printf("yes\n");
			return 0;
		}		
		return -1;
	}	
	else
	{
        printf("SendEnableCmd read r = %d\n",r);
		perror("read error");
		return -1;
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/281847.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【并行计算】GPU,CUDA

一、CUDA层次结构 1.kernel核函数 一个CUDA程序是一个kernel核函数被GPU的多个计算单元并行执行的过程&#xff0c;CUDA给了如下抽象 dim3 threadsPerBlock(4, 3, 1); dim3 numBlocks(3, 2, 1); matrixAdd<<<numBlocks, threadsPerBlock>>>(A, B, C); 2.G…

git(安装,常用命令,分支操作,gitee,IDEA集成git,IDEA集成gitee,IDEA集成github,远程仓库操作)

文章目录 1. Git概述1.1 何为版本控制1.2 为什么需要版本控制1.3 版本控制工具1.4 Git简史1.5 Git工作机制1.6 Git和代码托管中心 2. Git安装3. Git常用命令3.1 设置用户签名3.1.1 说明3.1.2 语法3.1.3 案例实操 3.2 初始化本地库3.2.1 基本语法3.2.2 案例实操3.2.3 结果查看 3…

Innosetup 调用c# dll 和 c# dll的函数导出

目标需求&#xff0c;基于现在安装包脚本。需要在用户安装和卸载成功时。进行数据记录,所以需要调用c#dll 主要涉及到的知识点 需要理解脚本的文件使用机制脚本的文件dll加载&#xff0c;和dll的调用c# dll的制作&#xff0c;和工具的使用 下面具体介绍 脚本的文件dll加载&…

详解Vue3中的鼠标事件mousedown、mouseup和contextmenu

本文主要介绍Vue3中的常见鼠标事件mousedown、mouseup和contextmenu。 目录 一、mousedown——鼠标按下事件二、mouseup——鼠标弹起事件三、contextmenu——页面菜单 下面是Vue 3中常用的鼠标事件mousedown、mouseup和contextmenu的详解。 一、mousedown——鼠标按下事件 mo…

CloneNotSupportedException的解决方案 + Object的clone方法分析

CloneNotSupportedException的解决方案 引入问题&#xff1a; 在一次测试clone方法时&#xff0c;D类Override了Object类的clone方法 public class D {private Integer A1;private Integer A2;public D() {}public D(Integer a1, Integer a2 {A1 a1;A2 a2;}Overrideprotec…

PAT 乙级 1042 字符统计

请编写程序&#xff0c;找出一段给定文字中出现最频繁的那个英文字母。 输入格式&#xff1a; 输入在一行中给出一个长度不超过 1000 的字符串。字符串由 ASCII 码表中任意可见字符及空格组成&#xff0c;至少包含 1 个英文字母&#xff0c;以回车结束&#xff08;回车不算在内…

软件测试/测试开发丨Python 内置库 sys 学习笔记分享

sys 概述 是 Python 自带的内置模块是与 Python 解释器交互的桥梁 sys 使用 常用属性常用方法导入 sys 模块 # 导入sys模块 import sys# 查看sys模块帮助文档 help(sys)# 查看sys模块的属性和方法 print(dir(sys))sys 常用属性 sys.version&#xff1a;返回 Python 解释器…

Linux基础知识学习2

tree命令的使用 可以看到dir2目录下的这些文件&#xff0c;要想显示dir2的具体结构&#xff0c;可用tree命令 mv命令 它可以实现两个功能 1.将文件移动到另一个目录中 2.对某一个文件进行重命名 1.将文件移动到另一个目录中 这里将dir1中的2.txt移动到他的子目录dir3中 执行…

虚拟化分类和实现原理

6、虚拟化分类 &#xff08;1&#xff09;完全虚拟化 直接将Hypervisor跑在0环内核态&#xff0c;客户机os跑在1环&#xff0c;一旦触发敏感指令&#xff0c;由0环的VMM进行捕获翻译&#xff0c;从而模 拟这些指令。而运行在1环的GuestOS永远都不知道自己是个虚拟机。是完全…

python统计分析——透视表

参考资料&#xff1a;用Python动手学统计学 pandas库的pivot_table函数相当于excel的透视表功能。此图为excel数据透视表字段设置窗口&#xff0c;下面将参照excel数据透视表相关设置图片学习pivot_table函数&#xff1a; 本次使用的数据集内容如下&#xff1a; import pandas…

python安装MongoDB与运算符优先级

python安装MongoDB MongoDB 是目前最流行的 NoSQL 数据库之一&#xff0c;使用的数据类型 BSON&#xff08;类似 JSON&#xff09;。 PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动&#xff0c;这里我们使用 PyMongo 驱动来连接。 pip 安装 pip 是一个通用的 Python 包…

【STM32】STM32学习笔记-PWM驱动LED呼吸灯 舵机 直流电机(16)

00. 目录 文章目录 00. 目录01. 输出比较相关API1.1 TIM_OC1Init1.2 TIM_OCInitTypeDef结构体1.3 TIM_OCMode1.4 TIM_OutputState1.5 TIM_OutputNState1.6 TIM_OCPolarity1.7 TIM_OCNPolarity1.8 TIM_OCPolarity1.9 TIM_OCNPolarity 02. PWM实现呼吸灯接线图03. PWM实现呼吸灯示…

普中STM32-PZ6806L开发板(前序)

前言 突然从柜子看到七八年前买的一块普中开发板, 在诸多的例如野火、原子中当时为什么选择他, 现在来看应该还是性价比较高&#xff0c;班上集成了很多学习者的进阶模块了&#xff0c;当然&#xff0c;买完大程度就吃灰了&#xff0c;当我再次发现他的时候&#xff0c; 我看到…

独立站的营销策略:吸引顾客的秘密武器

一、独立站的重要性 独立站是指企业自主建立的电子商务网站&#xff0c;具有独立的域名和运营管理权。通过独立站&#xff0c;企业可以展示产品信息、提供在线服务、进行促销活动等&#xff0c;与顾客建立互动和信任关系。独立站的重要性在于它可以帮助企业建立品牌认知度、提…

【NTN 卫星通信】Oneweb星座以及Oneweb与Starlink比较

1 什么是OneWeb OneWeb于2012年以WorldVu的名义成立&#xff0c;于2020年开始构建其星座。然而&#xff0c;对于这家英国公司来说&#xff0c;这是一个艰难的旅程&#xff0c;OneWeb于2020年3月宣布破产&#xff0c;并认为covid-19大流行是一个主要因素。OneWeb星座当时仅完成…

trino-435: 理论基础

一、trino介绍 Trino是⼀种⽀持使⽤ SQL 访问任意数据源的 开源的分布式SQL 查询引擎&#xff0c;其能够提供更加灵活与⾼效的查询服务。为不同的异构数据源提供统⼀的sql访问&#xff0c;并⽀持联邦查询和并⾏查询。 应⽤场景 Trino是定位在数据仓库和数据分析业务的分布式S…

#前后端分离# 头条发布系统

头条业务简介 新闻的分页浏览通过标题关键字搜索新闻查看新闻详情新闻的修改和删除用户注册、登录 预览界面 开源上线 https://gitcode.net/NVG_Haru/NodeJS_5161447 数据库设计 数据库脚本 CREATE DATABASE sm_db;USE sm_db;SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0…

python的pywebio库给孩子做加减法数学题

效果展示 程序执行后&#xff0c;打开浏览器&#xff0c;展示一些100以内的加减法混合运算的数学题并输入答案后判断对错&#xff0c;这样倒是省了买教材的钱了。 在题目下方的框中&#xff0c;输入答案&#xff0c;然后点击提交后&#xff0c; 会输出结果 pywebio库介绍 安装…

详解FreeRTOS:FreeRTOSConfig.h系统配置文件(拓展篇—1)

目录 1、“INCLUDE_”宏 2、“config”宏 实际使用FreeRTOS的时候,时常需要根据自己需求来配置 FreeRTOS,不同架构的MCU,配置也不同。 FreeRTOS的系统配置文件为FreeRTOSConfig.h,在配置文件中可以完成FreeRTOS的裁剪和配置,这是非常重要的一个文件,本篇博文就来讲解这…

文件批量整理,文件归类整理,文件批量归类

我们每天都要面对无数的文件&#xff0c;从工作报告、个人照片到电影和音乐。如何有效地管理和归类这些文件&#xff0c;成为了我们日常生活和工作中所要处理的。今天&#xff0c;小编就给大家介绍一款简单易用的工具——文件批量改名高手&#xff0c;助你轻松实现文件批量归类…