Files
Motor_v2/Robot_V2/device/ADC.cpp
T
2025-10-02 02:52:07 +08:00

114 lines
3.0 KiB
C++

#include "adc.h"
#include <cstdio>
#include <stdint.h>
#include "math.h"
constexpr float ERROR_ADC_VAL = 255.0f;
constexpr float ADC_SCALE = 3.3f / 4096.0f;
constexpr float TEMP_FACTOR = 1000.0f / 4.3f;
constexpr float VCC_FACTOR = 11.0f;
constexpr float CURRENT_FACTOR = 1.0f / 50.0f * 100.0f;
constexpr float MAX_TEMP = 150.0f;
constexpr float MIN_TEMP = -40.0f;
constexpr float MAX_CURRENT = 50.0f;
constexpr float MIN_CURRENT = -0.1f;
constexpr float MAX_VCC = 65.0f;
constexpr float MIN_VCC = -0.1f;
u16 adc_value[7] = {0}; // 显式初始化数组元素为0
/**
* @brief 获取MCU温度
* @return float
* 温度值,单位为摄氏度,范围应在-40到145之间,如果读取失败则返回0.0f
*/
float get_mcu_temp() {
float temp_latest = ERROR_ADC_VAL;
// 迭代采样5次,直到获得有效温度值
for (int i = 0; i < 5; i++) {
temp_latest = (1.43f - adc_value[0] * ADC_SCALE) * TEMP_FACTOR + 35.0f;
if (temp_latest < MIN_TEMP || temp_latest > MAX_TEMP)
return ERROR_ADC_VAL;
}
return temp_latest;
}
/**
* @brief 获取电机驱动温度
* @return float 温度值,单位为摄氏度
*
* 通过热敏电阻分压电路计算温度值,使用Steinhart-Hart方程进行温度转换。
* 如果计算结果超出有效范围(-40到255摄氏度),则重新采样计算。
*/
float get_drv_temp() {
float temp_latest = ERROR_ADC_VAL;
for (int i = 0; i < 5; i++) {
float ana_val = adc_value[1];
float R_now = ana_val / (4096 - ana_val) * 4700;
temp_latest =
1.0f / (0.00335f + 0.00025f * log(R_now / 10000.0f)) - 273.15f;
if (temp_latest < MIN_TEMP || temp_latest > MAX_TEMP) {
return ERROR_ADC_VAL;
}
}
return temp_latest;
}
/**
* @brief 获取电流值
* @param type 电流类型,'U'表示U相电流,'V'表示V相电流,'W'表示W相电流
* @return float 电流值,单位为安培
*
* 通过ADC采样计算各相电流值
*/
float get_current(char type) {
float current_latest = ERROR_ADC_VAL;
switch (type) {
case 'U': {
current_latest = adc_value[2] * ADC_SCALE * CURRENT_FACTOR;
break;
}
case 'V': {
current_latest = adc_value[3] * ADC_SCALE * CURRENT_FACTOR;
break;
}
case 'W': {
current_latest = adc_value[4] * ADC_SCALE * CURRENT_FACTOR;
break;
}
default: {
return ERROR_ADC_VAL;
}
}
// 检查电流读数是否在有效范围内
if (current_latest < MIN_CURRENT || current_latest > MAX_CURRENT) {
return ERROR_ADC_VAL;
}
return current_latest;
}
/**
* @brief 获取供电电压
* @return float 电压值,单位为伏特
*
* 通过ADC采样计算供电电压值,使用迭代方式确保获取有效的电压读数。
* 如果计算结果超出有效范围(-40到255伏特),则重新采样计算。
*/
float get_vbus_voltage() {
float vcc_latest = ERROR_ADC_VAL;
for (int i = 0; i < 5; i++) {
// 获取电压值
vcc_latest = adc_value[6] * ADC_SCALE * VCC_FACTOR;
// 检查电压读数是否在有效范围内
if (vcc_latest > MAX_VCC || vcc_latest < MIN_VCC) {
return ERROR_ADC_VAL;
}
}
return vcc_latest;
}