STM32单片机(七)ADC模拟数字转换器----第二节:ADC模数转换器练习(AD单通道和AD多通道)

news/2024/6/3 18:12:04 标签: 单片机, stm32, 嵌入式硬件, 程序人生

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
🌙专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。

⭐️ 专栏主要内容: 主要学习STM32单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机单片机的外设,全程手敲代码,实现我们所要实现的功能。
🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
💑专栏主页:http://t.csdn.cn/HCD8v

本学习过程参考:https://space.bilibili.com/383400717

STM3单片机安装软件、各种资料以及源码的路径:
链接:https://pan.baidu.com/s/1snD0uuTfMhchFqOMWvAiHA?pwd=asdf#list/path=%2F
提取码:asdf

链接里压缩包的解压密码:32

本大节主要学习ADC模拟数字转换器的相关知识,包含两小节:
第一小节主要学习ADC模拟数字转换器的理论基础知识,第二小节是对第一小节的内容写两个程序进行练习,分别是AD单通道和AD多通道;
最终附上所有的源代码;

本小节是对第一小节ADC模数转换器的内容写两个程序进行练习,分别是AD单通道和AD多通道;

文章目录

  • 一、本节目标
    • 目标1:AD单通道
    • 目标2:AD多通道
  • 二、练习一:AD单通道
    • 2.1 接线图
    • 2.2 源码
  • 三、练习二:AD多通道
    • 3.1 接线图
    • 3.2 源码

一、本节目标

目标1:AD单通道

屏幕第一行显示的是AD转换后的原始数据,第二行是经过处理后实际的电压值;
在这里插入图片描述
当拧动电位器时:

  • 往左拧,AD值减小,电压值也减小;AD值最小是0,对应的电压就是0;
    在这里插入图片描述

  • 往右拧,AD值变大,对应的电压值也变大;STM32的ADC是12位的,所以AD结果最大值时4095,对应的电压是3.3V;
    在这里插入图片描述

目标2:AD多通道

分别外接光敏电阻、热敏电阻和反射红外模块,把他们的AO、模拟电压输出端,分别接在A1、A2、A3引脚,加上目标1里的电位器,总共4个输出通道;然后测出来的4个AD数据分别显示在显示屏上:在这里插入图片描述

  • AD0表示电位器的AD数据;往左拧减小,往右拧增大;
  • AD1表示光敏电阻的AD数据,遮挡光敏电阻,光线减小,AD值增大;移开,光线增大,AD值减小;
  • AD2表示热敏电阻的AD数据;用手热一下热敏电阻,温度升高,AD值减小;移开,温度降低,AD值增大;
  • AD3表示反射红外传感器;手靠近,有反光,AD值减小;移开,没有反光,AD值增大;

二、练习一:AD单通道

2.1 接线图

在这里插入图片描述

  • 电位器左边引脚接负极,右边引脚接正极,中间引脚接PA0口;PA0-PB1这10个引脚都是ADC的通道,任选一个即可;

实物图如下所示:

在这里插入图片描述

2.2 源码

代码路径:

  • STM32入门教程资料\程序源码\STM32Project\7-1 AD单通道\User
  • STM32入门教程资料\程序源码\STM32Project\7-1 AD单通道\Hardware
#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, "Volatge: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.c:

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	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_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	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_Cmd(ADC1, ENABLE);
	
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}

uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}

三、练习二:AD多通道

3.1 接线图

在这里插入图片描述

  • 使用了4个AD通道,第一个通道还是电位器,接在PA0口,之后上面又接了3个传感器模块,分别是光敏传感器、热敏传感器、反射式红外传感器;他们的VCC和GND都分别接在面包板的正负极;然后AO是模拟量的输出引脚,三个模块的AO分别接在PA1、PA2和PA3口;

3.2 源码

代码路径:

  • STM32入门教程资料\程序源码\STM32Project\7-2 AD多通道\User
  • STM32入门教程资料\程序源码\STM32Project\7-2 AD多通道\Hardware
#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);
	}
}

AD.c

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	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_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_Cmd(ADC1, ENABLE);
	
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}

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);
}

http://www.niftyadmin.cn/n/459535.html

相关文章

macOS Sonoma编译OpenCV源码输出IOS平台库

1.macOS下载并编译OpenCV源码: 克隆源码: 主仓: git clone https://github.com/opencv/opencv.git 扩展仓: git clone https://github.com/opencv/opencv_contrib.git 编译xcode源码需要CMake与XCode命令行工具 确认已安装CMake 确认已安装XCode 安装xcode command l…

Redis 通用命令

通用命令介绍 Redis 通用命令是一些 Redis 下可以作用在常用数据结构上的常用命令和一些基础的命令,比如删除键、对键进行改名、判断键是否存在等。简单说,就是 keys 分类的命令,如下图。 上图中圈中的部分,就是所谓的通用的命令…

【Java|多线程与高并发】wait和notify方法详解

文章目录 1.前言2.wait和notify的基本使用3. notifyAll方法4. wait和sleep方法的对比5. 总结 1.前言 在Java多线程环境中,线程之间是抢占式执行的,线程的调度是随机的.这就很难受了. 在很多情况下我们希望线程以我们想要的顺序来执行. 这就需要wait和notify这两个方法 2.wait和…

『手撕 Mybatis 源码』08 - 动态代理 invoke 方法

动态代理 invoke 方法 问题 mapperProxy.findByCondition(1); 是怎么完成的增删改查操作? 当通过 JDK 代理方式生成代理对象后,可以通过代理对象执行代理方法 public class MybatisTest {/*** 问题3:mapperProxy.findByCondition(1); 是怎…

[Leetcode] 0706. 设计哈希映射

706. 设计哈希映射 点击跳转至leetcode 题目描述 不使用任何内建的哈希表库设计一个哈希映射(HashMap)。 实现 MyHashMap 类: MyHashMap() 用空映射初始化对象void put(int key, int value) 向 HashMap 插入一个键值对 (key, value) 。如果 key 已经存在于映射中&am…

适用于Uniapp快速开发小程序的5个开源UI框架

随着UniApp愈发流行,支持UniApp的UI组件库就显得更加受欢迎,这里就分享几款支持UniApp的UI组件库。让你跨端应用开发更快速、更高效 TMUI 优质Vue3 TS Pinia Vite跨端组件库,Uni App通用组件库跨端组件库,支持NVUE原生渲染,APP(安卓,IOS),微信小程序,H…

【深度学习】RepVGG解析和学习体会

文章目录 前言0. Vgg1.RepVGG Block 详解 前言 论文名称:RepVGG: Making VGG-style ConvNets Great Again 论文下载地址:https://arxiv.org/abs/2101.03697 官方源码(Pytorch实现):https://github.com/DingXiaoH/RepV…

Java-API简析_java.lang.SecurityManager类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/131346082 出自【进步*于辰的博客】 其实我的【Java-API】专栏内的博文对大家来说意义是不大的。…