文章目录
- 前言
- 一、ADC转换
- 1.介绍
- 2.实现
- 二、光敏电阻
- 1.模块介绍
- 2.功能实现
- 二、MQ系列气体传感器
- 1.模块介绍
- 2.功能实现
- 三、 DHT11温湿度传感器
- 四、 主函数实现
- 总结
前言
这部分主要介绍系统的采集端组成,这里有用到几种传感器,DHT11温湿度传感器,MQ系列气体采集传感器,光敏电阻(用来测量光照强度的),主要用来监测家庭居住环境的相关环境参数。
一、ADC转换
1.介绍
-
AD转换是把离散的模拟量转换为数字量的过程,其原理就是使用单片机的高频率和时钟来采样x轴的点样,根据电压的变化使用曲线函数来获取y轴数字值的过程,我们叫做AD转换。
-
ADC模块读到的数据是12位的数据,STM32读到的ADC值,是从0到4095(111111111111)。当把ADC引脚接了GND,读到的就是0;当把ADC引脚接了VCC,读到的就是4095。单片机在进行AD转换前需要先设置一个参考电压。假如把参考电压设置为5V,5V=4095,0V=0;根据这样的关系,就可以把模拟电压进行数字化了。比如:2V=2/5*4095=1638
-
STM32将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。规则通道相当于你正常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。
下面是ADC通道所使用的引脚:
2.实现
用ADC1的通道采集外部电压值
- 开启PA口时钟和ADC1时钟,设置PA1为模拟输入。调用函数:GPIO_Init();APB2PeriphClockCmd();
- 复位ADC1,同时设置ADC1分频因子。调用函数:ADC_DeInit(ADC1);RCC_ADCCLKConfig(RCC_PCLK2_Div6);
- 初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息。调用函数:void ADC_Init();
- 使能ADC并校准。调用函数:ADC_Cmd();
- 配置规则通道参数。调用函数:ADC_RegularChannelConfig();
- 开启软件转换:ADC_SoftwareStartConvCmd(ADC1);
- 等待转换完成,读取ADC值。调用函数:ADC_GetConversionValue(ADC1)。
/**************************************************************************
函数名: ADC1_Init(void)
函数功能:ADC初始化函数
入口参数:无
返回 值:无
**************************************************************************/
//初始化ADC
void ADC1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;/* 1.时钟配置 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启PA口的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启ADC1的时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6); 配置ADC时钟为PCLK2的分频因子6,72M/6=12,ADC最大时间不能超过14M/* 2.GPIO配置 */ //用作ADC采集的IO必须没有复用,否则采集电压会有影响GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入 GPIO_Init(GPIOA, &GPIO_InitStructure); /* 3.ADC配置 */
// ADC_DeInit(ADC1); //复位ADC1 //将外设 ADC1 的全部寄存器重设为缺省值ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 只使用一个ADC,属于独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE; //非扫描模式,多通道才要,单通道不需要ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件触发转换ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 转换结果右对齐ADC_InitStructure.ADC_NbrOfChannel = 1; // 转换通道1个ADC_Init(ADC1,&ADC_InitStructure); //初始化ADC1//ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器ADC_Cmd(ADC1,ENABLE); // 开启ADC1 ,并开始转换ADC_ResetCalibration(ADC1); //使能复位校准while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准结束ADC_StartCalibration(ADC1); //开启AD校准while(ADC_GetCalibrationStatus(ADC1));//等待校准结束}
//获取某个通道的值
u16 get_Adc_Value(u8 ch)//通道一采样值 光照强度ADC_Channel_4
{ //ADC转换器 通道号 采样顺序 采样时间ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5); // 配置 ADC 通道转换顺序和采样时间,ADC1,ADC通道1,采样时间为239.5个周期 ADC_SoftwareStartConvCmd(ADC1,ENABLE); //使能指定的ADC的软件转换功能,我们的是ADC1 while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); //检测软件转换是否完成return ADC_GetConversionValue(ADC1); //返回最后一次读到的AD值。最近一次规则组的转换结果
}
对于读取的模拟量肯定要进行滤波,不然模拟量变化过快无法使用。滤波的作用就是减少噪声与干扰对数据测量的影响。中值滤波的思路就是取一段时间内读取到的数据中间值,可以有效的消去异常值。
//中值平均滤波
#define N 20 //采样个数u16 ADC1_ReadData(u8 ch)
{u16 sum=0;u16 ADC1_ValueBuf[N];for(u8 i=0;i<N;i++){ADC1_ValueBuf[i] = get_Adc_Value(ch);}//从小到大排列(冒泡法)for(u8 j=0;j<N-1;j++) // 趟数 {for(u8 i=0;i<N-1-j;i++) // 一趟比较的次数 {if(ADC1_ValueBuf[i]>ADC1_ValueBuf[i+1]) // 把最大值往后放 {//交换 u16 temp;temp = ADC1_ValueBuf[i];ADC1_ValueBuf[i] = ADC1_ValueBuf[i+1];ADC1_ValueBuf[i+1] = temp;}}}for(u8 i=2;i<N-2;i++) // 去掉最低两位与最高两位{sum+=ADC1_ValueBuf[i];}return sum/(N-4); // 求平均值
}//获取某个通道给定次数采样平均值
u16 ADC_Get_Average(u8 ch,u8 times)
{u32 temp_val=0;u8 t;for(t=0;t<times;t++){temp_val+=get_Adc_Value(ch);delay_ms(5);}return temp_val/times;//得到平均值
}
二、光敏电阻
1.模块介绍
光敏电阻模块的原理图
光敏电阻内部就是一个PN结,光的强弱会引起其导通的变化,从而会引起电流的变化;电路设计方面,主要是利用电流的变化,然后在串联一个电阻,就可以转换成电压的变化,然后在利用ADC来采集电压的变化进行处理。同时光线与电压值成反比。
2.功能实现
//读取光照 0~100 0:最暗;100:最亮;
u16 Light_Data(void)//光照
{u16 ad;
// ad=ADC_Get_Average(ADC_Channel_4,20);ad=ADC1_ReadData(4);ad=(4095-ad)*100/4095;return ad;
}
二、MQ系列气体传感器
1.模块介绍
MQ2是MQ传感器系列中最常用的气体传感器之一。它是一种金属氧化物半导体(MOS)型气体传感器,也称为化学传感器,因为检测是基于当气体与材料接触时感测材料的电阻变化。使用简单的分压器网络,可以检测到气体浓度。
这里用到的是MQ2烟雾传感器,MQ7一氧化碳传感器,MQ135空气质量传感器。
2.功能实现
u16 MQ7_Data(void)//一氧化碳
{u16 ad;ad=ADC_Get_Average(ADC_Channel_5,20); ad=ad*3.3/4095;return ad;
}u16 MQ135_Data(void)//空气质量
{u16 ad;float volt;ad = ADC_Get_Average(ADC_Channel_6,20);volt = ad*3.3/4095;ad = pow((3.4880*10*volt)/(5-volt),(1.0/0.3203));return ad;
}u16 MQ2_Data(void)//烟雾 //丁烷300-5000ppm
{u16 ad;ad=ADC_Get_Average(ADC_Channel_7,20);
// ad=ADC1_ReadData(7);ad=ad*3.3/4095;return ad;
}
三、 DHT11温湿度传感器
/** 一次完整的数据传输为40bit,高位先出* 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{ /*输出模式*/DHT11_Mode_Out_PP();/*主机拉低*/DHT11_Dout_0;/*延时18ms*/delay_ms(18);/*总线拉高 主机延时30us*/DHT11_Dout_1; delay_us(30); //延时30us/*主机设为输入 判断从机响应信号*/ DHT11_Mode_IPU();/*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/ if(DHT11_Dout_IN()==Bit_RESET) {/*轮询直到从机发出 的80us 低电平 响应信号结束*/ while(DHT11_Dout_IN()==Bit_RESET);/*轮询直到从机发出的 80us 高电平 标置信号结束*/while(DHT11_Dout_IN()==Bit_SET);/*开始接收数据*/ DHT11_Data->humi_int= DHT11_ReadByte();DHT11_Data->humi_deci= DHT11_ReadByte();DHT11_Data->temp_int= DHT11_ReadByte();DHT11_Data->temp_deci= DHT11_ReadByte();DHT11_Data->check_sum= DHT11_ReadByte();/*读取结束,引脚改为输出模式*/DHT11_Mode_Out_PP();/*主机拉高*/DHT11_Dout_1;/*检查读取的数据是否正确*/if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)return SUCCESS;else return ERROR;}elsereturn ERROR;}
四、 主函数实现
u8 buff[30];//参数显示缓存数组
DHT11_Data_TypeDef Dht_Data; //温湿度
u16 light, mq2, mq7, mq135;//光照、烟雾、CO、空气ADC1_Init(); //ADC初始化
DHT11_Init(); //初始化DTT11
/*************************************************************
* 函数名称: Get_Data()
*
* 函数功能: 获取传感器数据
*
* 入口参数: 无
*
* 返回参数: 无
*************************************************************/
void Get_Data(void)//获取传感器数据
{DHT11_Read_TempAndHumidity(&Dht_Data);light = Light_Data();mq2 = MQ2_Data();mq7 = MQ7_Data();mq135 = MQ135_Data();
}
总结
就是对采集端所使用的传感器做一个简单的说明,为以后的系统整合做准备。