光敏电阻讲解
光敏电阻的电路连接图
Tr AO是光敏值的输出端,Tr DO是判断器LM393D的输出端,它是比较光敏电阻的电压和滑动变阻器电压的大小。
光敏电阻值的测量
Tr AO的跳线帽电路图为
光敏电阻的值的获取是利用ADC采集,其初始化代码为
void ADC_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// ADC1 工作模式配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
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 = 4;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_13Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
与普通的ADC代码差不多,只是选择的GPIO口不一样、ADC通道不一样等。光敏电阻的GPIO口为PA4,ADC通道为ADC_Channel_4,结构体ADC_InitStructure的元素ADC_NbrOfChannel 的值为4。
光敏值的读取代码为
u16 Read_ADC(void)
{
u16 ADC_VALUE = 0;
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
ADC_VALUE = ADC_GetConversionValue(ADC1);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
return ADC_VALUE;
}
光敏值的读取后显示代码为
tmp = Read_ADC();
snprintf((char *)str, sizeof(str), " R-P:%.2fK ", tmp/(4096.-tmp)*10);
LCD_DisplayStringLine(Line6, str);
Delay_Ms(200);
Tr DO(光敏电阻与滑动变阻器电压值比较)的跳线帽电路图为
Tr DO初始化代码为
void DO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
Tr DO判断代码为
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) == Bit_RESET)
{
LCD_DisplayStringLine(Line7, (u8*)" DO:High ");
}
else
{
LCD_DisplayStringLine(Line7, (u8*)" DO:Low ");
}
变量Bit_RESET的定义为
typedef enum
{ Bit_RESET = 0,
Bit_SET
}BitAction;
定义在stm32f10x_gpio.h文件中的第108行。
当PA3为低电平时,表示光敏电阻的电压大于滑动变阻器的电压,否则为小于滑动变阻器的电压。
ADC*2讲解
扩展板设有两个滑动变阻器,可以通过ADC采集获取他们的电压值。主要考查的是多通道ADC采集的使用方法。
ADC*2的电路图
跳线帽连接图为
ADC*2的初始化代码为
void ADC_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
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 = 2;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
与普通的ADC初始化的区别为选择的I/O口不一样、初始化的ADC通道个数和通道数不一样。ADC*2选择的是PA4和PA5,结构体ADC_InitStructure的元素ADC_NbrOfChannel 的值为2,初始化两个通道数,分别为ADC_Channel_4和ADC_Channel_5。
ADC*2的读取代码为
u16 Get_Filter(u8 channel)
{
u16 tmp;
u8 i = 0,j = 0;
for(i=0; i<ADC_BUFF_LEN; i++)
{
adc_buff[i] = Get_ADCs(channel);
}
for(i=0; i<=ADC_BUFF_LEN/2; i++)
{
for(j=0; j< ADC_BUFF_LEN-i-1; j++)
{
if(adc_buff[j+1] < adc_buff[j])
{
tmp = adc_buff[j+1];
adc_buff[j+1] = adc_buff[j];
adc_buff[j] = tmp;
}
}
}
if(ADC_BUFF_LEN % 2 == 0)
{
return(adc_buff[ADC_BUFF_LEN/2-1] + adc_buff[ADC_BUFF_LEN/2])/2;
}else
{
return(adc_buff[ADC_BUFF_LEN/2]);
}
}
其中函数的定义为
u16 Get_ADCs(u8 channel)
{
u16 ADC_Val = 0;
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
ADC_Val = ADC_GetConversionValue(ADC1);
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
return ADC_Val;
}
其参数是选择哪个ADC通道,与普通的ADC采集不同的就是需要从新初始化ADC通道。
变量ADC_BUFF_LEN的定义为
#define ADC_BUFF_LEN 50
表示对ADC采集50次,取其中的平均数。与ADC按键的做法一样。
ADC*2的显示代码为
x = Get_Filter(ADC_Channel_4);
y = Get_Filter(ADC_Channel_5);
snprintf((char *)str, sizeof(str), " VRp5:%3.2fV", x/4096.*3.3);
LCD_DisplayStringLine(Line6, str);
snprintf((char *)str, sizeof(str), " VRp6:%3.2fV", y/4096.*3.3);
LCD_DisplayStringLine(Line7, str);
Delay_Ms(200);
采用的公式与普通ADC的一样。