历史上的今天

今天是:2024年10月27日(星期日)

正在发生

2021年10月27日 | stm32专题二十四:ADC独立模式单通道采集

发布者:见贤思奇异果 来源: eefocus关键字:stm32  ADC  独立模式  单通道采集 手机看文章 扫描二维码
随时随地手机看文章

ADC独立单通道采集


使用的是野火stm32f103vet6指南者开发板,硬件连接图如下:

实验一:独立单通道中断读取ADC值


编程要点:


初始化ADC用到的GPIO;

初始化ADC初始化结构体;

配置ADC时钟,配置通道的转换顺序和采样时间;

使能ADC转换完成中断,配置中断优先级;

使能ADC,准备开始转换;

校准ADC;

软件触发ADC,真正开始转换;

编写中断服务函数,读取ADC转换数据;

编写main函数,把转换的数据打印出来;

代码如下:


bsp_adc.c


#include "bsp_adc.h"

 

static void ADCx_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

// 打开 ADC IO端口时钟

ADC_GPIO_APBxClock_FUN(ADC_GPIO_CLK, ENABLE);

// 配置 ADC IO 引脚模式

// 必须为模拟输入

GPIO_InitStructure.GPIO_Pin = ADC_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

// 初始化 ADC IO

GPIO_Init(ADC_PORT, &GPIO_InitStructure);

}

 

static void ADCx_Mode_Config(void)

{

ADC_InitTypeDef ADC_InitStruct;

// 打开ADC的时钟

ADC_APBxClock_FUN(ADC_CLK, ENABLE);

ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; // 独立模式

ADC_InitStruct.ADC_ScanConvMode = DISABLE; // 不使用扫描模式

ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; // 连续转换

/* 不使用外部触发 */

ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStruct.ADC_NbrOfChannel = 1;

ADC_Init(ADC_x, &ADC_InitStruct);

RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 配置ADC时钟为8分频 ADCCLK = 9M

ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5);

ADC_ITConfig(ADC_x, ADC_IT_EOC, ENABLE); // 配置ADC转换完成中断

ADC_Cmd(ADC_x, ENABLE); // 使能ADC

ADC_ResetCalibration(ADC_x); // 初始化ADC 校准寄存器  

while(ADC_GetResetCalibrationStatus(ADC_x)); // 等待校准寄存器初始化完成

ADC_StartCalibration(ADC_x); // ADC开始校准

while(ADC_GetCalibrationStatus(ADC_x)); // 等待校准完成

ADC_SoftwareStartConvCmd(ADC_x, ENABLE); // 使用软件触发

}

 

static void ADC_NVIC_Config(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

// 优先级分组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

 

  // 配置中断优先级

  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

 

/**

  * @brief  ADC初始化

  * @param  无

  * @retval 无

  */

void ADCx_Init(void)

{

ADCx_GPIO_Config();

ADCx_Mode_Config();

ADC_NVIC_Config();

}

 

bsp_adc.h


#ifndef __BSP_ADC_H

#define __BSP_ADC_H

 

#include "stm32f10x.h"

 

// ADC GPIO宏定义

#define    ADC_GPIO_APBxClock_FUN        RCC_APB2PeriphClockCmd

#define    ADC_GPIO_CLK                  RCC_APB2Periph_GPIOC  

#define    ADC_PORT                      GPIOC

#define    ADC_PIN                       GPIO_Pin_1

 

// ADC 编号选择

// 可以是 ADC1/2,如果使用ADC3,中断相关的要改成ADC3的

#define    ADC_APBxClock_FUN             RCC_APB2PeriphClockCmd

#define    ADC_x                         ADC2

#define    ADC_CLK                       RCC_APB2Periph_ADC2

 

// ADC 通道宏定义(PC1对应通道11)

#define    ADC_CHANNEL                   ADC_Channel_11

 

// ADC 中断相关宏定义

#define    ADC_IRQ                       ADC1_2_IRQn

#define    ADC_IRQHandler                ADC1_2_IRQHandler

 

void ADCx_Init(void);

 

 

#endif /* __BSP_ADC_H */

中断服务函数中,当转换完成后,把转换值不断刷新到全局变量中:


void ADC_IRQHandler(void)

{

if (ADC_GetITStatus(ADC_x, ADC_IT_EOC) == SET)

{

ADC_ConvertedValue = ADC_GetConversionValue(ADC_x);

}

ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC); // 清中断标志位,防止一直在中断里

}

最后在主函数中进行测试:


#include "stm32f10x.h"

#include "bsp_led.h"

#include "bsp_usart.h"

#include "bsp_adc.h"

#include

 

__IO uint16_t ADC_ConvertedValue;

 

// 局部变量,用于保存转换计算后的电压值  

float ADC_ConvertedValueLocal;        

 

void Delay(__IO uint32_t nCount)

{

  for(; nCount != 0; nCount--);

 

int main(void)

{

LED_GPIO_Config();

USART_config();

ADCx_Init();

printf("这是一个ADC独立单通道读取实验tn");

while (1)

{

ADC_ConvertedValueLocal =(float) ADC_ConvertedValue / 4096 * 3.3; 

printf("The current AD value = %#X tn", 

       ADC_ConvertedValue); 

printf("The current voltage = %f V tn",

       ADC_ConvertedValueLocal); 

printf("n");

LED_B_TOGGLE;

Delay(0x2fffee);  

}

}


实验现象如下:

实验二:独立单通道DMA读取


      当要传输大量的数据时,一般都是采用DMA。ADC + DMA本身的配置非常简单,就只需要注意,只能使用ADC1或ADC3,而ADC2无DMA传输功能。


这里主要看一下ADC + DMA配置:


/**

  * @brief ADC - DMA配置

  * @note  注意,ADC - DMA只能使用ADC1 或 ADC3,ADC2无DMA功能

  */

static void ADCx_DMA_Config(void)

{

DMA_InitTypeDef DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_DeInit(ADC_DMA_CHANNEL);

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC_x->DR));

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize = 1;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);

DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);

}

然后在ADC配置函数中进行调用,再使能ADC + DMA:


/* ADC - DMA设置要在使能ADC完成 */

ADCx_DMA_Config(); // 配置ADC - DMA

ADC_DMACmd(ADC_x, ENABLE); // 使能 ADC DMA 请求


然后在main.c中进行测试,结果如下:

关键字:stm32  ADC  独立模式  单通道采集 引用地址:stm32专题二十四:ADC独立模式单通道采集

上一篇:stm32专题二十四:ADC 标准库函数分析
下一篇:stm32专题二十四:ADC + DMA 多通道 规则同步

推荐阅读

集微网消息  10月25日,日月光控股子公司矽品SPIL (Cayman) Holding Limited发布公告称与晋华集成电路签订增资扩股协议。根据公告内容,双方将共同投资矽品电子(福建)有限公司(以下简称福建矽品),目的在于深化福建矽品与主要客户间的产销合作关系。晋华第一期预计投资福建矽品2250万元美元,福建矽品增资后资本额为1.125亿美元,晋华公司持股20%;未...
(记者 李玉坤)记者从市发改委了解到,世界仅有三个地区电力接入全免费,北京是其中之一。 2018年,北京在全国率先推出小微企业低压电力接入“零上门、零审批、零投资”的三零服务,使办理环节由6个缩减为2个,平均用时由141天大幅缩减到15天,接入成本由19.2万元降为0元,北京与日本、阿联酋成为世界上仅有的三个电力接入全免费的地区。 截至目前...
半导体是一个需要长期耕耘、持续投入创新才能开花结果的行业。1993年,国微集团聚焦安全芯片及其应用领域,在中国半导体的第一个黄金十年乘风破浪,并于2016年成功在香港联交所主板上市。有人说,中国半导体正在开启第二个黄金十年,半导体企业都在思考,这一历史机遇该如何把握?而国微集团早已开启新的征程,踏上了建立国产EDA产业平台之路。EDA代表电子...
感谢IT之家网友 @美滋滋_ 的线索投递,苹果在今日凌晨为 Apple TV 设备推送了 tvOS 15.1 正式版,新增支持 SharePlay 等,这是 2021 年 9 月推出的 tvOS 系统的首次重大更新。  苹果的 tvOS 更新包的体积一般都比较小,专注于底层错误修复、性能更新和小调整,而非增加面向外部的新功能。但今日的更新增加了对 SharePlay 的支...

史海拾趣

问答坊 | AI 解惑

WINCE 无线网卡驱动与NDIS

各位英雄:      小弟最近开始接触wince下wifi模块驱动,有几个基本的问题还没有弄明白,恳请各位英雄指教!             小弟对wince下的以太网卡驱动有一定的了解,知道它是基 ...…

查看全部问答∨

请问"禁能中断"的确切含义"

如果我禁能了一个中断源, 不论什么平台吧, ARM或51都无所谓. 那么当这个中断到来时, 中断标志位会被置上吗? "禁能"的意思究竟是中断标志位不会被置上, 还是说标志位会被置上, 但不会跳转到相应的处理函数? 如果被置上了, 我在什么时候清中断 ...…

查看全部问答∨

文件指针

如何使用Zw形势的函数把文件指针移到文件末尾以实现追加写…

查看全部问答∨

修改TFT驱动,导致只显示半个屏幕的现象

我修改了触摸屏驱动导致出现只显示上半个屏幕的现象,下半个屏幕是白色的;并且上半个屏幕的分辨率是正常的,程序窗口正适合3.5寸液晶屏幕。     ------------比以前有进步。 红色部分为修改后的内容: 修改部分:s2410.h   &nb ...…

查看全部问答∨

EVC有gridctrl这个控件吗?哪能下载到啊?

VC不自带这个控件,要下载.不知道EVC是否支持这个控件?…

查看全部问答∨

求救:在usb中的根文件中创建文件,windows不能打开

在单片机里开发usb的驱动,并支持fat的文件系统。 根据fat16的规则在usb文件系统中创建新的文件。 首先在FAT区查找可用的簇 然后根目录区查找可用的目录项,填充32字节的内容。 然后把FAT中的簇标记为0xffff 然后往实际的簇填入文件的内容。 ...…

查看全部问答∨

ST以为自己是胡哥

问他们能否提供STM32 的FFT,调查了好几次。决定用TMS320F2808,FFT现成的,相关系列产品价格差不多,特别明年推出的TMS320F2802X和TMS320F2803X,性价比更好。他们最后一次:“我是问你要做什么产品,产品的市场是什么,另外我们也需要知 ...…

查看全部问答∨

CodeSourcery免费吗

想了解下 如果把CodeSourcery的编译器嵌到软件中 随硬件卖给客户(软件算送) 这个犯法不?…

查看全部问答∨

如何用T0输出两个不同的频率(先低频率,然后高频率)

      我用T0定时,输出两个不同的频率,先输出一个低点的频率,延时一段时间输出高点的频率,本来是想通过改变装不同的初值来实现输出不同的频率,但程序下载在单片机后,用示波器观察不正确,一直只有低的频率,不论等 ...…

查看全部问答∨

高输入阻抗为什么好呢?

都说电压跟随器有高输入阻抗,低输出阻抗。在网上也查了 高输入阻抗为什么好:“假设讯源输出一个固定电压,传送往下一级,如果这一级的输入阻抗高,是不是由讯源所提供的讯号电流就可以降低?如果输入阻抗非常非常的高,则几乎不会消耗讯号电流(当 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved