STM32:ADC采集数据实例(采用DMA模式)

硬件平台:stm32f10xZET6
开发环境:keil MDK uVision v4.10
开发语言:C、ST_lib_3.5固件库

将STM32 开发板供电(DC5V),插上 JLINK,插上串口线(两头都是母的交叉线),打开超级终端,配置超级终端为 115200 8-N-1,将编译好的程序下载到开发板,即可看到超级终端打印数字信息显示电压值。
当旋转开发板开发板上的滑动变阻器时, ADC1 转换的电压值则会改变。板载的是 20K 的精密电阻,旋转的圈数要多点才能看到 ADC 值的明显变化。

/* 代码演示 main.c */
#include "stm32f10x.h"
#include "bsp_usart1.h"
#include "bsp_adc.h"

// ADC1转换的电压值通过MDA方式传到SRAM
extern __IO uint16_t ADC_ConvertedValue;

// 局部变量,用于保存转换计算后的电压值 	 
float ADC_ConvertedValueLocal;        

// 软件延时
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
} 

/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{	
	/* USART1 config */
	USART1_Config();
	
	/* enable adc1 and config adc1 to dma mode */
	ADC1_Init();
	
	printf("\r\n ----这是一个ADC实验(DMA传输)----\r\n");
	
	while (1)
	{
		ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3; // 读取转换的AD值
	
		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); 

		Delay(0xffffee);  
	}
}
/* 代码演示 bsp_adc模块 */
#ifndef __ADC_H
#define	__ADC_H

#include "stm32f10x.h"
void ADC1_Init(void);

#endif /* __ADC_H */
//---------------------------------------------------------
/**
  ******************************************************************************
  * @file    bsp_adc.c
  ******************************************************************************
  */ 
  
#include "bsp_adc.h"

#define ADC1_DR_Address    ((u32)0x40012400+0x4c)

__IO uint16_t ADC_ConvertedValue;
//__IO u16 ADC_ConvertedValueLocal;

/**
  * @brief  使能ADC1和DMA1的时钟,初始化PC.01
  * @param  无
  * @retval 无
  */
static void ADC1_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/* Enable DMA clock */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	/* Enable ADC1 and GPIOC clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
	
	/* Configure PC.01  as analog input */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOC, &GPIO_InitStructure);				// PC1,输入时不用设置速率
}

/**
  * @brief  配置ADC1的工作模式为MDA模式
  * @param  无
  * @retval 无
  */
static void ADC1_Mode_Config(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	/* DMA channel1 configuration, 参数传递基地址宏 */
	DMA_DeInit(DMA1_Channel1);
	
	DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;	 			    // ADC地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;	        // 内存地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                          // 指定外设是数据源地址或数据目的地址
	DMA_InitStructure.DMA_BufferSize = 1;                                       // 指定缓冲区大小为1个数据单元大小,其值等于外设或内存配置的大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;	        // 外设地址固定
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;  				    // 内存地址固定
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;	// 半字
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         // 半字
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;								// 循环传输
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;                         // 指定配置DMA通道的软件优先级
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                // 指定DMA通道是否使用内存到内存的传输方式

	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	/* Enable DMA channel1 */
	DMA_Cmd(DMA1_Channel1, ENABLE);
	
	/* ADC1 configuration */	
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;			            // 独立ADC模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE ; 	 				        // 禁止扫描模式,扫描模式用于多通道采集
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;			            // 开启连续转换模式,即不停地进行ADC转换
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	    // 不使用外部触发转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 	                // 采集数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	 								// 要转换的通道数量1个
	ADC_Init(ADC1, &ADC_InitStructure);
	
	/*配置ADC时钟,为PCLK2的8分频,即9MHz*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	/*配置ADC1的通道11为55.	5个采样周期,序列为1 */ 
	ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
	
	/* Enable ADC1 DMA */
	ADC_DMACmd(ADC1, ENABLE);
	
	/* Enable ADC1 */
	ADC_Cmd(ADC1, ENABLE);

        /* ADC的自校准,在开始ADC转换之前需要启动自校准 */	
	ADC_ResetCalibration(ADC1);                     // 复位校准寄存器
	while(ADC_GetResetCalibrationStatus(ADC1));     // 等待校准寄存器复位完成
	ADC_StartCalibration(ADC1);                     // ADC校准
	while(ADC_GetCalibrationStatus(ADC1));          // 等待校准完成
	
	/* 由于没有采用外部触发,所以使用软件触发ADC转换 */ 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

/**
  * @brief  ADC1初始化
  * @param  无
  * @retval 无
  */
void ADC1_Init(void)
{
	ADC1_GPIO_Config();
	ADC1_Mode_Config();
}



你可能感兴趣的:(ARM)