ADC单通道读取中断和DMA读取

中断读取

我们可以设置ADC数值转化转化完后触发一个中断,在中断服务函数去读取数据,以下是实验代码
bsp_adc.c
在这里插入图片描述
在这里插入图片描述

#include "bsp_adc.h"
static void gpio_Init()
{ 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);//使能GPIO时钟
    GPIO_InitTypeDef GPIO_Instrust;
	GPIO_Instrust.GPIO_Mode  = GPIO_Mode_AIN; //配置为模拟输入
    GPIO_Instrust.GPIO_Pin   = GPIO_Pin_1;//ADC采集的GPIO口
	GPIO_Instrust.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_Instrust);	//初始化GPIO结构体
}
static void adc_Init()
{ 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2,ENABLE);//使能ADC时钟
    ADC_InitTypeDef  ADC_Instruct;  //定义一个ADC初始化结构体
	ADC_Instruct.ADC_ContinuousConvMode = ENABLE;  //使能连续转化
	ADC_Instruct.ADC_DataAlign = ADC_DataAlign_Right;  //数据向右对齐
	ADC_Instruct.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_None; //取消外部触发
	ADC_Instruct.ADC_Mode = ADC_Mode_Independent;  //采用独立模式,一个ADC转化
	ADC_Instruct.ADC_NbrOfChannel = ADC_Channel_1; //采用通道1
	ADC_Instruct.ADC_ScanConvMode = DISABLE;   //不使能扫描模式,扫描模式为多通道ADC
    ADC_Init(ADC_X, &ADC_Instruct);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);  //配置ADC时钟源,为PCLK2的1/6
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
	ADC_ITConfig(ADC_X, ADC_IT_EOC, ENABLE);//选择ADC转换为触发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);	
}
static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
	// 优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
void ADC2_init(void)
{  
     gpio_Init();
	 adc_Init();
	 ADC_NVIC_Config();
	 
}

在stm32f10x_it.c里面定义ADC中断的服务函数

 __IO uint16_t ADC_ConvertedValue;
void  ADC1_2_IRQHandler(void)
{	
	if (ADC_GetITStatus(ADC_X,ADC_IT_EOC)==SET) 
	{
		// 读取ADC的转换值
		ADC_ConvertedValue = ADC_GetConversionValue(ADC_X);
	}
	ADC_ClearITPendingBit(ADC_X,ADC_IT_EOC);
}

main.c

#include "bsp_lcd.h"
#include "bsp_usart.h"
#include "bsp_systick.h"
#include "hseconfig.h"
#include "bsp_adc.h"
extern __IO uint16_t ADC_ConvertedValue;
// 局部变量,用于保存转换计算后的电压值 	 
float ADC_ConvertedValueLocal;     
// 软件延时
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
} 
int main(void)
{ 
	//uint8_t i=0;
	
	HseConfig(9);  //配置时钟为72Mhz
	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	USART1_Init(9600); //配置波特率为9600
	printf("这是一个ADC实验\n");
	ADC2_init();
	//printf("这是一个DAC实验\n");
	while (1)
	{
		ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3; 
	
		printf("\r\n The current AD value = 0x%04X \r\n", 
		       ADC_ConvertedValue); 
		printf("\r\n The current AD value = %f V \r\n",
		       ADC_ConvertedValueLocal); 
		printf("\r\n\r\n");

		Delay(0x0fee00);  
	}
}

实验现象:
随着电位器的移动,电压值会随着变化
在这里插入图片描述

DMA读取

DMA读取相对于中断读取其中一个优点就是快,还有一个就是方便,不需要写中断服务函数,中断方式适用于速度慢,数据少的情况,DMA读取适用于速度快,数据多的情况,DMA还有一个优点就是不占用CPU,你可以边读取边处理数据,
bsp_adc.c

#include "bsp_adc.h"
__IO uint16_t ADC_ConvertedValue;
static void gpio_Init()
{ 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  GPIO_InitTypeDef GPIO_Instrust;
	GPIO_Instrust.GPIO_Mode  = GPIO_Mode_AIN;
  GPIO_Instrust.GPIO_Pin   = GPIO_PIN_1;
	GPIO_Instrust.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_Instrust);	
} 
static void adc_Init()
{ 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//使能DMA时钟
  ADC_InitTypeDef  ADC_Instruct;
	DMA_InitTypeDef  DMA_Instruct;//初始化DMA结构体
	
	
	DMA_DeInit(DMA1_Channel1);//复位DMA控制器
	//配置DMA传输的外设基地址,为ADC数据寄存器地址
	DMA_Instruct.DMA_PeripheralBaseAddr = (uint32_t)(& ( ADC_X ->DR ));
	// 存储器地址,实际上就是一个内部SRAM的变量
	DMA_Instruct.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
	//数据源来自外设
	DMA_Instruct.DMA_DIR = DMA_DIR_PeripheralSRC;
	
	// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
	DMA_Instruct.DMA_BufferSize = 1;
	
	// 外设寄存器只有一个,地址不用递增
	DMA_Instruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

	// 存储器地址固定
	DMA_Instruct.DMA_MemoryInc = DMA_MemoryInc_Disable; 
	
	// 外设数据大小为半字,即两个字节,即ADC_X ->DR寄存器为16位
	DMA_Instruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	
	// 存储器数据大小也为半字,跟外设数据大小相同, ADC_ConvertedValue为16位
	DMA_Instruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	
	// 循环传输模式
	DMA_Instruct.DMA_Mode = DMA_Mode_Circular;	

	// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
	DMA_Instruct.DMA_Priority = DMA_Priority_High;
	
	// 禁止存储器到存储器模式,因为是从外设到存储器
	DMA_Instruct.DMA_M2M = DMA_M2M_Disable;
	
	// 初始化DMA,ADC1对应DMA通道1
	DMA_Init(DMA1_Channel1, &DMA_Instruct);
	
	// 使能 DMA 通道
	DMA_Cmd(DMA1_Channel1 , ENABLE);
	
	
	/*----------------------------------------------------*/
	ADC_Instruct.ADC_ContinuousConvMode = ENABLE;
	ADC_Instruct.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_Instruct.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_None;
	ADC_Instruct.ADC_Mode = ADC_Mode_Independent;
	ADC_Instruct.ADC_NbrOfChannel = ADC_Channel_1;
	ADC_Instruct.ADC_ScanConvMode = DISABLE;
  ADC_Init(ADC_X, &ADC_Instruct);
	RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_1,1,ADC_SampleTime_55Cycles5  );
		// 使能ADC DMA 请求
	ADC_DMACmd(ADC_X, ENABLE);
	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);	
}
void ADC2_init(void)
{  
   gpio_Init();
	 adc_Init();
	 //ADC_NVIC_Config();
}

现象和中断模式的一致

ADC多通道DMA读取

我们这里设置成6个通道采集ADC,单通道因为只有一个通道所以不用扫描模式,当我们设置成多通道的时候就需要不断扫描多个通道,所以我们这里我们用一个6位的数组来存放转化后的值(放在ADC数据寄存器 ),而且我们的DMA还要设置为存储器地址递增模式,也就是说数组的下标会自动加1来依次存放ADC采样后的值,我们采样GPIOA组的6个引脚来做ADC的采集
在这里插入图片描述
bsp_adc.c

#include "bsp_adc.h"
__IO uint16_t ADC_ConvertedValue[6] ={0,0,0,0,0,0};
static void gpio_Init()
{ 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
  GPIO_InitTypeDef GPIO_Instrust;
	GPIO_Instrust.GPIO_Mode  = GPIO_Mode_AIN;
  GPIO_Instrust.GPIO_Pin   =  GPIO_Pin_0| GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5;
	GPIO_Instrust.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_Instrust);	
} 
static void adc_Init()
{ 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//使能DMA时钟
  ADC_InitTypeDef  ADC_Instruct;
	DMA_InitTypeDef  DMA_Instruct;//初始化DMA结构体
	
	
	DMA_DeInit(DMA1_Channel1);//复位DMA控制器
	//配置DMA传输的外设基地址,为ADC数据寄存器地址
	DMA_Instruct.DMA_PeripheralBaseAddr = (uint32_t)(& ( ADC_X ->DR ));
	// 存储器地址,实际上就是一个内部SRAM的变量
	DMA_Instruct.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;
	//数据源来自外设
	DMA_Instruct.DMA_DIR = DMA_DIR_PeripheralSRC;
	
	// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
	DMA_Instruct.DMA_BufferSize = 6;
	
	// 外设寄存器只有一个,地址不用递增
	DMA_Instruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

	// 存储器地址递增
	DMA_Instruct.DMA_MemoryInc = DMA_MemoryInc_Enable; 
	
	// 外设数据大小为半字,即两个字节,即ADC_X ->DR寄存器为16位
	DMA_Instruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	
	// 存储器数据大小也为半字,跟外设数据大小相同, ADC_ConvertedValue为16位
	DMA_Instruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	
	// 循环传输模式
	DMA_Instruct.DMA_Mode = DMA_Mode_Circular;	

	// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
	DMA_Instruct.DMA_Priority = DMA_Priority_High;
	
	// 禁止存储器到存储器模式,因为是从外设到存储器
	DMA_Instruct.DMA_M2M = DMA_M2M_Disable;
	
	// 初始化DMA,ADC1对应DMA通道1
	DMA_Init(DMA1_Channel1, &DMA_Instruct);
	
	// 使能 DMA 通道
	DMA_Cmd(DMA1_Channel1 , ENABLE);
	
	
	/*----------------------------------------------------*/
	ADC_Instruct.ADC_ContinuousConvMode = ENABLE;
	ADC_Instruct.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_Instruct.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_None;
	ADC_Instruct.ADC_Mode = ADC_Mode_Independent;
	ADC_Instruct.ADC_NbrOfChannel = 6;
	ADC_Instruct.ADC_ScanConvMode = ENABLE;
  ADC_Init(ADC_X, &ADC_Instruct);
	RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_0,1,ADC_SampleTime_55Cycles5  );
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_1,2,ADC_SampleTime_55Cycles5  );
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_2,3,ADC_SampleTime_55Cycles5  );
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_3,4,ADC_SampleTime_55Cycles5  );
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_4,5,ADC_SampleTime_55Cycles5  );
	ADC_RegularChannelConfig(ADC_X,ADC_Channel_5,6,ADC_SampleTime_55Cycles5  );
	//ADC_ITConfig(ADC_X, ADC_IT_EOC, ENABLE);
		// 使能ADC DMA 请求
	ADC_DMACmd(ADC_X, ENABLE);
	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);	
}
/*static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
	// 优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}*/
void ADC2_init(void)
{  
   gpio_Init();
	 adc_Init();
	 //ADC_NVIC_Config();
	 
}

main.c

#include "bsp_lcd.h"
#include "bsp_usart.h"
#include "bsp_systick.h"
#include "hseconfig.h"
#include "bsp_adc.h"
extern __IO uint16_t ADC_ConvertedValue[6];
// 局部变量,用于保存转换计算后的电压值 	 
float ADC_ConvertedValueLocal[6];     
// 软件延时
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
} 
int main(void)
{ 
	//uint8_t i=0;
	
	HseConfig(9);
	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	USART1_Init(9600);
	printf("这是一个ADC实验\n");
	ADC2_init();
	//printf("这是一个DAC实验\n");
	while (1)
	{
	    ADC_ConvertedValueLocal[0] =(float) ADC_ConvertedValue[0]/4096*3.3;
			ADC_ConvertedValueLocal[1] =(float) ADC_ConvertedValue[1]/4096*3.3;
			ADC_ConvertedValueLocal[2] =(float) ADC_ConvertedValue[2]/4096*3.3;
			ADC_ConvertedValueLocal[3] =(float) ADC_ConvertedValue[3]/4096*3.3;
			ADC_ConvertedValueLocal[4] =(float) ADC_ConvertedValue[4]/4096*3.3;
			ADC_ConvertedValueLocal[5] =(float) ADC_ConvertedValue[5]/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]);
			printf("\r\n CH3 value = %f V \r\n",ADC_ConvertedValueLocal[3]);
			printf("\r\n CH4 value = %f V \r\n",ADC_ConvertedValueLocal[4]);
			printf("\r\n CH5 value = %f V \r\n",ADC_ConvertedValueLocal[5]);
		
			printf("\r\n\r\n");
			Delay(0x0fffee);		
	}
}

双ADC读取-规则同步

我们这里采样双ADC读出模拟量,规则同步指的是ADC1采集后ADC2也采集,ADC1转化完成后ADC2也转化完成,之前的做法都是使用一个ADC转化,所以ADC_DR寄存器只使用了低16位,现在是双ADC转化所以ADC_DR寄存器的高,低16位都被使用,ADC1数据放在低16位,ADC2数据放在高16位
bsp_adc.c

#include "bsp_adc.h"
__IO uint32_t ADC_ConvertedValue[2] ={0};
static void gpio_Init()
{ 
	/*ADC1 PA0初始化*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  GPIO_InitTypeDef GPIO_Instrust;
	GPIO_Instrust.GPIO_Mode  = GPIO_Mode_AIN;
  GPIO_Instrust.GPIO_Pin   =  GPIO_Pin_0;
	GPIO_Init(GPIOA, &GPIO_Instrust);	
	/*ADC2 PA1初始化*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  GPIO_InitTypeDef GPIO_Instrust1;
	GPIO_Instrust1.GPIO_Mode  = GPIO_Mode_AIN;
  GPIO_Instrust1.GPIO_Pin   =  GPIO_Pin_1;
	GPIO_Init(GPIOA, &GPIO_Instrust1);	
} 
static void adc_Init()
{ 
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2,ENABLE);
	 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//使能DMA时钟
	/*-----------------------DMA配置----------------------------------*/
	DMA_InitTypeDef  DMA_Instruct;//初始化DMA结构体
	DMA_DeInit(DMA1_Channel1);//复位DMA控制器
	//配置DMA传输的外设基地址,为ADC数据寄存器地址
	DMA_Instruct.DMA_PeripheralBaseAddr = (uint32_t)(& ( ADC_X ->DR ));
	// 存储器地址,实际上就是一个内部SRAM的变量
	DMA_Instruct.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;
	//数据源来自外设
	DMA_Instruct.DMA_DIR = DMA_DIR_PeripheralSRC;
	// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
	DMA_Instruct.DMA_BufferSize = 1;
	// 外设寄存器只有一个,地址不用递增
	DMA_Instruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	// 存储器地址递增
	DMA_Instruct.DMA_MemoryInc = DMA_MemoryInc_Enable; 
	// 外设数据大小为半字,即两个字节,即ADC_X ->DR寄存器为32位
	DMA_Instruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
	// 存储器数据大小也为半字,跟外设数据大小相同, ADC_ConvertedValue为32位
	DMA_Instruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
	// 循环传输模式
	DMA_Instruct.DMA_Mode = DMA_Mode_Circular;	
	// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
	DMA_Instruct.DMA_Priority = DMA_Priority_High;
	// 禁止存储器到存储器模式,因为是从外设到存储器
	DMA_Instruct.DMA_M2M = DMA_M2M_Disable;
	// 初始化DMA,ADC1对应DMA通道1
	DMA_Init(DMA1_Channel1, &DMA_Instruct);
	// 使能 DMA 通道
	DMA_Cmd(DMA1_Channel1 , ENABLE);
	/*------------------------配置ADC1-----------------------*/
	ADC_InitTypeDef  ADC_Instruct;
	ADC_Instruct.ADC_ContinuousConvMode = ENABLE;
	ADC_Instruct.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_Instruct.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_None;
	ADC_Instruct.ADC_Mode = ADC_Mode_RegSimult;
	ADC_Instruct.ADC_NbrOfChannel = 1;
	ADC_Instruct.ADC_ScanConvMode = ENABLE;
  ADC_Init(ADC1, &ADC_Instruct);
	RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5  );
	// 使能ADC DMA 请求
	ADC_DMACmd(ADC1, ENABLE);
	/*------------------------配置ADC2-----------------------*/
	ADC_InitTypeDef  ADC_Instruct1;
	ADC_Instruct1.ADC_ContinuousConvMode = ENABLE;
	ADC_Instruct1.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_Instruct1.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_None;
	ADC_Instruct1.ADC_Mode = ADC_Mode_RegSimult;
	ADC_Instruct1.ADC_NbrOfChannel = 1;
	ADC_Instruct1.ADC_ScanConvMode = ENABLE;
  ADC_Init(ADC2, &ADC_Instruct1);
	RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	ADC_RegularChannelConfig(ADC2,ADC_Channel_0,1,ADC_SampleTime_239Cycles5  );
			/* 使能ADCx_2的外部触发转换 */
  ADC_ExternalTrigConvCmd(ADC2, ENABLE);
	/*----------------------ADC1校准--------------------------*/
	//开启ADC,并开始转换
	ADC_Cmd(ADC1, ENABLE); 
  // 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADC1);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC1));
	// ADC开始校准
	ADC_StartCalibration(ADC1);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADC1));
	/*----------------------ADC2校准--------------------------*/
	//开启ADC,并开始转换
	ADC_Cmd(ADC2, ENABLE); 
  // 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADC2);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC2));
	// ADC开始校准
	ADC_StartCalibration(ADC2);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADC2));
		// 由于没有采用外部触发,所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);	
}
/*static void ADC_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
	// 优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}*/
void ADC2_init(void)
{  
   gpio_Init();
	 adc_Init();
	 //ADC_NVIC_Config();
	 
}

main.c

#include "bsp_lcd.h"
#include "bsp_usart.h"
#include "bsp_systick.h"
#include "hseconfig.h"
#include "bsp_adc.h"
extern __IO uint32_t ADC_ConvertedValue[1];
// 局部变量,用于保存转换计算后的电压值 	 
float ADC_ConvertedValueLocal[2];     
// 软件延时
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
} 
int main(void)
{ 
	//uint8_t i=0;
	uint16_t temp0=0 ,temp1=0;
	HseConfig(9);
	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	USART1_Init(9600);
	printf("这是一个ADC实验\n");
	ADC2_init();
	//printf("这是一个DAC实验\n");
	while (1)
	{
	 // 取出ADC1数据寄存器的高16位,这个是ADC2的转换数据
		temp0 = (ADC_ConvertedValue[0]&0XFFFF0000) >> 16;
		// 取出ADC1数据寄存器的低16位,这个是ADC1的转换数据
		temp1 = (ADC_ConvertedValue[0]&0XFFFF);	
	
		ADC_ConvertedValueLocal[0] =(float) temp0/4096*3.3;
		ADC_ConvertedValueLocal[1] =(float) temp1/4096*3.3;

	
		
		printf("\r\n ADCx_1 value = %f V \r\n",
		        ADC_ConvertedValueLocal[1]);
		printf("\r\n ADCx_2 value = %f V \r\n",
		        ADC_ConvertedValueLocal[0]);
		
		printf("\r\n\r\n");
	  Delay(0x0fffee);		
	}
}

发布了83 篇原创文章 · 获赞 3 · 访问量 1237

猜你喜欢

转载自blog.csdn.net/qq_41936794/article/details/105441018