企业网站模板下载哪里,昌平县城做网站,网页设计与制作项目化教程,园林景观网站模板一、简介
*ADC#xff08;Analog-Digital Converter#xff09;模拟-数字转换器
*ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量#xff0c;建立模拟电路到数字电路的桥梁
*12位逐次逼近型ADC#xff0c;1us转换时间
*输入电压范围#xff1a;0~3.3VAnalog-Digital Converter模拟-数字转换器
*ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量建立模拟电路到数字电路的桥梁
*12位逐次逼近型ADC1us转换时间
*输入电压范围0~3.3V转换结果范围0~409512位转换分辨率
*18个输入通道可测量16个外部和2个内部信号源在任意多个通道上以任意顺序进行的一系列转换构成成组转换规则通道。例如可以如下顺序完成转换通道3、通道8、通道2、通道0、通道2、通道2、通道15
*规则组和注入组两个转换单元规则通道我们平时用的一般通道按顺序进行转换注入通道可以理解为插入。它是一种在规则通道转换的时候强行插入要转换的一种。注入通道只有在规则通道存在的时候才会出现
*模拟看门狗自动监测输入电压范围
*转换时间最短的转化时间--Tconv 采样时间 12.5个周期 PCLK2 72M,ADC_CLK 72/6 12M Tconv 1.512.4 14周期 14/12us 1.17us
*AD转换的步骤采样保持量化编码
*STM32F103C8T6 ADC资源ADC1、ADC210个外部输入通道F4有三个ADC 1、电压输入范围
*输入电压 VREF- VIN VREF
*决定输入电压的引脚VREF-,VREF,VDDA,VSSA
*VSSA和VREF- 接地VREF 和VDDA 接3.3V
*得到ADC的电压输入范围为 0-3.3V 电压怎么测
电压输入范围ADC可以测量-10V ~ 10V 根据基尔霍夫定理Vin - Vout/R2 (3v3-Vout)/R1Vout/R3 Vout(Vint 10)/6 二、ADC的基本结构 ps:STM32f103c8t6有ADC1和ADC2有两个转换单元规则组、注入组规则组有16个通道注入组有4个通道。
规则通道有数据覆盖的问题用DMA来解决 只能用于ADC1只有一个数据寄存器注入通道没有数据覆盖的问题四个通道有四个存放寄存器
三、转换模式
1、单次转换非扫描模式 *单次转换模式下 ADC 只执行一次转换如果需要再进行转换需要软件来执行 *如果一个规则通道被转换转换数据被储存在 16 位 ADC_DR寄存器中EOC( 转换结束 )标志被设置为1如果设置了 EOCIE 则产生中断。 *非扫描模式只能用于只有一个转换通道有多个转换通道时要设置扫描模式 2、连续转换非扫描模式 *在连续转换模式中当前面 ADC 转换一结束马上就启动另一次转换。此模式可通过外部触发启 动或通过设置 ADC_CR2 寄存器上的 ADON 位启动此时 CONT 位是 1 。 *如果一个规则通道被转换转换数据被储存在 16 位 ADC_DR寄存器中EOC( 转换结束 )标志被设置为1如果设置了 EOCIE 则产生中断。 *非扫描模式只能用于只有一个转换通道有多个转换通道时要设置扫描模式 3、单次转换扫描模式 *ADC规则通道的转换次序是由由序列1到序列16依次转换有通道就转换没通道就跳过如果转换次序需要较高优先级那就要把该通道放在靠前序列 *连续转换模式是当前面ADC转换一结束马上就启动另一次转换。此模式可通过外部触发启动或通过设置ADC_CR2寄存器上的ADON位启动此时CONT位是1。 *扫描模式只用于一个规则组中有多个通道需要转换的情况 4、连续转换扫描模式 *在连续转换模式中当前面 ADC 转换一结束马上就启动另一次转换。此模式可通过外部触发启 动或通过设置 ADC_CR2 寄存器上的 ADON 位启动此时 CONT 位是 1 。 *如果一个规则通道被转换转换数据被储存在 16 位 ADC_DR寄存器中EOC( 转换结束 )标志被设置为1如果设置了 EOCIE 则产生中断。 *扫描模式只用于一个规则组中有多个通道需要转换的情况 PS转换序列里可以可以出现多个相同的转换通道 四、转换顺序 通过设置寄存器里面不同的值来配置不同通道的转换顺序以及转换的总通道数量 规则通道 注入通道 五、代码 1、ADC单通道DMA读取 #include adc.h
uint16_t ADC_conversionValue;//单ADC模式时数据寄存器只用到低16位用来存放 ADC发过来的数据
static void ACDx_GPIO_Config(void)
{GPIO_InitTypeDef ADC_GPIO_StructInit;ADCx_PIN_RCC_Clock_Cmd(ADCx_PIN_Periph,ENABLE);ADC_GPIO_StructInit.GPIO_Mode GPIO_Mode_AIN; //必须是模拟输入ADC_GPIO_StructInit.GPIO_Pin ADCx_PIN;GPIO_Init(ADCx_PIN_PORT, ADC_GPIO_StructInit);
}static void Config_ADC_Init(void)
{ADC_InitTypeDef ADC_StructInit;DMA_InitTypeDef DMA_StructInit;/*--------------------------DMA-----------------------------------------*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //打开时钟DMA_DeInit(DMA1_Channel1); //将DMA寄存器复位成刚上电的样子DMA_StructInit.DMA_MemoryBaseAddr (uint32_t)ADC_conversionValue; //存储器地址DMA_StructInit.DMA_PeripheralBaseAddr (uint32_t)((ADC_x-DR)); //外设地址 DMA_StructInit.DMA_DIR DMA_DIR_PeripheralSRC; //传输方向DMA_StructInit.DMA_BufferSize 1; //传输数目DMA_StructInit.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWord;//外设数据宽度数据寄存器只用到低16位DMA_StructInit.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord; //存储器数据宽度数据寄存器只用到低16位DMA_StructInit.DMA_PeripheralInc DMA_PeripheralInc_Disable; //外设地址是否递增DMA_StructInit.DMA_MemoryInc DMA_MemoryInc_Disable; //存储器地址是否递增DMA_StructInit.DMA_Mode DMA_Mode_Circular; //模式选择现在时循环模式DMA_StructInit.DMA_Priority DMA_Priority_High; //通道优先级DMA_StructInit.DMA_M2M DMA_M2M_Disable; //存储器到存储器模式DMA_Init( DMA1_Channel1, DMA_StructInit);DMA_Cmd(DMA1_Channel1, ENABLE);/*---------------------ADC------------------------------------*/ADCx_RCC_Clock_Cmd(ADCx_Periph, ENABLE);ADC_StructInit.ADC_Mode ADC_Mode_Independent; //设置独立模式因为只有一个ADC通道ADC_StructInit.ADC_ScanConvMode DISABLE; //配置是否扫描用在多通道ADC_StructInit.ADC_ContinuousConvMode ENABLE; //配置是否要连续转换ADC_StructInit.ADC_DataAlign ADC_DataAlign_Right; //配置数据的对齐模式ADC_StructInit.ADC_NbrOfChannel 1; //配置要转换通道的数目ADC_StructInit.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;//配置触发模式这里是软件触发外部触发是有定时器或者GPIO才会使用ADC_Init(ADC_x, ADC_StructInit);RCC_ADCCLKConfig(RCC_PCLK2_Div8); //时钟配置72/89MADC_RegularChannelConfig(ADC_x, ADCx_Channel, 1, ADC_SampleTime_55Cycles5); //规则通道的配置第三个参数是配置第几次转换第四个参数是配置采样周期ADC_Cmd(ADC_x, ENABLE); //使能ADC中断ADC_StartCalibration(ADC_x); //开始校准ADCwhile(ADC_GetCalibrationStatus(ADC_x)); //等待校准完成ADC_SoftwareStartConvCmd(ADC_x, ENABLE); //软件触发使能开始工作//使能DMA ADCADC_DMACmd(ADC_x, ENABLE);}void ADCx_Init(void)
{ACDx_GPIO_Config();Config_ADC_Init();
}extern uint16_t ADC_conversionValue;
int main()
{float conversionValue 0;initSysTick();usart_init();ADCx_Init();while(1){conversionValue (float)ADC_conversionValue/4096*3.3;printf(hex %04x\r\n,ADC_conversionValue);printf(conversionValue %f\r\n,conversionValue);ms_delay(2000);}}2、ADC单通道中断读取 #ifndef ADC_H
#define ADC_H
#include stm32f10x.h
static void ACDx_GPIO_Config(void);
static void Config_ADC_Init(void);
static void ADCx_NVIC_Config(void);
void ADCx_Init(void);//ADC引脚配置的宏
#define ADCx_PIN GPIO_Pin_1
#define ADCx_PIN_PORT GPIOA
#define ADCx_PIN_Periph RCC_APB2Periph_GPIOA
#define ADCx_PIN_RCC_Clock_Cmd RCC_APB2PeriphClockCmd//ADC配置的宏
#define ADCx_Periph RCC_APB2Periph_ADC2
#define ADCx_RCC_Clock_Cmd RCC_APB2PeriphClockCmd
#define ADC_x ADC2
#define ADCx_Channel ADC_Channel_1#define ADCx_IRQHandler ADC1_2_IRQHandler
#endif#include adc.hstatic void ACDx_GPIO_Config(void)
{GPIO_InitTypeDef ADC_GPIO_StructInit;ADCx_PIN_RCC_Clock_Cmd(ADCx_PIN_Periph,ENABLE);ADC_GPIO_StructInit.GPIO_Mode GPIO_Mode_AIN; //必须是模拟输入ADC_GPIO_StructInit.GPIO_Pin ADCx_PIN;GPIO_Init(ADCx_PIN_PORT, ADC_GPIO_StructInit);
}static void Config_ADC_Init(void)
{ADC_InitTypeDef ADC_StructInit;ADCx_RCC_Clock_Cmd(ADCx_Periph, ENABLE);ADC_StructInit.ADC_Mode ADC_Mode_Independent; //设置独立模式因为只有一个ADC通道ADC_StructInit.ADC_ScanConvMode DISABLE; //配置是否扫描用在多通道ADC_StructInit.ADC_ContinuousConvMode ENABLE; //配置是否要连续转换ADC_StructInit.ADC_DataAlign ADC_DataAlign_Right; //配置数据的对齐模式ADC_StructInit.ADC_NbrOfChannel 1; //配置要转换通道的数目ADC_StructInit.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;//配置触发模式这里是软件触发外部触发是有定时器或者输入引脚触发才会使用ADC_Init(ADC_x, ADC_StructInit);RCC_ADCCLKConfig(RCC_PCLK2_Div8); //时钟配置72/89MADC_RegularChannelConfig(ADC_x, ADCx_Channel, 1, ADC_SampleTime_55Cycles5); //规则通道的配置第三个参数是配置第几个转换换通道第四个参数是配置采样周期第二个参数是第几个通道例A0是通道1ADC_ITConfig(ADC_x, ADC_IT_EOC, ENABLE); //配置成规则通道中断ADC_Cmd(ADC_x, ENABLE); //使能ADC中断ADC_StartCalibration(ADC_x); //开始校准ADCwhile(ADC_GetCalibrationStatus(ADC_x)); //等待校准完成ADC_SoftwareStartConvCmd(ADC_x, ENABLE); //软件触发使能开始工作}static void ADCx_NVIC_Config(void)
{NVIC_InitTypeDef ADCx_NVIC_StructInit;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);ADCx_NVIC_StructInit.NVIC_IRQChannel ADC1_2_IRQn;ADCx_NVIC_StructInit.NVIC_IRQChannelCmd ENABLE;ADCx_NVIC_StructInit.NVIC_IRQChannelPreemptionPriority 1;ADCx_NVIC_StructInit.NVIC_IRQChannelSubPriority 1;NVIC_Init(ADCx_NVIC_StructInit);
}void ADCx_Init(void)
{ACDx_GPIO_Config();Config_ADC_Init();ADCx_NVIC_Config();
}extern uint32_t ADC_Conversion_value;
int main()
{float ADC_Value 0;initSysTick();usart_init();ADCx_Init();while(1){ADC_Value (float)ADC_Conversion_value/4096*3.3;printf(adc_float%fv\r\n,ADC_Value);printf(adc_Hex%04x\r\n,ADC_Conversion_value);ms_delay(2000);}}void ADCx_IRQHandler(void)
{if(ADC_GetITStatus(ADC_x, ADC_IT_EOC) SET){ADC_Conversion_value ADC_GetConversionValue(ADC_x);//读取转换的数值}ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC);
} 3、ADC多通道DMA读取 #ifndef ADC_H
#define ADC_H
#include stm32f10x.h
static void ACDx_GPIO_Config(void);
static void Config_ADC_Init(void);
void ADCx_Init(void);//ADC引脚配置的宏
#define ADCx_PIN GPIO_Pin_1
#define ADCx_PIN_PORT GPIOA
#define ADCx_PIN_Periph RCC_APB2Periph_GPIOA
#define ADCx_PIN_RCC_Clock_Cmd RCC_APB2PeriphClockCmd//ADC配置的宏
#define ADCx_Periph RCC_APB2Periph_ADC1
#define ADCx_RCC_Clock_Cmd RCC_APB2PeriphClockCmd
#define ADC_x ADC1
#define ADCx_Channel ADC_Channel_1#define len 3#endif#include adc.h
uint16_t ADC_conversionValue[len];//单ADC模式时数据寄存器只用到低16位用来存放 ADC发过来的数据
static void ACDx_GPIO_Config(void)
{GPIO_InitTypeDef ADC_GPIO_StructInit;ADCx_PIN_RCC_Clock_Cmd(ADCx_PIN_Periph,ENABLE);ADC_GPIO_StructInit.GPIO_Mode GPIO_Mode_AIN; //必须是模拟输入ADC_GPIO_StructInit.GPIO_Pin GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_Init(ADCx_PIN_PORT, ADC_GPIO_StructInit);
}static void Config_ADC_Init(void)
{ADC_InitTypeDef ADC_StructInit;DMA_InitTypeDef DMA_StructInit;/*--------------------------DMA-----------------------------------------*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //打开时钟DMA_DeInit(DMA1_Channel1); //将DMA寄存器复位成刚上电的样子DMA_StructInit.DMA_MemoryBaseAddr (uint32_t)ADC_conversionValue; //存储器地址DMA_StructInit.DMA_PeripheralBaseAddr (uint32_t)((ADC_x-DR)); //外设地址 DMA_StructInit.DMA_DIR DMA_DIR_PeripheralSRC; //传输方向DMA_StructInit.DMA_BufferSize len; //传输数目(缓冲区大小应该等于数据目的地的大小)// 外设数据大小为半字即两个字节DMA_StructInit.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWord;//外设数据宽度数据寄存器只用到低16位// 内存数据大小也为半字跟外设数据大小相同DMA_StructInit.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord; //存储器数据宽度数据寄存器只用到低16位DMA_StructInit.DMA_PeripheralInc DMA_PeripheralInc_Disable; //外设地址是否递增DMA_StructInit.DMA_MemoryInc DMA_MemoryInc_Enable; //存储器地址是否递增DMA_StructInit.DMA_Mode DMA_Mode_Circular; //模式选择现在时循环模式DMA_StructInit.DMA_Priority DMA_Priority_High; //通道优先级DMA_StructInit.DMA_M2M DMA_M2M_Disable; //存储器到存储器模式DMA_Init( DMA1_Channel1, DMA_StructInit);DMA_Cmd(DMA1_Channel1, ENABLE);/*---------------------ADC------------------------------------*/ADCx_RCC_Clock_Cmd(ADCx_Periph, ENABLE);ADC_StructInit.ADC_Mode ADC_Mode_Independent; //设置独立模式因为只有一个ADCADC_StructInit.ADC_ScanConvMode ENABLE; //配置是否扫描用在多通道ADC_StructInit.ADC_ContinuousConvMode ENABLE; //配置是否要连续转换ADC_StructInit.ADC_DataAlign ADC_DataAlign_Right; //配置数据的对齐模式ADC_StructInit.ADC_NbrOfChannel len; //配置要转换通道的数目ADC_StructInit.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;//配置触发模式这里是软件触发外部触发是有定时器或者输入引脚触发才会使用ADC_Init(ADC_x, ADC_StructInit);RCC_ADCCLKConfig(RCC_PCLK2_Div8); //时钟配置72/89MADC_RegularChannelConfig(ADC_x, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); //规则通道的配置第三个参数是配置第几次转换第四个参数是配置采样周期ADC_RegularChannelConfig(ADC_x, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC_x, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5);ADC_Cmd(ADC_x, ENABLE); //使能ADC中断// 初始化ADC 校准寄存器 ADC_ResetCalibration(ADC_x);// 等待校准寄存器初始化完成while(ADC_GetResetCalibrationStatus(ADC_x));ADC_StartCalibration(ADC_x); //开始校准ADCwhile(ADC_GetCalibrationStatus(ADC_x)); //等待校准完成ADC_SoftwareStartConvCmd(ADC_x, ENABLE); //软件触发使能开始工作//使能DMA ADC请求ADC_DMACmd(ADC_x, ENABLE);}void ADCx_Init(void)
{ACDx_GPIO_Config();Config_ADC_Init();
}// 局部变量用于保存转换计算后的电压值
float ADC_ConvertedValueLocal[len];
int main()
{float conversionValue 0;initSysTick();usart_init();ADCx_Init();printf(\r\n ----这是一个ADC多通道采集实验----\r\n);while(1){ADC_ConvertedValueLocal[0] (float) ADC_conversionValue[0]/4096*3.3;ADC_ConvertedValueLocal[1] (float) ADC_conversionValue[1]/4096*3.3;ADC_ConvertedValueLocal[2] (float) ADC_conversionValue[2]/4096*3.3;printf(\r\n CH0 value %f V \r\n,ADC_ConvertedValueLocal[0]);printf(\r\n CH1 value %f V \r\n,ADC_ConvertedValueLocal[1]);printf(\r\n CH2 value %f V \r\n,ADC_ConvertedValueLocal[2]);ms_delay(2000);}} 4、双ADC_DMA读取_同步规则 *此模式在 规则通道组 上执行。外部触发来自 ADC1 的规则组多路开关 ( 由 ADC1_CR2 寄存器的 EXTSEL[2:0] 选择 ) 它同时给 ADC2 提供同步触发。 *不要在2个ADC上转换相同的通道((两个ADC在同一个通道上的采样时间不能重善)。 * 在 ADC1 或 ADC2 的转换结束时产生一个32位DMA传输请求(如果设置了DMA位)32位的ADC1_DR寄存器内容传输到SRAM中它 上半个字包含ADC2的转换数据 低半个字包含ADC1的转换数据。 * 当所有 ADC1/ADC2 规则通道都被转换完时产生 EOC 中断 ( 若任一 ADC 接口开放了中断 ) 。 #ifndef ADC_H
#define ADC_H
#include stm32f10x.h
static void ACDx_GPIO_Config(void);
static void Config_ADC_Init(void);
void ADCx_Init(void);//ADC引脚配置的宏
#define ADCx_PIN GPIO_Pin_1
#define ADCx_PIN_PORT GPIOA
#define ADCx_PIN_Periph RCC_APB2Periph_GPIOA
#define ADCx_PIN_RCC_Clock_Cmd RCC_APB2PeriphClockCmd//ADC配置的宏
#define ADCx_Periph RCC_APB2Periph_ADC1
#define ADCx_RCC_Clock_Cmd RCC_APB2PeriphClockCmd
#define ADC_x ADC1
#define ADCx_Channel ADC_Channel_1#define len 1#endif#include adc.h
uint32_t ADC_conversionValue[len];//单ADC模式时数据寄存器只用到低16位用来存放 ADC发过来的数据
static void ACDx_GPIO_Config(void)
{GPIO_InitTypeDef ADC_GPIO_StructInit;ADCx_PIN_RCC_Clock_Cmd(ADCx_PIN_Periph,ENABLE);ADC_GPIO_StructInit.GPIO_Mode GPIO_Mode_AIN; //必须是模拟输入ADC_GPIO_StructInit.GPIO_Pin GPIO_Pin_1 | GPIO_Pin_2 ;GPIO_Init(ADCx_PIN_PORT, ADC_GPIO_StructInit);
}static void Config_ADC_Init(void)
{ADC_InitTypeDef ADC_StructInit;DMA_InitTypeDef DMA_StructInit;/*--------------------------DMA-----------------------------------------*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //打开时钟DMA_DeInit(DMA1_Channel1); //将DMA寄存器复位成刚上电的样子DMA_StructInit.DMA_MemoryBaseAddr (uint32_t)ADC_conversionValue; //存储器地址DMA_StructInit.DMA_PeripheralBaseAddr (uint32_t)((ADC_x-DR)); //外设地址 DMA_StructInit.DMA_DIR DMA_DIR_PeripheralSRC; //传输方向DMA_StructInit.DMA_BufferSize len; //传输数目(缓冲区大小应该等于数据目的地的大小)// 外设数据大小为半字即两个字节DMA_StructInit.DMA_PeripheralDataSize DMA_PeripheralDataSize_Word; //外设数据宽度(32位)// 内存数据大小也为半字跟外设数据大小相同DMA_StructInit.DMA_MemoryDataSize DMA_MemoryDataSize_Word; //存储器数据宽度(32位)DMA_StructInit.DMA_PeripheralInc DMA_PeripheralInc_Disable; //外设地址是否递增DMA_StructInit.DMA_MemoryInc DMA_MemoryInc_Enable; //存储器地址是否递增DMA_StructInit.DMA_Mode DMA_Mode_Circular; //模式选择现在时循环模式DMA_StructInit.DMA_Priority DMA_Priority_High; //通道优先级DMA_StructInit.DMA_M2M DMA_M2M_Disable; //存储器到存储器模式DMA_Init( DMA1_Channel1, DMA_StructInit);DMA_Cmd(DMA1_Channel1, ENABLE);/*---------------------ADC1------------------------------------*/ADCx_RCC_Clock_Cmd(ADCx_Periph, ENABLE);ADC_StructInit.ADC_Mode ADC_Mode_RegSimult; //设置成规则同步模式因为有两个ADCADC_StructInit.ADC_ScanConvMode ENABLE; //配置是否扫描用在多通道ADC_StructInit.ADC_ContinuousConvMode ENABLE; //配置是否要连续转换ADC_StructInit.ADC_DataAlign ADC_DataAlign_Right; //配置数据的对齐模式ADC_StructInit.ADC_NbrOfChannel len; //配置要转换通道的数目ADC_StructInit.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;//配置触发模式这里是软件触发外部触发是有定时器或者输入引脚触发才会使用ADC_Init(ADC_x, ADC_StructInit);RCC_ADCCLKConfig(RCC_PCLK2_Div8); //时钟配置72/89MADC_Cmd(ADC_x, ENABLE); //使能ADC中断ADC_RegularChannelConfig(ADC_x, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);//设置通道1PA1//使能DMA ADC请求ADC_DMACmd(ADC_x, ENABLE);/*--------------------ADC2-------------------------------------*/ADCx_RCC_Clock_Cmd(RCC_APB2Periph_ADC2, ENABLE);ADC_StructInit.ADC_Mode ADC_Mode_RegSimult; //设置成规则同步模式因为有两个ADCADC_StructInit.ADC_ScanConvMode ENABLE; //配置是否扫描用在多通道ADC_StructInit.ADC_ContinuousConvMode ENABLE; //配置是否要连续转换ADC_StructInit.ADC_DataAlign ADC_DataAlign_Right; //配置数据的对齐模式ADC_StructInit.ADC_NbrOfChannel len; //配置要转换通道的数目ADC_StructInit.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;//配置触发模式这里是软件触发外部触发是有定时器或者GPIO才会使用
// RCC_ADCCLKConfig(RCC_PCLK2_Div8); //时钟配置72/89MADC_Init(ADC2, ADC_StructInit);ADC_Cmd(ADC2, ENABLE); //使能ADC中断ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 1, ADC_SampleTime_55Cycles5);//设置通道2PA2/* 使能ADCx_2的外部触发转换 */ADC_ExternalTrigConvCmd(ADC2, ENABLE);// 初始化ADC1 校准寄存器 ADC_ResetCalibration(ADC_x);// 等待校准寄存器初始化完成while(ADC_GetResetCalibrationStatus(ADC_x));ADC_StartCalibration(ADC_x); //开始校准ADCwhile(ADC_GetCalibrationStatus(ADC_x)); //等待校准完成// 初始化ADC2 校准寄存器 ADC_ResetCalibration(ADC2);// 等待校准寄存器初始化完成while(ADC_GetResetCalibrationStatus(ADC2));ADC_StartCalibration(ADC2); //开始校准ADCwhile(ADC_GetCalibrationStatus(ADC2)); //等待校准完成ADC_SoftwareStartConvCmd(ADC_x, ENABLE); //软件触发使能开始工作}void ADCx_Init(void)
{ACDx_GPIO_Config();Config_ADC_Init();
}extern uint32_t ADC_conversionValue[len];//单ADC模式时数据寄存器只用到低16位用来存放 ADC发过来的数据
// 局部变量用于保存转换计算后的电压值
float ADC_ConvertedValueLocal[len*2];
int main()
{uint16_t temp00 ,temp10;initSysTick();usart_init();ADCx_Init();printf(\r\n ----这是一个双ADC规则同步采集实验----\r\n);while(1){// 取出ADC1数据寄存器的高16位这个是ADC2的转换数据temp0 (ADC_conversionValue[0]0XFFFF0000) 16;//取高16位ADC2的数据// 取出ADC1数据寄存器的低16位这个是ADC1的转换数据temp1 (ADC_conversionValue[0]0XFFFF); //取低16位ADC1的数据ADC_ConvertedValueLocal[0] (float) temp0/4096*3.3;ADC_ConvertedValueLocal[1] (float) temp1/4096*3.3;printf(\r\n ADC1 value %f V \r\n,ADC_ConvertedValueLocal[1]);printf(\r\n ADC2 value %f V \r\n,ADC_ConvertedValueLocal[0]);ms_delay(2000);}}PS *多路ADC模式的时候 ,要配置外部触发转换单路ADC只需要配置软件触发转换 *多路ADC模式的时候ADC1ADC2一起使用例如设置规则同步的时候通道的数目要一致ADC1有两个通道ADC2也需要有两个通道 * 五、触发源 *ADC 的触发转换有两种方法分别是通过软件或外部事件(也就是硬件)触发转换。 *软件触发转换的方法。方法是通过写 ADC_CR2 寄存器的 ADON 这个位来控制写 1 就开始转换写 0 就停止转换这个控制 ADC 转换的方式非常简单。 *外部事件触发转换的方法有定时器和输入引脚触发等等 六、校准 *ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间在每个电容器上都会计算出一个误差修正码(数字值)这个码用于消除在随后的转换中每个电容器上产生的误差 *建议在每次上电后执行一次校准 *启动校准前 ADC必须处于关电状态超过至少两个ADC时钟周期 七、DMA请求 *因为规则通道转换的值储存在一个仅有的数据寄存器中所以当转换多个规则通道时需要使用 DMA这可以避免丢失已经存储在ADC_DR寄存器中的数据。 *只有在规则通道的转换结束时才产生DMA请求并将转换的数据从ADC_DR寄存器传输到用户 指定的目的地址。 *只有ADC1和ADC3拥有DMA功能。由ADC2转化的数据可以通过双ADC模式利用ADC1的DMA功能传输。(ADC2转换的数据要用DMA传输的时候就可以用双ADC模式)。 八、中断 *规则和注入组转换结束时能产生中断当模拟看门狗状态位被设置时也能产生中断。它们都有 独立的中断使能位。 *ADC1和ADC2的中断映射在同一个中断向量上而ADC3的中断有自己的中断向量。 * ADC_SR 寄存器中有 2 个其他标志但是它们没有相关联的中断 九、数据对齐 *ADC_CR2 寄存器中的 ALIGN 位选择转换后数据储存的对齐方式。数据可以左对齐或右对齐 * 注入组通道转换的数据值已经减去了在 ADC_JOFRx 寄存器中定义的偏移量因此结果可以是一 个负值。 SEXT 位是扩展的符号值。 *对于规则组通道不需减去偏移值因此只有 12 个位有效。