STM32固件库案例 您所在的位置:网站首页 烟雾检测模块 STM32固件库案例

STM32固件库案例

2024-05-24 04:40| 来源: 网络整理| 查看: 265

STM32固件库案例——串口、7针脚OLED显示MQ135烟雾传感器

本章基于本人前面发的SPI驱动7针脚OLED屏幕文档。加入通过ADC模块对MQ135烟雾传感器的数值进行采样并在OLED上显示以及串口上打印。 一、MQ135烟雾传感器模块 正面: 在这里插入图片描述

背面 在这里插入图片描述

接线: 烟雾模块  STM32开发板 AO —— PA0 VCC —— 3.3V GND —— GND 二、ADC模块介绍: ADC模块中文名为模拟/数字转换器,是12位逐次逼近型的模拟数字转换器,一般用于数值的采样,比如我最近在做一个示波器,那么就需要对信号进行采样,这就需要用到ADC模块。 将ADC模块与自己定义的引脚相连,再用该引脚去接入所要测试的地方,ADC模块便可以经过换算得到所要测试部位的电位。 三、ADC配置库函数解读: 1、初始化函数ADC_Init

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)

功能:

typedef struct { uint32_t ADC_Mode; //将ADC配置为独立或操作双模式。 FunctionalState ADC_ScanConvMode;//执行转换Scan(多通道)或Single(单通道)模式,可设置为“ENABLE”或“DISABLE” */ FunctionalState ADC_ContinuousConvMode; //执行转换连续或单模。可设置为“ENABLE”或“DISABLE” uint32_t ADC_ExternalTrigConv; //定义用于启动模拟的外部触发器对常规信道进行数字转换 uint32_t ADC_DataAlign; //指定ADC数据是左对齐还是右对齐。 uint8_t ADC_NbrOfChannel; //指定要转换的ADC通道的数量使用顺序器为常规通道组。取值范围为1 ~ 16 }ADC_InitTypeDef;

ADC结构体配置如下(本次为单通道模数转换):

ADC_InitTypeDef ADC_InitStructure; //定义ADC结构体 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC独立模式 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件启动 ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道数目 ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC1外设 ADC_Cmd(ADC1, ENABLE); //使能ADC1

ADC的通道相对应的引脚做一个补充,如下图: 在这里插入图片描述

四、下面为ADC模块的整体代码, ADC.c文件

#include "stm32f10x.h" // Device header void Adc_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1通道时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA通道时钟 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子这里为6分频 GPIO_InitTypeDef GPIO_InitStructure; //定义结构体 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA.0引脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz  GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化gpioa ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//ADC1,通道0(GPIOA.0),采样顺序为1,采样周期为55.5个周期 ADC_InitTypeDef ADC_InitStructure; //定义ADC结构体 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC独立模式 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件启动 ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道数目 ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC1外设 ADC_Cmd(ADC1, ENABLE); //使能ADC1 ADC_ResetCalibration(ADC1); //开启复位校准 while (ADC_GetResetCalibrationStatus(ADC1) == SET); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while (ADC_GetCalibrationStatus(ADC1) == SET); //等待校准结束 } uint16_t Adc_GetValue(void) { ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能软件转换功能   while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //等待转换结束 return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果 }

ADC.h文件

#ifndef __ADC_H #define __ADC_H void Adc_init(void); uint16_t Adc_GetValue(void); #endif

五、串口打印数据 我们需要导入我们的USART函数 用printf串口打印接收到的数值我们需要在串口代码中加入串口重定向

int fputc(int ch,FILE *f) { Usart_SendByte(ch); return ch; }

main.c文件

uint16_t ADValue; float Voltage; int main(void) { Usart_Init(); Adc_init(); NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 OLED_Init(); //初始化OLED OLED_Clear(0); //清屏(全黑) while (1) { ADValue = Adc_GetValue(); Voltage = (float)ADValue / 4095 * 3.3; // GUI_ShowCHinese(0,20,16,"数值:",1); // GUI_ShowNum(30,20,ADValue,6,16,1);//oled显示数字 printf("检测到的数值为 %d, 转换后的电压值为: %.1f V\n", ADValue, Voltage); Delay_ms(1000); } }

结果展示: 在这里插入图片描述

6、7针脚OLED显示数值

显示中文(GUI_ShowCHinese) x:中文字符串的起始x坐标 y:中文字符串的起始y坐标 hsize:中文字符串的大小 *str:中文字符串的起始地址 模式: 0-白底黑字,1-黑底白字 void GUI_ShowCHinese(u8 x,u8 y,u8 hsize,u8 *str,u8 mode) { while(*str!='\0') { if(hsize == 16) { GUI_ShowFont16(x,y,str,mode); } else if(hsize == 24) { GUI_ShowFont24(x,y,str,mode); } else if(hsize == 32) { GUI_ShowFont32(x,y,str,mode); } else { return; } x+=hsize; if(x>WIDTH-hsize) { x=0; y+=hsize; } str+=2; } }

显示数值(GUI_ShowNum)

x: 数字的开始坐标x Y: 数字的起始Y坐标 num: (0 ~ 4294967295) Len: 显示号的长度 大小: 显示编号的大小 模式: 0-白底黑字,1-黑底白字 void GUI_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 Size,u8 mode) { u8 t,temp; u8 enshow=0,csize; if(Size == 16) { csize = Size/2; } else if(Size == 8) { csize = Size/2+2; } else { return; } for(t=0;t if(temp==0) { GUI_ShowChar(x+csize*t,y,' ',Size,mode); continue; }else enshow=1; } GUI_ShowChar(x+csize*t,y,temp+'0',Size,mode); } }

main.c

int main(void) { Usart_Init(); Adc_init(); NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 OLED_Init(); //初始化OLED OLED_Clear(0); //清屏(全黑) while (1) { ADValue = Adc_GetValue(); Voltage = (float)ADValue / 4095 * 3.3; GUI_ShowCHinese(0,20,16,"数值:",1); GUI_ShowNum(30,20,ADValue,6,16,1);//oled显示数字 // printf("检测到的数值为:%d 电压值为:%.1fV\n", ADValue, Voltage); Delay_ms(1000); } }

最后效果图 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

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