STM32L051电阻分压ADC电量采集

更新时间:2024-04-09 10:26:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

电阻分压ADC电量采集

STM32的ADC特点:

※STM32L051单片机具有12位ADC(逐次逼近型ADC); ※ADC具有四中工作模式:单次、连续、扫描、不连续;

※ADC采集的结果具有左对齐和右对齐两种方式的16位寄存器;

※ADC模拟看门狗功能允许开发人员监测ADC的电压输入是否超过设置上下门限; ※一个高效的低功耗模式允许ADC采集在极低的功耗下运行;

※ADC具有多点连续采集模式,该模式通过硬件完成多点采集减少了CPU的占用率提高采样效率;

STM32的ADC功能描述:

ADC具有内部独立的电压调节器,调节器必须在使用ADC前使能并且等待调节器稳定后才能使用ADC;调节器的稳定时间由硬件自己决定,开发人员无需关注;

校准:ADC具有自动校准功能,开发人员在校准ADC之后才能使用ADC,校准能够消除芯片和芯片之间的差异以及其他硬件偏移;

ADC时钟:ADC具有双时钟模式,ADC有一个独立的内部时钟源; 1 初始化:

Linki2u产品的ADC采集通过STM32的ADC单次采样模式进行;电量检测通过电阻分压的方式进行,ADC的初始化配置:

AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4; //初始化ADC的时钟,这个参数只能在ADC停止工作的时候更改 **** AdcHandle.Init.Resolution = ADC_RESOLUTION12b; //初始化ADC的分辨率 ****

AdcHandle.Init.ScanDirection = ADC_SCAN_DIRECTION_UPWARD; //采样方向

AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIG_EDGE_NONE; //触发方式

AdcHandle.Init.EOCSelection = EOC_SINGLE_CONV;

//采样完成EOC标志位置位

AdcHandle.Init.DMAContinuousRequests = DISABLE; //DMA连续模式关闭

AdcHandle.Init.DiscontinuousConvMode = DISABLE; //非连续模式关闭

AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐

AdcHandle.Init.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; //采样周期设置

AdcHandle.Init.OversamplingMode = DISABLE; //过量采集模式禁止

AdcHandle.Init.LowPowerAutoOff = ENABLE; //使能单次采集模式

AdcHandle.Init.LowPowerFrequencyMode = DISABLE; //

AdcHandle.Init.LowPowerAutoWait = DISABLE; //

AdcHandle.Init.ContinuousConvMode = DISABLE; // HAL_ADC_Init(&AdcHandle); //初始化ADC参数 2ADC校准 HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED); //开启ADC校准 3设置ADC通道 sConfig.Channel = ADC_CHANNEL_7; //ADC采样通道 HAL_ADC_ConfigChannel(&AdcHandle, &sConfig); //设置ADC采样通道 4使能ADC功能 HAL_ADC_Start(&AdcHandle);

单次采集流程:

电池电量通过电阻分压ADC采样的方式获取; 1) 程序中定义了一个电池电量的结构体:

typedef uint16_t (* ARRAYAVRAGE ) (uint16_t buf[],uint8_t len); typedef uint16_t (* PARAMEMPTYFUN) (void); typedef struct Tag_Framet_Battery {

uint8_t lnvalue; //电池电量的线性系数 uint8_t adcnt; //电池电量ADC采样次数 uint8_t delay_cnt; //延时次数 uint16_t *ptr; //电池电量采样指针 uint16_t ADCValue[10]; //电池电量采样数据数组 float bat_value; //电池电量

ARRAYAVRAGE AvgFun; //电池电量数据处理函数 PARAMEMPTYFUN ValueFun; //电池电量采样函数 }Framet_Battery;

2 初始化电池电量采集的参数

void BatTest_funInit(Framet_Battery *bat) {

bat->lnvalue=0; bat->adcnt=0; bat->delay_cnt=0; bat->bat_value=0; bat->ValueFun=(PARAMEMPTYFUN)Get_singleADCValue;//单次采样模式 bat->ptr=bat->ADCValue; bat->AvgFun=(ARRAYAVRAGE) StrBubble_Sort; //数据求均值 }

3 ADC采集

主循环中进行数据采集;

#define FILTERCOUNTER 10 //?¨ò?êy?Y??2¨??êy

#define VDD_ADCREF (3.3) #define MAX_ADCSAMPLE (4096.0)

#define ADCRESOLUTION (VDD_ADCREF/MAX_ADCSAMPLE)

#define RES_UP (133000.0) #define RES_DOWN (100000.0)

#define RES_SUM (RES_UP+RES_DOWN)

#define BAT_MAXVALUE (4.1)//?aá??ú×???μ?3?ì?D???é??T??D? #define BAT_MINVALUE (3.0)

#define BAT_ABSOLUTE (BAT_MAXVALUE-BAT_MINVALUE)

#define PERCENTAGE (100.0)

uint16_t Get_singleADCValue() { uint16_t ADCvalue; ADC1->CR |= ADC_CR_ADSTART;

HAL_ADC_PollForConversion(&AdcHandle,5000); ADCvalue=HAL_ADC_GetValue(&AdcHandle); return ADCvalue; }

void Get_BatLinValue(Framet_Battery *bat) {

bat->delay_cnt++; if(bat->delay_cnt==100) { bat->delay_cnt=0; bat->ADCValue[bat->adcnt++]=bat->ValueFun(); if(bat->adcnt==10) { bat->adcnt=0; bat->bat_value=

bat->AvgFun(bat->ptr,FILTERCOUNTER)*ADCRESOLUTION*RES_SUM/RES_DOWN;

bat->lnvalue=(uint8_t)((bat->bat_value-BAT_MINVALUE)*PERCENTAGE/BAT_ABSOLUTE); if(bat->lnvalue>100) bat->lnvalue=100; } } }

本文来源:https://www.bwwdw.com/article/dd7r.html

Top