历史上的今天
返回首页

历史上的今天

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

正在发生

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

2021-10-27 来源:eefocus

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中进行测试,结果如下:

推荐阅读

史海拾趣

AMS公司的发展小趣事

AMS(Austria Microsystems)公司是一家总部位于奥地利的半导体制造商,专注于开发和生产高性能的模拟半导体解决方案。以下是 AMS 公司发展的五个相关故事:

  1. 创立与早期阶段:AMS 公司成立于1981年,最初是一家从事晶圆制造的小型企业。公司创始人团队以其对半导体技术的深刻理解和创新能力,在短时间内取得了一定的成就。早期产品主要包括模拟集成电路(IC)和传感器,为医疗、汽车、工业等领域提供解决方案。

  2. 技术创新与产品扩展:随着市场需求的不断变化和技术的进步,AMS 公司不断进行技术创新,并扩展了产品线。公司致力于开发具有高性能、低功耗和小尺寸的模拟半导体产品,以满足智能手机、消费电子、工业自动化等领域的需求。公司的产品涵盖了光学传感器、环境传感器、声学传感器等多个领域。

  3. 全球化发展与市场拓展:AMS 公司通过不断拓展全球市场,加强与客户和合作伙伴的合作关系,实现了快速的业务增长。公司在欧洲、亚洲和美洲设立了多个销售办事处和生产基地,建立了完善的全球供应链和销售网络。公司的产品销售网络覆盖了全球范围,得到了国内外客户的广泛认可。

  4. 收购与合并:随着公司规模的扩大和市场竞争的加剧,AMS 公司通过收购和合并等方式不断强化自身实力。公司先后收购了一些技术领先的公司,扩大了产品线和市场份额。此举进一步提升了公司在模拟半导体领域的竞争优势,加速了公司的业务增长。

  5. 持续创新与未来展望:AMS 公司将继续致力于技术创新和产品研发,不断提升产品性能和品质水平。公司将关注新兴技术和市场趋势,积极布局未来的发展方向,包括人工智能、物联网、汽车电子等领域。同时,公司还将加强与客户和合作伙伴的合作,共同推动行业的发展和进步。

C&D公司的发展小趣事

C&D公司自创立之初,就专注于电子技术的研发与创新。创始团队凭借深厚的行业经验和前瞻性的市场洞察力,成功开发出一系列具有竞争力的电子产品。在市场竞争激烈的背景下,C&D公司凭借卓越的产品性能和精准的市场定位,迅速在行业中崭露头角。

Focus公司的发展小趣事

在数字化转型的大潮中,一家名为Focus的电子产品制造商(虚构)意识到传统制造模式的局限性,决定实施全面的数字化转型战略。公司首先引入了先进的ERP系统和智能制造技术,实现了生产流程的自动化和智能化。同时,为了快速扩大市场份额和增强技术实力,Focus积极寻求并购机会,先后收购了多家在物联网、人工智能等领域具有核心竞争力的初创企业。通过资源整合和优势互补,Focus迅速成长为行业内的领军企业。

EAO公司的发展小趣事

面对全球市场的竞争压力,EAO公司坚定实施全球化战略。公司在全球范围内建立了完善的销售网络和售后服务体系,为客户提供及时、高效的服务。同时,EAO公司还积极寻求与国际知名企业的合作机会,共同开拓市场、分享资源。通过全球化战略的实施,EAO公司不断提升品牌影响力和市场竞争力。

Device Engineering Incorporated公司的发展小趣事

在电子行业快速发展的背景下,DEI公司意识到只有不断创新才能保持竞争力。因此,公司加大了对研发的投入,积极引进新技术和人才。通过不断的努力,DEI公司成功推出了一系列具有自主知识产权的创新产品,涵盖了多个领域。这些产品不仅提升了公司的竞争力,也为公司赢得了更多的市场份额。

Capax Technologies Inc公司的发展小趣事

随着国内市场的饱和,Capax Technologies Inc开始积极拓展海外市场。公司制定了详细的国际化战略,通过设立海外研发中心、建立销售网络等方式,逐步进入国际市场。在国际化的过程中,Capax Technologies Inc不仅提升了自身的技术水平和市场竞争力,还积累了丰富的国际经验,为公司的长远发展奠定了坚实基础。

问答坊 | AI 解惑

为什么单片机开发板国内外有明显差异?

为什么单片机开发板国内外有明显差异?                 文章内容: 初学者遍寻国内各地开发板,已经形成了基本概念 偶然查阅国外网站 发现至少外观形式有明显差异-- 1.-国外使用“面包板 ...…

查看全部问答>

晶振计算工具

晶振计算工具 晚上补充附件…

查看全部问答>

DS18B20单总线温度传感器

DS18B20单总线温度传感器…

查看全部问答>

求助C8051f930的中文资料

哪位达人能给点资料, C8051f930的中文资料. 或者相关的中文资料也可.…

查看全部问答>

WINCE6下自动运行程序和任务栏相关问题

WINCE6下开机自动运行自己的应用程序,但偶尔会出现CE6的任务栏,怎么才能把任务栏给disable呢?…

查看全部问答>

关于GX.DLL

客户要求我们的平台提供GX.DLL的支持,平台是Telechips 7901+wince 5.0. 以前没有搞过这个东东,从网上找了一些gx.dll都不合适,客户说,这个dll是根据我们的BSP自己编译出来的,我们也没有源码,不知道该如何做。 请用过gx.dll的大侠帮帮忙,我 ...…

查看全部问答>

wince下的c# winfrom程序如果防止多重启动

wince下的c# winfrom程序如果防止多重启动…

查看全部问答>

4200脉冲IV测量CMOS晶体管系统配置

4200-PIV[1]包在4200-SCS[2]主机更高编号的插槽中增加了2个卡,如图2所示。此外,脉冲IV的互连也显示在图2和3中。 图2. PIV的连接图     图3. 4200-SCP2侧视图。4200-SCP2[3]连接的适配器细节显示了示波器通道输入的BNC到SMA ...…

查看全部问答>

cc2430组网

毕业设计要做zigbee的组网实验,之前完全没接触过,用的是cc2430学习版。在做协调器组网实验时,下载程序后,打开协调器,理论上是LED3点亮表示建网成功,但实际上是LED2亮了(下图),换成路由器或终端设备,仍然是LED2灯亮,希望大家能帮忙指点迷 ...…

查看全部问答>

求LPC11xx IAR启动文件

小弟想把keil mdk下的LPC1114工程移植到IAR for ARM下,目前来说已经成了一个半成品,在keil下工程调试时可以在IDE中复位MCU,然后从头开始运行。但这个功能在IAR下不知道为何就是无法正常使用,如果点击回到程序开头那个按钮,程序依然不会回去到m ...…

查看全部问答>