ADC配置问题

来源:互联网 发布:mac office 秒退 编辑:程序博客网 时间:2024/06/14 01:04

问题重申:板子中用到7路AD,分别是PA0,PA1,PA2,PA3,PA4,PA6,PA7分别采集VREF+3V VREF/2    V-3I0    VIx        V-IC    V-IB    V-IA信号,

设计思路:采用STM32F103VET6,有三个ADC模块,其中ADC1和ADC3能用DMA模式传输,ADC1只能用DMA1的1通道,ADC3只能用DMA2的5通道,(详细规定看芯片手册)

将ADC1和ADC2启动双AD模式,组成32位的data用DMA1传输,加快数据传输效率,具体代码如下:

__IO u32 ADC1_ConvertedValue[3];
__IO u16 ADC2_ConvertedValue;
__IO u16 ADC3_ConvertedValue;

//ADC_DR数据寄存器保存了ADC转换后的数值,以它作为DMA的传输源地址,
//由ADC1(ADC2)外设基地址0x40012400(0x40012800)加上ADC数据寄存器地址偏移0x4c得到
#define ADC1_DR_Address ((u32)0x40012400+0x4c)
#define ADC3_DR_Address ((u32)0x40013C00+0x4c)// ADC转换的电压值通过MDA方式传到SRAM

/*
* 函数名:ADC_Config
* 描述 :ADC初始化,DMA模式
* PA0 PA1 PA2 PA3 PA4 PA6 PA7
* | | | | | | |
*VREF+3V VREF/2 V-3I0 VIx V-IC V-IB V-IA
* | | | | | | |
*AD12IN0 AD12IN1 AD12IN2 AD12IN3 AD12IN4 AD12IN6 AD12IN7
* 输入 :无
* 输出 : 无
* 返回值:无
* 调用 :HalInit调用
* 其他 :PA0/PA1/PA2/PA3可设置为ADC123_IN0/IN1/IN2/IN3, PA4/PA5/PA6/PA7可设置为ADC12_IN4/IN5/IN6/IN7,
* 移植说明:复制此函数,包含*adc.h和*dma.h头文件,外部定义有1、__IO uint16_t ADC_ConvertedValue; 2、__IO uint16_t ADC_ConvertedValue;
*/
void ADC_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

/* Configure and enable ADC interrupt */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 |RCC_AHBPeriph_DMA2, ENABLE);

/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3 | RCC_APB2Periph_GPIOA, ENABLE);

/* Configure PA as analog input: VREF+3V VREF/2 V-3I0 VIx V-IC V-IB V-IA*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure); // 输入时不用设置速率

/////////////////////////////////////////////////////////////////////////////////////////

/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1); //ADC1只能用DMA1的1通道
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //ADC地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC1_ConvertedValue; //内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 3;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址不固定
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //一字节,32位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //同一个DMA请求的优先级别
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);

/* DMA2 channel5 configuration ----------------------------------------------*/
DMA_DeInit(DMA2_Channel5); //ADC3只能用DMA2的5通道
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC3_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC3_ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 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_Init(DMA2_Channel5, &DMA_InitStructure);
/* Enable DMA2 channel5 */
DMA_Cmd(DMA2_Channel5, ENABLE);

/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;; //双ADC同步规则模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //禁止扫描模式,扫描模式用于多通道采集
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换模式,即不停地进行ADC转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 3; //要转换的通道数目1
ADC_Init(ADC1, &ADC_InitStructure);
/*配置ADC1的通道0为28.5个采样周期,序列为1 */
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_28Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);

/* ADC2 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;; //双ADC同步规则模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 3;
ADC_Init(ADC2, &ADC_InitStructure);
/* ADC2 regular channels configuration */
ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 2, ADC_SampleTime_28Cycles5);
ADC_RegularChannelConfig(ADC2, ADC_Channel_7, 3, ADC_SampleTime_28Cycles5);

/* ADC3 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC3, &ADC_InitStructure);
/* ADC3 regular channel14 configuration */
ADC_RegularChannelConfig(ADC3, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5);
/* Enable ADC3 DMA */
ADC_DMACmd(ADC3, ENABLE);

/*配置ADC时钟,为PCLK2的8分频,即9Hz*/
RCC_ADCCLKConfig(RCC_PCLK2_Div8);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));

/* Enable ADC2 */
ADC_Cmd(ADC2, ENABLE);
/* Enable ADC2 reset calibaration register */
ADC_ResetCalibration(ADC2);
/* Check the end of ADC2 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC2));
/* Start ADC2 calibaration */
ADC_StartCalibration(ADC2);
/* Check the end of ADC2 calibration */
while(ADC_GetCalibrationStatus(ADC2));

/* Enable ADC3 */
ADC_Cmd(ADC3, ENABLE);
/* Enable ADC3 reset calibaration register */
ADC_ResetCalibration(ADC3);
/* Check the end of ADC3 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC3));
/* Start ADC3 calibaration */
ADC_StartCalibration(ADC3);
/* Check the end of ADC3 calibration */
while(ADC_GetCalibrationStatus(ADC3));

/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
/* Start ADC2 Software Conversion */
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
/* Start ADC3 Software Conversion */
ADC_SoftwareStartConvCmd(ADC3, ENABLE);
}