炒冷饭系列-STM32F103之光敏传感器
作者:互联网
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
void myLseorInit(void);
u16 myLseorHandler(u8 ch);
u16 LseorcArc(u8 ch,u8 time);
int main(void)
{
u8 lightval=0;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
KEY_Init();
LCD_Init();
myLseorInit();
LCD_ShowString(30,130,200,16,16,"LSENS_VAL:");
while(1)
{
lightval=LseorcArc(6,20);
LCD_ShowxNum(30+10*8,130,lightval,3,16,0);//显示 ADC 的值
LED0=!LED0;
delay_ms(250);
}
}
//利用 ADC3 的通道 6(PF8)来读取光敏二极管电压的变化
void myLseorInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStruct;
//1) 开启 PF 口时钟和 ADC3 时钟,设置 PF8 为模拟输入。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);//使能ADC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);//使能GPIO时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PA8 为模拟输入。
GPIO_Init(GPIOF, &GPIO_InitStructure);//
//2) 复位 ADC1,同时设置 ADC1 分频因子
ADC_DeInit(ADC3);
//ADC最大转换频率为1MHz,对应的最大转换时间就是1us
// ADC 的转换时间公式=Tcovn=采样时间+12.5个周期
// ADCCLK=14Mhz 的时候,设置 1.5 个周期的采样时间,则得到: Tcovn=1.5+12.5=14 个周
//期=1us。
//APB2对应的时钟频率是72MHz,分频因子要确保 ADC1 的时钟(ADCCLK)不超过14Mhz。
//6分频之后72/6=12Mhz,所以ADC的频率是12Mhz
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//3) 初始化 ADC1 参数, 设置 ADC1 的工作模式以及规则序列的相关信息。
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//ADC 工作模式:独立模式
ADC_InitStruct.ADC_ScanConvMode=DISABLE;//AD 单通道模式
ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//AD 单次转换模式
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//ADC 数据右对齐ADC_DataAlign_Right,左对齐会咋样?ADC_DataAlign_Left
ADC_InitStruct.ADC_NbrOfChannel=1;//顺序进行规则转换的 ADC 通道的数目 1
ADC_Init(ADC3, &ADC_InitStruct);
//4) 使能 ADC 并校准。
//执行复位校准和 AD 校准,注意这两步是必须的!不校准将导致结果很不准确。
ADC_Cmd(ADC3,ENABLE);//使能 ADC
ADC_ResetCalibration(ADC3);//复位校准
ADC_StartCalibration(ADC3);//AD 校准
//记住,每次进行校准之后要等待校准结束。 这里是通过获取校准状态来判断是否校准是否结束
//一旦校准结束, CAL位被硬件复位 校准状态复位完成的返回值是0,
while(ADC_GetResetCalibrationStatus(ADC3));//等待复位校准完成 为0时退出while
while(ADC_GetCalibrationStatus(ADC3));//等待AD 校准完成
}
//返回 ADC 值
//ch:通道值6
u16 myLseorHandler(u8 ch)
{
//5) 设置规则通道6的参数
//ADC3的通道6,Rank:规则顺序中的第一个转换1,ADC_SampleTime:采样周期要大于17.1us
ADC_RegularChannelConfig(ADC3, ch, 1,ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC3,ENABLE);//使能指定的 ADC3 的软件转换启动功能
while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC3);//获取转换 ADC 转换结果数据,16位里面含有12位,右对齐,高位对齐
}
//读取 Light Sens 的值
//0~100:0,最暗;100,最亮
u16 LseorcArc(u8 ch,u8 time)
{
u8 i=0;
u32 adc_value=0;
for(i=0;i<time;i++)
{
adc_value+=myLseorHandler(ch);
delay_ms(10);
}
adc_value/=time;//取平均值
if(adc_value>4000)
{
adc_value=4000;//12位最大值是4096,去掉96,有点小误差,
}
adc_value=(100-(adc_value/40));//(adc_value/40)为了让取值范围在0-100,100-(adc_value/40)光线越强,电压值越低
return (u8)adc_value;
}
标签:STM32F103,校准,炒冷饭,value,ADC3,光敏,GPIO,adc,ADC 来源: https://blog.csdn.net/chenyouledashen/article/details/120683365