shuichan_old/V1.5/STM32F103_App1/HardWare/ADC/adc.c

83 lines
2.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "adc.h"
#include "hlw8032.h"
#include "main.h"
#include "network.h"
#include "led.h"
#include "reset_log.h"
#include <string.h>
#include <stdio.h>
ADC_HandleTypeDef hadc1;
void adcInit(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK) Error_Handler();
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) Error_Handler();
}
uint16_t getAdc(void)
{
uint16_t adc_value = 0;
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
adc_value = HAL_ADC_GetValue(&hadc1);
}
HAL_ADC_Stop(&hadc1);
return adc_value;
}
void update_batter(void)
{
static _Bool powoff = 0;
uint16_t adc_value = getAdc();
float batter_valtage = adc_value * (3.3 / 4096.0);
batter_valtage = batter_valtage * 11.0;
batter_valtage += 0.6;
batter_valtage = 100 * (batter_valtage - 10.8) / (12.6 - 10.8);
/* 限幅 0~100%:法拉电容放电时 3.3V 基准下跌ADC 读数失真可能算出负数 */
if (batter_valtage < 0) batter_valtage = 0;
if (batter_valtage > 100) batter_valtage = 100;
/* 电量 <10% 基本等同外部 12V 断开。法拉电容(5.5F)续航有限,
* 首次低于阈值立即 50ms 快速复核 2 次(约 100ms 出结果),仍低马上按断电处理:
* 优先把掉电消息发出去,再做本地记录,最后留 500ms 让模组把报文真正发完 */
if (batter_valtage < 10 && powoff == 0) {
uint8_t confirm = 1;
for (int k = 0; k < 2; k++) {
HAL_Delay(50);
adc_value = getAdc();
float v = adc_value * (3.3 / 4096.0);
v = v * 11.0 + 0.6;
v = 100 * (v - 10.8) / (12.6 - 10.8);
if (v >= 10) { confirm = 0; break; }
}
if (!confirm) return;
/* 分毫必争:先发掉电消息,后打日志(串口打印也要十几 ms
* 发送通道被占用(如 GPS 轮询)时丢弃返回 -1不锁存下个 50ms 周期重试,
* 直到发出或电容耗尽 */
if (NET_publish_power(0) != 0) return;
powoff = 1;
log_info("> 电量低: %d%%", (int)batter_valtage);
hlw8032_save(); /* 本地记录:电量、断电原因(都很快) */
reset_log_power_loss();
HAL_Delay(500); /* 给模组把 MQTT 报文发出去的时间 */
NVIC_SystemReset();
/* BootLoader 会检测主电源12V 未恢复前不跳 APP防止外设没上电时程序乱跑 */
}
/* LED1: 低电量时常亮 */
if (powoff) LED1_ON; else LED1_OFF;
}