opt101在stm32上如何实现,能否给出代码参考,原理是什么,是用adc转化读取电压值嘛?
请参考自己开发板的硬件电路,没有下面的电路,可以找一个可调的电源接到引脚上(注意电压要小于3,3V)
问题解答:
opt101光电传感器的实现方式:opt101光电传感器可以通过使用ADC转化来实现。
opt101光电传感器的原理:opt101光电传感器是一种光电二极管,通过光电二极管将光转化为电流,并通过放大驱动电路产生一个输出电压。所以可以通过ADC转化来读取光电二极管输出的电压来获得光线的强度。
相应的代码参考:
adc.c:
void ADC_init(void)
{
GPIO_InitTypeDef ADC_GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStruct;// 结构体的定义需要先于RCC的开启,否者报警告
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
// 由于ADC的最大时钟不超过14MHz,所以需要把时钟降下来。
// ADC时钟分频器;六分频;时钟从APB2总线来,最大为72MHz,所以需要六分频后12MHz。
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
// 初始化ADC1,光电流模块输入引脚为PA4
ADC_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;// 模拟输入
ADC_GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN; // 由于是输入模式,所以不需要配置Speed.
GPIO_Init(ADC_GPIO_PORT, &ADC_GPIO_InitStructure);
ADC_InitStruct.ADC_ScanConvMode = DISABLE;//扫描多通道还是单通道?单通道。
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;// 连续转换还是单次转换?连续。
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;// 数据对齐方式。右对齐。
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//定义用于启动模拟的外部触发器到常规频道的数字转换。
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//将ADC配置为独立还是多模?
ADC_InitStruct.ADC_NbrOfChannel = 1;//通道数量
ADC_Init(ADC1, &ADC_InitStruct);
// ADC规则组配置
ADC_RegularChannelConfig(ADC1,ADC_GPIO_CHANNEL,1,ADC_SampleTime_71Cycles5);
// ADC1,通道0
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);//对ADC进行复位
while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC复位完成
ADC_StartCalibration(ADC1);//校验ADC
while(ADC_GetCalibrationStatus(ADC1));//等待ADC校验完成
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启ADC的软件触发
}
// 获取转化后的值
float ADC_GetValue(void)
{
uint32_t Value = 0;
float ret = 0.0;
for(uint8_t i = 0;i < 30;i++)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//转换结束标志, 转换完成该标志就清零
Value += ADC_GetConversionValue(ADC1);
}
Value /= 30; // 这里求的是平均值
ret = 30.303 * (3.3 - Value *(3.3/4095));
// 整体上表示模数转换后的光度;4095表示12为的ADC的精度(不能变);
// 3.3表示这个引脚最大承受电压
return ret;
}
main.c:
#include "stm32f10x.h"
#include "adc.h"
int main(void)
{
float value;
//初始化ADC
ADC_init();
while(1)
{
value = ADC_GetValue();
if (value < 0.001)
value = 0;
printf("Value = %.3f\n", value);
}
}
需要注意的是,其中的GPIO引脚等需要根据自己的硬件连接来修改。
代码中的ADC_GetValue()函数可以读取光电二极管的输出电压,并转化为对应的光线强度值。ADC_GetValue()函数中的30.303是由3.3V对应的最大光强值100除以3.3V得到的。
希望可以帮到您!