×
单片机 > 单片机程序设计 > 详情

Stm32f103rct6ADC电压采集简介及注意点

发布时间:2020-06-09 发布时间:
|

STM32f103 系列有 3 个 ADC,精度为12 位,每个 ADC 最多有 16 个外部通道。其中ADC1和ADC2 都有 16 个外部通道,ADC3根据CPU 引脚的不同通道数也不同,一般都有8 个外部通道。ADC 的模式非常多,功能非常强大。

ADC 输入范围为:V REF-  ≤ V IN ≤ V REF+ ,一般把 V SSA 和 V REF- 接地,把 V REF+ 和 V DDA 接3V3,得到ADC 的输入电压范围为:0~3.3V。

通道:

注入通道:

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

转换顺序:规则序列:

规则序列寄存器有 3 个,分别为 SQR3、SQR2、SQR1。

SQR3 控制着规则序列中的第一个到第六个转换,对应的位为:SQ1[4:0]~SQ6[4:0],第一次转换的是位 4:0 SQ1[4:0],如果通道 16想第一次转换,那么在 SQ1[4: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 还支持触发转换,这个触发包括内部定时器触发和外部 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 经过分频产生,最大是 14M,分频因子由 RCC时钟配置寄存器 RCC_CFGR 的位 15:14 ADCPRE[1:0]设置,可以是 2/4/6/8 分频,注意这里没有 1 分频。一般我们设置 PCLK2=HCLK=72M。

采样时间:

ADC 使用若干个 ADC_CLK 周期对输入的电压进行采样,采样的周期数可通过 ADC采样时间寄存器 ADC_SMPR1 和 ADC_SMPR2 中的 SMP[2:0]位设置,ADC_SMPR2 控制的是通道0~9,ADC_SMPR1 控制的是通道 10~17。

数据寄存器:

规则数据寄存器:

ADC 规则组数据寄存器 ADC_DR 只有一个,是一个 32 位的寄存器,低 16 位在单 ADC时使用,高 16 位是在 ADC1 中双模式下保存 ADC2 转换的规则数据,双模式就是 ADC1 和ADC2同时使用。

注入数据寄存器:

DMA:

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

 

 

 

ADC_InitTypeDef结构体

1 typedef struct

2 {

3        uint32_t ADC_Mode; // ADC 工作模式选择

4       FunctionalState ADC_ScanConvMode;

6        FunctionalState ADC_ContinuousConvMode; // ADC 单次转换或者连续转换选择

7        uint32_t ADC_ExternalTrigConv; // ADC 转换触发信号选择

8       uint32_t ADC_DataAlign; // ADC 数据寄存器对齐格式,右对齐ADC_DataAlign_Right 或者左对齐 ADC_DataAlign_Left。一般我们选择右对齐模式。

9        uint8_t ADC_NbrOfChannel; // ADC 采集通道数

10 } ADC_InitTypeDef;


主要配置代码:

#define    ADC_APBxClock_FUN             RCC_APB2PeriphClockCmd

#define    ADC_CLK                       RCC_APB2Periph_ADC1

#define    ADC_GPIO_APBxClock_FUN        RCC_APB2PeriphClockCmd

#define    ADC_GPIO_CLK                  RCC_APB2Periph_GPIOC  

#define    ADC_PORT                      GPIOC

#define    NOFCHANEL 6

#define    ADC_PIN1                      GPIO_Pin_0

#define    ADC_CHANNEL1                  ADC_Channel_10

#define    ADC_PIN2                      GPIO_Pin_1

#define    ADC_CHANNEL2                  ADC_Channel_11

#define    ADC_PIN3                      GPIO_Pin_2

#define    ADC_CHANNEL3                  ADC_Channel_12

#define    ADC_PIN4                      GPIO_Pin_3

#define    ADC_CHANNEL4                  ADC_Channel_13

#define    ADC_PIN5                      GPIO_Pin_4

#define    ADC_CHANNEL5                  ADC_Channel_14

#define    ADC_PIN6                      GPIO_Pin_5

#define    ADC_CHANNEL6                  ADC_Channel_15

// ADC1 对应 DMA1通道1,ADC3对应DMA2通道5,ADC2没有DMA功能

#define    ADC_x                         ADC1

#define    ADC_DMA_CHANNEL               DMA1_Channel1

#define    ADC_DMA_CLK                   RCC_AHBPeriph_DMA1

static void ADCx_Mode_Config(void)

{

DMA_InitTypeDef DMA_InitStructure;

ADC_InitTypeDef ADC_InitStructure;

// 打开DMA时钟

RCC_AHBPeriphClockCmd(ADC_DMA_CLK, ENABLE);

// 打开ADC时钟

ADC_APBxClock_FUN ( ADC_CLK, ENABLE );

// 复位DMA控制器

DMA_DeInit(ADC_DMA_CHANNEL);

// 配置 DMA 初始化结构体

// 外设基址为:ADC 数据寄存器地址

DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 ) ( & ( ADC_x->DR ) );

// 存储器地址

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;

// 数据源来自外设

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

// 缓冲区大小,应该等于数据目的地的大小

DMA_InitStructure.DMA_BufferSize = NOFCHANEL;

// 外设寄存器只有一个,地址不用递增

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

// 存储器地址递增

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

// 外设数据大小为半字,即两个字节

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

// 内存数据大小也为半字,跟外设数据大小相同

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

// 循环传输模式

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

// 禁止存储器到存储器模式,因为是从外设到存储器

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

// 初始化DMA

DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);

// 使能 DMA 通道

DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);

// ADC 模式配置

// 只使用一个ADC,属于单模式

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

// 扫描模式

ADC_InitStructure.ADC_ScanConvMode = ENABLE ; 

// 连续转换模式

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

// 不用外部触发转换,软件开启即可

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

// 转换结果右对齐

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

// 转换通道个数

ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;

// 初始化ADC

ADC_Init(ADC_x, &ADC_InitStructure);

// 配置ADC时钟N狿CLK2的8分频,即9MHz

RCC_ADCCLKConfig(RCC_PCLK2_Div8); 

// 配置ADC 通道的转换顺序和采样时间

ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL1, 1, ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL2, 2, ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL3, 3, ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL4, 4, ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL5, 5, ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL6, 6, ADC_SampleTime_55Cycles5);

// 使能ADC DMA 请求

ADC_DMACmd(ADC_x, ENABLE);

// 开启ADC ,并开始转换

ADC_Cmd(ADC_x, ENABLE);

// 初始化ADC 校准寄存器  

ADC_ResetCalibration(ADC_x);

// 等待校准寄存器初始化完成

while(ADC_GetResetCalibrationStatus(ADC_x));

// ADC开始校准

ADC_StartCalibration(ADC_x);

// 等待校准完成

while(ADC_GetCalibrationStatus(ADC_x));

// 由于没有采用外部触发,所以使用软件触发ADC转换 

ADC_SoftwareStartConvCmd(ADC_x, ENABLE);

}



关键字:Stm32f103rct6  ADC  电压采集

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32中断向量表的位置.重定向