目录
实验概述
实验平台:原子的mini开发板(主控RCT6)
使用ADC1的1到6通道采集六路电压,通过串口输出在PC端(XCOM)
ADC_Channel_1--------PA1
ADC_Channel_2--------PA2
ADC_Channel_3--------PA3
ADC_Channel_4--------PA4
ADC_Channel_5--------PA5
ADC_Channel_6--------PA6
DMA概要
直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。
两个DMA控制器有12个通道 (DMA1有7个通道,DMA2有5个通道) ,每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。
使用多路规则通道转换ADC数据时转换好的结果只能存储在一个仅有的数据寄存器之中,如果不对ADC_DR寄存器中的内容做处理,则将会被新转换好的数据覆盖。因此在使用多路ADC数据的转换过程中必须使用DMA对结果进行保存,保证数据不会被覆盖。
初始化源码
以下为初始化代码,包括引脚,DMA,ADC
DMA将每一路ADC的转换结果按顺序存放在adc_original_data[6]中,往复循环,需要哪一路ADC结果就把对应的数组里的值返回处理就好
u16 adc_original_data[6] = {0,0,0,0,0,0};//存放六路ADC原始数据的数组
void adc_init(void){
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitInstructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能 ADC1通道时钟
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//初始化两个GPIO
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//初始化两个GPIO
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//初始化两个GPIO
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//初始化两个GPIO
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//初始化两个GPIO
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
DMA_DeInit(DMA1_Channel1);//复位
DMA_InitInstructure.DMA_PeripheralBaseAddr =(u32)(&(ADC1->DR));//配置外设的基址,取adc 数据寄存器的地址
DMA_InitInstructure.DMA_MemoryBaseAddr = (u32)adc_original_data;//把DMA的数据存入数组
DMA_InitInstructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到DMA
DMA_InitInstructure.DMA_BufferSize = 6;//2个通道
DMA_InitInstructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//
DMA_InitInstructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitInstructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitInstructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitInstructure.DMA_Mode = DMA_Mode_Circular;//不断地传输,有数据就传输
DMA_InitInstructure.DMA_Priority = DMA_Priority_High;//DMA优先级
DMA_InitInstructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1,&DMA_InitInstructure);
DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA请求
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
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数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄 存器
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_1,1, ADC_SampleTime_239Cycles5 );
//ADC1,ADC1通道1,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_2,2, ADC_SampleTime_239Cycles5 );
//ADC1,ADC1通道2,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_2,3, ADC_SampleTime_239Cycles5 );
//ADC1,ADC1通道3,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_2,4, ADC_SampleTime_239Cycles5 );
//ADC1,ADC1通道4,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_2,5, ADC_SampleTime_239Cycles5 );
//ADC1,ADC1通道5,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_2,6, ADC_SampleTime_239Cycles5 );
//ADC1,ADC1通道6,采样时间为239.5周期
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
//while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
}
结果
实物接线,就接了三个通道PA1、PA2、PA3
XCOM上的输出
such is life