STM32——ADC采集

2023-05-16

目录

ADC简介

ADC主要特征

ADC功能框图

ADC引脚

电压输入范围

通道选择

单次转换模式

连续转换模式

转换顺序

规则序列

 注入序列

触发源

转换时间

中断

转换结束中断

模拟看门狗中断

DMA请求

代码讲解

宏定义:


ADC简介

12位ADC是一种逐次逼近型模拟数字转换器,它有多达18个通道,可以测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行.ADC的结果可以是左对齐或者是右对齐方式存储在16位数据寄存器中。

模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阈值。

ADC的输入时钟不得超过14MHZ,它是由PCLK2经分频产生。

ADC主要特征

  • 12位分辨率
  • 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
  • 单次和连续转换模式
  • 从通道0到通道n的自动扫描模式
  • 自校准
  • 带内嵌数据一致性的数据对齐
  • 采样间隔时间可以按通道分别编程
  • 规则转换和注入转换均有外部触发选项
  • 间断模式
  • 双重模式(带2个或以上ADC的器件)
  • ADC转换时间
  • ADC供电要求:2.4V到3.6v
  • ADC输入范围:Vref-<Vin<Vref+
  • 规则通道转换期间有DMA请求产生

ADC功能框图

 注意:1、ADC3的规则转换和注入转换触发与ADC1和ADC2的不同

            2、TIM8_CH4和TIM8_TRGO及他们的重映射位只存在于大容量产品中

ADC引脚

名称信号类型注解
Vref+输入,模拟参考正极ADC使用的高端。正极参考电压,2.4V<=Vref+<=VDDA
VDDA输入,模拟电源等效于VDD的模拟电源且:2.4V<=VDDA<=VDD(3.6V)
Vref-输入,模拟参考负极ADC使用的低端/负极参考电压,Vref=VSSA
VSSA输入,模拟电源地等效于VSS的模拟电源地
ADCx_IN[15:0]模拟输入信号16个模拟输入通道

VDDA和VSSA应该分别连接到VDD和VSS。

电压输入范围

ADC输入范围为Vref-<y=Vin<=Vref+.由Vref+、Vref-、VDDA、VSSA这四个外部引脚决定。如果我们想让输入的电压范围变宽,去到可以测试负电压或者更高的正电压,我们可以在外部加一个电压调整电路,把需要转换的电压抬升或者降低到0~3.3V,这样ADC就可以测量。

通道选择

有16个通道,可以把转换组织分成两组:规则组和注入组。在任意多个通道上以任意顺序进行的一系列转换构成成组转换。例如,可以如下顺序完成转换:通道3、通道8、通道2、通道0、通道2、通道15。

规则组:由多达16个转换组成,规则通道和它们的转换顺序在ADC_SQRx寄存器中选择,规则组中转换的总数应写入ADC_SQR1寄存器的了L[3:0]位中

注入组:由多达4个转换组成,注入通道和它们的转换顺序在ADC_JSQR寄存器中选择,注入组里的转换总数目应写入ADC_JSQR寄存器的L[1:0]中

如果 ADC_SQRx ADC_JSQR 寄存器在转换期间被更改,当前的转换被清除,一个新的启动脉
冲将发送到 ADC 以转换新选择的组。
温度传感器/Vrefint内部通道
温度传感器和通道ADC_IN16相连接,内部参照电压Vrefint和ADC_IN17相连接。可以按注入或规则通道对这两个内部通道进行转换

单次转换模式

单次转换模式下,ADC只执行一次转换,该模式下即可通过设置ADC_CR2寄存器的ADON位(只适用于规则通道)启动也可通过外部触发启动(适用于规则通道或注入通道),这时CONT位为0.

一旦选择通道的转换完成:

  • 如果一个规则通道被转换:

-转换数据被存储在16位ADC_DR寄存器中

-EOC(转换结束)标志被设置

-如果设置了EOCIE,则产生中断

  • 如果一个注入通道被转换

-转换数据被存储在16位的ADC_DRJ1寄存器中

-JEOC(注入转换结束)标志被设置

-如果设置了JEOCIE位,则产生中断

连续转换模式

在连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。此模式可通过外部触发启动或通过设置ADC_CR2寄存器上的ADON位启动,此时的CONT位是1.

每个转换后:

  • 如果一个规则通道被转换

-规则数据被存储在16位的ADC_DR寄存器中

-EOC(转换结束)标志被设置

-如果设置了EOCIE,则产生中断

  • 如果一个注入通道被转换:

-转换数据被存储在16位的ADC_DRJ1寄存器中

-JEOC(注入转换结束)标志被设置

-如果设置了JEOCIE位,则产生中断

规则通道:顾名思义,规则就是规矩的意思,我们平时一般使用的就是这个通道,或者应该说我们用到的就是这个通道,没有什么要特别注意的。

注入通道:注入,可以理解为插入,插队的意思,就是一种不安分的意思,它是一种在规则通道转换的时候强行插入的一种转换通道,如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注入通道,等注入通道完成之后,再回到规则通道的转换流程。这点跟中断程序很像,都是不安分的主,所以注入通道只有在规则通道存在时才会出现。

转换顺序

规则序列

规则序列寄存器有3个,分别为SQR3、SQR2、SQR1。SQR3控制着规则序列中的第一个到第六个转换,对应的位为:SQ1[4:0]~SQ6[4:0],第一次转换的是位 4:0 SQ1[4:0],如果通道 16 想第一 次转换,那么在 SQ1[4:0] 16 即可。SQR2 控制着规则序列中的第 7 到第 12 个转换,对应的位 为:SQ7[4:0]~SQ12[4:0],如果通道 1 想第 8 个转换,则 SQ8[4:0] 1 即可。SQR1 控制着规则序 列中的第 13 到第 16 个转换,对应位为:SQ13[4:0]~SQ16[4:0],如果通道 6 想第 10 个转换,则 SQ10[4:0] 写 6 即可。具体使用多少个通道,由 SQR1 的位 L[3:0] 决定,最多 16 个通道。

 注入序列

注入序列寄存器JSQR只有一个,最多支持4个通道,具体多少个由JSQR的JL[2:0]决定。如果JL的值小于4的话,则JSQR跟SQR决定转换顺序的设置不一样,第一次转换的不是JSQR1[4:0];而是JCQRx[4:0],x=4-JL,跟SQR刚好相反,如果 JL=00(1 个转换),那么转换的顺序是从 JSQR4[4:0] 开始,而不是从 JSQR1[4:0] 开始,这个要注意,编程的时候不要搞错。当 JL 等于 4 时,跟 SQR 一样。

触发源

通道选好了,转换的顺序也设置好了,那接下来就开始转换了,ADC的转换可以由ADC控制寄存器2:ADC_CR2的ADON这个位来控制,写1的时候开始转换,写0的时候停止转换,这个是最简单也是最好理解的开启ADC转换的控制方式。

除了这种控制方法,ADC还支持触发转换,这个触发包括内部定时器触发和外部IO触发。触发源有很多,具体选择哪一种触发源,由ADC控制寄存器2:ADC_CR2的EXTSEL[2:0]和JEXTSEL [2:0]位来控制。EXTSEL[2:0]用于选择规则通道的触发源JEXTSEL [2:0]用于选择注入通道的触发源。选定好触发源之后,触发源是否要激活,则由 ADC控制寄存器2:ADC_CR2 的

EXTTRIG JEXTTRIG 这两位来激活。其中 ADC3 的规则转换和注入转换的触发源与 ADC1/2
的有所不同,在框图上已经表示出来.

转换时间

ADC时钟
ADC输入时钟ADC_CLK由PCLK2经过分频产生,最大是14MHZ,分频因子由RCC时钟配置寄存器RCC_CFGR的位15:14设置,可以是2/4/6/8分频,注意这里没有1分频。一般我们设置PCLK2=HCLK=72M。
采样时间
ADC使用若干个ADC_CLK周期对输入的电压进行采样,采样的周期数可通过ADC采样时间寄存器ADC_SMPR1控制的是通道10~17.每个通道可以分别使用不同的时间采样,其中采样周期最小是1.5个。
ADC 的转换时间跟 ADC 的输入时钟和采样时间有关,公式为: Tconv = 采样时间 + 12.5 个周期。 当 ADCLK = 14MHZ (最高),采样时间设置为 1.5 周期(最快),那么总的转换时间(最短) Tconv = 1.5 周期 + 12.5 周期 = 14 周期 = 1us
一般我们设置 PCLK2=72M ,经过 ADC 预分频器能分频到最大的时钟只能是 12M ,采样周期设
置为 1.5 个周期,算出最短的转换时间为 1.17us ,这个才是最常用的。

中断

转换结束中断

数据转换结束后可以产生中断,中断分为3种:规则通道转换结束中断,注入转换通道转换结束中断,模拟看门狗中断。其中转换结束很好理解,跟我们平时接触的中断一样,有相应的中断标志位和中断使能位,我们还可以根据中断类型写相应的中断服务程序。

模拟看门狗中断

当被ADC转换的模拟电压低于阈值或者高于阈值时,就会产生中断,前提是我们开起了模拟看门狗中断,其中低阈值和高阈值由ADC_LTR和ADC_HTR设置。例如我们设置高阈值是2.5V,那么模拟电压超过2.5V的时候,就会产生模拟看门狗中断,反之低阈值也一样。

DMA请求

规则和注入通道转换结束后,除了产生中断外,还可以产生DMA请求,把转换好的数据直接存储在内存里面。要注意的是只有ADC1和ADC3可以产生DMA请求。

代码讲解

ADC初始化结构体详解
typedef struct
{
  uint32_t ADC_Mode;                 //ADC工作模式选择
      
  FunctionalState ADC_ScanConvMode;   //ADC扫描(多通道)或者单通道模式选择
  
  FunctionalState ADC_ContinuousConvMode;     //ADC单次转换或者连续转换选择
    
  uint32_t ADC_ExternalTrigConv;      //ADC转换触发信号选择

  uint32_t ADC_DataAlign; // ADC 数据寄存器对齐格式
        
  uint8_t ADC_NbrOfChannel;           //ADC采集通道数
        
}ADC_InitTypeDef;
ADC_Mode :配置 ADC 的模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,
在双模式下还有很多细分模式可选,我们一般使用一个 ADC 的独立模式。
ScanConvMode :可选参数为 ENABLE DISABLE ,配置是否使用扫描。如果是单通道 AD 转换
使用 DISABLE ,如果是多通道 AD 转换使用 ENABLE
ADC_ContinuousConvMode :可选参数为 ENABLE DISABLE ,配置是启动自动连续转换还是单
次转换。使用 ENABLE 配置为使能自动连续转换;使用 DISABLE 配置为单次转换,转换一次后
停止需要手动控制才重新启动转换。一般设置为连续转换。
ADC_ExternalTrigConv :外部触发选择,图 单个 ADC 功能框图 中列举了很多外部触发条件,可
根据项目需求配置触发来源。实际上,我们一般使用软件自动触发。
ADC_DataAlign :转换结果数据对齐模式,可选右对齐 ADC_DataAlign_Right 或者左对齐
ADC_DataAlign_Left 。一般我们选择右对齐模式。
ADC_NbrOfChannel AD 转换通道数目,根据实际设置即可。
其中实验可以分为4个实验:独立模式单通道采集实验(分为中断存储和DMA直接存储)、独立模式多通道采集实验、双重ADC同步规则模式采集实验
我直接以双重ADC同步规则模式采集实验为例

宏定义:

#ifndef __BSP_ADC_H
#define __BSP_ADC_H

#include "stm32f10x.h"

/*定义ADC相关的引脚*/
#define ADC_x_1_GPIO_PORT				GPIOC
#define ADC_x_1_PIN_0						GPIO_Pin_1
#define ADC_x_1_PIN_1						GPIO_Pin_2

#define ADC_x_2_GPIO_PORT				GPIOC
#define ADC_x_2_PIN_0						GPIO_Pin_3
#define ADC_x_2_PIN_1						GPIO_Pin_4

#define ADC_GPIO_CLK		RCC_APB2Periph_GPIOC

#define NUMOFCHANNEL		2
/*定义ADC相关的模式配置*/
#define ADC_x_1								ADC1
#define ADC_x_1_CHANNEL_0			ADC_Channel_11
#define ADC_x_1_CHANNEL_1			ADC_Channel_12
#define ADC_x_1_CLK						RCC_APB2Periph_ADC1

#define ADC_x_2					 			ADC2
#define ADC_x_2_CHANNEL_0			ADC_Channel_13
#define ADC_x_2_CHANNEL_1			ADC_Channel_14
#define ADC_x_2_CLK						RCC_APB2Periph_ADC2


/*DMA的相关定义*/
#define DMA_CHANNEL			DMA1_Channel1
#define DMA_CLK				  RCC_AHBPeriph_DMA1

/*ADC中断相关宏定义*/
//#define ADC_IRQ					ADC1_2_IRQn
//#define ADC_IRQHandler	ADC1_2_IRQHandler					

void ADCx_Init(void);

#endif /*__BSP_ADC_H*/

#include "bsp_adc.h"

__IO uint32_t ADC_ConvertedValue[NUMOFCHANNEL]={0,0};
/*
编程思路
(1)初始ADC用到的GPIO;
(2)设置ADC的工作参数并初始化
(3)设置ADC的工作时钟
(4)设置ADC转换通道顺序及采样时间
(5)配置使能ADC转换完成中断,在中断内读取转换完数据
(6)使能ADC
(7)使能软件触发ADC转换
	ADC转换结果数据使用中断方式读取,这里没有使用DMA进行数据传输

*/

/*
*@brief	ADC相关GPIO引脚初始化
*@param	None
*@retval:None
*/
static void ADC_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(ADC_GPIO_CLK,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode	=	GPIO_Mode_AIN;
	GPIO_InitStruct.GPIO_Speed	=	GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Pin	=	ADC_x_1_PIN_0;
	GPIO_Init(ADC_x_1_GPIO_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin	=	ADC_x_1_PIN_1;	
	GPIO_Init(ADC_x_1_GPIO_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin	=	ADC_x_2_PIN_0;
	GPIO_Init(ADC_x_2_GPIO_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin	=	ADC_x_2_PIN_1;	
	GPIO_Init(ADC_x_2_GPIO_PORT,&GPIO_InitStruct);
}

/*
*@brief ADC模式配置
*@param None
*@retvla None
*/
static void ADC_Mode_Config(void)
{
	ADC_InitTypeDef ADC_InitStruct;
	DMA_InitTypeDef DMA_InitStruct;
	RCC_APB2PeriphClockCmd(ADC_x_1_CLK,ENABLE);
	RCC_APB2PeriphClockCmd(ADC_x_2_CLK,ENABLE);
	RCC_AHBPeriphClockCmd(DMA_CLK,ENABLE);
	
	DMA_DeInit(DMA_CHANNEL);

	
	/*-------------- Reset DMA init structure parameters values ------------------*/
  /* Initialize the DMA_PeripheralBaseAddr member */
  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t) ( & ( ADC_x_1->DR ) ) ;
  /* Initialize the DMA_MemoryBaseAddr member */
  DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;
  /* Initialize the DMA_DIR member */
  DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
  /* Initialize the DMA_BufferSize member */
  DMA_InitStruct.DMA_BufferSize = NUMOFCHANNEL;
  /* Initialize the DMA_PeripheralInc member */
  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  /* Initialize the DMA_MemoryInc member */
  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
  /* Initialize the DMA_PeripheralDataSize member */
  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  /* Initialize the DMA_MemoryDataSize member */
  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  /* Initialize the DMA_Mode member */
  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
  /* Initialize the DMA_Priority member */
  DMA_InitStruct.DMA_Priority= DMA_Priority_High;
  /* Initialize the DMA_M2M member */
  DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA_CHANNEL,&DMA_InitStruct);
	DMA_Cmd(DMA_CHANNEL,ENABLE);
	/********************以下是ADC初始化部分************************/
	/* Reset ADC init structure parameters values */
  /* Initialize the ADC_Mode member */
  ADC_InitStruct.ADC_Mode = ADC_Mode_RegSimult;
  /* initialize the ADC_ScanConvMode member */
  ADC_InitStruct.ADC_ScanConvMode = ENABLE;
  /* Initialize the ADC_ContinuousConvMode member */
  ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
  /* Initialize the ADC_ExternalTrigConv member */
  ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  /* Initialize the ADC_DataAlign member */
  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
  /* Initialize the ADC_NbrOfChannel member */
  ADC_InitStruct.ADC_NbrOfChannel = NUMOFCHANNEL;
	//初始化ADC
	ADC_Init(ADC_x_1,&ADC_InitStruct);
	//配置ADC时钟,CLK2的6分频,即12MHZ
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	//配置ADC通道转换顺序为1,第一个转换,采样时间28.5个时钟周期
	ADC_RegularChannelConfig(ADC_x_1,ADC_x_1_CHANNEL_0,1,ADC_SampleTime_28Cycles5);
	ADC_RegularChannelConfig(ADC_x_1,ADC_x_1_CHANNEL_1,2,ADC_SampleTime_28Cycles5);
	ADC_DMACmd(ADC_x_1,ENABLE);
	ADC_Cmd(ADC_x_1,ENABLE);
	/*******************ADC2初始化配置********************/
	ADC_InitStruct.ADC_Mode = ADC_Mode_RegSimult;
  ADC_InitStruct.ADC_ScanConvMode = ENABLE;
  ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStruct.ADC_NbrOfChannel = NUMOFCHANNEL;

	ADC_Init(ADC_x_2,&ADC_InitStruct);
	//配置ADC时钟,CLK2的6分频,即12MHZ
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	//配置ADC通道转换顺序为1,第一个转换,采样时间28.5个时钟周期
	ADC_RegularChannelConfig(ADC_x_2,ADC_x_2_CHANNEL_0,1,ADC_SampleTime_28Cycles5);
	ADC_RegularChannelConfig(ADC_x_2,ADC_x_2_CHANNEL_1,2,ADC_SampleTime_28Cycles5);
	//使用外部触发ADC转换
	ADC_ExternalTrigConvCmd(ADC_x_2, ENABLE);
	ADC_Cmd(ADC_x_2,ENABLE);
	//ADC转换结束产生中断,在中断服务函数中读取转换值
  //	ADC_ITConfig(ADC_x,ADC_IT_EOC,ENABLE);

	/*************ADC1*************/
	//初始化ADC校准寄存器
	ADC_ResetCalibration(ADC_x_1);
	//等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC_x_1));
	//ADC开始校准
	ADC_StartCalibration(ADC_x_1);
	//等待校准完成
	while(ADC_GetCalibrationStatus(ADC_x_1));
	
	/*************ADC2**************/
	//初始化ADC校准寄存器
	ADC_ResetCalibration(ADC_x_2);
	//等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC_x_2));
	//ADC开始校准
	ADC_StartCalibration(ADC_x_2);
	//等待校准完成
	while(ADC_GetCalibrationStatus(ADC_x_2));
	//由于没有采用外部触发,所以使用软件触发ADC转换
	ADC_SoftwareStartConvCmd(ADC_x_1,ENABLE);
}

/*
*@brief ADC中断配置
*@param None
*@retval:None
*/
//static void ADC_NVIC_Config(void)
//{
//	NVIC_InitTypeDef NVIC_InitStruct;
//	
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

//	NVIC_InitStruct.NVIC_IRQChannel	=	ADC_IRQ;
//	
//	NVIC_InitStruct.NVIC_IRQChannelCmd	=	ENABLE;
//	
//	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority	=	0;
//	
//	NVIC_InitStruct.NVIC_IRQChannelSubPriority	=	1;
//	

//	
//	NVIC_Init(&NVIC_InitStruct);


//}

/*
*brief ADC初始化
*@param None
*retval None
*/

void ADCx_Init(void)
{
	ADC_GPIO_Config();
	ADC_Mode_Config();
//	ADC_NVIC_Config();
}



main.c

/*
双重ADC多通道采集实验
*/

#include "stm32f10x.h"
#include "bsp_uart.h"
#include "led.h"
#include "bsp_adc.h"

extern __IO uint32_t ADC_ConvertedValue[NUMOFCHANNEL];

float ADC_ConvertedValueLocal[NUMOFCHANNEL*2];

void Delay(uint32_t count)
{
	for(;count!=0;count--);
}

int main(void)
{
	uint16_t temp0=0,temp1=0,temp2=0,temp3=0;
	GPIO_LED_Config();
	USART1_Config();
	ADCx_Init();
	
	printf("**********这是一个ADC测试实验***********\n");
	while(1)
	{
		temp0	=	(ADC_ConvertedValue[0]&0xFFFF0000)>>16;//ADC2CH1
		temp1	= (ADC_ConvertedValue[0]&0xFFFF);//ADC1 CH1
		temp2	=	(ADC_ConvertedValue[1]&0xFFFF0000)>>16;//ADC2 CH2
		temp3	= (ADC_ConvertedValue[1]&0xFFFF);//ADC1 CH2
		
		ADC_ConvertedValueLocal[0]	=	(float)temp0/4096*3.3;		//ADC2 CH1
		ADC_ConvertedValueLocal[1]	=	(float)temp1/4096*3.3;		//ADC1 CH1
		ADC_ConvertedValueLocal[2]	=	(float)temp2/4096*3.3;		//ADC2 CH2
		ADC_ConvertedValueLocal[3]	=	(float)temp3/4096*3.3;		//ADC1 CH2

		printf("\r\nADC1的通道11的值为:%f",ADC_ConvertedValueLocal[1]);
		printf("\r\nADC1的通道12的值为:%f",ADC_ConvertedValueLocal[3]);
		printf("\r\nADC2的通道13的值为:%f",ADC_ConvertedValueLocal[0]);
		printf("\r\nADC1的通道14的值为:%f",ADC_ConvertedValueLocal[2]);

		printf("\r\r\r\n");
		
		Delay(0xffffee);
		
	}	
	
}

 个人总结

关于ADC程序驱动的编写,STM32官方的例程中有一些帮助,对于程序编写的步骤我总结如下:
1、初始ADC用到的GPIO

2、设置ADC的工作参数并初始化

3、设置ADC工作时钟(在RCC文件的ADC设置)

4、设置ADC转换通道顺序和采样时间

5、配置使能ADC转换完成中断,在中断内读取转换数据

6、如果是DMA读取数据,需要配置ADC的响应DMA

7、使能软件触发ADC转换

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32——ADC采集 的相关文章

  • 如何更改闪存的起始地址?

    我正在使用 STM32F746ZG 和 FreeRTOS Flash的起始地址是0x08000000 但我想把它改成0x08040000 我通过谷歌搜索了这个问题 但没有找到解决方案 我更改了链接器脚本 如下所示 MEMORY RAM xr
  • 初始化 ST-Link 设备时出错 - 无法连接到设备

    我目前正在使用 ST Link 调试器对我的 STM32F3 Discovery 板进行编程 我使用的IDE是Atollic TrueStudio 5 5 2 现在我面临一个非常奇怪的问题 那就是我不断收到消息 初始化 ST Link 设备
  • 在没有 IDE 的情况下如何使用 CMSIS?

    我正在使用 STM32F103C8T6 并想使用 CMSIS 这本质上只是寄存器定义 没有代码 让我的生活更轻松 同时仍保持在较低水平 问题是我不知道如何安装该库以便在命令行上使用 Makefile 使用 所有文档似乎都与特定于供应商的 I
  • CMSIS 库是否应该包含在版本控制中? [复制]

    这个问题在这里已经有答案了 通常 我曾经在版本控制中包含芯片供应商 ST 提供的设备特定标头和源以及 CMSIS Core 标头 数量不多 也没有更新的习惯 我使用STM32微控制器 但我不使用立方体框架 or the 标准外设库 最近 我
  • 135-基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真+源程序

    资料编号 135 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 电机 超声波传感器 制作一个基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真 2 通过DHT11传感器检测当前
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • 我使用 opencv python 形式将模拟时钟转换为数字数据的小时和分钟,但我也需要它显示秒数

    我已经使用 opencv 来读取图像 将其转换为灰度 并使用 canny kernel thesh erode 等找到边缘 并且我已经使用 HooughLineP 检测到图像中的所有线条 并且我已经检测到时间和分针 但我还需要找到秒针 这是
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • Arm:objcopy 如何知道 elf 中的哪些部分要包含在二进制或 ihex 中?

    我正在开发一个项目 其中涉及解析arm elf 文件并从中提取部分 显然 elf 文件中有很多部分没有加载到闪存中 但我想知道 objcopy 到底如何知道要在二进制文件中包含哪些部分以直接闪存到闪存中 以arm elf文件的以下reade
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 嵌入式开发--STM32G4系列片上FLASH的读写

    这个玩意吧 说起来很简单 就是几行代码的事 但楞是折腾了我大半天时间才搞定 原因后面说 先看代码吧 读操作 读操作很简单 以32位方式读取的时候是这样的 data IO uint32 t 0x0800F000 需要注意的是 当以32位方式读
  • 特殊寄存器

    特殊寄存器 文章目录 前言 一 背景 二 2 1 2 2 总结 前言 前期疑问 STM32特殊寄存器到底是什么 特殊寄存器怎么查看和调试代码 本文目标 记录和理解特殊寄存器 一 背景 最近在看ucosIII文章是 里面提到特殊寄存器 这就进
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE

随机推荐

  • RT-Thread之入门跑代码

    本文将讲述如何在window10中利用tensorflow跑代码 xff0c 并且编译成bin文件 xff0c 最后在k210中运行 一 在window上安装tensorflow框架 xff08 python3 7 xff09 1 安装An
  • keil5的基本使用

    项目文件后缀 硬件下载 1 编译 2 下载 软件仿真 一 基本知识 1 选择软件仿真选项 2 编译 3 启动软件仿真 4 运行代码 二 软件仿真的具体使用 1 我们想运行到 哪一步就在那一步添加断点 xff08 在左边的空白处左键点一下就可
  • pytorch之池化层

    实际图像里 xff0c 我们感兴趣的物体不会总出现在固定位置 xff1a 即使我们连续拍摄同一个物体也极有可能出现像素位置上的偏移 这会导致同一个边缘对应的输出可能出现在卷积输出 Y中的不同位置 xff0c 进而对后面的模式识别造成不便 在
  • 串口通信协议

    通信协议的基本概念 用于定义通信过程及细节规则的协议称为通信协议 xff0c 通信系统之间为了完成通信所必须遵循的规则和约定 xff08 数据包格式 字段的内容 字段的含义 发送的时间 接收的时间等细节 xff09 个人理解 xff1a 就
  • gazebo的安装

    安装ros 1 1设置软件源 xff1a 清华源或者阿里都可 sudo sh c 39 etc lsb release amp amp echo 34 deb Index of ros ubuntu 清华大学开源软件镜像站 Tsinghua
  • 驱动开发基础

    1 Hello驱动 我们应用程序使用open函数的时候 xff0c 会调用内核的sys open函数 xff0c 然后接下来 1 然后打开普通文件的话会使用文件系统操作硬件 xff0c 2 要是打开驱动文件 xff0c 会使用驱动程序对应的
  • ARM架构与编程 · 基于IMX6ULL

    一 嵌入式系统硬件介绍 cpu 43 RAM xff08 内存 xff09 43 FALSH 集成 xff08 flash存储设备 xff09 61 MCU 单片机 AP MPU 进化之后可以外接内存和存储设备 跑复杂的操作系统 xff0c
  • 嵌入式常用算法

    1 冒泡排序 1 两两之间对比 xff0c 要是顺序排 xff0c 一轮过后最大的就是最后一个 2 下一轮参加排序的数比上一轮少一个 include lt iostream gt using namespace std void paixu
  • 实习面试的总结

    2023 4 3 阿凡达机器人 驱动开发实习生 1 怎么注册一个字符设备 注销 1 注册一个设备号 2 设备号加载进内核 3 创建类 4 创建设备 注销 1 从内核中删除 2 删除设备 3 删除类 2 怎么将新加入的网络设备加入到内核中去
  • 字符设备结构体与probe函数

    1 设备结构体 设备结构体 struct ap3216c dev dev t devid 设备号 主设备号 43 次设备号 struct cdev cdev cdev 字符设备对象 xff0c 字符设备驱动的一种结构体类型 struct c
  • SLAM --- VIO 基于 EKF 开源

    1 VIO based on EKF 已知一致性的Visual Inertial EKF SLAM 实现添加链接描述
  • 暗夜精灵7 linux

    Ubuntu18 04 安装nvidia显卡驱动 distro non free 小乌坞的博客 CSDN博客 注意在关闭显示界面的时候需要输入密码 xff0c 不然会一直卡着 在验证是否屏蔽驱动的时候 xff0c 要先重启一下 cuda L
  • linux应用编程

    项目内容 开发板内部使用c语言调用硬件驱动实现各种测试功能 xff0c 保存测试结果 外部程序通过socket接口使用tcp协议与开发板通信进行信息传输 xff0c 最后使用python GUI构造一个界面按照测试顺序逐步显示出各个模块的测
  • NUC10快乐装机

    NUC10装机 由于为了RoboMaster比赛 xff0c 身为全队唯一一个视觉队员兼队长的我 xff0c 经过疫情期间的再三斟酌 xff0c 最后决定工控机选择为nuc10 为什么选择nuc10 作为第一年参赛的新队伍 xff0c 视觉
  • 什么是PID?讲个故事,通俗易懂

    什么是PID xff1f PID xff0c 就是 比例 xff08 proportional xff09 积分 xff08 integral xff09 微分 xff08 derivative xff09 xff0c 是一种很常见的控制算
  • C语言对寄存器的封装

    目录 1 封装总线和外设基地址 2 封装寄存器列表 3 修改寄存器的位操作的方法 把变量的某位清零 把变量的某几个连续位清零 对变量的某几位进行赋值 对变量的某位取反 1 封装总线和外设基地址 在编程上为了方便理解和记忆 xff0c 我们把
  • STM32——串口通信及实验

    目录 1 按照数据传送的方向 xff0c 分为 xff1a 2 按照通信方式 xff0c 分为 xff1a STM32串口通信基础 串口通信过程 UART xff08 USART xff09 框图 串口通信实验 编程要点 代码分析 通信接口
  • 【STM32】DMA原理,配置步骤超详细,一文搞懂DMA

    目录 DMA xff08 Direct Memory Access xff09 简介 DMA传输方式 DMA功能框图 DMA请求映像 DMA1控制器 DMA2控制器 通道 仲裁器 DMA主要特性 DMA处理 DMA数据配置 从哪里来到哪里去
  • [STM32学习]——一文搞懂I2C总线

    目录 I2C总线的概念 I2C最重要的功能包括 xff1a I2C的物理层 I2C主要特点 xff1a I2C的高阻态 I2C物理层总结 xff1a I2C的协议层 初始 xff08 空闲 xff09 状态 开始信号 xff1a 停止信号
  • STM32——ADC采集

    目录 ADC简介 ADC主要特征 ADC功能框图 ADC引脚 电压输入范围 通道选择 单次转换模式 连续转换模式 转换顺序 规则序列 注入序列 触发源 转换时间 中断 转换结束中断 模拟看门狗中断 DMA请求 代码讲解 宏定义 xff1a