注意上述右图的配置需要根据我们实际所使用的通道来,239.5这个是采样时间,根据需要调整,然后我们打到DMA配置项,如下图
这个地方只有DMA模式需要调整,完成上述配置后我们就可以生成代码了,然后我们按照如下步骤:
1、校准ADC,开启DMA接收,在main函数初始化部分调用
#define ADC_MAX_NUM 5 //表明通道数
#define BTN_BUFF_LEN 100 //采样次数
static uint16_t dma_adc_data[BTN_BUFF_LEN * ADC_MAX_NUM];
2、调用如下两句语句进行ADC校准
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)dma_adc_data, BTN_BUFF_LEN * ADC_MAX_NUM);
DMA采集的数据存放buff,采集5个通道,每个通道采集BTN_BUFF_LEN次,dma_adc_data数据存放方式:HAL_ADC_Start_DMA(&hadc1, (uint32_t *)dma_adc_data, BTN_BUFF_LEN * ADC_MAX_NUM);
* 数据采集u32类型,dma_adc_data为u16类型,
* 第1个u32:通道1和通道2 * 第2个u32:通道3和通道4
* 第3个u32:通道5和通道1 * 第4个u32:通道2和通道3 * 第5个u32:通道4和通道5
3、进行数据获取,我们可以在循环调用如下函数,这样采集到的原始值会保存在ADC_Values,数据顺序为我们设置的顺序,比如ADC_Values[0],为我们第一个通道的值。
这里我们使用如下代码将其转换为电压:
// 常量定义
const float ADC_VREF = 3.3f;
const float ADC_RESOLUTION_12BIT = 4096.0f;
const float ADC_RESOLUTION_10BIT = 1023.0f;
const float ADC_CH1_CONV_FACTOR = 4980.0f / ADC_RESOLUTION_10BIT; // CH1 为 10-bit,参考电压 4980mV
// 计算五个 ADC 通道的电压值
adc_ch1.adc_voltage = ADC_Values[0] * ADC_CH1_CONV_FACTOR; // mv
adc_ch2.adc_voltage = ADC_Values[1] * ADC_VREF / ADC_RESOLUTION_12BIT; // v
adc_ch3.adc_voltage = ADC_Values[2] * ADC_VREF / ADC_RESOLUTION_12BIT;
adc_ch4.adc_voltage = ADC_Values[3] * ADC_VREF / ADC_RESOLUTION_12BIT;
adc_ch5.adc_voltage = ADC_Values[4] * ADC_VREF / ADC_RESOLUTION_12BIT;
// 打印通道的转换电压
debug_print("\r\nADC1 通道电压: CH1 %.3f mV, CH2 %.3f V, CH3 %.3f V, CH4 %.3f V, CH5 %.3f V\r\n",
adc_ch1.adc_voltage, adc_ch2.adc_voltage, adc_ch3.adc_voltage, adc_ch4.adc_voltage, adc_ch5.adc_voltage);
/**
* @brief Get the Adc Value object 处理原始数据,获取5个通道的数据
*/
static void Get_Adc_Value(void)
{
if (DMA_RECEIVE_OVER == 1) // DMA数据采集完处理数据
{
DMA_RECEIVE_OVER = 0;
for (uint8_t adc_channel = 0; adc_channel < ADC_MAX_NUM; adc_channel++)
{
adc_max = 0;
adc_add = 0;
adc_min = 0xffff;
for (uint16_t i = 0; i < BTN_BUFF_LEN; i++)
{
adc_add += dma_adc_data[ADC_MAX_NUM * i + adc_channel];
adc_max = adc_max > dma_adc_data[ADC_MAX_NUM * i + adc_channel] ? adc_max : dma_adc_data[ADC_MAX_NUM * i + adc_channel];
adc_min = adc_min < dma_adc_data[ADC_MAX_NUM * i + adc_channel] ? adc_min : dma_adc_data[ADC_MAX_NUM * i + adc_channel];
}
ADC_Values[adc_channel] = (adc_add - adc_max - adc_min) / (BTN_BUFF_LEN - 2);
}
}
}
计算后debug结果如下:
我们可以通过接入3.3V电压判断一下我们的转换是否正确,注意最大只能接入3.3V,否则会损坏管脚
我在通道2上接入3.3V电压,经过转换后我们得到的电压值为3.298,这个值与3.3V基本没啥差别,说明我们的ADC还是挺准的,到这里我们第一步已经完成了,下面就是根据电压值套公式转换了。这一步没啥讲的,直接查手册,套进去算就好了。
我们这里使用串口进行debug,打印出每个通道的电压,如下