【LM401】ADC采集代码解读

本文主要实现基于LM401模组,,测试ADC低功耗采集,详细解析代码基于计算方式

对于小白理解ADC有更详细的理解

【LM401】ADC采集代码解读

  • 1. 单片机ADC与DAC简单理解
  • 2. 模组ADC通道介绍
  • 3. ADC初始化
  • 4. 采集值的计算

硬件基于易智联的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;    // 分辨率为 12bit
  hadc.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;      // 不使用 DMA
  hadc.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__))

( V R E F / 2 n ) ∗ A d c D a t a (VREF/2^n)*AdcData (VREF/2n)AdcData

你可能感兴趣的:(单片机,stm32,嵌入式硬件)