stm32-模拟数字转化器ADC

 

 接线图:

#include "stm32f10x.h"                  // Device header
		//1: 开启RCC时钟,包括ADC和GPIO的时钟
		//2:配置GPIO将GPIO配置为模拟输入模式
		//3:配置多路开关将左边的通道接入到规则组中
		//4:配置ADC转换器,单次转换,连续转换,扫描还是非扫描
		//5:开关控制调用ADC_COM参数ADC配置完成就能正常工作
void AD_Init(void){
// void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); RCC_ADCCLKConfig配置ADCCLK分频器
// void ADC_DeInit(ADC_TypeDef* ADCx); 恢复缺省配置
// void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); Init初始化
// void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); 结构体初始化
// void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); 给ADC上电
// void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); 开始DMA输出信号
// void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); // 中断输出控制
// void ADC_ResetCalibration(ADC_TypeDef* ADCx); 复位校准
// FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);获取复位校准状态
// void ADC_StartCalibration(ADC_TypeDef* ADCx); 开始校准
// FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx); 获取开始校准状态
// void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); ADC软件开始转换函数用于软件触发的函数
// FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); ADC获取软件开始转换状态
// void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); 配置间断模式每隔几个通道间断一次
// void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 是否启用间断模式
// void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); ADC规则组通道配置
// void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); ADC外部触发转换控制是否允许外部触发转换
// uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); ADC获取外部触发转换值
// uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); 获取ADC转换的数据寄存器,读取电平转换结果需要使用这个函数
// uint32_t ADC_GetDualModeConversionValue(void); ADC_获取双模式转换值,ADC双模式读取转换结果的函数
// 以下的三个函数是对模拟看门狗进行配置的函数:第一个是是否启动模拟看门狗,第二个是配置高低阈值,第三个是配置看门的通道
// void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
// void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);
// void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
// void ADC_TempSensorVrefintCmd(FunctionalState NewState); ADC温度传感器,内部参考电压控制
// 以下的4个函数:第一个是获取标志位状态,第二个是清除标志位,第三个获取中断状态,第四个清除中断挂起位
// FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
// void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
// ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);
// void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);
	
	
}

AD.C代码

#include "stm32f10x.h"                  // Device header
		//	  1: 开启RCC时钟,包括ADC和GPIO的时钟
		//    2:配置GPIO将GPIO配置为模拟输入模式
		//	  3:配置多路开关将左边的通道接入到规则组中
		//    4:配置ADC转换器,单次转换,连续转换,扫描还是非扫描
		//	  5:开关控制调用ADC_COM参数ADC配置完成就能正常工作
		 
void AD_Init(void){
	  
	  // 开启ADC的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	  // 开启GPIOA的时钟
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	  // 配置ADC_CLK,72MHz/6 = 12MHz
	  RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	  // 配置GPIO
	  GPIO_InitTypeDef GPIO_InitStructre;
	  // 将GPIO的模式引用出来
	  GPIO_InitStructre.GPIO_Mode =GPIO_Mode_AIN;       //  选择GPIO的模式,设置为AN模拟输入的模式在AIN模式下GPIO口是没有效果的
	  GPIO_InitStructre.GPIO_Pin = 	GPIO_Pin_0;         //  选择GPIO的输出模式,选择输出的管脚
	  GPIO_InitStructre.GPIO_Speed = GPIO_Speed_50MHz;  //  选择GPIO的时钟频率
	  GPIO_Init(GPIOA,&GPIO_InitStructre);              //  初始化GPIO
	
	  // 第二步 ---》 选择规则组的输入通道,参数二:指定通道,参数三:规则组序列器里面的次序1-16之间,参数4:指定通道的采样时间
	  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); 
	  
	  // 第三步 ---> 使用结构体初始化ADC
	  ADC_InitTypeDef ADC_InitStructure;
	  // 引出结构体成员
	  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE ;                //  配置扫描的模式
		ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;              //  配置ADC的数据对齐方式
		ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //  配置ADC的外部触发转换选择:这里使用内部软件触发的方式
		ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                  //  配置ADC的工作模式为独立模式
		ADC_InitStructure.ADC_NbrOfChannel = 1;                             //  配置通道数目
		ADC_InitStructure.ADC_ScanConvMode = DISABLE;                       //  配置扫描的模式
	  ADC_Init(ADC1,&ADC_InitStructure);
	
	  // 以下还可以配置中断和模拟看门狗,根据自己的需求进行配置
		
		
		// 开启ADC设置,第一个ENABLE第二个开启ADC的电源
		ADC_Cmd(ADC1,ENABLE); 
	  // 对ADC进行校准,这里分别有四个函数可以进行配置
		ADC_ResetCalibration(ADC1);  						              // 复位校准
		while(ADC_GetResetCalibrationStatus(ADC1) == SET);    // 返回复位校准的状态
	  ADC_StartCalibration(ADC1);                           // 启动校准
		while(ADC_GetCalibrationStatus(ADC1) == SET);         // 获取校准后的状态        
	  

}
uint16_t AD_GetValue(void){
    // 1: 软件触发转换 2:等待触发完成也就是等待EOC标志位设置为1,3:读取ADC数据寄存器
	  ADC_SoftwareStartConvCmd(ADC1,ENABLE); 
	  // 获取标志位状态共有5个参数,
	  // 第一个参数AWD模拟看门狗标志位,
	  // 第二个参数EOC规则组转换完成标志位,
	  // 第三个参数JEOC注入组转换完成标志位,
	  // 第四个参数:JSTRT:注入组开始转换标志位,
	  // 第五个参数:STRT规则组开始转换标志位
	  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); // 这里添加一个while空循环实现一个等待的过程
    // 获取ADC的结果--->使用ADC获取转换值的方式
	  return ADC_GetConversionValue(ADC1);
}


AD.H代码

#ifndef __AD_H
#define __AD_H

uint16_t AD_GetValue(void);
void AD_Init(void);

#endif

main函数代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t ADValue;
float Votage;
int main(void)
{
  // 初始化oled
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1,1,"ADVALUE!");
  OLED_ShowString(2,1,"Votage:0.00V");
	
	while (1)
	{
	  ADValue = AD_GetValue();
		Votage = (float)ADValue / 4095 * 3.3;
		OLED_ShowNum(1, 9, ADValue, 4); 
		OLED_ShowNum(2, 9, Votage,  1); 
		OLED_ShowNum(2, 11, (int)(Votage * 100) % 100,  1);
		Delay_ms(100);
	}
}

切换为连续转换模式需要修改的代码

ADC多通道实现

接线图:

#include "stm32f10x.h"                  // Device header
		//	  1: 开启RCC时钟,包括ADC和GPIO的时钟
		//    2:配置GPIO将GPIO配置为模拟输入模式
		//	  3:配置多路开关将左边的通道接入到规则组中
		//    4:配置ADC转换器,单次转换,连续转换,扫描还是非扫描
		//	  5:开关控制调用ADC_COM参数ADC配置完成就能正常工作
		 
void AD_Init(void){
	  
	  // 开启ADC的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	  // 开启GPIOA的时钟
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	  // 配置ADC_CLK,72MHz/6 = 12MHz
	  RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	  // 配置GPIO
	  GPIO_InitTypeDef GPIO_InitStructre;
	  // 将GPIO的模式引用出来
	  GPIO_InitStructre.GPIO_Mode =GPIO_Mode_AIN;       //  选择GPIO的模式,设置为AN模拟输入的模式在AIN模式下GPIO口是没有效果的
	  GPIO_InitStructre.GPIO_Pin = 	GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3;         //  选择GPIO的输出模式,选择输出的管脚
	  GPIO_InitStructre.GPIO_Speed = GPIO_Speed_50MHz;  //  选择GPIO的时钟频率
	  GPIO_Init(GPIOA,&GPIO_InitStructre);              //  初始化GPIO
	

	  
	  // 第三步 ---> 使用结构体初始化ADC
	  ADC_InitTypeDef ADC_InitStructure;
	  // 引出结构体成员
	  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE ;                //  配置扫描的模式
		ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;              //  配置ADC的数据对齐方式
		ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //  配置ADC的外部触发转换选择:这里使用内部软件触发的方式
		ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                  //  配置ADC的工作模式为独立模式
		ADC_InitStructure.ADC_NbrOfChannel = 1;                             //  配置通道数目
		ADC_InitStructure.ADC_ScanConvMode = DISABLE;                       //  配置扫描的模式
	  ADC_Init(ADC1,&ADC_InitStructure);
	
	  // 以下还可以配置中断和模拟看门狗,根据自己的需求进行配置
		
		
		// 开启ADC设置,第一个ENABLE第二个开启ADC的电源
		ADC_Cmd(ADC1,ENABLE); 
	  // 对ADC进行校准,这里分别有四个函数可以进行配置
		ADC_ResetCalibration(ADC1);  						              // 复位校准
		while(ADC_GetResetCalibrationStatus(ADC1) == SET);    // 返回复位校准的状态
	  ADC_StartCalibration(ADC1);                           // 启动校准
		while(ADC_GetCalibrationStatus(ADC1) == SET);         // 获取校准后的状态        
	  // 1: 软件触发转换 2:等待触发完成也就是等待EOC标志位设置为1,3:读取ADC数据寄存器
	  ADC_SoftwareStartConvCmd(ADC1,ENABLE);

}
uint16_t AD_GetValue(uint8_t ADC_Channel){
 
    // 第二步 ---》 选择规则组的输入通道,参数二:指定通道,参数三:规则组序列器里面的次序1-16之间,参数4:指定通道的采样时间
	  ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5); 
	  ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
	  return ADC_GetConversionValue(ADC1);
}


main函数部分代码编译和下载

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t AD0,AD1,AD2,AD3;
float Votage;
int main(void)
{
  // 初始化oled
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1,1,"AD0:");
  OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD3:");
  OLED_ShowString(4,1,"AD4:");
	
	while (1)
	{
    AD0 = AD_GetValue(ADC_Channel_0);
		AD1 = AD_GetValue(ADC_Channel_1);
		AD2 = AD_GetValue(ADC_Channel_2);
		AD3 = AD_GetValue(ADC_Channel_3);
		OLED_ShowNum(1, 5, AD0, 4);
		OLED_ShowNum(2, 5, AD1, 4);
		OLED_ShowNum(3, 5, AD2, 4);
		OLED_ShowNum(4, 5, AD3, 4);
		Delay_ms(100);
	}
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32是STMicroelectronics公司开发的一系列32位微控制系列,采用ARM Cortex-M内核。其中,ADCSTM32微控制中的一种模块,用于模拟信号的采集和转换。麦克(麦克风)是一种常用的音频输入设备,可将声音信号转化模拟电压信号。 在使用STM32ADC模块采集麦克风信号时,首先需要将麦克风连接到STM32微控制的相应引脚,通常是通过模拟输入通道。然后,根据麦克风的灵敏度和输出电平范围设置ADC的参考电压和采样率。参考电压用于将模拟电压信号转换为数字信号,而采样率决定了每秒钟采样的次数。 接下来,需要在STM32的编程环境中配置ADC模块。首先,需要选择合适的ADC通道,它指定了从哪个引脚读取模拟信号。然后,需要设置ADC的分辨率,即每次采样时的位数,一般可以选择8位或12位。还需要设置ADC的工作模式,包括单次采样、连续采样等。 在开始ADC的采样之前,需要启动ADC模块并等待其初始化完成。一旦初始化完成,就可以开始连续地读取麦克风信号。读取过程中,ADC会将模拟信号转换为数字值,并将其存储在相应的寄存中。可以通过读取这些寄存来获取采样到的麦克风信号。为了保证精确度和稳定性,最好对多次采样进行平均处理。 最后,在完成采样后需要及时关闭ADC模块以节省功耗,并对采样结果进行后续处理,如滤波、数据分析等。另外,还可以根据需要使用DMA(直接内存访问)功能,使ADC数据的传输更加高效。 总之,使用STM32ADC模块采集麦克风信号,需要进行配置和初始化,然后读取模拟信号并转换为数字信号。在整个过程中,需要注意ADC的参数设置,以及采样结果的后续处理和应用。 ### 回答2: STM32是一种嵌入式微控制,它具有强大的性能和丰富的外设功能。其中之一是ADC(模数转换),可以用来采集麦克风的信号。 首先,我们需要将麦克风连接到STM32的一个模拟输入引脚。常用的模拟输入引脚有ADC1_IN0、ADC1_IN1等,可以根据需要选择合适的引脚。 然后,我们需要配置ADC模块。首先,设置ADC的时钟和分辨率。时钟设置通常使用外部时钟或内部时钟源,分辨率设置决定了采样的精度。其次,设置ADC的采样率和转换模式。采样率决定了采集信号的频率,而转换模式可以选择单次转换模式或连续转换模式,根据实际需求选择合适的模式。 接下来,我们需要设置ADC的通道和触发源。通过设置ADC通道,我们可以选择要采集的信号源,这里选择连接麦克风的模拟输入引脚。而触发源则决定了启动ADC转换的条件,可以是软件触发或外部触发,具体选择根据实际需求。同时,还需要设置ADC的对齐方式和数据对应关系。 最后,我们可以使用中断或DMA来处理ADC转换完成后的数据。中断是一种常用的方法,当ADC转换完成后会产生中断请求,我们可以在中断服务函数中读取ADC转换结果并进行相应的处理。另一种方法是使用DMA,通过配置DMA通道,可以将ADC转换结果直接传输到指定的内存区域中,节省了CPU的负担。 以上就是使用STM32 ADC采集麦克风的简要过程。当然,具体的配置和代码编写需要根据实际情况进行调整和扩展,这里只是提供一个大致的框架。希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值