利用论坛推广网站,装修公司前十强排名榜,一级a做爰片免费网站 新闻,ui设计培训机构哪家好一、项目需求
1. 使用 mq-2 获取环境烟雾值#xff0c;并显示在 LCD1602 上#xff1b;
2. 按键修改阈值#xff0c;并显示在 LCD1602 上#xff1b;
3. 烟雾值超过阈值时#xff0c;蜂鸣器长响#xff0c;风扇打开#xff1b;烟雾值小于阈值时#xff0c;蜂鸣器不响…一、项目需求
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.huint16_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);//adcadc_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.hDMA_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;//间断个数0adc_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;//外设的时钟选择ADCadc_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;//通道1dma_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();//启动adcADC转化完的数据通过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;
}