STM32——ADC模块 (附代码)

1.什么是ADC?

        ADCAnalog-Digital Converter模拟-数字转换器可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。

2.ADC是如何转换的?

ADC是通过逐次逼近进行AD转换的,那么什么是逐次逼近呢?如上图示,比较器左侧是输入的未知电压,右侧是DAC输出的已知电压(知道电压值并且知道电压对应的数字信号值),外部输入的未知编码的电压与DAC输出的已知编码的电压,它俩同时输入到电压比较器,进行大小判断,如果DAC输出的电压大,就调小DAC的数据,如果小,就增大DAC数据,为了提高比较速度,ADC选择二分法比较。如:数字转换的范围是0~128,利用二分法的原则,先比较输入电压对应的值是否大于64,如果小于64,则比较是否大于32,依此类推。直到DAC输出的电压与外部通道输入的电压近视相等。这样DAC对应的的数据就是外部输入电压的编码数据了。

上图中,EOC(End Of Convert)为:转换结束信号。START:是开始转换CLOCK:是ACD的时钟。VREF(+)、VREF(-)是DAC的参考电压,即是对应5v还是3.3v。

3.STM32逐次逼近型框图

触发ADC转换的方式:

        硬件触发:如定时器定时等(红框表示硬件出发源)。

        软件触发:软件调用触发ADC转换

ADC转换通道(绿框):1.规则组;2.注入组

        规则组:有16个ADC通道,同时可以进行16个AD转换,但是只有一个DR(数据寄存器),也就是说,如果同时转换16个AD,那么前15个转换结果将会被覆盖。

        注入组:有4个ADC通道,同时可以进行4个AD转换,有4个DR(数据寄存器),所以数据不会被覆盖。

图中模拟至数字转换器就是逐次比较的过程,比较的数据放入数据寄存器里。

ADC时钟(蓝框):来自内部时钟72MHZ,可以进行2、4、6、8预分频,不过这里规定ADC最大的频率为14MHZ,也就是说,2、4分频无效。

规则组有四种转换模式:

        单次转换,非扫描模式

        连续转换,非扫描模式

        单次转换,扫描模式

        连续转换,扫描模式

单次转换,转换一次就停止;连续转换:只需要触发一次,就一直转换;扫描模式:可以选择多个通道;非扫描模式:只能选择一个通道。

单次转换,非扫描模式:

连续转换,非扫描模式:

单次转换,扫描模式

连续转换,扫描模式

4.STM32 ADC代码

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	//第一步:开启RCC时钟(ADC,GPIO,ADCCLK)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	//第二步:配置GPIO(把GPIO配置成模拟输入的模式)
	GPIO_InitTypeDef GPIO_InitStructure;
	//在AIN模式下GPIO口是无效的,断开GPIO,防止GPIO口的输入/出对模拟电压造成干扰
	//AIN模式是ADC的专属模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//第三步:配置多路开关,把左边的通道接入到右边的规则列表里(点菜)
	//规则通道选择
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	//第四步:配置ADC转换器(连续扫描、转换、几个通道、触发源、左右对齐)
	ADC_InitTypeDef  ADC_InitStructure;
	//连续转换模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	//数据对齐
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	//外部触发转换选择(触发控制的触发源)
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	//ADC的工作模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	//通道数目(在扫描模式下用几个通道)
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	//扫描转换模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	
	ADC_Init(ADC1,&ADC_InitStructure);
	//第五步:模拟看门狗或开启中断
	
	//第六步:调用ADC_Cmd()函数,开启ADC(给ADC通电)
	ADC_Cmd(ADC1,ENABLE);
	//第七步:开启ADC之后,最好对ADC进行校准,较小误差。
	//7.1复位校准
	ADC_ResetCalibration(ADC1);
	//7.2等待复位校准完成
	while (ADC_GetResetCalibrationStatus(ADC1));
	//7.3开始校准
	ADC_StartCalibration(ADC1);
	//7.4等待校准完成
	while (ADC_GetCalibrationStatus(ADC1));
	//触发ADC转换
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}

//启动转换,获取结果
uint16_t AD_GetValue(void)
{
	
	//while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);
	//获取转换值
	return ADC_GetConversionValue(ADC1);
}

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ADC(模拟数字转换器)是将模拟信号转换成数字信号的重要模块,通常用于电压、温度、光强等模拟量的测量。以下是一个基于STM32F4的ADC模块代码设计示例: 首先,需要对ADC进行初始化设置,包括时钟使能、参考电压设置、采样时间配置等。示例代码如下: ```c //使能GPIO和ADC时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //GPIO初始化 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); //ADC初始化 ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADC1, &ADC_InitStructure); //参考电压初始化 ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); //采样时间初始化 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_144Cycles); ``` 以上代码实现了对ADC的初始化设置,包括采样时间、参考电压等参数的配置。 接下来,读取ADC转换结果并进行处理。在这个示例中,我们将转换结果通过串口输出。示例代码如下: ```c //开启ADC ADC_Cmd(ADC1, ENABLE); //等待ADC开启 while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)) {} while (1) { //开始转换 ADC_SoftwareStartConv(ADC1); //等待转换完成 while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)) {} //获取转换结果 uint16_t value = ADC_GetConversionValue(ADC1); //将转换结果通过串口输出 char str[16]; sprintf(str, "ADC Value: %d\r\n", value); USART_SendString(USART1, str); //延时一段时间 delay_ms(1000); } ``` 以上代码每次进行一次ADC转换,并将转换结果通过串口输出。同时,程序通过延时的方式控制转换频率,实现定时采集ADC数据的功能。 总之,这是一个基于STM32F4的ADC模块代码设计示例,具体实现根据不同的芯片和使用需求可能有所不同。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值