STM32F4XX - ADC设置

STM32F4XX ADC:
分辨率:

  • 可配置 12 位、10 位、8 位或 6 位分辨率

通道组:

  • 每一个ADCX都有两种通道(规则通道(最多16个)和注入通道(最多4个)),可以将规则写入到ADC_SQRx寄存器中,个数写入到这个寄存器的低[3:0]中。

  • 它具有多达 19 个复用通道,可测量来自 16 个外部源、两个内部源和 V BAT 通道的信号

转换模式:

  • 包含单次转换和连续转换
  • [? 不太清楚] 当有多个规则通道时,连续转换后的数据是哪一个通道的? (当有多个通道时,可以使用DMA的方式可防止数据寄存器数据被覆盖,每完成规则通道组中的一个通道转换后,都会生成一个 DMA 请求。如果没有来得及取出数据,会发生溢出错误)

扫描模式:

  • 如果是规则通道,根据ADC_SQRx中的规则顺序转换,转换结束后开始下一次转换。如果是连续转换模式,那么就会一直循环转换。

各通道采样时间设置:
可使用 ADC_SMPR1 和 ADC_SMPR2寄存器中的 SMP[2:0] 位修改周期数。
总转换时间的计算公式如下:
T conv = 采样时间 + 12 个周期
示例:
ADCCLK = 30 MHz 且采样时间 = 3 个周期时:
T conv = 3 + 12 = 15 个周期 = 0.5 μs(APB2 为 60 MHz 时)

外部触发转换:
定时器触发(TIMx_CHy)或者外部引脚(EXTI)触发。本例中使用软件设置触发转换。

初始化代码如下:

void  Adc_Init(void)
{  
                GPIO_InitTypeDef       GPIO_InitStructure;
                ADC_CommonInitTypeDef ADC_CommonInitStructure;
                ADC_InitTypeDef       ADC_InitStructure;
                
                RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOA时钟
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟

                
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PB0 通道8
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
                GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化  
                
                RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);       //ADC1复位
                RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);    //复位结束       
                
                ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
                ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
                ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
                ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;//预分频4分频。ADCCLK=PCLK2/6=84/6=14Mhz,ADC时钟最好不要
超过36Mhz       
                ADC_CommonInit(&ADC_CommonInitStructure);//初始化
                
                ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
                ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式       
                ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
                ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
                ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐  
                ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 
                ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
                ADC_Cmd(ADC1, ENABLE);//开启AD转换器     
}

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
使能对应GPIO与ADC外设控制器时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PB0 通道8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
配置gpio接口,模拟输入,不带上下拉,使用的pin脚。

ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要
超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
这段主要设置通用寄存器,包括ADC通用设置。设置ADC通用控制寄存器(ADC common control register),除了CCR通用寄存器外,还有ADC_CSR与ADC_CDR通用寄存器。
1. 设置为独立模式
2. 多重模式下两次采样的间隔时钟,这个在独立模式下不影响
3. DMA失能,DMA在多规则时比较好用。
4. ADC时钟频率为 PCLK / 6

在继续说明后面代码之前,对通用寄存器做下相关理解说明:
ADC_CSR: 通用状态寄存器
ADC_CCR: 通用控制寄存器
ADC_CDR: 通用规则数据寄存器

ADC_CDR
是存放规则数据的寄存器,只读。32位。如果是双重模式下,高16位存放ADC2的规则数据。低16位存放ADC1的规则数据。
ADC_CCR
控制通用ADC寄存器设置
如ADCPRE位表示可以设置分频系数。

  • 00:PCLK2 2 分频
  • 01:PCLK2 4 分频
  • 10:PCLK2 6 分频
  • 11:PCLK2 8 分频
    如DMA 针对的是多重ADC模式,所以我们禁用。
    如DELAY 也是针对多重ADC模式下,两个ADC采用之间的延时。
    如MULTI 配置是独立模式、双重模式还是三重模式。

ADC_CSR
只读的通用状态寄存器,32位。挑选其中的几个位进行说明:
OVR1 位表示ADC1 的溢出标志
STRT1 位表示ADC1 规则通道开始标志
JSTRT1 位表示ADC1 注入通道开始标志
JEOC1 位表示ADC1 的注入通道转换结束
EOC1 位表示ADC1 的规则通道转换结束
AWD1位表示模拟看门狗标志。(如果ADC 转换的模拟电压低于阈值下限或高于阈值上限,则 AWD 模拟看门狗状态位会置1。)

…所以设置ADC_Mode为独立模式后,配置也变得很简单了。

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
ADC_Cmd(ADC1, ENABLE);//开启AD转换器
这个设置也是比较简单的,如12位模式,因为组内就只有一个通道所以设置为非扫描模式。关闭连续转换,使用手动触发转换,禁止外部触发,右对齐,规则组内一个通道。

获取adc数据代码如下:

u16 Get_Adc(u8 ch)   
{
        //Sets the specified ADC rule group channel, one sequence, and sampling time
        //设置指定ADC的规则组通道,一个序列,采样时间
                                                                                                                                   
        //ADC1,ADC通道,采样时间为480周期
        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );
  //Enable the specified ADC1 software transformation startup function  
  //使能指定的ADC1的软件转换启动功能    
        ADC_SoftwareStartConv(ADC1);
        //Wait for the conversion to finish
  //等待转换结束        
        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
        //Returns the result of the last ADC1 rule group conversion
        //返回最近一次ADC1规则组的转换结果
        return ADC_GetConversionValue(ADC1);    
}

  • ADC_RegularChannelConfig(ADC1, ch, 1,ADC_SampleTime_480Cycles );
    设置采样周期,ADCCLK 现在计算为14MHz,ADC_SMPR1设置的值为480个时钟周期。所以每次采样时间为: T conv =
    480 + 12 = 492 个周期 采样时间为: 492 / 14MHz = 35 us
  • ADC_SoftwareStartConv(ADC1); 开始转换。
  • while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
    等待转换完成。
  • ADC_GetConversionValue(ADC1);
    获取转换数据

附上单个ADC框图:
在这里插入图片描述

  • 15
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值