Stm32_标准库_8_ADC_光敏传感器_测量具体光照强度

这篇具有很好参考价值的文章主要介绍了Stm32_标准库_8_ADC_光敏传感器_测量具体光照强度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ADC简介

stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件
测量方式

stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件
采用二分法比较数据

IO通道

stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件
ADC基本结构及配置路线

stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件


获取数字变量需要用到用到光敏电阻的AO口,AO端口接在PA0引脚即可
stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件
测得的模拟数据与实际光照强度之间的关系为

光照强度 = 100 - 模拟量 / 40;

代码:

完整朴素代码:

#include "stm32f10x.h"    // Device header
#include "Delay.h"
#include "OLED.h"

GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;


void AD_Init(void){//初始化AD
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC1的时钟
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA的时钟
	   RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC模块工作时钟 72 / 6 = 12MHZ
	   
	   /*配置GPIO口*/
	   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	   GPIO_Init(GPIOA, &GPIO_InitStruct);
	   
	   /*在规则组列表第一个位置,写入通道0这个通道*/
	   ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	   /*结构体初始化ADC*/
	   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工作模式为独立模式
	   ADC_InitStruct.ADC_NbrOfChannel = 1;//通道数目
	   ADC_InitStruct.ADC_ScanConvMode = DISABLE;//非扫描
	   ADC_Init(ADC1, &ADC_InitStruct);
		 
		 //开启ADC电源
		 ADC_Cmd(ADC1, ENABLE);
		 
		 /*给ADC校准*/
		 ADC_ResetCalibration(ADC1);//复位校准
		 while(ADC_GetResetCalibrationStatus(ADC1) == SET);//返回ADC1复位校准状态
		 ADC_StartCalibration(ADC1);//开始校准
		 while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
}
 
uint16_t AD_Getvailue(void){//获取信息
	   ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发转换
	   while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//等待转换完成
	   return ADC_GetConversionValue(ADC1);//读取数据
}
 
uint16_t Reality_ADLight(uint16_t ADCnum){//获取光照强度
	  return 100 - ADCnum / 40;
}

 
int main(void){
	 
	OLED_Init();//初始化OLED
	AD_Init();
	while(1){
		    uint16_t num  = AD_Getvailue();
		    uint16_t num1 = Reality_ADLight(num); 
		    
		    OLED_ShowString(1, 1, "ADO:");
        OLED_ShowNum(1, 5, num, 5);
		    OLED_ShowString(2, 1, "LUX:");
		    OLED_ShowNum(2, 5, num1, 3);
		    Delay_ms(300);
		     
	}
}

效果:

stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件
此代码的不足之处在于每次写入数字都会提前占据固定位置,这个固定位置在整个过程是不能更改的,十分影响观感

所以添加求数字长度的函数,方便随时捕捉并调正所占空间
添加代码:

uint8_t length(uint16_t num){
	  uint8_t length = 0;
	  while(num > 0){
		   num = num / 10;
		   length = length + 1;
	  }
	  return length;
}

完整优化代码1:

#include "stm32f10x.h"    // Device header
#include "Delay.h"
#include "OLED.h"

GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;


void AD_Init(void){//初始化AD
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC1的时钟
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA的时钟
	   RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC模块工作时钟 72 / 6 = 12MHZ
	   
	   /*配置GPIO口*/
	   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	   GPIO_Init(GPIOA, &GPIO_InitStruct);
	   
	   /*在规则组列表第一个位置,写入通道0这个通道*/
	   ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	   /*结构体初始化ADC*/
	   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工作模式为独立模式
	   ADC_InitStruct.ADC_NbrOfChannel = 1;//通道数目
	   ADC_InitStruct.ADC_ScanConvMode = DISABLE;//非扫描
	   ADC_Init(ADC1, &ADC_InitStruct);
		 
		 //开启ADC电源
		 ADC_Cmd(ADC1, ENABLE);
		 
		 /*给ADC校准*/
		 ADC_ResetCalibration(ADC1);//复位校准
		 while(ADC_GetResetCalibrationStatus(ADC1) == SET);//返回ADC1复位校准状态
		 ADC_StartCalibration(ADC1);//开始校准
		 while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
}
 
uint16_t AD_Getvailue(void){//获取信息
	   ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发转换
	   while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//等待转换完成
	   return ADC_GetConversionValue(ADC1);//读取数据
}
uint8_t length(uint16_t num){
	  uint8_t length = 0;
	  while(num > 0){
		   num = num / 10;
		   length = length + 1;
	  }
	  return length;
}
uint16_t Reality_ADLight(uint16_t ADCnum){//获取光照强度
	  return 100 - ADCnum / 40;
}

 
int main(void){
	 
	OLED_Init();//初始化OLED
	AD_Init();
	while(1){
		    uint16_t num  = AD_Getvailue();
		    uint16_t num1 = Reality_ADLight(num); 
		    
		    OLED_ShowString(1, 1, "ADO:");
        OLED_ShowNum(1, 5, num, length(num));
		    OLED_ShowString(2, 1, "LUX:");
		    OLED_ShowNum(2, 5, num1, length(num1));
		    Delay_ms(300);
		    OLED_Clear();
	}
}

效果:stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件

写入数据是采用覆盖制,例如上次写入的数据是1234,本次写入的数据是999,那么此时展现的效果为9994,由于ADO取值范围为[0 ~4095],LUX(光照强度)取值范围为[1, 100],所以为了不影响数据的合理性,所以必须要在每次写入新数据时必须要清理一下OLED

但是由于提供的清屏函数每次都是将全部数据清理掉,所以画面刷新也要从新再全部刷新一次所以整体画面会不连贯

所以我写入了一个只清屏某个部分的函数
添加代码:

/* 
   直接用清屏函数整体刷新会导致OLED画面不连贯
   清除行函数:保留本行字符串,清除本行剩余部分
   row:清除的具体行
   len:不希望被清除的字符串长度
*/

void OLED_LoactionClear(uint8_t row, uint8_t len)
{  
	uint8_t i, j;
	for (j = row * 2 - 2; j < row * 2; j++)
	{
		OLED_SetCursor(j, len * 8);
		for(i = len * 8; i < 128; i++)
		{
			OLED_WriteData(0x00);
		}
	}
}

放入位置

需要将其copy到OLED.c文件下,并在OLED.h文件内声明一下
stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件
stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件
具体函数使用方法:

OLED_LoactionClear(uint8_t row, uint8_t len);
此函数有两个参数:

其中row指你想要进行清屏操作的具体行,OLED上一共能显示4行
其中len代表row行从左到右len长度区间的字符串将会被保留,row行剩余其他数据将全被清除

完整优化代码2:

#include "stm32f10x.h"    // Device header
#include "Delay.h"
#include "OLED.h"

GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;


void AD_Init(void){//初始化AD
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC1的时钟
	   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA的时钟
	   RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC模块工作时钟 72 / 6 = 12MHZ
	   
	   /*配置GPIO口*/
	   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	   GPIO_Init(GPIOA, &GPIO_InitStruct);
	   
	   /*在规则组列表第一个位置,写入通道0这个通道*/
	   ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	   /*结构体初始化ADC*/
	   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工作模式为独立模式
	   ADC_InitStruct.ADC_NbrOfChannel = 1;//通道数目
	   ADC_InitStruct.ADC_ScanConvMode = DISABLE;//非扫描
	   ADC_Init(ADC1, &ADC_InitStruct);
		 
		 //开启ADC电源
		 ADC_Cmd(ADC1, ENABLE);
		 
		 /*给ADC校准*/
		 ADC_ResetCalibration(ADC1);//复位校准
		 while(ADC_GetResetCalibrationStatus(ADC1) == SET);//返回ADC1复位校准状态
		 ADC_StartCalibration(ADC1);//开始校准
		 while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
}
 
uint16_t AD_Getvailue(void){//获取信息
	   ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发转换
	   while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//等待转换完成
	   return ADC_GetConversionValue(ADC1);//读取数据
}
uint8_t length(uint16_t num){
	  uint8_t length = 0;
	  while(num > 0){
		   num = num / 10;
		   length = length + 1;
	  }
	  return length;
}
uint16_t Reality_ADLight(uint16_t ADCnum){//获取光照强度
	  return 100 - ADCnum / 40;
}

 
int main(void){
	 
	OLED_Init();//初始化OLED
	AD_Init();
	while(1){
		    uint16_t num  = AD_Getvailue();
		    uint16_t num1 = Reality_ADLight(num); 
		    
		    OLED_ShowString(1, 1, "ADO:");
		    OLED_LoactionClear(1, length(num) + 3);//"ADO:"长度为3所以要加3
        OLED_ShowNum(1, 5, num, length(num));
		    OLED_ShowString(2, 1, "LUX:");
		    OLED_LoactionClear(2, length(num1) + 3);
		    OLED_ShowNum(2, 5, num1, length(num1));
		    Delay_ms(300);
	}
}

效果:

stm32光敏电阻测试光强度,stm32,单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-765121.html

到了这里,关于Stm32_标准库_8_ADC_光敏传感器_测量具体光照强度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32学习记录——光敏传感器的使用

    文章目录 前言 一、学习目的 二、模块介绍 三、代码记录 总结        只做 学习记录 ,记录自己如何从零学会使用一个模块,仅仅只是会用,缺乏专业知识。如果需要了解更多原理,可以从我推荐的技术大佬的文章中获取。        我的学习目的就是通过STM32的ADC功能,学

    2024年02月07日
    浏览(53)
  • 【STM32】STM32学习笔记-按键控制LED 光敏传感器控制蜂鸣器(08)

    led.h led.c key.h key.c main.c 电路图: 实物图: buzzer.h buzzere.c lightsensor.h lightsensor.cpp main.c 04-Key控制LED.rar 05-光敏传感器控制蜂鸣器.rar 参考: 【STM32】江科大STM32学习笔记汇总

    2024年04月23日
    浏览(45)
  • STM32第三课:按键控制LED灯,光敏传感器控制蜂鸣器

            STM32的第三课,我们来学习如何使用按键来控制LED灯的亮灭。上一节课我们通过代码控制了LED的状态,但是还是处于一种较为低级的方式控制LED灯,缺少交互性,用按键进行控制属于更高的一个层次。然后我们将学习通过光敏传感器控制蜂鸣器的通断,让我们的学

    2024年04月29日
    浏览(26)
  • STM32-风速传感器(ADC)

    目录 0 说明 1 传感器介绍 2 代码说明      2.1 ADC.c      2.2 adc.h     2.3 main.c          本篇文章主要是说明怎么使用STM32单片机读取风速传感器采集到的数据,读取方式是ADC,并且附带着STM32所需要的全部代码,所使用的风速传感器如下图所示。 附: 使用单片机STM32f103系

    2024年02月15日
    浏览(40)
  • 【江科大STM32合集】day2按键控制LED&光敏传感器控制峰鸣器

    运算放大器-在江科大51单片机b站视频(AD/DA)复习 原理:两个极端 同相输入端电压 》反相输入端 电压输出最大值 接Vcc 同相输入端电压《 反向输入端 电压输出最小值 接GNd LED.c用来存放驱动程序的主体代码 (ps:逻辑运算代码都在这 LED.h用来存放驱动程序可以 对外 提供的函

    2024年01月17日
    浏览(51)
  • STM32开发——ADC(烟雾传感器)

    目录 1.ADC简介 2.项目简介 3.CubeMX设置 4.函数代码 作用:用于读取电压值,然后转换为数字量传给单片机,单片机再通过计算,可以得到电压值。  ADC的性能指标 量程:能测量的电压范围 分辨率:ADC能辨别的最小模拟量,通常以输出二进制数的位数表示,比如:8、10、12、1

    2024年02月09日
    浏览(35)
  • STM32实现气压传感器测量(BMP180)

    目录 0.接线设计 1.功能描述 2.四种方式实现大气压采集 3.模块选择 4.编程环境 5.模块主要参数 6.代码实现         1)标准库模拟IIC实现气压值采集          2)标准库硬件IIC实现气压值采集          3)HAL库模拟IIC实现气压值采集         4)HAL库硬件IIC实现气

    2024年02月04日
    浏览(35)
  • STM32—ADC详解入门(ADC读取烟雾传感器的值)

    目录 一、ADC是什么 二、ADC的性能指标 三、ADC特性 四、ADC通道 五、ADC转换顺序 六、ADC触发方式 七、ADC转化时间 八、ADC转化模式 九、实验(使用ADC读取烟雾传感器的值) 1、配置 2、代码         ADC是Analog-to-DigitalConverter的缩写。指模/数转换器或者模拟/数字转换器。是指

    2024年02月11日
    浏览(32)
  • STM32--ADC数值采样/附ADC采集热敏传感器使用

    目录 一丶ADC介绍 二丶ADC工作原理及管脚分布 三丶代码部分详解 (一)库函数介绍 (二)代码部分整合         ADC模块中文名为模拟/数字转换器,是12位逐次逼近型的模拟数字转换器,一般用于数值的采样   可以将引脚上连续变化的模拟电压转换为内存中存储的数字变

    2024年02月03日
    浏览(40)
  • 【正点原子STM32连载】 第三十二章 光敏传感器实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

    本章,我们将学习使用STM32开发板板载的一个光敏传感器。我们还是要使用到ADC采集,通过ADC采集电压,获取光敏传感器的电阻变化,从而得出环境光线的变化,并在TFTLCD上面显示出来。 本章分为如下几个小节: 32.1 光敏传感器简介 32.2 硬件设计 32.3 程序设计 32.4 下载验证

    2024年02月03日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包