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位清0ADC1->SQR3 |= 0x05<<0;//选择第一个转换通道5ADC1->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]){//过去500msledcnt[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;//使能GPIOARCC->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位清0ADC1->SQR3 |= 0x05<<0;//选择第一个转换通道5ADC1->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.rhkb.cn/news/363792.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 中的抽象语法树

Abstract Syntax Trees in Python 注&#xff1a;机翻&#xff0c;未校对。 Requirement: All examples are compatible with at least Python v3.6, except for using ast.dump() with the attribute indent which has been added in Python v3.9. 要求&#xff1a;所有示例至…

线性代数知识点搜刮

求你别考太细... 目录 异乘变零定理 行列式转置 值不变 重要关系 中间相等&#xff0c;取两头 特征值公式 向量正交 点积为0 拉普拉斯定理 矩阵的秩 特征值和特征向量 |A|特征值的乘积 & tr(A)特征值的和 要记要背 增广矩阵 异乘变零定理 某行&#xff08;…

视频共享融合赋能平台LntonCVS安防监控平台现场方案实现和应用场景

LntonCVS国标视频融合云平台采用端-边-云一体化架构&#xff0c;部署简单灵活&#xff0c;功能多样化。支持多协议&#xff08;GB28181/RTSP/Onvif/海康SDK/Ehome/大华SDK/RTMP推流等&#xff09;和多类型设备接入&#xff08;IPC/NVR/监控平台&#xff09;。主要功能包括视频直…

贾英才主任的中医探索之路

在北京崇文门中医医院&#xff0c;贾英才主任在中医领域的钻研从未停歇。他对药理的探究和药物搭配的研究&#xff0c;展现出了非凡的专注与执着。 贾英才主任常常埋首于浩瀚的中医典籍之中&#xff0c;逐字逐句地研读古代名医的论述&#xff0c;试图从那些古老的智慧中汲取精…

阿里云服务器数据库迁云: 数据从传统到云端的安全之旅(WordPress个人博客实战教学)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 一、 开始实战1.2创建实验资源1.3重置云服务器ECS的登录密码&#xff08;请记住密码&#xff09;1.4 设置安全组端口1…

scatterlist的相关概念与实例分析

概念 scatterlist scatterlist用来描述一块内存&#xff0c;sg_table一般用于将物理不同大小的物理内存链接起来&#xff0c;一次性送给DMA控制器搬运 struct scatterlist {unsigned long page_link; //指示该内存块所在的页面unsigned int offset; //指示该内存块在页面中的…

用C/C++写一个客户端和服务器之间进行TCP通信的DEMO

目录 一、Visual Sudio 2022 二、配置 三、说明 四、客户端 五、服务端 六、演示 一、Visual Sudio 2022 Visual Studio 2022是微软公司推出的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在为开发人员提供全面的工具集&#xff0c;支持从Windows到MacOS…

开源大模型RAG企业本地知识库问答机器人-ChatWiki

ChatWiki ChatWiki是一款开源的知识库 AI 问答系统。系统基于大语言模型&#xff08;LLM &#xff09;和检索增强生成&#xff08;RAG&#xff09;技术构建&#xff0c;提供开箱即用的数据处理、模型调用等能力&#xff0c;可以帮助企业快速搭建自己的知识库 AI 问答系统。 开…

LeetCode刷题之HOT100之数组中的第K个最大元素

2024 6/29 今天天气很好啊&#xff0c;想爬山&#xff0c;奈何下午还有最后的一个汇报。做个题先 1、题目描述 2、算法分析 看到这个题我想到的就是: public int findKthLargest(int[] nums, int k) {Arrays.sort(nums);return nums[nums.length - k ];}哈哈&#xff0c;我提…

从零开始:Spring Boot 中使用 Drools 规则引擎的完整指南

规则引擎作用 规则引擎主要用于将业务逻辑从应用程序代码中分离出来&#xff0c;提高系统的灵活性和可维护性。规则引擎通过预定义的规则来处理输入数据并做出相应的决策&#xff0c;从而实现业务逻辑的自动化和动态调整。 例如 门店信息校验&#xff1a;美团点评在门店信息…

Websocket在Java中的实践——握手拦截器

大纲 依赖握手拦截器消息处理测试参考资料 在《Websocket在Java中的实践——最小可行案例》一文中&#xff0c;我们看到如何用最简单的方式实现Websocket通信。本文中&#xff0c;我们将介绍如何在握手前后进行干涉&#xff0c;以定制一些特殊需求。 在《Websocket在Java中的实…

.net 项目中配置 Swagger

一、前言 二、Swagger 三、.net 项目中添加Swagger 1、准备工作 &#xff08;1&#xff09;.net项目 &#xff08;2&#xff09;SwaggerController &#xff08;3&#xff09;XML文档注释 2、安装Swagger包 3、 添加配置swagger中间件 &#xff08;1&#xff09;添加S…

Dijkstra算法C代码

一个带权图n个点m条边&#xff0c;求起点到终点的最短距离 先定义一个邻接矩阵graph&#xff0c;graph[i][j]表示从i到j的距离&#xff0c;i到j没有路就表示为无穷 然后定义一个visit数组&#xff0c;visit[i]表示i结点是否被访问 然后定义一个dist数组&#xff0c;dist[i]表…

计算机等级考试二级Java-第二篇:基本数据类型

1.运算符的优先级以及复杂表达式 优先级运算符结合性1( ) [ ]  .从左到右2!  ~    –从右到左3*  /  %从左到右4  -从左到右5<<  >>  >>>从左到右6<  <  >  >  instanceof从左到右7  !从左到右8&从左到右9^从左到右10|从…

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

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

「51媒体」浙江地区媒体邀约

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 浙江地区的媒体邀约资源丰富多样&#xff0c;涵盖了电视台…

EXCEL 复制后转置粘贴

nodepad 转置参考&#xff1a; https://editor.csdn.net/md/?articleId140014651 1. WPS复制后转置粘贴 复制-》右键-》顶部第一行-》粘贴行列转置&#xff0c;如下图&#xff1a; 2. Excel office365 本地版 2. Excel office365 在线版

Shell编程之正则表达式与文本处理器

正则表达式 正则表达式概述 1. 正则表达式的定义 正则表达式又称正规表达式、常规表达式。在代码中常简写为regex 、regexp 或 RE 。 正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串&#xff0c;简单来说&#xff0c;是一种匹配字符串的方法&…

Linux操作系统--软件包管理(保姆级教程)

RPM软件包的管理 大多数linux的发行版本都是某种打包系统。软件包可以用来发布应用软件&#xff0c;有时还可以发布配置文件。他们比传统结构的.tar和.gz存档文件有几个优势。如它们能让安装过程尽可能成为不可分割的原子操作。 软件包的安装程序会备份它们改动过的文件。如果…

华为昇腾NPU实战:LLM ChatGLM2模型推理体验

参考&#xff1a;https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/glm2.md#chatglm2-6b 1、安装环境&#xff1a; 昇腾NPU卡对应英伟达GPU卡&#xff0c;CANN对应CUDA底层&#xff1b; mindspore对应pytorch&#xff1b;mindformers对应transformers 本…