第二十八天-光敏传感器实验
一、光敏传感器简介
二、硬件连接
1、电路图
2、电路原理
R34与LS1组成了一个分压电路,PF8测的是LSENS节点的电压值。
当无光照时,LS1的电阻非常大,此时LSENS节点电压约等于3.3v。
当光照逐渐强烈时,LS1的阻值慢慢减小,R34进行分压,LSENS节点电压变小。
总而言之,光照与所测电压成反比。
R37是一个保护电阻,避免电流过大,损坏ADC引脚。并且它也不会分压,造成测量结果不准确,因为ADC具有非常高的输入阻抗,远高于R37的电阻值。
三、实验代码
1、详细代码
①lsensor.h
#ifndef __LSENSOR_H
#define __LSENSOR_H
#include "stm32f10x.h"u8 Get_LightValue(void); //获取内部温度传感器温度值
void L_Adc_Init(void); //ADC通道初始化
u16 L_Get_Adc(u8 ch); //获得某个通道值
u16 L_Get_Adc_Average(u8 ch,u8 times);
u8 Dis_Get_LightValue(void);
#endif
②lsenor.c
#include "lsensor.h"
#include "lcd.h"
#include "delay.h"
#include "usart.h"void L_Adc_Init(void)
{//时钟使能 GPIOF ADC3RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF | RCC_APB2Periph_ADC3,ENABLE);//使能GPIOFGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOF, &GPIO_InitStruct);ADC_DeInit(ADC3);RCC_ADCCLKConfig(RCC_PCLK2_Div6);ADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;ADC_InitStruct.ADC_NbrOfChannel = 1;ADC_InitStruct.ADC_ScanConvMode = DISABLE;ADC_Init(ADC3, &ADC_InitStruct);ADC_Cmd(ADC3,ENABLE);//校验ADC_ResetCalibration(ADC3);while(ADC_GetResetCalibrationStatus(ADC3));ADC_StartCalibration(ADC3);while(ADC_GetCalibrationStatus(ADC3));}
u16 L_Get_Adc(u8 ch)
{ADC_RegularChannelConfig(ADC3,ch,1,ADC_SampleTime_239Cycles5);ADC_SoftwareStartConvCmd(ADC3,ENABLE);while(!ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC));printf("1\r\n");u16 AdcValue = ADC_GetConversionValue(ADC3);ADC_ClearFlag(ADC3, ADC_FLAG_EOC);return AdcValue;}
u16 L_Get_Adc_Average(u8 ch,u8 times)
{u32 sum = 0;for(u8 i = times;i > 0;i--){sum += L_Get_Adc(ch);delay_ms(10);}return sum / times;
}
u8 Dis_Get_LightValue(void)
{u16 Vol = L_Get_Adc_Average(ADC_Channel_6,10);if(Vol > 4000)Vol = 4000;u8 LValue = 100 - (Vol / 40);LCD_ShowNum(144,50,LValue,2,24);
}
2、代码调试
①发现无法软件触发ADC
经多轮调试,发现ADC_DeInit()在RCC_ADCCLKConfig之后,并且ADC_DeInit()会reset时钟,所以之前的时钟设置就没有意义了。
解决办法是调换位置,使设置时钟在后面。