IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 蓝桥杯嵌入式_STM32学习_ADC配置 -> 正文阅读

[嵌入式]蓝桥杯嵌入式_STM32学习_ADC配置

原理

基础知识

1、GPIO

在这里插入图片描述
根据滑动变阻器的引脚,我们可以知道应该用 PB0 来作为ADC的获取引脚。
在这里插入图片描述
再通过芯片手册(注意,不是数据手册哈),我们可以知道ADC是通道8.
板子有三个ADC,那么用哪个ADC呢?
咱们就默认ADC1就行。反正比赛就先讲效率吧(摆烂)。

2、通道

ADC有规则通道和注入通道。
规则通道就是很正常的通道。
注入通道就是类似中断一样的,且前提是有规则通道的存在。
但是我们比赛只用得到规则通道。
所以,初始化时,我们要默认配置成规则通道。

3、触发方式

肯定用软件啊!!!
Pass.

4、转换时间

转换时间:Tconv = 采样时间 + 12.5 个周期

先看周期——
ADC_CLK:ADC模拟电路时钟,最大值为14M,由
PCLK2提供,还可分频,2/4/6/8,RCC_CFGR 的
ADCPRE[1:0]设置。PCLK2=72M
所以我们最大分频为72 / 6 = 12M。
这里是后面初始化分频时要注意的地方,分频系数注意要大于等于6。

采样时间在库里会有枚举好的变量,这里只要知道采样时间越长,精度越高就行。
我们比赛当然还是精度高点好。

5、数据

数据的寄存器是十六位有效,但是ADC数据的分辨率是12位的,
所以初始化中会有一个数据左对齐或者右对齐。
我们使用右对齐会方便很多。

另外,由于精度是12位,且最大电压为3.3V,所以最小精度为(3.3 / pow(2,12)) //(这里是2的十二次方哈,最近二级把我搞麻了)
所以直接写成 3.3 / 4096.
即计算公式为 Y = (3.3 / 4096)*X

初始化结构体

在这里插入图片描述
第一个,我们选择独立模式,因为我们只用到了ADC1.
第二个也是一样的道理,所以DISABLE。
第三个,这个看自己吧,开连续转换和不开的区别我还不清楚,很多人都说关,但是我开了(狗头)。等我会了再来改。
第四个,是否选择外部触发,选否,ADC_ExternalTrigConv_None 这个。
第五个,右对齐啦,上面讲过了。
第六个,我们只用了一个通道(那个通道8的),所以这里选1.

常用库函数

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);

配置ADC时钟分频。这里我们就选 六分频就行——RCC_PCLK2_Div6
**注意这个函数在RCC头文件里哈。 **

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);

这个就不用多说了吧。

void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);

使能 ADC。

void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);

使能ADC的中断,注意这里的标志位是 ADC_IT_EOC,EOC是规则转换完的标志位。

void ADC_ResetCalibration(ADC_TypeDef* ADCx);

使能 ADC 复位校准。

FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);

获取复位校准标志位。

void ADC_StartCalibration(ADC_TypeDef* ADCx);

开启 ADC 校准。

FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);

获取校准标志位。

void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

软件转换使能;

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

规则通道配置。
第二个参数是通道,我们填通道8——ADC_Channel_8
第三个是转换顺序,我们只有一个,所以就填 1
第四个是采样时间,找到参数列表,自己选择,根据前面讲的越大越好(当然只是在蓝桥杯比赛中,实际应用肯定要注意效率),我选 ADC_SampleTime_239Cycles5,239.5。

uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);

获取转换后的数值。

ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);

获取中断标志位。

void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);

清零中断标志位。

代码

//bsp_adc.c

#include "bsp_adc.h"

static void ADC1_GPIO_Comfig(void){
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

static void ADC1_Comfig(void){
	ADC_InitTypeDef ADC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//ADC配置
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	//使能ADC、中断、软件触发,配置规则通道
	ADC_Cmd(ADC1, ENABLE);
	ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
	
	//ADC校准
	ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
}

static void ADC1_NVIC_Comfig(void){
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void ADC1_Init(void){
	ADC1_GPIO_Comfig();
	ADC1_Comfig();
	ADC1_NVIC_Comfig();
}

//bsp_adc.h

#ifndef __BSP_ADC_H
#define __BSP_ADC_H

#include "stm32f10x.h"

void ADC1_Init(void);


#endif /* __BSP_ADC_H */

//stm32f10x_it.c

uint16_t ADC_ConversionValue;
void ADC1_2_IRQHandler(void){
	if(ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET){
		ADC_ConversionValue = ADC_GetConversionValue(ADC1);
	}
	ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
}

//main.c

extern uint16_t ADC_ConversionValue;
float ADC_ConversionValueLocal = 0;
ADC1_Init();
while(1){
    ADC_ConversionValueLocal = (float)ADC_ConversionValue * 3.3 / 4096 ;
	printf("ADC : %f V \r\n",ADC_ConversionValueLocal);
}

要点

1-初始化ADC用到的GPIO ;
2-初始化ADC初始化结构体 ;
3-配置ADC时钟,配置通道的转换顺序和采样时间 ;
4-使能ADC转换完成中断,配置中断优先级;
5-使能ADC,准备开始转换 ;
6-校准ADC ;
7-软件触发ADC,真正开始转换 ;
8-编写中断服务函数,读取ADC转换数据 ;
9-编写main函数,把转换的数据打印出来 ;

注意

记得开 ADC 时钟!!!

代码快速配置

打开文件:赛点资源数据包_嵌入式\6-STM32固件库代码V3.5版\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\ADC\ADC1_DMA
打开main.c文件——
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
复制修改为——

void Adc1_Init(void){
  ADC_InitTypeDef ADC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
	
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);//PB0

  /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
	
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//关闭多通道模式 
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
	 /* ADC1 regular channel14 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));
     
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

获取函数

u16 Adc_get(void){
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == 0);
	return ADC_GetConversionValue(ADC1);
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:07:25  更:2022-03-21 21:08:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:46:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码