【STM32 标准库】ADC
目录
1.STM32 ADC
1.1 ADC简介
1.2 结构框图
2.ADC配置
2.1 配置步骤
3.硬件设计
4.软件设计
4.1功能描述
4.2软件实现
1.STM32 ADC
1.1 ADC简介
模数转换器(Analog to Digital Converter, ADC),将模拟信号转换为数字信号。按照原理可分为:逐次逼近型、双积分型、电压频率转换型3种。
特性:
●12位分辨率(18个通道:16个外部通道,2个内部通道)
● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
● 单次和连续转换模式、从通道0到通道n的自动扫描模式
● 自校准
● 带内嵌数据一致性的数据对齐
● 采样间隔可以按通道分别编程
● 规则转换和注入转换均有外部触发选项
● 间断模式
● 双重模式(带2个或以上ADC的器件)
● ADC转换时间:
─ STM32F103xx增强型产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs)
─STM32F101xx基本型产品:时钟为28MHz时为1μs(时钟为36MHz为1.55μs)
─STM32F102xxUSB型产品:时钟为48MHz时为1.2μs
─STM32F105xx和STM32F107xx产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs)
●ADC供电要求:2.4V到3.6V
●ADC输入范围:VREF-≤VIN≤VREF+
● 规则通道转换期间有DMA请求产生
1.2 结构框图
2.ADC配置
2.1 配置步骤
(1)添加源文件和头文件:stm32f10x_adc.c 和 stm32f10x_adc.h
(2)使能端口时钟和 ADC 时钟,设置引脚模式为模拟输入
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,E NABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
(3)设置 ADC 的分频因子
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //包括2、4、6、8分频,一般用6分频
(4)初始化 ADC 参数,包括 ADC 工作模式、规则序列等
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
typedef struct
{
uint32_t ADC_Mode; // ADC 工作模式选择
FunctionalState ADC_ScanConvMode;//ADC 扫描(多通道)或者单次(单通道)模式选择
FunctionalState ADC_ContinuousConvMode; // ADC 单次转换或者连续转换选择
uint32_t ADC_ExternalTrigConv; // ADC 转换触发信号选择
uint32_t ADC_DataAlign; // ADC 数据寄存器对齐格式
uint8_t ADC_NbrOfChannel; // ADC 采集通道数
} ADC_InitTypeDef;
(5)使能 ADC 并校准
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
ADC_ResetCalibration(ADC1);
ADC_StartCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
(6)读取 ADC 转换值
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel,uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
3.硬件设计
4.软件设计
4.1功能描述
通过 ADC1 通道 1 采样外部电压值,将采样的 AD 值和转换后的电压值通过串口打印出来,同时 DS0 指示灯闪烁,提示系统正常运行。
4.2软件实现
(1)初始化 ADC1_IN1 相关参数,开启 ADC1
1.#include "ADC.h"
2.
3.void ADCx_Iint(void)
4.{
5. //1 使能端口时钟和 ADC 时钟
6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
7.
8. //2 设置引脚模式为模拟输入
9. GPIO_InitTypeDef GPIO_InitStructure;
10.
11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
13. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
14. GPIO_Init(GPIOA, &GPIO_InitStructure);
15.
16. //3 设置 ADC 的分频因子?
17. RCC_ADCCLKConfig(RCC_PCLK2_Div6);
18.
19. //4 初始化 ADC 参数,包括 ADC 工作模式、规则序列等
20. ADC_InitTypeDef ADC_InitStructure;
21. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
22. ADC_InitStructure.ADC_ScanConvMode = DISABLE;
23. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
24. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
25. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
26. ADC_InitStructure.ADC_NbrOfChannel = 1;
27. ADC_Init(ADC1,&ADC_InitStructure);
28.
29. //5 使能 ADC 并校准
30. ADC_Cmd(ADC1,ENABLE);
31.
32. ADC_ResetCalibration(ADC1); //复位校准
33. while(ADC_GetResetCalibrationStatus(ADC1));
34.
35. ADC_StartCalibration(ADC1); //开启校准
36. while(ADC_GetCalibrationStatus(ADC1));
37.
38. //6 软件开启
39. ADC_SoftwareStartConvCmd(ADC1,ENABLE);
40.}
(2)编写获取 ADC1_IN1 的 AD 转换值函数
1.u16 Get_ADC_Value(u8 ch, u8 times)
2.{
3. ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);
4.
5. u8 i = 0;
6. u32 Temp_val = 0;
7.
8. for(i=0;i<=times;i++)
9. {
10. ADC_SoftwareStartConvCmd(ADC1,ENABLE); //因为使用的是单次转换,所以每次循环后都要开启转换
11. while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
12. Temp_val += ADC_GetConversionValue(ADC1);
13. delay_ms(5);
14. }
15. return Temp_val/times;
16.}
(3)编写主函数
1./* Includes ------------------------------------------------------------------*/
2.#include "system.h"
3.#include "LED.h"
4.#include "SysTick.h"
5.#include "USART.h"
6.#include "ADC.h"
7.
8./* 主函数main() --------------------------------------------------------------*/
9.int main()
10.{
11. // 自定义变量
12. u8 i = 0;
13. u16 value = 0;
14. float voltage;
15.
16. // 初始化
17. SysTick_Iint(72);
18. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断分组
19. LED_Init();
20. USART1_Iint(115200);
21. ADCx_Iint();
22.
23. while(1)
24. {
25. i++;
26. if(i%20==0)
27. {
28. LED0 = !LED0;
29. }
30. delay_ms(10);
31.
32. if(i%100==0)
33. {
34. value = Get_ADC_Value(ADC_Channel_1, 20);
35. printf("检测到的AD值为:%d\r\n",value);
36. //电压转换:voltage = AD_voltage * V_ref / 4096
37. voltage = (float) value * (3.3/4096);
38. printf("检测到的电压值为:%.2f V\r\n",voltage);
39. }
40. }
41.}
作者:微风の清风