STM32G431轮询ADC DMA实验总结

一,关于ADC的简单介绍

STM32芯片上的ADC(模数转换器)是一个模拟电路,可以将模拟信号转换为数字信号。这些数字信号可以用来表示被转换的模拟信号值,例如测量温度、光强、压力、电压等。

框图:

二,STM32Cubemx可配置部分参数说明

一,ADC部分

                       配置参数                                    可选项

ADCs_Common_Settings

(模式选择)

选lndependent mode

独立模式,同一时刻一个管脚只有一个ADC转换

Clock Prescaler

(时钟分频)

选Asynchronous clock mode divided by 1

同异步时钟1分频

Resolution

(分辨率)

一般选ADC12-bit resolution

(12位分辨率)

Gain Compensation

(增益介质)

一般选0,校准用的

Scan Conversion Mode

(扫描模式)

多通道的时候使能

Continuous Conversion Mode

(连续转换模式)

使能后完成当前ADC转换自动开始下一次ADC转换

Discontinuous Conversion Mode

(不连续转换模式)

多通道的时候使能,(例子:你使能了4个ADC通道为1-4,使能这个可以做的让1,2先转换,3,4再转换不能单独配置,要配合其他的参数配置)

DMA Continuous Requests

(DMA连续请求)

使能后DMA完成一次搬运请求后自动开始下一次搬运请求,要配合DMA的循环模式使用
Enable Regular Conversions
(启用常规转换)
即规则通道使能
Enable Regular Oversampling
(启用常规过采样)
过采样时使用(如12位分辨率变16位时)
Number Of Conversion
(转换数)
使能的规则通道数量
External Trigger Conversion Source
(外部触发转换源)

一般选Regular Conversion launched by software

(软件启动的定期转换,即软件触发)

Rank

(规则通道的转换顺序)

多通道时,按照这个顺序配置进行转换

(如:配置了1-3,从1开始转换一直到3)

Channel
(通道)
通道相关序号
Sampling Time
(取样时间)

选择的时间越大,转换越精准,耗时越长

(1个Cycles为ADC时钟频率的倒数,如

ADC时钟为40MHZ,1Cycles=0.025us)

Oversampling Right Shift
(过采样右移)
使能过采样可选(如分辨率为16位时右移一位变成15位分辨率)
Oversampling Ratio
(过采样比)

12位分辨率时选Oversampling ratio 16x

可变为16位分辨率(它们的关系自己类推)

Regular Oversampling Mode
(规则过采样模式)
一般选Oversampling Continued Mode
(过采样连续模式,完成当前的过采样,立即开始下一次)
Triggered Regular Oversampling
(触发规则过采样)
一般选Single trigger for all oversampled conversions
(所有过采样转换的单触发器,触发一次完成所有通道过采样)

Data Alignment 

(数据对齐)

一般选Right alignment (右侧对齐)

二,MDA部分

                     配置参数                            可选项

DMA Request
(DMA请求)
选择相应的外设
Channel
(通道)
选择对应DMA与通道(如:DMA1 Channel 2)
Direction
(方向)
一般选Peripheral To Memory外设到内存
(也可以是内存到外设,内存到内存,指数据的流向,如ADC的DMA模式就是外设到内存)
Priority
(优先权)
有高,超高,中低等,越高可以先运行
 
DMA Request Settings
DMA(请求设置)

其下有Mode,lncrement Address,Data Width

参数可配置

Mode
(模式)

Normal(搬运完一次需要再次使能)

Circular(完成本次搬运离开开始下一次)

lncrement Address
(增值地址)

Peripheral(使能这个,外设地址自增,一般不使能)

Memory (使能这个内存地址自增,即自己写代码时,用数组来存数据时,数据自动逐个放入数组中,一般使能)

Data Width
(数据宽度)

根据自己的需求选(DAM一次搬多少位数据)

选Half Word半字,即为一次搬16位

 三,实战

一,单规则通道非DMA

STM32Cubemx配置

以下实验皆为该时钟配置 

 核心代码:

/*
函数名:MyAdcInit
作用 :进行ADC校准
参数 :无
返回值 ;无
*/
void MyAdcInit(void) 
{
    //校准
    HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
}


/*
函数名:AdcGetValue
作用 :获得ADC的值
参数 hadc :ADC的句柄
参数 time :取多少个数进行平均
返回值 temp :返回测到的电压
*/
float AdcGetValue(ADC_HandleTypeDef* hadc,u8 time)
{
	float temp=0;
	uint32_t value=0;
	HAL_ADC_Start(hadc);
	//等待通道转换完成
	HAL_ADC_PollForConversion(hadc, 10);
	for(int i=0;i<time;++i)
	{
		value+=HAL_ADC_GetValue(hadc);
		HAL_Delay(5);
	}
	value=value/time;
	temp = (float)value * (3.3 / 4096);
	return temp;
}

使用说明:

将校准函数放入main()函数中初始化的相应位置即可,因为是轮询AdcGetValue()要放入while(1)中一次调用。

二,单规则通道DMA

STM32Cubemx配置

 核心代码:

​
/*-----------------------------------相关变量------------------------------------------*/

#define bufSize   100
uint16_t buf[bufSize]={0};
uint32_t Value=0;
float endValue=0;

/*-----------------------------------相关函数------------------------------------------*/

/*
函数名 :AdcToDmaGetValue
作用 :获取电压值
参数 :无
返回值 :ADC获取的电压
*/
float AdcToDmaGetValue(void)
{
	HAL_ADC_Start_DMA(&hadc2,(uint32_t*)buf,bufSize);
    //等待DMA搬运完成
	while(__HAL_DMA_GET_FLAG(&hdma_adc2,DMA_FLAG_TC1))
	{
        //hdma_adc2要进行外部声明,cbuemx生成时选分别生产.c .h文件即可在adc.c中找到
		__HAL_DMA_CLEAR_FLAG(&hdma_adc2,DMA_FLAG_TC1);
        //这个函数是必要的不然标志位查看时会一直卡住
		HAL_ADC_Stop_DMA(&hadc2);
	}
	for(int i=0;i<bufSize;++i)
	{
		Value+=buf[i];
	}
	Value/=bufSize;
	endValue=(float)Value*(3.3f/4096.0f);
	return endValue;
}


/*
函数名 :myAdcToDmaInit
作用 :ADC校准
参数 :无
返回值 :无
*/
void myAdcToDmaInit(void)
{
	//校准
	HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
}

​

三,多通道DMA

STM32Cubemx配置

 核心代码:

/*-----------------------------------相关变量定义---------------------------------------*/

//通道数量
#define TCxNum  2
//每个通道采集的次数
#define TCxCollNumm 20
#define bufSize  TCxNum*TCxCollNumm
uint16_t buf[bufSize];
uint32_t sum[2];
float sum0=0,sum1=0;

/*-----------------------------------相关函数-------------------------------------------*/

/*
函数名 :MyAdcToDmaInit
作用 :进行ADC校准
参数 :无
返回值 :无
*/
void MyAdcToDmaInit(void)
{
	HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
}


/*
函数名 :MyAdcToDmaGetValue
作用 :获取电压值
参数 :无
返回值 :无
*/
void MyAdcToDmaGetValue(void)
{
	HAL_ADC_Start_DMA(&hadc1,(uint32_t*)buf,bufSize);
	while(__HAL_DMA_GET_FLAG(&hdma_adc1,DMA_FLAG_TC1))
	{
		__HAL_DMA_CLEAR_FLAG(&hdma_adc1,DMA_FLAG_TC1);
		HAL_ADC_Stop_DMA(&hadc1);
	}
	for(int i=0;i<bufSize;++i)
	{
		sum[i%2]+=buf[i];
	}
	sum[0]/=TCxCollNumm;
	sum[1]/=TCxCollNumm;
    //通道5结果
	sum0=sum[0]*(3.3f/4096.0f);
    //通道11结果
	sum1=sum[1]*(3.3f/4096.0f);
}

四,未完待续

。。。。。。(点击跳转下一篇)

作者:野区萧炎

物联沃分享整理
物联沃-IOTWORD物联网 » STM32G431轮询ADC DMA实验总结

发表评论