当前位置: 首页 > news >正文

江协科技STM32学习- P22 实验-ADC单通道/ADC多通道

      🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚 

🚀Projeet source code🚀   

💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com

引用:

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

Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客

STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客

【STM32】江科大STM32学习笔记汇总(已完结)_stm32江科大笔记-CSDN博客

江科大STM32学习笔记(上)_stm32博客-CSDN博客

STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客

STM32 MCU学习资源-CSDN博客

stm32学习笔记-作者: Vera工程师养成记

stem32江科大自学笔记-CSDN博客

术语:

英文缩写描述
GPIO:General Purpose Input Onuput通用输入输出
AFIO:Alternate Function Input Output复用输入输出
AO:Analog Output模拟输出
DO:Digital Output数字输出
内部时钟源 CK_INT:Clock Internal内部时钟源
外部时钟源 ETR:External clock 时钟源 External clock 
外部时钟源 ETR:External clock mode 1外部时钟源 Extern Input pin 时钟模式1
外部时钟源 ETR:External clock mode 2外部时钟源 Extern Trigger 时钟模式2
外部时钟源 ITRx:Internal trigger inputs外部时钟源,ITRx (Internal trigger inputs)内部触发输入
外部时钟源 TIx:external input pin 外部时钟源 TIx (external input pin)外部输入引脚
CCR:Capture/Comapre Register捕获/比较寄存器
OC:Output Compare输出比较
IC:Input Capture输入捕获
TI1FP1:TI1 Filter Polarity 1Extern Input 1 Filter Polarity 1,外部输入1滤波极性1
TI1FP2:TI1 Filter Polarity 2Extern Input 1 Filter Polarity 2,外部输入1滤波极性2

正文:

0. 概述

从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。


定时器共四个部分,分为八个小节笔记。本小节为第一部分第一节。

🌳在第一部分,是定时器的基本定时的功能:定时中断功能、内外时钟源选择

🌳在第二部分,是定时器的输出比较功能,最常见的用途是产生PWM波形,用于驱动电机等设备

🌳在第三部分,是定时器的输入捕获功能和主从触发模式,来实现测量方波频率

🌳在第四部分,是定时器的编码器接口,能够更加方便读取正交编码器的输出波形,编码电机测速


1.🚢第一个代码:AD单通道

接线图:

电位器的内部结构是这样的:

左边和右边的两个引脚接的是电阻的两个固定端,中间这个引脚接的是滑动抽头。电位器外边这里有个十字形状的槽,可以拧,往左拧抽头就往左靠,往右拧,抽头就往右靠。所以外围电路这里,我们把左边的固定端接在负极,右边的固定端接在正极,中间就可以输出,从负极到正极可调的电压了,把可调的电压输出接在PA0。

2.🚢ADC初始化步骤

AD的初始化看这个结构图

ADC初始化的步骤具体的步骤:

🦄第一步,开启RCC时钟,包括ADC和GPIO的时钟。另外这里ADC CLK的分频器也需要配置一下。

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

🦄第三步,配置多路开关

把左边的通道接入到右边的规则组列表里。这个过程就是我们之前说的点菜,把各个通道的菜列在菜单里。

🦄第四步,配置ADC转换器,在库函数里是用结构体来配置的,可以配置这一大块电路的参数。

如果需要模拟看门狗,会有几个函数用来配置阈值和监测通道的。

如果想开启中断,就在中断输出控制里用ITconfig函数开启对应的中断输出,然后再在NVIC里配置一下优先级,这样就能触发中断了。

不过模拟看门狗中断我们本节暂时不用。

第五步,开关控制,调用一下ADC_Cmd的函数开启ADC。

这样ADC就配置完成了就能正常工作了。

第六步,校准

当然在开启ADC之后,根据手册里的建议,我们还可以对ADC进行一下校准,这样可以减小误差。在ADC工作的时候,如果想要软件触发转换,会有函数可以触发。如果想读取转换结果,也会有函数,可以读取结果。这个等会介绍扩函数的时候就可以看到了。

3.🚢ADC相关的库函数

首先我们看一下ADC CLK的配置函数,打开这个rcc.h文件,拖到最后。

这个函数是用来配置ADC CLK分频器的。它可以对APB2的72MHz时钟选择二、四、六、八分频,输入到ADC CLK,这就是这个函数的作用。

然后我们找一下ADC的库函数,打开adc.h文件,拖到最后。

三个初始化相关函数

这三个函数和其它模块的库函数一样,都是老朋友,不用多讲了。

ADC_Cmd

这个是用于给ADC上电的,也就是这里的开关控制

ADC_DMACmd

这个是用于开启DMA输出信号的。如果使用DMA转运数据,就得调用这个函数。这个我们下节讲DMA的时候再用。

ADC_ITConfig

中断输出控制,也就是这里用于控制某个中断能不能通过NVIC

四个校准相关函数

接下来这里有四个函数

分别是复位校准、获取复位校准状态、开始校准、获取开始校准状态,这就是用于控制校准的函数。我们在ADC初始化完成之后依次调用就行了。

ADC_SoftwareStartConvCmd

ADC软件开始转换控制这个就是用于软件触发的函数了调用一下就能软件触发转换了也就是这里的触发控制,我们目前使用软件触发。

ADC_GetSoftwareStartConvStatus

ADC获取软件开始转换状态,从名字上来看,这个函数好像是判断转换是不是正在进行的。我们是不是可以调用这个函数来判断转换是否已经结束?答案是不行的。这个函数就是用来获取CR2SWSTART这一位。

在手册里可以看到这一位的作用是开始转换规则通道由软件设置该位启动转换转换开始后硬件马上清除此位。

因此,ADC_SoftwareStartConvCmd这个函数就是给SWSTART位置1,以开始转换的。

而ADC_GetSoftwareStartConvStatus这个函数是返回SWSTART的状态。

由于SWSTART位在转换开始后立刻清零了。所以这个函数的返回值跟转换是否结束毫无关系。

那如何才能知道转换是否结束?

我们需要用到下面这个函数:

ADC_GetFlagStatus

获取标志位状态,然后参数给EOC的标志位,判断EOC标志位是不是置1了。如果转换结束,EOC标志位置1,然后调用这函数判断标志位。这样才是正确的判断转换是否结束的方法。

所以ADC_GetSoftwareStartConvStatus这个函数其实没啥用,我们一般不用,不要被它误导了。

然后下面这两个函数是用来配置间断模式的。

 第一个函数是每隔几个通道间断一次。第二个函数是是不是启用间断模式。需要间断模式的话,可以了解一下。

ADC_RegularChannelConfig

DC规则组通道配置,这个函数比较重要。它的作用就是给序列的每个位置填写指定的通道,就是填写点菜菜单的过程

第一个参数是ADCx,第二个ADC channel就是理想指定的通道。第三个rank就是序列几的位置。然后第四个sample time就是指定通道的采样时间。

ADC_ExternalTrigConvCmd

ADC外部触发转换控制,就是是否允许外部触发转换。

ADC_GetConversionValue

ADC获取转换值,这个函数也比较重要,就是获取AD转换的数据寄存器读取转换结果就要使用这个函数。

ADC_GetDualModeConversionValue

之后,ADC获取双模式转换值,这个是双ADC模式读取转换结果的函数,我们暂时不用。

以上这些函数就是对ADC的一些基本功能和规则组的配置。

九个配置ADC注入组的函数

然后接下来这里有一大批函数,里面都带了一个injected,就是注入组的意思。

这一大批函数都是对ADC注入组进行配置的。

三个模拟看门狗配置的函数

然后下面的这三个函数就是对模拟看门狗进行配置的。

第一个是是否启动模拟看门狗。第二个是配置高低阈值。第三个是配置看门的通道。

ADC_TempSensorVrefintCmd

 ADC温度传感器内部参考电压控制,这个是用来开启内部的两个通道的。如果你要用这两个通道,得调用一下这个函数开启一下,要不然是读不到正确的结果的。

四个获取或清除标志位函数

分别是获取标志位状态、清除标志位、获取中断状态、清除中断挂起位,这些函数也是常用函数了,不用多说。

看完这些函数我们来开始写代码。

4.🚢代码实现

//配置ADC是工作在独立模式,还是双ADC模式
//独立模式,ADC1和ADC2各转换各的
#define ADC_Mode_Independent                       ((uint32_t)0x00000000)
//其余的都是双ADC模式,相对比较复杂
#define ADC_Mode_RegInjecSimult                    ((uint32_t)0x00010000)
#define ADC_Mode_RegSimult_AlterTrig               ((uint32_t)0x00020000)
#define ADC_Mode_InjecSimult_FastInterl            ((uint32_t)0x00030000)
#define ADC_Mode_InjecSimult_SlowInterl            ((uint32_t)0x00040000)
#define ADC_Mode_InjecSimult                       ((uint32_t)0x00050000)
#define ADC_Mode_RegSimult                         ((uint32_t)0x00060000)
#define ADC_Mode_FastInterl                        ((uint32_t)0x00070000)
#define ADC_Mode_SlowInterl                        ((uint32_t)0x00080000)
#define ADC_Mode_AlterTrig                         ((uint32_t)0x00090000)

ADC校准,如下四个函数对应ADC校准的四个步骤

//1.复位校准
void ADC_ResetCalibration(ADC_TypeDef* ADCx);
//2.等地复位校准
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
//3.开始校准
void ADC_StartCalibration(ADC_TypeDef* ADCx);
//4.等待校准完成
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);

4.1 实验1-单ADC转换

代码 AD.C

#include "stm32f10x.h"                  // Device header
#include "AD.h"void AD_Init(void)
{//开启RCC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//APB2 GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//APB2 GPIOA时钟//RCC_ADC Clock预分频值RCC_ADCCLKConfig(RCC_PCLK2_Div6);	//RCC_ADC_Clock=72Mhz/6=12Mhz//GPIOA_Pin0配置为模拟输入//GPIOA_Pin0作为ADC1的输入通道1GPIO_InitTypeDef gpioInitStructure;gpioInitStructure.GPIO_Mode = GPIO_Mode_AIN;gpioInitStructure.GPIO_Pin = GPIO_Pin_0;gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &gpioInitStructure);//ADC模拟输入多路开关选择ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//ADC_Init初始化ADC_InitTypeDef ADC_InitStruct;ADC_StructInit(&ADC_InitStruct);ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//非外部触发,软件触发方式ADC_InitStruct.ADC_ScanConvMode = DISABLE;			//ADC使用非扫描模式ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;	//ADC使用非连续转换模式(单次模式)ADC_InitStruct.ADC_NbrOfChannel = 1;				//ADC规则组转换列表里的数目ADC_Init(ADC1, &ADC_InitStruct);//ADC开关ADC_Cmd(ADC1, ENABLE);//ADC校准ADC_ResetCalibration(ADC1);							//软件置标志位while(ADC_GetResetCalibrationStatus(ADC1) == SET);	//当校准完成之后,硬件自动清除标志位ADC_StartCalibration(ADC1);							//软件置标志位while(ADC_GetCalibrationStatus(ADC1) == SET);		//当校准完成之后,硬件自动清除标志位
}uint16_t GetValue(void)
{uint16_t ADCValue;//软件ADC触发转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);//等待ADC完成while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);ADCValue = ADC_GetConversionValue(ADC1);	//读取清除EOC标志位return ADCValue;
}

代码AD.h

#ifndef __AD_H__
#define __AD_H__void AD_Init(void);
uint16_t GetValue(void);#endif

代码 main.c

#include "stm32f10x.h"                  // Device header
#include "oled.h"
#include "Countersensor.h"
#include "Encoder.h"
#include "Timer.h"
#include "AD.h"
#include "Delay.h"extern uint16_t Num;int main(int argc, char *argv[])
{	uint16_t ADValue;OLED_Init();OLED_ShowString(1, 1, "Cnt:");AD_Init();OLED_ShowString(1, 1, "ADValue:");while(1){ADValue = GetValue();OLED_ShowNum(2, 1, ADValue, 6);Delay_ms(100);}return 1;
}

实验结果:

 4.2 实验2,多通道ADC

http://www.lryc.cn/news/469854.html

相关文章:

  • RL学习笔记-马尔可夫过程
  • LeetCode Hot 100:动态规划
  • 使用Python制作雪景图片教程
  • S-Function
  • 如何具备阅读JAVA JDK虚拟机源码能力
  • Python | Leetcode Python题解之第514题自由之路
  • Docker 镜像下载问题及解决办法
  • 2分钟搞定 HarmonyOs Next创建模拟器
  • 方形件排样优化与订单组批问题探析
  • vue3组件通信--自定义事件
  • ubuntu 安装k3s
  • SQL CHECK 约束:确保数据完整性的关键
  • C++ | Leetcode C++题解之第502题IPO
  • 《虚拟现实的边界:探索虚拟世界的未来可能》
  • Rust教程
  • 测试代理IP的有效性和可用性
  • 散列表:为什么经常把散列表和链表放在一起使用?
  • 计算机网络:网络层 —— IPv4 地址与 MAC 地址 | ARP 协议
  • PMP--一、二、三模、冲刺、必刷--分类--10.沟通管理--技巧--文化意识
  • FileReader和FileWriter
  • 【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第六篇-阶段总结篇】
  • 地球村上一些可能有助于赚钱的20个思维方式
  • 0基础入门matlab
  • 【前端】实操tips集合
  • 基于Springboot+Vue 传统文化管理系统(源码+LW+部署讲解+数据库+ppt)
  • 质量漫谈一
  • 个体化神经调控 Neurolnavigation介绍
  • 02-RT1060 双ADC采样+eDMA传输
  • 单值集合总复习
  • Pyside6 布局管理器(4)--- QGridLayout的使用