中国建设信用卡网站首页广州seo工程师
本文主要实现基于LM401模组,,测试ADC低功耗采集,详细解析代码基于计算方式
对于小白理解ADC有更详细的理解
【LM401】ADC采集代码解读
- 1. 单片机ADC与DAC简单理解
- 2. 模组ADC通道介绍
- 3. ADC初始化
- 4. 采集值的计算
- 5.测试结果
硬件基于易智联的LM401
的LoRa模组,用的 LM401-pro-kit
开发板,开发板资料以及参考资料如下:
【基于STM32WL的LM401 Lora评估板】
【STM32WLE5之lora:5、易智联LM40评估板ADC定时采集上报】
1. 单片机ADC与DAC简单理解
-
ADC:模数转换,单片机的IO口接一个传感器,传感器输出模拟值,单片机读取模拟量转化为数字量。( 单片机输入模拟值,转化为数字值)
-
DAC:数模转换,给单片机数字值,从单片机的IO口输出模拟信号量。( 单片机IO口输出模拟信号量)
2. 模组ADC通道介绍
12位DAC、2Msps 低功耗采样保持电路 ,12通道,采用 16-bit 硬件过采样,转化范围1.62—3.6V,给出部分引脚,具体查看手册
PB1 — ADC_IN5 PB2 — ADC_IN4
PB3 — ADC_IN2 PB4 — ADC_IN3
PB13 — ADC_IN0 PB14 — ADC_IN1
其中三个通道说明:
#define ADC_CHANNEL_VREFINT (LL_ADC_CHANNEL_VREFINT) // 内部参考电压
#define ADC_CHANNEL_TEMPSENSOR (LL_ADC_CHANNEL_TEMPSENSOR) // MCU 内部温度,精确度不高 1度左右
#define ADC_CHANNEL_VBAT (LL_ADC_CHANNEL_VBAT) // 外部连接电压值
3. ADC初始化
void MX_ADC_Init(void)
{/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)*/hadc.Instance = ADC;hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 时钟分频数hadc.Init.Resolution = ADC_RESOLUTION_12B; // 分辨率为 12bithadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 一般选择右对齐hadc.Init.ScanConvMode = ADC_SCAN_DISABLE; // 单通道(单次)或者多通道(扫描)模式选择,扫描的话就是序列的形式hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; // 单一转换结束hadc.Init.LowPowerAutoWait = DISABLE; // 低功耗hadc.Init.LowPowerAutoPowerOff = DISABLE;hadc.Init.ContinuousConvMode = DISABLE;hadc.Init.NbrOfConversion = 1;hadc.Init.DiscontinuousConvMode = DISABLE;hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;hadc.Init.DMAContinuousRequests = DISABLE; // 不使用 DMAhadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;hadc.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;hadc.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;hadc.Init.OversamplingMode = ENABLE; //使能过采样hadc.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_16; // ,16倍过采样hadc.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;hadc.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;hadc.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;if (HAL_ADC_Init(&hadc) != HAL_OK){Error_Handler();}/* USER CODE BEGIN ADC_Init 2 *//* USER CODE END ADC_Init 2 */}
4. 采集值的计算
比如,demo中通过PA11引脚读取ADC的值,读取后的计算方式:
注意::计算时用的12位分辨率,和ADC初始化设置的分辨率要对应
bat_v = SYS_GetBatteryLevel(); // 获取内部参考电压-> ADC_ReadChannels(ADC_CHANNEL_VREFINT);
temp = GetADC_PA11();
pa11_v = __LL_ADC_CALC_DATA_TO_VOLTAGE(bat_v, temp,ADC_RESOLUTION_12B); // 将PA11的ADC转换成电压,单位mV 通过这个函数计算出实际电压值,单位是 mV/// @brief 将采集到的模拟电压值转换为实际电压值,计算结果单位是 mV
/// @param 参数1:ADC转换环境的参考电压值
/// 参数2:采集到的模拟电压值
/// 参数3:AD芯片分辨率(本系列可可以是6 8 10 12)
#define __HAL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__,\__ADC_DATA__,\__ADC_RESOLUTION__) \
__LL_ADC_CALC_DATA_TO_VOLTAGE((__VREFANALOG_VOLTAGE__),\(__ADC_DATA__),\(__ADC_RESOLUTION__))
(VREF/2n)∗AdcData(VREF/2^n)*AdcData (VREF/2n)∗AdcData
5.测试结果
测试 PB4
和 PB3
两路ADC,分别将PB3
直接接地,PB4
接3.3v
,测试过程代码
说明:本例 参考电压为 3.3v 用的12位ADC
#define VREF_MV (3300UL)
#define ADC_MAX_RESULT ((1 << 12)-1) // 12 bit ADCuint16_t batteryLevel = SYS_GetBatteryLevel(); // 获取系统的参考电压 单位 mv(3300mv)
APP_PRINTF("batteryLevel= %d \r\n",batteryLevel);uint16_t ADC_PB3_Value = GetADC_PB3_Value();uint16_t ADC_PB4_Value = GetADC_PB4_Value();APP_PRINTF("ADC_PB3_Value= %d \r\n", ADC_PB3_Value);APP_PRINTF("ADC_PB4_Value= %d \r\n ",ADC_PB4_Value);APP_PRINTF("*********************************** \r\n ");APP_PRINTF("ADC_PB3_Value= %d \r\n",(ADC_PB3_Value * VREF_MV) / ADC_MAX_RESULT);APP_PRINTF("ADC_PB4_Value= %d \r\n ",(ADC_PB4_Value * VREF_MV) / ADC_MAX_RESULT);
打印信息如下: