stm32单片机个人学习笔记11(ADC模数转换器)

前言

本篇文章属于stm32单片机(以下简称单片机)的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

一、 ADC简介

逐次逼近型ADC 

ADC基本结构 

输入通道 

转换模式有单次转换或多次转换、扫描模式或非扫描模式 

非扫描模式只选中一个通道,单次转换后就停下来了,多次转换不停止 

扫描模式可以一次选中多个通道 

数据对齐的方式,一般使用右对齐 

 

ADC的自校准,在初始化完上电后启动校准 

ADC的硬件电路 

二、实例一(AD单通道) 

AD.c

#include "stm32f10x.h"                  // Device header/*** @brief  AD初始化* @param  无* @retval 无*/
void AD_Init(void)
{//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//ADC预分频RCC_ADCCLKConfig(RCC_PCLK2_Div6);//GPIO初始化GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//ADC选择通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//ADC初始化ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);//开启ADC电源ADC_Cmd(ADC1, ENABLE);//ADC校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));
}/*** @brief  AD获取转换值* @param  无* @retval 转换得到的值*/
uint16_t AD_Getvalue(void)
{ADC_SoftwareStartConvCmd(ADC1, ENABLE);while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);return ADC_GetConversionValue(ADC1);
}

 main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t ADValue;
float Voltage;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"ADValue:");OLED_ShowString(2,1,"Voltage:0.00V");while (1){ADValue = AD_Getvalue();Voltage = (float)ADValue / 4095 * 3.3;OLED_ShowNum(1,9,ADValue,4);OLED_ShowNum(2,9,Voltage,1);OLED_ShowNum(2,11,(uint16_t)(Voltage * 100) % 100,2);Delay_ms(100);}
}

 三、实例二(AD多通道)

AD.c

#include "stm32f10x.h"                  // Device header/*** @brief  AD初始化* @param  无* @retval 无*/
void AD_Init(void)
{//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//ADC预分频RCC_ADCCLKConfig(RCC_PCLK2_Div6);//GPIO初始化GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//ADC初始化ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);//开启ADC电源ADC_Cmd(ADC1, ENABLE);//ADC校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));
}/*** @brief  AD获取转换值* @param  无* @retval 转换得到的值*/
uint16_t AD_Getvalue(uint8_t ADC_Channel)
{ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);ADC_SoftwareStartConvCmd(ADC1, ENABLE);while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);return ADC_GetConversionValue(ADC1);
}

 main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t AD0,AD1,AD2,AD3;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"AD0:");OLED_ShowString(2,1,"AD1:");OLED_ShowString(3,1,"AD2:");OLED_ShowString(4,1,"AD3:");while (1){AD0 = AD_Getvalue(ADC_Channel_0);AD1 = AD_Getvalue(ADC_Channel_1);AD2 = AD_Getvalue(ADC_Channel_2);AD3 = AD_Getvalue(ADC_Channel_3);OLED_ShowNum(1,5,AD0,4);OLED_ShowNum(2,5,AD1,4);OLED_ShowNum(3,5,AD2,4);OLED_ShowNum(4,5,AD3,4);Delay_ms(100);}
}

 

 这里是通过单次转换非扫描模式,每次转换选取不同的通道来达到多通道的目的,用扫描模式达到多通道的目的要通过DMA,这个下节再使用

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

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

相关文章

Linux系列-Linux的常见指令(三)

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” mv 1.剪切文件,目录 2.重命名 首先,我们先来看第一个作用 假如说,我们原先存在一个hello.txt,我们如果想要将这个文件移动到其他的…

上拉电阻和下拉电阻在电路中的作用(一)

上拉电阻和下拉电阻在电路中的作用(一) 1.什么是上下拉电阻2.上下拉电阻的作用:2.1.维持输入引脚处于稳定状态。2.2.配合三极管和MOS进行电平转换电路设计2.3.OC、OD电路(Open Collector集电极开路、Open Drain漏电极开路&#xf…

什么是分库分表?为什么要分库分表?什么时候需要分库分表?怎么样拆分?(数据库分库分表详解)

文章目录 1、什么是分库分表?1.1、分库分表的概念1.2、分库分表的方式1.2.1、垂直分库1.2.2、垂直分表1.2.3、水平分库1.2.4、水平分表 2、为什么要分库分表?3、什么时候需要分库分表?4、分库分表的数据路由4.1、数据路由的目的4.2、数据路由…

class 9: vue.js 3 组件化基础(2)父子组件间通信

目录 父子组件之间的相互通信父组件传递数据给子组件Prop为字符串类型的数组Prop为对象类型 子组件传递数据给父组件 父子组件之间的相互通信 开发过程中,我们通常会将一个页面拆分成多个组件,然后将这些组件通过组合或者嵌套的方式构建页面。组件的嵌套…

2024开放原子开源生态大会 | 麒麟信安携手openEuler共建开源生态,共塑产业未来

9月25日-27日,由开放原子开源基金会主办的2024开放原子开源生态大会在北京开幕,大会以“开源赋能产业,生态共筑未来”为主题。工业和信息化部党组书记、部长金壮龙,北京市委副书记、市长殷勇,工业和信息化部总经济师、…

汇川机器人与PLC通信-ModbusTCP超详细案例

#SCARA机器人与H5UPLC通过ModbusTCP通信,HMI界面手动操作# 应用背景: 本项目案例部分软件界面已被更新,如机器人示教软件旧版本S01.19R03。但通信的原理基本一致,废话少说,我们直接上图。 一、PLC端配置 1.添加ROB通讯表(自定义),变量表内容包括ROB系统变量,IN区和…

Cadence元件A属性和B属性相互覆盖

最近在使用第三方插件集成到Cadence,协助导出BOM到平台上,方便对BOM进行管理和修改,结果因为属性A和属性B不相同,导致导出的BOM错误。如下图: ​​ 本来我们需要导出Q12,结果给我们导出了Q13,或者反之&…

基于opencv的人脸闭眼识别疲劳监测

1. 项目简介 本项目旨在实现基于眼部特征的眨眼检测,通过监测眼睛开闭状态来计算眨眼次数,从而应用于疲劳监测、注意力检测等场景。使用了面部特征点检测算法,以及眼部特征比率(EAR, Eye Aspect Ratio)来判断眼睛的闭…

Python 实现 excel 数据过滤

一、场景分析 假设有如下一份 excel 数据 shop.xlsx, 写一段 python 程序,实现对于车牌的分组数据过滤。 并以车牌为文件名,把店名输出到 车牌.txt 文件中。 比如 闽A.txt 文件内容为: 小林书店福州店1 小林书店福州店2 二、依赖安装 程序依…

【C++】拆分详解 - 模板

文章目录 一、泛型编程二、函数模板1. 概念2. 语法3. 函数模板的原理4. 函数模板的实例化5. 模板参数的匹配原则 三、类模板1. 语法2. 实例化 四、模板的特化1. 概念2. 函数模板特化3. 类模板特化3.1 全特化3.2 偏特化 / 半特化3.3 应用示例 4. 小结 五、模板的分离编译1. 分离…

Java:抽象类和接口

一.抽象类 1.抽象类概念和语法 ⨀概念: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 ⨀语…

JMeter使用不同方式传递接口参数

1、使用 HTTP 请求中的参数: 在 JMeter 的测试计划中,添加一个 "HTTP 请求" 元件。 在 "HTTP 请求" 元件的参数化选项中,可以添加参数的名称和值。可以手动输入参数,也可以使用变量来传递参数值。 如果要使…

Golang | Leetcode Golang题解之第497题非重叠矩形中的随机点

题目: 题解: type Solution struct {rects [][]intsum []int }func Constructor(rects [][]int) Solution {sum : make([]int, len(rects)1)for i, r : range rects {a, b, x, y : r[0], r[1], r[2], r[3]sum[i1] sum[i] (x-a1)*(y-b1)}return Sol…

自定义多级联动选择器指南(uni-app)

多端支持:可以运行在H5、APP、微信小程序还是支付宝小程序,都可以轻松使用改组件。自定义配置:您可以根据需要配置选择器的级数,使其适应不同的数据结构和用例。无限级联:此组件支持无限级联选择,使您能够创…

最好的ppt模板网站是哪个?做PPT不可错过的18个网站!

现在有很多PPT模板网站,但真正免费且高质量的不多,今天我就分享主流的国内外PPT模板下载网站,并且会详细分析这些网站的优缺点,这些网站都是基于个人实际使用经验的,免费站点会特别标注,让你可以放心下载&a…

信息安全工程师(64)其他恶意代码分析与防护

前言 恶意代码是指那些能够损害系统用户和系统所有者利益的软件,是故意在计算机系统上执行恶意任务的恶意代码的集合。 一、恶意代码分析 病毒(Virus) 定义:病毒是一种人为制造的、能够进行自我复制的、具有对计算机资源的破坏作用…

国家信息安全水平考试(NISP一级)最新题库-第十七章

目录 另外免费为大家准备了刷题小程序和docx文档,有需要的可以私信获取 1 受到了ARP欺骗的计算机,发出的数据包,     地址是错误的() A.源IP;B.目的IP;C.源MAC;D.目的MAC 正…

rust入门基础总结

文章目录 前言1、输出格式规范一、占位符相关(一){}与{:?} 二、参数替换方式(一)位置参数(二)具名参数 三、格式化参数(一)宽度(二)对齐(三&…

基于K8S的StatefulSet部署mysql主从

StatefulSet特性 StatefulSet的网络状态 拓扑状态:应用的多个实例必须按照某种顺序启动,并且必须成组存在,例如一个应用中必须存在一个A Pod和两个B Pod,且A Pod必须先于B Pod启动的场景 存储状态:应用存在多个实例&…

Golang | Leetcode Golang题解之第500题键盘行

题目: 题解: func findWords(words []string) (ans []string) {const rowIdx "12210111011122000010020202" next:for _, word : range words {idx : rowIdx[unicode.ToLower(rune(word[0]))-a]for _, ch : range word[1:] {if rowIdx[unico…