STM32编写ADC功能,实现单路测量电压值(OLED显示)

news2025/2/25 0:24:41

先来看看本次实验的结果吧:stm32点电压测量范围为0-3.3V,数值为:0-4095

来看看这个工程的文件布局吧:

实现ADC功能总共分为六步:

第一步:开始RCC时钟,包括ADC和GPIO的时钟,ADCCLK的分频器也需要配置一下。

第二步:配置GPIO,把需要用的GPIO配置成模拟输入的模式

第三步:配置多路开关,把左边的通道接入规则组列表里

第四步:配置ADC转换器,用结构体配置,一大块的参数。

第五步:打开ADC_CMD()开启ADC。

第六步:校准ADC

接着来学习一下ADC相关的库函数:(看起来好像有点乱,后面有截图)

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); 用来配置ADCCLK分频器的 void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); 这个是用来给ADC上电的函数 void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); 用来开启DMA输出信号的 void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); 中断输出控制 void ADC_ResetCalibration(ADC_TypeDef* ADCx); 复位校准 FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx); 获取复位校准状态 void ADC_StartCalibration(ADC_TypeDef* ADCx); 开始校准 FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx); 获取开始校准状态 void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); ADC软件开始转换控制 软件触发的函数 FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); ADC获取软件开始转换状态 FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); 获取转换完成标志位状态,判断EOC标志位是不是置1了。 void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); 间隔几个通道采集信

void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 是否启用间隔模式 void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); 规则组通道配置 void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); ADC 外部触发转换控制,就是是否允许外部触发转换 uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); ADC获取转换值 uint32_t ADC_GetDualModeConversionValue(void); ADC获取双模式转换值,这个是双ADC模式读取转换结果 void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);  //是否启动看门口 void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold); //配置高低阈值 void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); //配置看门的通道 配置模拟看门狗的三个函数 void ADC_TempSensorVrefintCmd(FunctionalState NewState);  //ADC温度传感器内部参考电压控制,用来开启内部通道 FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);  //获取标志位状态 void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);        // 清楚标志位状态 ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);     //获取中断状态 void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);   //清楚中断挂起位

接下来就是每个文件的源码了:

MyADC.c文件:

#include "stm32f10x.h"                  // Device header


void MyADC_Init(void)
	
{
	//第一步:开始RCC时钟,包括ADC和GPIO的时钟,ADCCLK的分频器也需要配置一下。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);   //开启ADC1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //开启GPIOA的时钟
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);      // ADC的时钟选择6分频,也就是72M/6=12M
	
	//第二步:配置GPIO,把需要用的GPIO配置成模拟输入的模式
	GPIO_InitTypeDef GPIO_InitStruct;    //GPIO初始化的结构体
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;  // 模式为模拟输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;       // 初始化端口0
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  //端口频率50M
	GPIO_Init(GPIOA, &GPIO_InitStruct);           // GPIOA初始化
	
	//第三步:配置多路开关,把左边的通道接入规则组列表里
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5); //ADC1规则配置(ADC1,通道1,列表1,转换时间28.5个时钟(12M))
	
	//第四步:配置ADC转换器,用结构体配置,一大块的参数。
	ADC_InitTypeDef ADC_InitStruct;                    //ADC初始化结构体
	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;            //连续转换模式:关闭
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;            // 数据对齐:右对齐
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;   //ADC中断触发:空,也就是软件触发
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;               // ADC模式:独立模式
	ADC_InitStruct.ADC_NbrOfChannel = 1;                   //规则组中的通道数:1
	ADC_InitStruct.ADC_ScanConvMode = DISABLE;             //扫描模式:关闭
	ADC_Init(ADC1, &ADC_InitStruct);                    //ADC初始化
	//第五步:打开ADC_CMD()开启ADC。
	ADC_Cmd(ADC1, ENABLE);                        // ADC开启
	//第六步:校准ADC
	ADC_ResetCalibration(ADC1);                        // 复位校准ADC
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);    // 等待校准标志位置0
	ADC_StartCalibration(ADC1);                         // 开始复位校准ADC
	while(ADC_GetCalibrationStatus(ADC1) == SET);          // 等待开始校准结束标志位置0
	
}

uint16_t Get_val(void)
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);                  // 软件触发ADC使能
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);   // 等待获取EOC标志位置1
	return ADC_GetConversionValue(ADC1);                    // 返回ADC转换的结果值

}

MyADC.h文件:

#ifndef __MYADC_H
#define __MYADC_H


void MyADC_Init(void);

uint16_t Get_val(void);


#endif

主函数main.c文件:

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

uint16_t ADValue;			//定义AD值变量
float Voltage;				//定义电压变量

int main(void)
{
	/*模块初始化*/
	OLED_Init();			//OLED初始化
	AD_Init();				//AD初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "ADValue:");
	OLED_ShowString(2, 1, "Voltage:0.00V");
	
	while (1)
	{
		ADValue = AD_GetValue();					//获取AD转换的值
		Voltage = (float)ADValue / 4095 * 3.3;		//将AD值线性变换到0~3.3的范围,表示电压
		
		OLED_ShowNum(1, 9, ADValue, 4);				//显示AD值
		OLED_ShowNum(2, 9, Voltage, 1);				//显示电压值的整数部分
		OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2);	//显示电压值的小数部分
		
		Delay_ms(100);			//延时100ms,手动增加一些转换的间隔时间
	}
}

还有一个OLED的代码就不展示了,没有的可以在之前的博文中找到,都有公布过,自己挨片的看就能找到的,编译后写入到STM32中就能看到实验结果了,调整电位器就能看到电压和数值的变化,电位器中间抽头接A0,另外两个头中的一个接3.3V电源,这就是整个的接线图了。

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

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

相关文章

【Linux】——进程地址空间 Linux2.6内核进程调度队列

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 文章目录 前言 一、环境变量的补充 二、进程空间的地址 2.1、程序地址空间 2.2、研究背景 2.3、程序地址空间 来段代码感受一下 2.4、进程地址空间 2.5、如何…

【计算机网络】IP 协议

网络层IP协议 一、认识 IP 地址二、IP 协议报头格式三、网段划分1. 初识子网划分2. 理解子网划分3. 子网掩码4. 特殊的 IP 地址5. IP 地址的数量限制6. 私有 IP 地址和公网 IP 地址7. 理解全球网络(1)理解公网(2)理解私网&#xf…

一文搞懂IP

IP 1. 基本介绍2. IP地址定义3. IP地址分类4. 子网掩码5. 全局地址与私有地址 1. 基本介绍 TCP/IP 协议的心脏是网络层,主要“实现节点之间的通信”,即“点对点(end-to-end)通信”。 网络层包含IP(Internet Protocol)及DNS(Domain Name Sys…

代码随想录算法训练营 DAY 14 | 二叉树的递归遍历和迭代遍历

二叉树基础 种类 满二叉树:深度为k,有2^k-1个节点的二叉树 完全二叉树:除了最底层可能没满,且都在靠左侧 优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。 二叉搜索树&…

redis学习-String类型的命令介绍以及特殊情况分析

目录 1. set key value 2. get key 3. append key string 4. strlen key 5. incr key 和 decr key 6. incrby key num 和 decrby key num 7. getrange key start end 8. setrange key start string 9. setex key time value 10. setnx key value 11. mset key1 val…

AI论文速读 | UniST:提示赋能通用模型用于城市时空预测

本文是时空领域的统一模型——UniST,无独有偶,时序有个统一模型新工作——UniTS,感兴趣的读者也可以阅读今天发布的另外一条。 论文标题:UniST: A Prompt-Empowered Universal Model for Urban Spatio-Temporal Prediction 作者&…

Linux进程通信补充——System V通信

System V进程通信 ​ System V是一个单独设计的内核模块; ​ 这套标准的设计不符合Linux下一切皆文件的思想,尽管隶属于文件部分,但是已经是一个独立的模块,并且shmid与文件描述符之间的兼容性做的并不好,网络通信使…

Linux入门级别命令(下载远程连接工具)

$pwd(当前所在位置,显示打印当前工作目录)$mkdir 创建目录$cd dir 换个位置(进入某一个目录)$cd 什么都不加回到最开始的目录$ls当前目录位置下的文件信息(列出当前所在位置下有哪些东西)$mv移动…

SpringBoot与SpringCloud的版本对应详细版

在实际开发过程中,我们需要详细到一一对应的版本关系:Spring 官方对应版本地址: (https://start.spring.io/actuator/info),建议用firefox浏览器打开,你会看见格式化好了json信息: 手动记录一些经本人实际…

导师评价网最全整合版

目录 简介 下载地址 打开index.html即可查询。 简介 下载地址 链接:https://pan.baidu.com/s/1QU6PgoF3Fi8NqtaGHzfAuw?pwdoc0s 提取码:oc0s --来自百度网盘超级会员V5的分享

【Frida】06_分析扫雷游戏的数据,显示地雷位置

🛫 系列文章导航 【Frida】 00_简单介绍和使用 https://blog.csdn.net/kinghzking/article/details/123225580【Frida】 01_食用指南 https://blog.csdn.net/kinghzking/article/details/126849567【Frida】 03_初识frida-node https://blog.csdn.net/kinghzking/ar…

python基于django的高校迎新系统 flask新生报到系统

系统的登录界面和业务逻辑简洁明了,采用一般的界面窗口来登录界面,整个系统更加人性化,用户操作更加简洁方便。本系统在操作和管理上比较容易,还具有很好的交互性等特点,在操作上是非常简单的。因此,本系统可以进行设计…

【代码】YOLOv8标注信息验证

此代码的功能是标注信息验证,将原图和YOLOv8标注文件(txt)放在同一个文件夹中,作为输入文件夹 程序将标注的信息还原到原图中,并将原图和标注后的图像一同保存,以便查看 两个draw_labels函数,分…

【译文】使用ANSI码丰富命令行输出

每个人都习惯了在终端中打印输出的程序,当新文本出现时,它会滚动,但这并不是您所能做的全部:您的程序可以为文本上色,上下左右移动光标,或者在以后要重新打印时清除屏幕的部分内容。这就是为什么像Git这样的程序可以实…

远程过程调用-buttonrpc源码解析2-元组与可变参模板

在不考虑远程调用的情况下&#xff0c;假设我们调用的是本地某个函数&#xff0c;为了支持参数的数量和类型可变&#xff0c;需要使用可变参模板&#xff0c;常见形式如下&#xff1a; // 具体实现函数&#xff1a;利用C17提供的折叠表达式来解析参数包 template<typename …

JAVA实战手册-开篇总述

该专题以实战为出发点&#xff0c;总结概述了实际工作中常用的java知识点&#xff0c;掌握了这些知识点&#xff0c;日常工作开发以及面试都不在话下。 话不多说&#xff0c;直入正题&#xff0c;以下为JAVA知识点概括总结&#xff08;总计涵盖了10大类78小项&#xff09; 针对…

激光打标机:精准定位,实现个性化标识需求

激光打标机&#xff1a;精准定位&#xff0c;实现个性化标识需求 激光打标机&#xff0c;以其精准定位的特性&#xff0c;成为实现个性化标识需求的得力工具。在现代制造业中&#xff0c;个性化标识已成为产品差异化、品牌塑造和提升附加值的重要手段。激光打标机通过其独特的打…

前后端项目笔记

前端项目创建 准备工作 nodejs安装 vue cli安装 vue create frontend 最后一个y的话 它会保存 方便下次创建项目 我这是手快敲错了 随自己 前端项目组件及作用 Element-UI引入 安装 npm i element-ui -S main.js中引入 清空路口App.vue 清空Home页面 随便写个按钮 原因…

【docker】Docker打包SpringBoot镜像

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;中间件 ⛺️稳中求进&#xff0c;晒太阳 前置说明 最为原始的打包方式spring-boot-maven-plugin插件jib-maven-plugin插件dockerfle-maven-plugin插件 最为原始的方式 也就是使用Docker的打…

Ubuntu Desktop - Desktop

Ubuntu Desktop - Desktop 1. Amazon2. Ubuntu Software3. Desktop4. 系统桌面快捷方式5. 用户桌面快捷方式References 1. Amazon Amazon -> Unlock from Launcher 2. Ubuntu Software Installed -> Games -> Remove 3. Desktop /home/strong/Desktop 4. 系统桌面…