第一是AD的单通道转换,第二是AD的多通道转换。首先先将单通道转换。
STM32中自带的AD最大的转换频率是14MHZ,共有16个转换通道,每个转
ADC123_IN10表明PC0管脚可以作为AD1,AD2,AD3的第10通道。
下面我们将PC0配置成AD1的通道10为例进行讲解。
3.1首先我们应将PC0设置成模拟输入:
#include "adc.h"
/*为何定义ADC1_DR_Address 为((u32)0x40012400+0x4c)
,因为存放AD转换结果的寄存器的地址就是0x4001244c*/
#define ADC1_DR_Address ((u32)0x40012400+0x4c)
/*定义变量ADC_ConvertedValue,放AD1通道10转换的数据*/
__IO uint16_t ADC_ConvertedValue;
static void ADC1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1
RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/* 函数名:ADC1_Mode_Config
* 描述 :配置ADC1的工作模式为MDA模式
* 输入 : 无
* 输出 :无
* 调用 :内部调用
*/
static void ADC1_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/* 将与DMA有关的寄存器设我初始值 */
DMA_DeInit(DMA1_Channel1);
/*定义DMA外设基地址, 这里的ADC1_DR_Address 是用户自己定义的,即为存放转换结果的寄存器 ,他的作用就是告诉DMA取数就到ADC1_DR_Address 这里来取。*/
DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;
/*定义内存基地址,即告诉DMA要将从AD中取来的数放到ADC_ConvertedValue中 */
DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADC_ConvertedValue;
/*定义AD外设作为数据传输的来源,即告诉DMA是将AD中的数据取出放到内存中,不能反过来*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*指定DMA通道的DMA缓存的大小,即告诉DMA开辟几个内存空间,由于我们只取通道10的AD数据所以只需开辟一个内存空间*/
DMA_InitStructure.DMA_BufferSize = 1;
/*设定寄存器地址固定,即告诉DMA,只从固定的一个地方取数*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
/*设定内存地址固定,即每次DMA,,只将数搬到固定的内存中*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/*设定外设数据宽度,即告诉DMA要取的数的大小*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
/*设定内存的的宽度*/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
/*设定DMA工作再循环缓存模式,即告诉DMA要不停的搬运,不能偷懒*/ DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/*设定DMA选定的通道软件优先级*/
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA channel1,CPU有好几个DMA秘书,现在只用 DMA1_Channel1
这个秘书*/
DMA_Cmd(DMA1_Channel1, ENABLE);
/*设置ADC工作在独立模式*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
/*规定AD转换工作在单次模式,即对一个通道采样*/
ADC_InitStructure.ADC_ScanConvMode = DISABLE ;
/*设定AD转化在连续模式*/
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
/*不使用外部促发转换*/
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; /*采集的数据在寄存器中以右对齐的方式存放*/
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
/*设定要转换的AD通道数目*/
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/*配置ADC时钟,为PCLK2的8分频,即9MHz*/
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
/*配置ADC1的通道11为55.5个采样周期 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/*复位校准寄存器 */
ADC_ResetCalibration(ADC1);
/*等待校准寄存器复位完成 */
while(ADC_GetResetCalibrationStatus(ADC1));
/* ADC校准 */
ADC_StartCalibration(ADC1);
/* 等待校准完成*/
while(ADC_GetCalibrationStatus(ADC1));
/* 由于没有采用外部触发,所以使用软件触发ADC转换 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
配置完以上的程序,那么AD每转换一次,DMA都会将转换结果搬到变量
ADC_ConvertedValue中,而不需用每次都用赋值语句来取值AD转换的值。
第二部分:AD多路采样
#include "adc.h"
#define ADC1_DR_Address ((u32)0x40012400+0x4c)
/*定义数组变量ADC_ConvertedValue[2],分别放AD1通道10和11转换的数据*/
__IO uint16_t ADC_ConvertedValue[2];
/*
* 函数名:ADC1_GPIO_Config
* 描述 :使能ADC1和DMA1的时钟,设置PC0,PC1为模拟输入
* 输入 : 无
* 输出 :无
* 调用 :内部调用
*/
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);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/* 函数名:ADC1_Mode_Config
* 描述 :配置ADC1的工作模式为MDA模式
* 输入 : 无
* 输出 :无
* 调用 :内部调用
*/
static void ADC1_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/* DMA channel1 configuration */
DMA_DeInit(DMA1_Channel1);
/*定义DMA外设基地址,即为存放转换结果的寄存器*/
DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address; /*定义内存基地址*/
DMA_InitStructure.DMA_MemoryBaseAddr
=(u32)&ADC_ConvertedValue;
/*定义AD外设作为数据传输的来源*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,本实验有两个转换通道,所以开辟两个*/
DMA_InitStructure.DMA_BufferSize = 2;
/*设定寄存器地址固定*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到两个内存空间中*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*设定外设数据宽度*/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
/*设定内存的的宽度*/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
/*设定DMA工作再循环缓存模式*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/*设定DMA选定的通道软件优先级*/
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/*设置ADC工作在独立模式*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
/*规定AD转换工作在扫描模式,即对多个通道采样*/ ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
/*设定AD转化在连续模式*/
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
/*不使用外部促发转换*/
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
/*采集的数据在寄存器中以右对齐的方式存放*/
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
/*设定要转换的AD通道数目*/
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStructure);
/*配置ADC时钟,为PCLK2的8分频,即9MHz*/
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
/*配置ADC1的通道10和11的转换先后顺序以及采样时间为为55.5个采样周期 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/*复位校准寄存器 */
ADC_ResetCalibration(ADC1);
/*等待校准寄存器复位完成 */
while(ADC_GetResetCalibrationStatus(ADC1));
/* ADC校准 */
ADC_StartCalibration(ADC1);
/* 等待校准完成*/
while(ADC_GetCalibrationStatus(ADC1));
/* 由于没有采用外部触发,所以使用软件触发ADC转换 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
来源: 整理文章为传播相关技术,网络版权归原作者所有,如有侵权,请联系删除。