一、ADC介绍
通过介绍我们可以了解到,ADC是12位的转换器,所以采样值范围是0~4095。18个通道可同时进行转换,也可以单独转换某个通道。
二、单通道单次ADC采样
使用ADC的流程应为:
- 初始化IO口。
我这里使用的是PA1进行采样,也就是ADC1的通道1
void ADC_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);//打开IO时钟
//配置ADC对应的IO为模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN ;
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化结构体
}
- 初始化ADC。
void ADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//单通道模式
ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;//单次转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发转换
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
ADC_InitStructure.ADC_NbrOfChannel=1;//顺序转化的ADC通道数量
ADC_Init(ADC1,&ADC_InitStructure);
//耗时 1/14KHz*239 ≈ 17.07us
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1,ENABLE);
/*ADC校准*/
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
- 转换、获取采样值。
uint16_t ReadADC(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //启用ADC软件转换
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1的转换结果
}
三、多通道采样+DMA搬运
多通道的时候我们一般用DMA来搬运数据,与单通道不同的是,ADC配置时有些变化,DMA需要进行配置。
void ADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/*使能DMA通道1*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC1->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &DMA_Getvalue;//DMA_Getvalue[10]; 搬运数据的存放地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 10; // 每次传输10个通道的值,就停止
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//存储地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//递增模式,可将上面的数组填充完整,否则永远是第一个
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_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
/*ADC1工作模式为扫描模式、单次转换、14个通道、数据右对齐,*/
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel=SixChannelMax;
ADC_Init(ADC1,&ADC_InitStructure);
//排列好各通道的顺序,此顺序对应DMA数组内数据的顺序
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2,2,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_3,3,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_4,4,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5,5,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6,6,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7,7,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_8,8,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_9,9,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,10,ADC_SampleTime_239Cycles5);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
/*ADC校准*/
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
/*启用ADC软件转换*/
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}
然后获取转化值函数也发生相应的改变,此函数可以放在一个定时中断或定时任务中,固定多少间隔去读取文章来源:https://www.toymoban.com/news/detail-634962.html
void Read_ADCValue(void)
{
uint32_t Value[10];
ADC_Cmd(ADC1,DISABLE);//先失能ADC
int i = 0;
//将读取到的值保存
for(i =0; i < 10; i++)
{
Value[i] += DMA_Getvalue[i];//将搬运的数据取出
}
memset(DMA_Getvalue,0,sizeof(DMA_Getvalue)); //每次读取数据后清空DMA存储空间
ADC_Cmd(ADC1,ENABLE);//使能ADC
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开始转换
}
读取函数也可以使用DMA中断,进行配置然后在中断内取出数据即可。文章来源地址https://www.toymoban.com/news/detail-634962.html
到了这里,关于STM32 ADC单/多通道采样+DMA搬运的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!