STM32第十一课:ADC采集光照

news2024/11/26 22:52:51

文章目录

  • 需求
  • 一、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.coloradmin.cn/o/1875082.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小柴冲刺软考中级嵌入式系统设计师系列一、计算机系统基础知识(1)嵌入式计算机系统概述

flechazohttps://www.zhihu.com/people/jiu_sheng 小柴冲刺嵌入式系统设计师系列总目录https://blog.csdn.net/qianshang52013/article/details/139975720?spm1001.2014.3001.5501 根据IEEE&#xff08;国际电气电子工程师协会&#xff09;的定义&#xff0c;嵌入式系统是&q…

lvs+上一章的内容

书接上回这次加了个keepalived 一、集群与分布式 1.1 集群介绍 **集群&#xff08;Cluster&#xff09;**是将多台计算机组合成一个系统&#xff0c;以解决特定问题的计算机集合。集群系统可以分为以下三种类型&#xff1a; **LB&#xff08;Load Balancing&#xff0c;负载…

rtthread stm32h743的使用(十一)spi设备使用

我们要在rtthread studio 开发环境中建立stm32h743xih6芯片的工程。我们使用一块stm32h743及fpga的核心板完成相关实验&#xff0c;核心板如图&#xff1a; 1.建立新工程&#xff0c;选择相应的芯片型号及debug引脚及调试器 2.编译下载&#xff0c;可以看到串口打印正常 3.…

SOAP vs REST介绍

SOAP&#xff08;简单对象访问协议&#xff09; 定义&#xff1a;SOAP是一种基于XML的通信协议&#xff0c;用于在网络中交换结构化信息&#xff0c;特别是在分布式环境和需要中介&#xff08;如网关或防火墙&#xff09;的环境中。它通过HTTP、SMTP等多种传输协议传输信息&…

APP项目测试 之 APP功能测试

1. APP测试流程 需求评审——计划编写——用例设计——用例执行——缺陷管理——测试报告 2. APP测试内容 功能测试 专项测试 性能测试 3.注册测试点扩充 4.登录测试点扩充 5.购物车测试点扩充 6.搜索测试点扩充 7.支付测试点扩充 8.评论测试点扩充 未完待续。…

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

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

新版周易测算系统源码 去授权完美运行

已经去掉授权可以完美运行 更新了三个模板市面上都是几千几千的卖 更新了三套首页新ui 自己后台切换就行 源码大小&#xff1a;338M 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89447857 更多资源下载&#xff1a;关注我.

深入解析Android的Sound Trigger中间件架构

深入解析Android的Sound Trigger中间件架构 在现代移动设备中,应用程序对声音事件的检测需求越来越多,如热词检测和背景音乐识别等。为了实现低功耗和隐私敏感的声音事件检测,Android引入了Sound Trigger中间件。本文将详细介绍Sound Trigger的架构、工作原理以及其在不同层…

JavaWeb——MySQL:事务的简单学习

前面学习完了数据库增删查改的SQL语言&#xff0c;约束&#xff0c;数据库设计&#xff0c;以及多表查询&#xff0c;再学完事务就达到初级工程师的水平了。 6. 事务 6.1 概念 事务类似于编程语言的方法&#xff0c;包含一组SQL指令。 事务是不可分割的&#xff1b; 该指令步…

十四、Maven(2)

&#x1f33b;&#x1f33b;目录 一、maven项目的目录结构&#xff1f;---约定二、在创建maven项目的时候三、依赖四、依赖的传递性五、依赖的排除性六、继承---项目结构的设计七、聚合---项目的设计方式 一、maven项目的目录结构&#xff1f;—约定 Maven是自动化构建工具&am…

java用pdf.js在线预览pdf文件(jeecg框架)

最近在jeecg框架的后台要做一个pdf在线预览的页面功能&#xff0c;可是每次点预览都是下载&#xff0c;所以就要解决这个问题&#xff0c;现在解决了&#xff0c;记录一下&#xff0c;防止后面踩坑。 先放代码&#xff1a; 下面是点“预览”按钮的点击事件&#xff0c;代码放…

算法基础-----【动态规划】

动态规划(待完善) 动规五部曲分别为&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式&#xff08;状态转移公式&#xff09;dp数组如何初始化确定遍历顺序举例推导dp数组、 动态规划的核心就是递归剪枝&#xff08;存储键值&#xff0c;…

TS_开发一个项目

目录 一、编译一个TS文件 1.安装TypeScript 2.创建TS文件 3.编译文件 4.用Webpack打包TS ①下载依赖 ②创建文件 ③启动项目 TypeScript是微软开发的一个开源的编程语言&#xff0c;通过在JavaScript的基础上添加静态类型定义构建而成。TypeScript通过TypeScript编译器或…

simulink开发stm32,使用中断模块,无法产生中断,其中包括使用timer模块,以及ADC都无法产生中断,需要注意的地方

1&#xff0c;其中包括使用timer模块&#xff0c;以及ADC都无法产生中断&#xff0c;需要注意的地方 原来是需要在配置文件里开启一下timer的中断&#xff0c;其他模块自动加载ioc就可以了&#xff0c;这个timer需要注意力&#xff0c;需要自己勾选一下 如下图&#xff1a; 看…

Android简介-历史、API等级与体系结构

1. Android简介 Android是一种基于Linux内核的自由及开放源代码的操作系统。最初是由安迪鲁宾(Andy Rubin)开发的一款相机操作系统。2005年8月被Google收购。2007年11月&#xff0c;Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。…

【漏洞复现】I doc view——任意文件读取

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 I doc view 在线文档预览是一个用于查看、编辑、管理文档的工具…

Why is Kafka fast?(Kafka性能基石)

Kafka概述 Why is kafka fast&#xff1f; 思考一下&#xff0c;当我们在讨论Kafka快的时候我们是在谈论什么呢&#xff1f;What does it even mean that Kafka is fast? 我们是在谈论kafka的低延迟&#xff08;low latency&#xff09;还是在讨论吞吐量&#xff08;through…

CTF-PWN-LLVM-【红帽杯-2021 simpleVM】

文章目录 参考检查逆向漏洞思路调试定位到PASS名exp 参考 https://bbs.kanxue.com/thread-274259.htm#msg_header_h2_6 http://www.blackbird.wang/2022/08/30/LLVM-PASS%E7%B1%BBpwn%E9%A2%98%E6%80%BB%E7%BB%93/ 检查 因为是用opt运行&#xff0c;加载动态库VMPASS.so的P…

【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering

【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering 一、前言Abstract1 INTRODUCTION2 RELATED WORK2.1 Traditional Scene Reconstruction and Rendering2.2 Neural Rendering and Radiance Fields2.3 Point-Based Rendering and Radiance Fields 3 O…

15秒下雨短视频:成都柏煜文化传媒有限公司

15秒下雨短视频&#xff1a;瞬间的诗意与情感共鸣 在数字时代的浪潮中&#xff0c;短视频以其独特的魅力&#xff0c;成为了人们生活中不可或缺的一部分。其中&#xff0c;一段仅15秒的下雨短视频&#xff0c;成都柏煜文化传媒有限公司 或许在时间长河中只是一瞬间&#xff0c…