其实一些简单的传感器模块使用的都是同一个电路,就比如光敏模块、热敏模块以及红外接收管等,用的都是图2的电路,改变的也就是电路中N1的属性,如果将热敏电阻放到N1位置上,那么就可以组成一个热敏模块。
引脚和器件说明
VCC:电源正极 3.3V—5V
GND:电源负极
DO(Digital Output):数字量输出接口
AO(Analog Output):模拟量输出接口
LED1:电源指示灯
LED2:数字量输出指示灯
LM393:在此用作电压比较器
R2:电位器(用于调节模块的灵敏度)
电路原理(以NTC热敏模块为例)
1,模拟量输出原理
由图可知,模拟输出口通过网路标签接到了R1与热敏电阻中间,此时AO口的电压为
,当NTC热敏电阻( NTC是英文Negative Temperature Coefficient的缩写。 其含义为负温度系数 。它的电阻值随温度的升高而降低。)的温度上升后,其阻值将会下降,因此热敏电阻分的电压会降低,AO口的电压也随之降低,同理可得,当热敏电阻的温度降低后,AO口的电压将会上升,其赋值将在VCC至GND之间变化。
下面给大家在STM32下接受AO口模拟量的代码
void AD_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADC分频器(CLOCK信号),72MHz/6=12MHz
GPIO_InitTypeDef GPIO_InitStruture;
GPIO_InitStruture.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStruture.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruture); //配置模拟数据输入通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //配置多路开关
ADC_InitTypeDef ADC_InitStruture;
ADC_InitStruture.ADC_Mode = ADC_Mode_Independent; //模数转换方式,ADC_Mode_Independent(独立模式):ADC1与ADC2互不干扰
ADC_InitStruture.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐方式
ADC_InitStruture.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //触发源选择,ADC_ExternalTrigConv_None(内部软件触发)
ADC_InitStruture.ADC_ContinuousConvMode = DISABLE; //连续转换模式选择,DISABLE(单次转换)
ADC_InitStruture.ADC_ScanConvMode = DISABLE; //扫描模式选择,DISABLE(非扫描模式)
ADC_InitStruture.ADC_NbrOfChannel = 1; //需要几个通道,非扫描模式只有1位有效,此时此参数无效
ADC_Init(ADC1,&ADC_InitStruture);
ADC_Cmd(ADC1,ENABLE); //开关控制
ADC_ResetCalibration(ADC1);
while((ADC_GetResetCalibrationStatus(ADC1)) == SET); //复位校准
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) == SET); //开始校准
}
uint16_t AD_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //检测标志位
return ADC_GetConversionValue(ADC1); //AD转换后得到的数值:0-4096
}
只要不断调用uint16_t AD_GetValue(void)函数,就可以接受到AO口的模拟量的值,但是这个函数返回的数值是一个整数,其数值变化范围为0—4096,如果返回为0,则代表AO的电压为0,如果为4096,则代表AO的电压为VCC,所以想要精确得到AO的电压,还需加上。
ADValue = AD_GetValue();
Voltage = (float)ADValue / 4095 * VCC; //VCC需自己定义
此时Voltage就为AO口的模拟电压值。
2、数字量输出原理
先给大家介绍一下,电压比较器工作过程,当用LM393电压比较器时,如果阳极电压大于阴极电压,那么输出将会使高电平,如果阴极电压大于阳极电压,将会输出低电平。
由图2可知,DO是LM393电压比较器的输出端,其阳极连接到了R1电阻与N1电阻之间,作被比较电压,而阴极接到了一个电位器上,作校准电压,所以当阳极的电压大于校准电压时,LM393电压比较器DO端口输出高电位,反之亦然,但是DO口本就通过电阻连接VCC,所以DO口默认输出高电位,只有当被比较电压低于校准电压时,DO口才输出低电压,此时LED2灯发光。
灵敏度调节:灵敏度调节是通过R2电位器进行调节的,当电位器端的电压调的较小时,也就是电压比较器的阴极电压比较小时,NTC热敏电阻将需要承受更高的温度,才能使阳极电压小于阴极电压,从而输出低电位。
下面给大家在STM32下接受DO口数字量的代码
void LightSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启时钟
GPIO_InitTypeDef GPIO_InitStruture;
GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU; //上拉输入模式
GPIO_InitStruture.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruture);
}
uint8_t LightSensor_Get(void)
{
return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13); //读取端口电平
}
调用uint8_t LightSensor_Get(void)函数,将返回端口的值,高电位时返回1,低电位返回0.
在这里提醒一下,因为DO口默认为高电位,因此读取时,设置IO端口为上拉输入模式是最好的。
要是觉得文章对你有帮助,那就给一个小小的赞吧。