STM32-笔记37-吸烟室管控系统项目

一、项目需求

1. 使用 mq-2 获取环境烟雾值,并显示在 LCD1602 上;

2. 按键修改阈值,并显示在 LCD1602 上;

3. 烟雾值超过阈值时,蜂鸣器长响,风扇打开;烟雾值小于阈值时,蜂鸣器不响,风扇关闭;

二、项目框图

三、介绍烟雾传感器(MQ-2)

四、项目实现

复制项目文件夹19-串口打印功能

重命名为46-烟雾报警系统项目

打开项目工程,加载文件

main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "adc.h"
#include "key.h"
#include "LCD1602.h"
#include "fan.h"
#include "beep.h"


uint16_t adc_result = 0;

int main(void)
{
    float smoke_value = 0;
    float limit_value = 1.0;
    uint8_t key_num = 0;
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    led_init();//初始化led灯
    uart1_init(115200);
    //adc
    adc_dma_init();
    key_init();
    lcd1602_init();
    beep_init();
    fan_init();
    printf("hello world!\r\n");
    
    lcd1602_show_line(1,1,"Smoke:   0.0 V");
    lcd1602_show_line(2,1,"Limit: - 1.0 +");
    
    while(1)
    { 
        key_num = key_scan();
        if(key_num == 1)
            limit_value +=0.1;
        else if(key_num == 2)
            limit_value -=0.1;
        //通过按键更改阈值
        lcd1602_display_limit(limit_value);
        
        smoke_value = adc_get_smoke();
        lcd1602_display_smoke(smoke_value);
        //判断smoke_value的值是不是大于limit_value
        //判断烟雾的值是不是大于我们限定的值
        if(smoke_value > limit_value)
        {
            beep_ON();
            fan_ON();
        }
        else
        {
            beep_OFF();
            fan_OFF();
        }
    }
}

LCD1602.c

adc.c

#include "adc.h"

DMA_HandleTypeDef dma_handle = {0};//DMA的句柄
ADC_HandleTypeDef adc_handle = {0};//ADC的句柄

uint16_t adc_value = 0;

//初始化ADC函数
void adc_config(void)
{
    adc_handle.Instance = ADC1;//基地址
    adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;//数据右对齐
    adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE;//要不要扫描?不需要扫描
    adc_handle.Init.ContinuousConvMode = ENABLE;//连续模式?连续转换模式
    adc_handle.Init.NbrOfConversion = 1;//转换个数?1个
    adc_handle.Init.DiscontinuousConvMode = DISABLE;//间断模式?不间断模式
    adc_handle.Init.NbrOfDiscConversion = 0;//间断个数0
    adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;//触发方式:软件触发
    HAL_ADC_Init(&adc_handle);
    
    HAL_ADCEx_Calibration_Start(&adc_handle);//ADC校准
}
//初始化msp函数
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    if(hadc->Instance == ADC1)//判断是不是ADC1
    {
        RCC_PeriphCLKInitTypeDef adc_clk_init = {0};//ADC时钟句柄
        GPIO_InitTypeDef gpio_init_struct = {0};//GPIO的句柄
        
        __HAL_RCC_ADC1_CLK_ENABLE();//打开ADC1的时钟
        __HAL_RCC_GPIOB_CLK_ENABLE();//打开GPIO口的时钟
        
        gpio_init_struct.Pin = GPIO_PIN_0;//引脚
        gpio_init_struct.Mode = GPIO_MODE_ANALOG;//模式:虚拟量的输入
        HAL_GPIO_Init(GPIOB, &gpio_init_struct);
        
        adc_clk_init.PeriphClockSelection = RCC_PERIPHCLK_ADC;//外设的时钟选择:ADC
        adc_clk_init.AdcClockSelection = RCC_ADCPCLK2_DIV6;//分频?6分频
        HAL_RCCEx_PeriphCLKConfig(&adc_clk_init);//ADC时钟初始化函数
    }
}
void dma_config(void)
{
    __HAL_RCC_DMA1_CLK_ENABLE();
    dma_handle.Instance = DMA1_Channel1;//通道1
    dma_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;//外设到内存
    
    //内存相关配置
    dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;//半字对齐
    dma_handle.Init.MemInc = DMA_MINC_ENABLE;//内存增量失能模式
    
    //外设相关配置
    dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;//半字对其
    dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;//内存增量失能模式
    
    dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;//DMA优先级
    dma_handle.Init.Mode = DMA_CIRCULAR;//模式:循环搬运模式
    HAL_DMA_Init(&dma_handle);
    //这行代码的作用是将ADC的句柄(adc_handle)与DMA的句柄(dma_handle)关联起来
    __HAL_LINKDMA(&adc_handle, DMA_Handle, dma_handle);//当ADC完成数据采集时,数据可以直接通过DMA传输到指定的内存地址,而不需要CPU的干预。
}
//通道配置的函数
void adc_channel_config(ADC_HandleTypeDef* hadc, uint32_t ch, uint32_t rank, uint32_t stime)
{
    //
    ADC_ChannelConfTypeDef adc_ch_config = {0};
    
    adc_ch_config.Channel = ch;//指定通道-外界传进来
    adc_ch_config.Rank = rank;//序列-外界传进来
    adc_ch_config.SamplingTime = stime;//取样时间-外界传进来
    HAL_ADC_ConfigChannel(hadc, &adc_ch_config);//通道配置
}
//adc dma 初始化函数
void adc_dma_init(void)
{
    adc_config();
    //adc句柄,通道,序列号,ADC采样的时间
    adc_channel_config(&adc_handle, ADC_CHANNEL_8, ADC_REGULAR_RANK_1, ADC_SAMPLETIME_239CYCLES_5);
    dma_config();
    //启动adc,ADC转化完的数据通过DMA搬运出来,从ADC外设传输到存储器的长度
    HAL_ADC_Start_DMA(&adc_handle, (uint32_t *)&adc_value, 1);//mar是目标缓冲区的地址
}
//定义一个函数:把获取电压的值给返回出来
float adc_get_smoke(void)
{
    return (float)adc_value / 4096 * 3.3;
}

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

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

相关文章

【Linux】记录一下考RHCE的学习过程(七)

年底了,公司接的北京地铁轨道交通的项目做不完了,一百多列地铁的设备都得调,派我出差了几周,这几天才回来,出差累死了实在是没办法更新。(YOASOBI的二开票还没抢到ToT,哭死,看看回滚…

[读书日志]从零开始学习Chisel 第六篇:Scala面向对象编程——特质(敏捷硬件开发语言Chisel与数字系统设计)

3.4特质 3.4.1什么是特质 特质使用trait开头,它与单例对象很像,两者都不能有输入参数,但单例对象是具体的,特质是抽象的。两者都不能用new实例化,类,单例对象,特质三者内部都可以包含字段和方…

VuePress2配置unocss的闭坑指南

文章目录 1. 安装依赖:准备魔法材料2. 检查依赖版本一定要一致:确保魔法配方准确无误3. 新建uno.config.js:编写咒语书4. 配置config.js和client.js:完成仪式 1. 安装依赖:准备魔法材料 在开始我们的前端魔法之前&…

游戏引擎学习第77天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾昨天的 bug 今天我们继续开发进度,进行调试昨天代码的问题,主要是关于如何跟踪玩家和敌人在世界中的高度位置。虽然我们做的是一款 2D 游戏,但我们希望能够处理多层的房间,玩家…

uniapp结合movable-area与movable-view实现拖拽功能2

前言 上篇我们写了&#xff0c;固定高度的拖拽&#xff0c;这篇我们将进行不固定高度的拖拽模块编写完成。 开始 一、初始化 我们在list数组里面增加一个data的动态数组&#xff0c;这样可以动态改变元素的高度。 当前元素y 上一个元素的高度 <template><view s…

ubuntu为Docker配置代理

终端代理 我们平常在ubuntu终端中使用curl或git命令时&#xff0c;往往会很慢。 所以&#xff0c;首先需要给ubuntu终端环境添加代理。 查看自身那个软件的端口号&#xff0c;我这里是7890。 sudo gedit ~/.bashrcexport http_proxyhttp://localhost:7890 export https_pr…

【Uniapp-Vue3】v-if条件渲染及v-show的选择对比

如果我们想让元素根据响应式变量的值进行显示或隐藏可以使用v-if或v-show 一、v-show 另一种控制显示的方法就是使用v-show&#xff0c;使用方法和v-if一样&#xff0c;为true显示&#xff0c;为false则不显示。 二、v-if v-if除了可以像v-show一样单独使用外&#xff0c;还…

wujie无界微前端框架初使用

先说一下项目需求&#xff1a;将单独的四套系统的登录操作统一放在一个入口页面进行登录&#xff0c;所有系统都使用的是vue3&#xff0c;&#xff08;不要问我为啥会这样设计&#xff0c;产品说的客户要求&#xff09; 1.主系统下载wujie 我全套都是vue3&#xff0c;所以直接…

C语言 数组编程练习

1.将数组A的内容和数组B中的内容进行交换。&#xff08;数组一样大&#xff09; 2.创建一个整形数组&#xff0c;完成对数组的操作 实现函数Init()初始化数组全为0 实现print()打印数组的每个元素 实现reverse()函数完成数组元素的逆置 //2.创建一个整形数组&#xff0c;完…

【three.js】模型-几何体Geometry,材质Material

模型 在现实开发中&#xff0c;有时除了需要用代码创建模型之外&#xff0c;多数场景需要加载设计师提供的使用设计软件导出的模型。此时就需要使用模型加载器去加载模型&#xff0c;不同格式的模型需要引入对应的模型加载器&#xff0c;虽然加载器不同&#xff0c;但是使用方式…

MySQL和Hive中的行转列、列转行

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 MySQL1.行转列2.列转行 Hive1.行转列2.列转行(1)侧窗(2)union MySQL 1.行转列 把多行转成列。直接group&#xff0c;sum(if()) 2.列转行 Hive 1.行转列 select name,sum(if(kmshuxu…

unity学习8:unity的基础操作 和对应shortcut

目录 1 unity的基础操作的工具&#xff0c;就在scene边上 1.1 对应shortcut快捷键 2 物体的重置/ 坐标归到0附近 3 F&#xff1a;快速找到当前gameobject 4 Q&#xff1a;小手和眼睛&#xff0c;在场景中移动 5 W&#xff1a;十字箭头&#xff0c;移动gameobject 6 …

对话|全年HUD前装将超330万台,疆程技术瞄准人机交互“第一屏”

2024年&#xff0c;在高阶智驾进入快速上车的同时&#xff0c;座舱人机交互也在迎来新的增长点。Chat GPT、AR-HUD、车载投影等新配置都在带来新增量机会。 高工智能汽车研究院监测数据显示&#xff0c;2024年1-10月&#xff0c;中国市场&#xff08;不含进出口&#xff09;乘用…

Openwrt @ rk3568平台 固件编译实践(二)- ledeWRT版本

目录 ledeWRT介绍固件编译下载代码修改feed源更新并安装编译第三方软件包制作用于eMMC烧写的rootfs基于lede发行版验证烧写rk3568.img, LEDE wrt启动成功refhttps://blog.csdn.net/zc21463071/article/details/106751361介绍rk3568平台下, lede 大神版 openwrt固件的下载、编译…

【Unity3D】Text文本文字掉落效果

相关技术&#xff1a;Text、TextMesh、Rigidbody&#xff08;刚体&#xff09;、BoxCollider&#xff08;碰撞体&#xff09;、TextGenerator、文本网格、文字网格 原理&#xff1a;使用UGUI Text获取其文字的每个字符网格坐标&#xff0c;转世界坐标生成对应的3D文本(TextMesh…

Spring Boot教程之四十九:Spring Boot – MongoRepository 示例

Spring Boot – MongoRepository 示例 Spring Boot 建立在 Spring 之上&#xff0c;包含 Spring 的所有功能。由于其快速的生产就绪环境&#xff0c;使开发人员能够直接专注于逻辑&#xff0c;而不必费力配置和设置&#xff0c;因此如今它正成为开发人员的最爱。Spring Boot 是…

el-table-fixed滚动条被遮挡导致滚动条无法拖动

/* 设置默认高度-滚动条高度 */ .el-table__fixed { height: calc(100% - 16px) !important; } .el-table__fixed {height: calc(100% - 16px) !important; } .el-table__fixed:before {height: 0px; }

探索大型语言模型新架构:从 MoE 到 MoA

探索大型语言模型新架构&#xff1a;从 MoE 到 MoA 当前&#xff0c;商业科技公司纷纷投身于一场激烈的竞赛&#xff0c;不断扩大语言模型的规模&#xff0c;并为其注入海量的高质量数据&#xff0c;试图逐步提升模型的准确性。然而&#xff0c;这种看似顺理成章的发展路径逐渐…

【通识安全】煤气中毒急救的处置

1.煤气中毒的主要症状与体征一氧化碳中毒&#xff0c;其中毒症状一般分为轻、中、重三种。 (1)轻度&#xff1a;仅有头晕、头痛、眼花、心慌、胸闷、恶心等症状。如迅速打开门窗&#xff0c;或将病人移出中毒环境&#xff0c;使之吸入新鲜空气和休息&#xff0c;给些热饮料&am…

分享:osgb倾斜数据转cesium-3dtiles 小工具.

背景: 很多知识殊途同归,在三维软件这块,少不了要和各种各样的数据格式打交道.osgb,stl,obj,3dtiles,3ds等等..虽然里面本质核心基本都是几何数据拓扑数据材质纹理数据等等,但是由于其组织方式不同和特殊的应用场景,导致很多模型需要转来转去...相信很多人在这方面都或多或少吃…