ADC實驗之光敏感測器

2020-10-03 12:01:43

ADC實驗之光敏感測器

硬體連線

 

我們可以測量A的電位,進而測量光的強度,光強與A點電壓的對應關係如下:

 

電流反應的光敏二極體的導通狀態,光強與電流對應關係如下:

 

因此,我們可以得出ADC讀取的電壓值的數位量(12位元)與光照強度的關係:

 

軟體設定(採用單通道單次轉換的ADC)

Main.c

#include "stm32f10x.h"
#include "delay.h"
#include "lcd.h"
#include "usart.h"
#include "LightSensor.h"

int main()
{
	u8 LightSensor = 0;
	
	delay_init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	LightSensor_InitConfig();
	uart_init(115200);
	LCD_Init();
	
	while(1)
	{
		LightSensor = DigitalConvLight();
		printf("LightSensor = %d\n",LightSensor);
		LCD_ShowNum(10,10,LightSensor,4,16);
		delay_ms(50);
	}
}

 

LightSensor.c

#include "LightSensor.h"
#include "stm32f10x.h"
#include "delay.h"

void LightSensor_InitConfig()
{
	ADC_InitTypeDef ADC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3|RCC_APB2Periph_GPIOF,ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOF,&GPIO_InitStructure);
	
	ADC_DeInit(ADC3); // ADC3復位
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6); // ADC正常工作的頻率<=14MHz
	
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_Init(ADC3,&ADC_InitStructure); // 設定ADC3的屬性
	
	ADC_Cmd(ADC3,ENABLE); // 設定完ADC3的屬性就使能ADC3
	
	ADC_ResetCalibration(ADC3);
	
	while(ADC_GetResetCalibrationStatus(ADC3) == SET); // 當函數返回為SET說明還在復位校準當中,當退出復位校準後函數返回RESET
	
	ADC_StartCalibration(ADC3);
	
	while(ADC_GetCalibrationStatus(ADC3) == SET); // 當函數返回為SET說明還在啟動校準當中,當校準完成後函數返回RESET
}

u16 GetSingleADCValue()
{
	u16 temp = 0;
	
	ADC_RegularChannelConfig(ADC3,ADC_Channel_6,1,ADC_SampleTime_28Cycles5); // 設定ADC3_CH6規則通道的屬性
	ADC_SoftwareStartConvCmd(ADC3,ENABLE); // ADC3的規則通道開始轉換
	
	while(ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC) == RESET); // 等待ADC3_CH6規則通道轉換完成
	temp = ADC_GetConversionValue(ADC3);
	temp = temp>=4000?4000:temp;
	
	return temp;
}

u8 DigitalConvLight()
{
	u8 i = 0;
	float temp = 0;
	
	while(i<=4)
	{
		temp += GetSingleADCValue();
		i++;
	}
	temp = 100*(1 - temp/5/4000);
	
	return (u8)temp;
}

 

LightSensor.h

#ifndef _LIGHT_SENSOR_H
#define _LIGHT_SENSOR_H

#include "sys.h"

void LightSensor_InitConfig();
u16 GetSingleADCValue();
u8 DigitalConvLight();

#endif

 

疑難排解

為什麼ADC轉換的數值會大於4096?

STM32的ADC 的轉換結果可以左對齊或右對齊,結果大於4095 應該是採用了左對齊的方式。

你看一下手冊把設定暫存器的相應位設定改成右對齊應該就是你想要的了