STM32第十一课:ADC采集光照

文章目录

  • 需求
  • 一、ADC概要
  • 二、实现流程
    • 1.开时钟,分频,配IO
    • 2.配置ADC工作模式
    • 3.配置通道
    • 4.复位校准
    • 5.数值的获取
  • 三、需求的实现
  • 总结


需求

通过ADC转换实现光照亮度的数字化测量,最后将实时测量的结果打印在串口上。
`


一、ADC概要

   ADC全称是Analog-to-Digital Converter模数转换器,一般我们把模拟信号(Analog signal) 用A来进行简写,数字信号(digital signal) 用D来表示。
  自然界中绝大部分都是模拟信号,例如压力或温度的测量,为了方便储存,处理和传输,我们会通过ADC把模拟信号转化成数字形式给计算机处理。将模拟转换成数字的形式有两个步骤:采样和量化。
  本例中就是将光照亮度这种模拟量转换为具体的数字量。

本次使用的ADC:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、实现流程

1.开时钟,分频,配IO

先打开原理图,找到该光敏电阻的位置。
在这里插入图片描述
由该电路可知VAL测量的是该光敏电阻的分压,而随着光照的变化,该光敏电阻的电压也会发生实时的波动。
此时我们就利于该光敏电压的变化来实现需求。
先找到CPU上对应的引脚
在这里插入图片描述
由上图可知该模块对应的引脚为PA5,ADC为ADC12_IN5,代表该引脚PA5是ADC1/2的通道5。
此时我们就开GPIOA的时钟和ADC1的通道(1,2都行,无所谓)
代码如下:

	RCC->APB2ENR |= 0x01<<9;//ADC1通道
	RCC->APB2ENR |= 0x01<<2;//使能GPIOA

下面就要进行分频了,由于本次使用的ADC的特征为12分辨率,而APB2所传输的频率为72M,所以此时我们要进行6分频(72 ÷ 6 = 12)
在这里插入图片描述
在这里插入图片描述

	RCC->CFGR &= ~(0x03<<14);
	RCC->CFGR |= (0x02<<14);//6分频

最后进行PA5引脚的模式配置,由于要获得该引脚的电压值,而该电压值为动态变化的模拟量,所以此处要将模式置为模拟输入模式(0000)

GPIOA->CRL &= ~(0x0F<<20);//配置成模拟输入

2.配置ADC工作模式

首先打开手册找ADC1的控制寄存器(CR1,CR2),一个一个查看,看是否需要配置。
在这里插入图片描述
一般常用的是第8位扫描模式
在这里插入图片描述
不过此处只传输光照一个变量,所以可以不开置零就行。
在这里插入图片描述
双模式选择也是必要的,此处选独立模式就行,因为只用这一个ADC1。
到这里ADC1的CR1寄存器的基本配置就算完成了。
下面来看ADC1的CR2寄存器。
在这里插入图片描述
在这里插入图片描述
先来看第20位规则通道的外部触发转换模式。规则通道组每转换一次,代表着ADC1把数据传输到DR规则组通道数据寄存器上,该寄存器为16位,并且每传输一次,数据就会被覆盖一次。
此处我们选择开启1:使用外部时间启动转换
在这里插入图片描述
再来看19-17位,规则通道组转换的外部触发条件。
我们这里选择111:SWSTART(软件触发)因为是通过软件代码置位来触发。
在这里插入图片描述
第十一位数据对齐的模式要选择为右对齐,方便后续操作。
在这里插入图片描述
第一位的连续转换可开可关,因为只有光照一个量。
在这里插入图片描述
最后使能一下第0位:开启ADC并启动转换。

	//3、配置ADC的工作模式
	ADC1->CR1 &= ~(0x0F<<16);//独立模式
	ADC1->CR1 &= ~(0x01<<8);//不开扫描
	ADC1->CR2 |= 0x01<<20;//选择开启外部触发
	ADC1->CR2 |= 0x07<<17;//触发方式swsatrt(软件触发)
	ADC1->CR2 &= ~(0x01<<11);//选择数据右对齐
	ADC1->CR2 &= ~(0x01<<1);//关闭连续转换
	ADC1->CR2 |= 0x01<<0;//ADC使能

3.配置通道

由于该引脚PA5对应的是ADC12_IN5,所以我们只需要配置通道5即可。
配置通道在ADC规则序列寄存器和ADC采样时间寄存器中。
先找到SQR1寄存器
在这里插入图片描述
在这里插入图片描述
ADC规则序列寄存器负责通道数量的选择,共有16个,由于我们只用通道5,所以此时我们将L配置成0000,只配只配一个通道。
在这里插入图片描述
接下来配置我们选的SQ1通道,将其配成通道0x05。
在这里插入图片描述
最后配置一下采样周期,周期越大越准,所以我选择了111:239.5周期。

	//配置一个通道:通道5,第一个转换,采样周期最大(239.5)
	ADC1->SQR1 &= ~(0x0F<<20);//规则组通道只转换一个(配置通道数量)
	//具体某个通道的配置
	ADC1->SQR3 &= ~(0x1F<<0);//0-5位清0
	ADC1->SQR3 |= 0x05<<0;//选择第一个转换通道5
	ADC1->SMPR2 |= 0x07<<15;//采样周期最大(239.5)

4.复位校准

复位校准可有可无,不过为了更加保险,我还是加上了。
总共校准了两次,校准位在CR2寄存器的第三位。
在这里插入图片描述
每次校准后会自动置位0,所以此处while(1)等待非0,若为1就等待,为0就校准完成,继续往下执行。

	ADC1->CR2 |= 0x01<<3;//启动复位校准
	//等待复位校准结束
	while((ADC1->CR2&(0x01<<3))!=0)//判断寄存器的位3是不是等于1
	{}
	ADC1->CR2 |= 0x01<<2;//启动AD校准
	//等待AD校准结束
	while((ADC1->CR2&(0x01<<2))!=0)//判断寄存器的位2是不是等于1,是1就等待
	{}

5.数值的获取

对于数值的获取,我是单独写了个函数来执行,放便主函数调用并发送给串口。
想要获取数据,就要让ADC的CR2寄存器的第22位置1转换一下。
在这里插入图片描述
每转换一次,就代表着ADC1把数据传输到DR规则组通道数据寄存器上,该寄存器为16位,并且每传输一次,数据就会被覆盖一次。
所以此时我们让ADC的CR2寄存器的第22位置为1

那么什么时候代表转换完了?此时就要查看ADC的状态寄存器SR了
在这里插入图片描述
在这里插入图片描述
可以看到,每一次转换结束时,ADC_SR寄存器的第一位就会置1,并且不用我们去清零,每当我们去ADC_DR读取数据时,就会自动清除。
那么此时我们就可判断转换结束位的0,1来进行数据的读取了。
最后,将读取到的光照强度数据打印即可。(之前已经给printf重定向了,会自动打印到串口中)

void GetLightValue()
{
	uint16_t Light=0;
	//让规则通道转换一次
	ADC1->CR2 |= 0x01<<22;
	while((ADC1->SR&(0x01<<1))==0)//判断寄存器的位2是不是等于1,是0就等待转换完成
	{}
	Light = ADC1->DR; //读规则组通道数据寄存器
	printf("光照强度参数 = %d \r\n",Light);
}

三、需求的实现

关键代码如下:
main.c

#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
#include "delay.h"
#include "string.h"
#include "pwm.h"
#include "adc.h"

int main()
{
		NVIC_SetPriorityGrouping(5);//两位抢占两位次级
    Usart1_Config(); 
	  SysTick_Config(72000);
	  RGBpwm_Config();
	  uint8_t cai_count=0;
	  uint16_t cont=0;
	  Adc_Config();
    while(1)
    {	
	
	
			if(ledcnt[0]>=ledcnt[1]){//过去500ms
			ledcnt[0]=0;
					GetLightValue();
		}
    }
}

adc.c

#include "ADC.h"

void Adc_Config(void)
{
	//PA5
	//1、设置ADC的时钟(开时钟和时钟分频6分频)
	RCC->APB2ENR |= 0x01<<9;//ADC1通道
	RCC->APB2ENR |= 0x01<<2;//使能GPIOA
	
	RCC->CFGR &= ~(0x03<<14);
	RCC->CFGR |= (0x02<<14);//6分频
	//2、配置IO模式(模拟输入)
	GPIOA->CRL &= ~(0x0F<<20);//配置成模拟输入
	//3、配置ADC的工作模式
	ADC1->CR1 &= ~(0x0F<<16);//独立模式
	ADC1->CR1 &= ~(0x01<<8);//不开扫描
	ADC1->CR2 |= 0x01<<20;//选择开启外部触发
	ADC1->CR2 |= 0x07<<17;//触发方式swsatrt(软件触发)
	ADC1->CR2 &= ~(0x01<<11);//选择数据右对齐
	ADC1->CR2 &= ~(0x01<<1);//关闭连续转换
	ADC1->CR2 |= 0x01<<0;//ADC使能
	//配置一个通道:通道5,第一个转换,采样周期最大(239.5)
	ADC1->SQR1 &= ~(0x0F<<20);//规则组通道只转换一个(配置通道数量)
	//具体某个通道的配置
	ADC1->SQR3 &= ~(0x1F<<0);//0-5位清0
	ADC1->SQR3 |= 0x05<<0;//选择第一个转换通道5
	ADC1->SMPR2 |= 0x07<<15;//采样周期最大(239.5)

	ADC1->CR2 |= 0x01<<3;//启动复位校准
	//等待复位校准结束
	while((ADC1->CR2&(0x01<<3))!=0)//判断寄存器的位3是不是等于1
	{}
		ADC1->CR2 |= 0x01<<2;//启动AD校准
	//等待AD校准结束
	while((ADC1->CR2&(0x01<<2))!=0)//判断寄存器的位2是不是等于1,是1就等待
	{}
}

void GetLightValue()
{
	uint16_t Light=0;
	//让规则通道转换一次
	ADC1->CR2 |= 0x01<<22;
	while((ADC1->SR&(0x01<<1))==0)//判断寄存器的位2是不是等于1,是0就等待转换完成
	{}
	Light = ADC1->DR; //读规则组通道数据寄存器
	printf("光照强度参数 = %d \r\n",Light);
}

adc.h

#ifndef _ADC_H_
#define _ADC_H_
#include "stm32f10x.h"
#include "stdio.h"
void GetLightValue();

void Adc_Config(void);
#endif
		

delay.c

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

uint32_t systicktime=0;

uint16_t ledcnt[2]={0,1000};//500ms   每个任务执行的时间
uint16_t led2cnt[2]={0,2000};//700ms
uint16_t keycnt[2]={0,10};//10ms检测一次
void SysTick_Handler(void)//1ms调用一次
{
	//不需要清中断挂起位
	systicktime++;
	ledcnt[0]++;
	led2cnt[0]++;
	keycnt[0]++;
}

void Delay_ms(uint32_t time)
{
    uint32_t nowtime = systicktime;
		while(systicktime < time+nowtime);
}

void Delay_nus(uint32_t time)
{
    uint32_t i=0;
    for(i=0;i<time;i++){
        delay1us();
    }    
}

void Delay_nms(uint32_t time)
{
    uint32_t i=0;
    for(i=0;i<time;i++){
         Delay_nus(1000);//延时1ms
    }    
}

delay.h

#ifndef _DELAY_H_
#define _DELAY_H_
#include "stm32f10x.h"

#define delay1us() {__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();\
    __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();}

extern uint16_t ledcnt[2];
extern uint16_t led2cnt[2];
extern uint16_t keycnt[2];		
		
void Delay_nus(uint32_t time);
void Delay_ms(uint32_t time);
void Delay_nms(uint32_t time);
#endif
		

总结

1.先看该光敏电阻的电路图,分析如何获取光照的数值。
2.想到可以通过ADC转换得到光照的树数值,开始学习ADC的知识。
3.先看ADC的功能描述,然后开时钟,分频,配IO。
4.看手册中的ADC的控制寄存器,一个一个查看,看看究竟需要配置那些。
5.看该引脚的ADC是那个通道的,开始配置通道。
6.都配置完后进行复位校准和数据获取函数的编写。
7.最后在主函数按照需求调用即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/755341.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

气膜建筑消防设计:安全与创新的完美结合—轻空间

随着气膜建筑在各个领域的广泛应用&#xff0c;其消防安全问题也日益受到关注。气膜建筑由于其独特的结构和材料&#xff0c;在消防设计上面临着不同于传统建筑的挑战和要求。轻空间将深入探讨气膜建筑的消防设计原则、具体措施以及未来的发展方向。 气膜建筑的消防设计原则 1.…

Git(涵盖GitHub\Gitee码云\GitLab)

Git(涵盖GitHub\Gitee码云\GitLab) 文章目录 Git(涵盖GitHub\Gitee码云\GitLab)课程介绍Git概述官网介绍版本控制介绍两种版本控制工具集中式版本控制工具分布式版本控制工具 Git工作机制代码托管中心 Git安装和客户端的使用Git常用命令设置用户签名初始化本地库查看本地库状态…

常微分方程算法之编程示例四(龙格-库塔法)

目录 一、算例一 1.1 研究问题 1.2 C++代码 1.3 计算结果 二、算例二 2.1 研究问题 2.2 C++代码 2.3 计算结果 一、算例一 本节我们采用龙格-库塔法(Runge-Kutta法)求解算例。 龙格-库塔法的原理及推导请参考: 常微分方程算法之龙格-库塔法(Runge-Kutta法)…

智能加湿器,让湿度平衡更简单-NV040B加湿器语音方案

一、语音加湿器开发背景&#xff1a; 随着智能家居的普及&#xff0c;人们越来越追求家居环境的舒适度和智能化程度。传统的加湿器虽然能够调节室内湿度&#xff0c;但操作繁琐&#xff0c;不够人性化。而语音加湿器的出现&#xff0c;正是为了解决这一痛点。通过语音技术&…

“论模型驱动架构设计方法及其应用”,软考高级论文,系统架构设计师论文

论文真题 模型驱动架构设计是一种用于应用系统开发的软件设计方法&#xff0c;以模型构造、模型转换和精化为核心&#xff0c;提供了一套软件设计的指导规范。在模型驱动架构环境下&#xff0c;通过创建出机器可读和高度抽象的模型实现对不同问题域的描述&#xff0c;这些模型…

Mysql存储过程用法:使用存储过程编程,来判断数据库中数据表中的字段是否重复,避免重复插入记录

目录 一、mysql的存储过程介绍 二、. 创建存储过程 1、准备 2、创建插入记录的存储过程 三. 调用存储过程 四. 删除存储过程 五. 修改存储过程&#xff0c;避免数据表的姓名出现重复 1、修改存储过程的方式 2、重新创建存储过程 六. 验证新的存储过程 1、插入新的记…

Java校园跑腿小程序校园代买帮忙外卖源码社区外卖源码

&#x1f525;校园跑腿与外卖源码揭秘&#x1f525; &#x1f680; 引言&#xff1a;为何需要校园跑腿与外卖源码&#xff1f; 在快节奏的校园生活里&#xff0c;学生们对于便捷、高效的服务需求日益增长。校园跑腿和外卖服务成为了解决这一需求的热门选择。然而&#xff0c;…

MYSQL搜索排序:根据搜索匹配的权重进行从高到低排序

我们在使用 MySQL 进行模糊查询的时候&#xff0c;受到默认排序的影响&#xff0c;我们会发现与查询关键字相似的记录有时候并没有排到最前面。 如 &#xff1a; CREATE TABLE user(id BIGINT(11) AUTO_INCREMENT PRIMARY KEY,name varchar(255) )engineInnoDB,DEFAULT CHARSE…

泽众云真机-平台华为机型HarmonyOS NEXT系统已上线!

泽众云真机平台华为机型HarmonyOS NEXT系统已上线&#xff01; 之前文章《泽众云真机-平台即将升级支持华为机型HarmonyOS NEXT系统泽众云真机-平台即将升级支持华为机型HarmonyOS NEXT系统》&#xff0c;为什么要升级HarmonyOS NEXT系统&#xff1f;我们之前有说过&#xff0c…

[数据集][目标检测]睡岗检测数据集VOC+YOLO格式3290张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3316 标注数量(xml文件个数)&#xff1a;3316 标注数量(txt文件个数)&#xff1a;3316 标注…

高级运维工程师讲述银河麒麟V10SP1服务器加固删除snmp服务引起keeplived莫名连带删除引起生产事故实战

高级运维工程师讲述银河麒麟V10SP1服务器加固删除snmp服务引起keeplived莫名连带删除引起生产事故实战 一、核实操作系统信息 uname -a Linux localhost.localdomain 4.19.90-23.8.v2101.ky10.x86_64 #1 SMP Mon May 17 17:08:34 CST 2021 x86_64 x86_64 x86_64 GNU/Linuxcat…

收银系统源码-千呼新零售【手机端收银】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

44.商城系统(二十五):k8s基本操作,ingress域名访问,kubeSphere可视化安装

上一章我们已经配置好了k8s集群,如果没有配置好先去照着上面的配。 一、k8s入门操作 1.部署一个tomcat,测试容灾恢复 #在主机器上执行 kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8#查看k8s中的所有资源 kubectl get all kubectl get all -o wide#查看po…

【项目实训】对前期面经爬取为空的页面重新爬取

在前期经过团队成员对牛客网面试经验帖子的爬取&#xff0c;已经获得了部分面试经验的相关数据&#xff0c;但是在使用过程中&#xff0c;发现存在大量内容为空的数据记录&#xff0c;为了保证数据的可用性&#xff0c;我对这些页面重新进行了爬取。 牛客中之前爬取的面经存在…

【面试干货】Object 类中的公共方法详解

【面试干货】Object 类中的公共方法详解 1、clone() 方法2、equals(Object obj) 方法3、hashCode() 方法4、getClass() 方法5、wait() 方法6、notify() 和 notifyAll() 方法 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在 Java 中&#…

【环境配置】ubuntu中 Docker的安装

前言 Docker的使用&#xff0c;一直没有系统的梳理和记录&#xff0c;刚好最近看视频又再次的全面介绍到docker。于是记录下方便后面自己的使用&#xff0c;毕竟安装过程中还是会存在小的不丝滑。 1 Docker的简单介绍 这里的介绍来自于大模型的问答&#xff08;LLM时代的到来&a…

Linux /proc目录总结

1、概念 在Linux系统中&#xff0c;/proc目录是一个特殊的文件系统&#xff0c;通常被称为"proc文件系统"或"procfs"。这个文件系统以文件系统的方式为内核与进程之间的通信提供了一个接口。/proc目录中的文件大多数都提供了关于系统状态的信息&#xff0…

葡萄串目标检测YoloV8——从Pytorch模型训练到C++部署

文章目录 软硬件准备数据准备数据处理脚本模型训练模型部署数据分享软硬件准备 训练端 PytorchultralyticsNvidia 3080Ti部署端 fastdeployonnxruntime数据准备 用labelimg进行数据标注 数据处理脚本 xml2yolo import os import glob import xml.etree.ElementTree as ETxm…

Linux下VSCode的安装和基本使用

应用场景&#xff1a;嵌入式开发。 基本只需要良好的编辑环境&#xff0c;能支持文件搜索和跳转&#xff0c;就挺OK的。 之所以要在Linux下安装&#xff0c;是因为在WIN11上安装后&#xff0c;搜索功能基本废了&#xff0c;咋弄都弄不好&#xff0c;又不方便重装win系统&#x…

波音危机:星际客机飞船故障,宇航员被困太空!马斯克的SpaceX的“龙”飞船来救援?

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 在人类探索宇宙的漫漫征途中&#xff0c;波音公司的“星际客机”承载着无限的希望与梦想&#xff0c;却也面临着前所未有的挑战。从原计划的8天…