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

88 lines
2.9 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 "oled.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;
/* 分毫必争:发掉电消息并等模组回 OK最多 ~1.5s/次,最多试 3 次)。
* 3 次都发不出(通道忙/模组已掉线)也照常记录复位,不能因发送失败就不记录 */
{
static uint8_t pub_try = 0;
if (NET_publish_power_wait(0) != 0 && ++pub_try < 3) return;
pub_try = 0;
}
powoff = 1;
log_info("> 电量低: %d%%", (int)batter_valtage);
oled_off(); /* 屏幕黑屏(省电+避免残影) */
hlw8032_save(); /* 本地记录:电量、断电原因(都很快) */
reset_log_power_loss();
HAL_Delay(800); /* OK 后再留 800ms 让报文上空口 */
NVIC_SystemReset();
/* BootLoader 会检测主电源12V 未恢复前不跳 APP防止外设没上电时程序乱跑 */
}
/* LED1: 低电量时常亮 */
if (powoff) LED1_ON; else LED1_OFF;
}