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

先来看看本次实验的结果吧: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.kler.cn/a/274579.html

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

相关文章

六、C#快速排序算法

简介 快速排序是一种常用的排序算法,它基于分治的思想,通过将一个无序的序列分割成两个子序列,并递归地对子序列进行排序,最终完成整个序列的排序。 其基本思路如下: 选择数组中的一个元素作为基准(pivot…

SQL server服务连接失败,通过端口1433连接到主机 localhost的 TCP/IP 连接失败

SQL server服务连接失败,通过端口1433连接到主机 localhost的 TCP/IP 连接失败 出现这个错误的时候,首先确保sql的服务正常启动 通常来说正常安装的SQL server之后,会自带一个软件 打开:SQL server配置管理器 确认一下红框内的…

GitHub Copilot+ESP开发实战-串口

上篇文章讲了GitHub Copilot在应用中可能遇到的问题,接下来小启就简单介绍下GitHub Copilot在ESP32开发中C语言实现串口功能,感兴趣的可以看看。 一、向Copilot提问: 1. ESP32用C语言实现串口初始化; 2.配置uart为1&#xff0c…

【STM32嵌入式系统设计与开发】——6矩阵按键应用(4x4)

这里写目录标题 一、任务描述二、任务实施1、SingleKey工程文件夹创建2、函数编辑(1)主函数编辑(2)LED IO初始化函数(LED_Init())(3)开发板矩阵键盘IO初始化(ExpKeyBordInit())&…

QT配置libtorch(一步到位!!!防止踩坑)

QT配置libtorch Qt下载QT配置MSVCQT配置Libtorch Qt下载 Qt点击下载 Qt的安装选择MSVC2017 64-bit(一定要安装,这关乎后面的配置!!!),其他的根据自己的选择进行安装 QT配置MSVC Visual Studio点击安装 这里需要安装VS以…

Flutter-实现扫描线移动效果

效果 唠叨 在许多应用中,我们经常会看到扫描线的动画效果,比如二维码扫描、条形码扫描等。在Flutter中,我们可以通过自定义控件来实现这种扫描线移动的效果。本文将介绍如何使用Flutter创建一个扫描线移动的控件,并分析其实现思路…

HarmonyOS NEXT应用开发之Navigation实现多设备适配案例

介绍 在应用开发时,一个应用需要适配多终端的设备,使用Navigation的mode属性来实现一套代码,多终端适配。 效果图预览 使用说明 将程序运行在折叠屏手机或者平板上观看适配效果。 实现思路 本例涉及的关键特性和实现方案如下&#xff1a…

学习总结1

算法 这两天对搜索(主要是dfs)进行了复习,写了四道题目. 解题思路 这道题我用dfs进行解题,这道题比起其他的只多了一个Z轴也就是多了两个方向. 代码 #include <string.h> #include <stdio.h> char g[31][31][31]; int ne[7][3]{{1,0,0},{-1,0,0},{0,1,0},{0,-1…

React状态管理库快速上手-Redux(一)

基本使用 安装 pnpm install reduxjs/toolkit react-redux创建一个仓库 定义state createSlice相当于创建了一个模块仓库&#xff0c;initialState存放状态&#xff0c;reducers存放改变状态的方法。 import { createSlice } from reduxjs/toolkitexport const counterSli…

2024.3.19

思维导图 模拟面试 1.友元的作用 答&#xff1a;通过关键字friend&#xff0c;可以让一些函数或者类&#xff0c;可以访问一个类中的私有数据成员。 2.匿名对象的作用 答&#xff1a;匿名对象就是没有名字的对象&#xff0c;是用来给有名对象进行初始化工作的。 3.常成员函…

使用Vscode连接云进行前端开发

使用Vscode连接云进行前端开发 1、ssh连接腾讯云 本人使用的是腾讯云。 然后vscode,用最新版&#xff0c;插件选择remote ssh&#xff0c;或者remote xxx下载过来。 然后点击远程资源管理器&#xff0c;选择SSH通道 然后输入命令如下。 ssh rootip然后输入密码 腾讯云应该…

Java使用itextpdf往pdf中插入图片

引入maven依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.9</version> </dependency>java代码 import cn.hutool.extra.qrcode.QrCodeUtil; import com.itextpdf.text.*; i…

nodejs 使用express插件multer文件上传,接收不到文件的bug

把路径改成绝对路径即可 改成 temp是你想上传到文件夹的路径&#xff0c;一般是在项目根目录下

未来汽车EE架构趋势

多种趋势推动着电动汽车&#xff08;EV&#xff09;、混合动力电动汽车&#xff08;HEV&#xff09;和插电式混合动力电动汽车&#xff08;PHEV&#xff09;的发展。城市化和可持续发展的压力促使各国政府出台支持性法规&#xff0c;使制造商从中受益&#xff0c;而税收优惠政策…

C#,图论与图算法,计算无向连通图中长度为n环的算法与源代码

1 无向连通图中长度为n环 给定一个无向连通图和一个数n,计算图中长度为n的环的总数。长度为n的循环仅表示该循环包含n个顶点和n条边。我们必须统计存在的所有这样的环。 为了解决这个问题,可以有效地使用DFS(深度优先搜索)。使用DFS,我们可以找到特定源(或起点)的长度…

湖北省地质灾害分布数据 崩塌滑坡泥石流空间分布地质灾害详查等数据集

地质灾害是指在自然或者人为因素的作用下形成的&#xff0c;对人类生命财产造成的损失、对环境造成破坏的地质作用或地质现象。地质灾害在时间和空间上的分布变化规律&#xff0c;既受制于自然环境&#xff0c;又与人类活动有关&#xff0c;往往是人类与自然界相互作用的结果。…

Spark-Scala语言实战(3)

在之前的文章中&#xff0c;我们学习了如何在来如何在IDEA离线和在线安装Scala&#xff0c;想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实…

Linux:Gitlab:16.9.2 创建用户及项目仓库基础操作(2)

我在上一章介绍了基本的搭建以及邮箱配置 Linux&#xff1a;Gitlab:16.9.2 (rpm包) 部署及基础操作&#xff08;1&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/136821311?spm1001.2014.3001.5501 本章介绍一下用户的创建&#xff0c;组内设置用户&…

xAI开发的一款巨大型语言模型(HLM)--Grok 1

在xAI发布Grok的权重和架构之后&#xff0c;很明显大型语言模型&#xff08;LLM&#xff09;的时代已经过去&#xff0c;现在是巨大型语言模型&#xff08;HLM&#xff09;的时代。这个混合专家模型发布了3140亿个参数&#xff0c;并且在Apache 2.0许可下发布。这个模型没有针对…

力扣--回溯算法51.N皇后

思路分析&#xff1a; isValue函数用于判断当前位置是否可以放置皇后&#xff0c;通过检查当前列、左上方斜线和右上方斜线是否有皇后来确定。dfs函数采用深度优先搜索的方式&#xff0c;在每一行尝试放置皇后&#xff0c;如果当前位置合法&#xff0c;则递归继续尝试下一行&a…
最新文章