使用嵌入式进行adc_电压采集

目录

前言

一、ADC-电压采集的基本原理

二、ADC-电压采集的应用场景

三、数据寄存器

1 规则数据寄存器

 2 注入数据寄存器

四.ADC-电压采集的实现方法


前言

        在当前的嵌入式系统开发中,STM32系列微控制器凭借其卓越的性能和广泛的应用场景,成为了工程师们的首选。其中,ADC(模数转换器)模块作为STM32微控制器的重要组成部分,对于实现电压数据的精确采集和转换起着至关重要的作用。在嵌入式系统开发中,电压数据的采集和处理是许多应用的基础,如电池监控、传感器信号读取、电机控制等。因此,熟练掌握STM32 ADC电压采集技术,对于提高系统的整体性能和稳定性具有重要意义。

一、ADC-电压采集的基本原理

        ADC-电压采集是一种将连续的模拟电压信号转换为离散的数字信号的过程。这个过程主要通过ADC转换器实现,转换器内部包含了一个或多个比较器、计数器、时钟电路等元件。当模拟电压信号输入到ADC转换器时,转换器会根据设定的分辨率(即转换精度)和采样率(即转换速度)进行转换。具体来说,转换器会不断比较输入电压与一系列参考电压,然后根据比较结果输出对应的数字编码。

原理图

二、ADC-电压采集的应用场景

        ADC-电压采集技术在许多领域都有着广泛的应用。以下是一些典型的应用场景:

  1.  工业自动化:在工业自动化系统中,需要对各种传感器采集的模拟信号进行数字化处理,以便进行后续的分析和控制。ADC-电压采集技术可以将传感器输出的模拟电压信号转换为数字信号,为工业自动化系统提供可靠的数据支持。

        2. 能源管理:在能源管理系统中,需要对电网电压、电流等参数进行实时监测和控制。 ADC- 电压采集技术可以实现对电网电压的精确采集,为能源管理系统提供准确的数据支持。

3. 智能家居:在智能家居系统中,ADC-电压采集技术可以实现对家庭用电设备的电压监测,从而及时发现设备故障或异常用电情况,保障家庭用电安全。

4. 医疗设备:在医疗设备中,ADC-电压采集技术可以实现对患者生理参数的实时监测,如心电图、血压等。这些参数对于医生诊断和治疗疾病具有重要意义。

、数据寄存器

        数据寄存,简单来说,就是将数据暂时存储在一个特定的位置或设备中,以便后续的使用或处理。这种存储可以是临时的,也可以是长期的,具体取决于数据的重要性和使用需求。

1 规则数据寄存器

        ADC规则组数据寄存器ADC_DR只有一个,是一个32位的寄存器,低16位在单 ADC时使用,高16位是在ADC1中双模式下保存 ADC2 转换的规则数据,双模式就是 ADC1和ADC2同时使用。在单模式下,ADC1/2/3 都不使用高16位。因为ADC的精度是12位,无论ADC_DR的高16或者低16位都放不满,只能左对齐或者右对齐,具体是以哪一种方式存放,由 ADC_CR2 的 11 位 ALIGN 设置。

寄存图

        规则通道可以有 16 个这么多,可规则数据寄存器只有一个,如果使用多通道转换,那转换的数 据就全部都挤在了 DR 里面,前一个时间点转换的通道数据,就会被下一个时间点的另外一个通 道转换的数据覆盖掉,所以当通道转换完成后就应该把数据取走,或者开启 DMA 模式,把数据 传输到内存里面,不然就会造成数据的覆盖。最常用的做法就是开启 DMA 传输

 2 注入数据寄存器

       ADC 注入组最多有 4 个通道,刚好注入数据寄存器也有4个,每个通道对应着自己的寄存器,不会跟规则寄存器那样产生数据覆盖的问题。ADC_JDRx 是 32 位的,低16位有效,高16位保留,数据同样分为左对齐和右对齐,具体是以哪一种方式存放,由ADC_CR2的11位ALIGN 设置。

      

四.ADC-电压采集的实现方法

ADC-电压采集的实现方法主要包括以下几个步骤:

  1. 选择合适的ADC转换器:根据应用场景和需求选择合适的ADC转换器,包括转换精度、采样率、输入电压范围等参数。
  2. 设计采集电路:根据ADC转换器的要求设计采集电路,包括信号放大、滤波、偏置等电路。这些电路可以确保输入到ADC转换器的模拟电压信号满足转换器的要求。
  3. 编写采集程序:编写控制ADC转换器进行数据采集的程序。程序需要设置ADC转换器的参数(如分辨率、采样率等),并读取转换结果。
  4. 数据处理与分析:对采集到的数字信号进行处理和分析,如滤波、校准、存储等操作。这些操作可以进一步提高数据的准确性和可靠性。

部分代码实现:

#include"gpioinit.h"
//#include"key.h"

int adc;

void gpio_setup(void)
{
	//2创建结构体对象
	GPIO_InitTypeDef GPIO_InitStruct;
	//3打开管脚时钟
	   RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOH,ENABLE);
    // 开AB       1
	//4管脚模式设置(方向、模式、上下拉方式,速度)
	      // 输入   不拉       23
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
    
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP ;
	GPIO_InitStruct.GPIO_Speed= GPIO_Fast_Speed;
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;//10号管脚      
	//1调用初始化库函数 init
	GPIO_Init(GPIOH,&GPIO_InitStruct);
	
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOA, ENABLE);
	
	
	GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_PuPd= GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Pin= GPIO_Pin_0;
	
	GPIO_Init( GPIOA,&GPIO_InitStruct);
		GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_13;
	
	GPIO_Init( GPIOC,&GPIO_InitStruct);
	
}

void NVIC_setup()
{
	NVIC_InitTypeDef NVIC_InitStruct;         //创建结构体对象
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;                 //设置中断请求通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;         //设置中断主优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;                //设置中断子优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;                     //中断请求开关
		NVIC_Init(&NVIC_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;                 //设置中断请求通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;         //设置中断主优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;                //设置中断子优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;     
	
	NVIC_Init(&NVIC_InitStruct);
	
}

void EXTI_setup()
{
	EXTI_InitTypeDef EXTI_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	
	NVIC_setup();
	
	SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOA,  EXTI_PinSource0);
	SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOC,  EXTI_PinSource13);
	
	EXTI_InitStruct.EXTI_Line = EXTI_Line0|EXTI_Line13;   //中断线
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;                //中断开关
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;       //触发模式
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;     //触发方式
	
	EXTI_Init(&EXTI_InitStruct);
}


void send()
{
  USART_InitTypeDef USART_InitStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
  NVIC_InitTypeDef  NVIC_InitStruct;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
	
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = 1;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = ENABLE;
	
	NVIC_Init(&NVIC_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;
	
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	USART_InitStruct.USART_BaudRate = 9600;         // 波特率,负责通信快慢,常用数据9600,19200.
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;        //硬件流控制,关闭
	USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                      //工作模式:发送,接收
	USART_InitStruct.USART_Parity = USART_Parity_No;                  //奇偶校验位,关闭
	USART_InitStruct.USART_StopBits = USART_StopBits_1;                  //停止位。1位
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;                  //每一组发送字位宽度,常用8bit
	
	USART_Init(USART1,&USART_InitStruct);
	
	//USART_ITConfig( USART1, USART_IT_RXNE, ENABLE);
	//USART_ITConfig( USART1, USART_IT_TXE, ENABLE);
	
	USART_Cmd(USART1,ENABLE);
}

void Sendstring(char* str)    //str定义为指针类型,存储的是char数据类型
{
	while(*str!='\0')
	{
		USART_SendData(USART1, *str);
		while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
		str++;
	}
}

void PWMint(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
	TIM_OCInitTypeDef TIM_OCInitStruct;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
	RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM5, ENABLE );
	 
	//第一步对PH10初始化
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;
	GPIO_Init( GPIOH, &GPIO_InitStruct);
	
	GPIO_PinAFConfig(GPIOH, GPIO_PinSource10, GPIO_AF_TIM5);
	//第二对定时器TIM5的基础初始化
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV2;     //分频器
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down;    
	TIM_TimeBaseInitStruct.TIM_Period =800;                     //周期
	TIM_TimeBaseInitStruct.TIM_Prescaler = 1;             //预分频器,相当简单频率用的
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;
	
	TIM_TimeBaseInit( TIM5, &TIM_TimeBaseInitStruct);
	//定时器通道初始化
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_Low;
	
	TIM_OC1Init(TIM5, &TIM_OCInitStruct);
	
	TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM5, ENABLE);
	TIM_Cmd(TIM5,ENABLE);
	
}



void ADC_config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
//	DMA_InitTypeDef DMA_InitStruct;
	ADC_InitTypeDef ADC_InitStruct;
	ADC_CommonInitTypeDef ADC_CommonInitStruct;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
//	GPIO_InitStruct.GPIO_OType = ;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
//	GPIO_InitStruct.GPIO_Speed = ;

	GPIO_Init(GPIOC, &GPIO_InitStruct);
	
//	DMA_InitStruct.DMA_PeripheralBaseAddr = ((u32)ADC1+0x4c);
//	DMA_InitStruct.DMA_Memory0BaseAddr = (u32)&adc;
//	DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
//	DMA_InitStruct.DMA_BufferSize = 1;
//	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable ;
//	DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
//	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//	DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
//	DMA_InitStruct.DMA_Priority = DMA_Priority_High;
//	DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
//	DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
//	DMA_InitStruct.DMA_MemoryBurst =DMA_MemoryBurst_Single;
//	DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
//	DMA_InitStruct.DMA_Channel = DMA_Channel_0;
//	
//	DMA_Init(DMA2_Stream0, &DMA_InitStruct);
	
  ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
	ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;
	ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
	ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
	
	ADC_CommonInit(& ADC_CommonInitStruct);
	
	ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;
	ADC_InitStruct.ADC_ScanConvMode=DISABLE;
	ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;
	ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
	ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;
	ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStruct.ADC_NbrOfConversion=1;
	
	ADC_Init( ADC1,&ADC_InitStruct);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_13,1, ADC_SampleTime_56Cycles);
	
  ADC_Cmd(ADC1,ENABLE);
//	ADC_DMACmd(ADC1,ENABLE);
  //ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
//	ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
	ADC_SoftwareStartConv(ADC1);
}
 __IO uint16_t ADC_ConvertedValue;

//static void ADC_NVIC_Config(void)
//{
//	NVIC_InitTypeDef NVIC_InitStruct;
//	
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//	
//	NVIC_InitStruct.NVIC_IRQChannel = ADC_IRQn;                 //设置中断请求通道
//	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;         //设置中断主优先级
//	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;                //设置中断子优先级
//	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; 
//	
//	NVIC_Init(&NVIC_InitStruct);
//}



void Rheostat_Init(void)
{
	//ADC_NVIC_Config();
	ADC_config();
}

 总之,ADC-电压采集技术是一种重要的电子技术,在许多领域都有着广泛的应用。通过了解ADC-电压采集的基本原理、应用场景、实现方法以及注意事项,我们可以更好地应用这一技术,为各种系统提供可靠的数据支持。

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值