Update RX
This commit is contained in:
@@ -12,99 +12,16 @@
|
||||
* TX(P3.1) - UART1 TX / SBUS 输出 (经板上三极管反相)
|
||||
* RX(P3.0) - UART1 RX / 命令输入
|
||||
*
|
||||
* NRF24L01 (软件SPI):
|
||||
* NRF24L01 (硬件SPI):
|
||||
* SCK(P1.5) CE(P1.6) IRQ(P1.7) CSN(P5.4) MISO(P1.3) MOSI(P1.4)
|
||||
*/
|
||||
#include "STC8_SDCC.H"
|
||||
# ifndef CONFIG
|
||||
# define CONFIG
|
||||
# include "CONFIG.h"
|
||||
# endif
|
||||
|
||||
#include "NRF24.h"
|
||||
#include <string.h>
|
||||
|
||||
/* ========================================================================
|
||||
* 系统常量
|
||||
* ======================================================================== */
|
||||
|
||||
#define FOSC 24000000UL /* 系统主频 24MHz */
|
||||
#define PWM_PERIOD 5000 /* 20ms / 4us = 5000 步 */
|
||||
#define PWM_MIN 250 /* 1.0ms 脉宽 (4us/步) */
|
||||
#define PWM_MAX 500 /* 2.0ms 脉宽 */
|
||||
#define PWM_MID 375 /* 1.5ms 脉宽 */
|
||||
#define CHANNEL_COUNT 4 /* 4路PWM输出 */
|
||||
|
||||
#define UART_BUF_SIZE 32
|
||||
|
||||
/* 接收状态 */
|
||||
#define RX_STATE_DISCONNECTED 0
|
||||
#define RX_STATE_BINDING 1
|
||||
#define RX_STATE_CONNECTED 2
|
||||
|
||||
/* 输出模式 */
|
||||
#define OUT_MODE_PWM 0
|
||||
#define OUT_MODE_SBUS 1
|
||||
#define OUT_MODE_UART 2
|
||||
#define OUT_MODE_CRFS 3
|
||||
|
||||
/* EEPROM 地址 (IAP) */
|
||||
#define EEPROM_ADDR_BIND_FLAG 0x0000
|
||||
#define EEPROM_ADDR_TX_ADDR 0x0001 /* 5字节 */
|
||||
#define EEPROM_ADDR_RF_CH 0x0006
|
||||
#define EEPROM_ADDR_BIND_PHRASE 0x0007 /* 6字节 */
|
||||
#define EEPROM_BIND_MAGIC 0x5A /* 已对频标志 */
|
||||
|
||||
/* 数据包格式 (与发射机一致) */
|
||||
#define RF_SYNC_BYTE0 0xAA
|
||||
#define RF_SYNC_BYTE1 0x55
|
||||
#define RF_PACKET_SIZE 32
|
||||
#define RF_PHRASE_LEN 6
|
||||
|
||||
/* LED 闪烁模式 */
|
||||
#define LED_BLINK_SLOW 0 /* 1Hz - 未连接 */
|
||||
#define LED_BLINK_FAST 1 /* 3Hz - 对频中 */
|
||||
#define LED_ON 2 /* 常亮 - 已连接 */
|
||||
#define LED_OFF 3 /* 熄灭 */
|
||||
#define LED_BLINK_DOUBLE 4 /* 双闪 - NRF硬件错误 */
|
||||
|
||||
/* ========================================================================
|
||||
* 全局变量
|
||||
* ======================================================================== */
|
||||
|
||||
/* PWM 通道脉宽值 (4us单位, 放在 xdata) */
|
||||
static volatile uint16_t __xdata pwm_ch[CHANNEL_COUNT];
|
||||
|
||||
/* 接收状态 */
|
||||
static uint8_t rx_state = RX_STATE_DISCONNECTED;
|
||||
static uint8_t out_mode = OUT_MODE_PWM;
|
||||
|
||||
/* 对频信息 (放在 xdata) */
|
||||
static uint8_t __xdata bind_phrase[RF_PHRASE_LEN] = "LOVE";
|
||||
static uint8_t __xdata tx_addr[NRF_ADDR_WIDTH] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7};
|
||||
static uint8_t rf_channel = 40;
|
||||
|
||||
/* 信号丢失计数 */
|
||||
static uint16_t lost_packet_cnt = 0;
|
||||
#define LOST_PACKET_TIMEOUT 500 /* 500次接收超时后判丢失 (~5秒 @ 100Hz) */
|
||||
|
||||
/* NRF 硬件错误标志 */
|
||||
static uint8_t nrf_hw_error = 0;
|
||||
|
||||
/* 电池电压 */
|
||||
static volatile uint16_t bat_voltage_mv = 0;
|
||||
|
||||
/* 回传数据 */
|
||||
static uint8_t telem_rssi = 0; /* 信号强度 (0-100) */
|
||||
static uint8_t telem_packet_loss = 0; /* 丢包率 (0-100%) */
|
||||
static uint8_t telem_rate_hz = 2; /* 回传频率 1-10Hz, 默认2Hz */
|
||||
|
||||
/* CRFS 模式下接收的飞控转发数据 */
|
||||
static uint8_t __xdata crfs_forward_buf[24];
|
||||
static uint8_t crfs_forward_len = 0;
|
||||
|
||||
/* UART 接收缓冲 (放在 xdata) */
|
||||
static uint8_t __xdata uart_rx_buf[UART_BUF_SIZE];
|
||||
static uint8_t uart_rx_idx = 0;
|
||||
static volatile uint8_t uart_cmd_ready = 0;
|
||||
|
||||
/* 定时器计数 (用于LED闪烁) */
|
||||
static volatile uint16_t sys_tick = 0;
|
||||
#include "UART.h"
|
||||
|
||||
/* ========================================================================
|
||||
* 函数声明
|
||||
@@ -513,13 +430,27 @@ static void ADC_Init(void) {
|
||||
ADC_CONTR = (ADC_CONTR & 0xF0) | 0x0B;
|
||||
}
|
||||
|
||||
static uint16_t ADC_Read(void) {
|
||||
ADC_CONTR |= ADC_START; /* 启动转换 */
|
||||
while (!(ADC_CONTR & ADC_FLAG)); /* 等待完成 */
|
||||
ADC_CONTR &= ~ADC_FLAG; /* 清除标志 */
|
||||
/* 读取指定ADC通道 */
|
||||
static uint16_t ADC_ReadChannel(uint8_t ch) {
|
||||
ADC_CONTR = (ADC_CONTR & 0xF0) | ch; /* 切换通道 */
|
||||
__asm nop __endasm; /* 等待通道切换稳定 */
|
||||
__asm nop __endasm;
|
||||
ADC_CONTR |= ADC_START; /* 启动转换 */
|
||||
while (!(ADC_CONTR & ADC_FLAG)); /* 等待完成 */
|
||||
ADC_CONTR &= ~ADC_FLAG; /* 清除标志 */
|
||||
return ((uint16_t)ADC_RES << 8) | ADC_RESL;
|
||||
}
|
||||
|
||||
static uint16_t ADC_Read(void) {
|
||||
return ADC_ReadChannel(0x0B); /* P3.3/ADC11 */
|
||||
}
|
||||
|
||||
/* 读取内部带隙基准电压 (通道14), 用于反算VCC */
|
||||
/* VCC(mV) = 1190 * 4096 / bandgap_adc */
|
||||
static uint16_t ADC_ReadBandgap(void) {
|
||||
return ADC_ReadChannel(0x0E); /* 内部带隙基准 */
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* IAP/EEPROM 操作
|
||||
* ======================================================================== */
|
||||
@@ -701,323 +632,6 @@ static void PWM_SetAllFailsafe(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* NRF24L01 硬件 SPI 实现 (STC8H 内置 SPI)
|
||||
* P1.3=MISO, P1.4=MOSI, P1.5=SCLK, P5.4=CSN(GPIO)
|
||||
* ======================================================================== */
|
||||
|
||||
/* SPI 初始化: 主模式, 模式0, 6MHz @ 24MHz */
|
||||
static void NRF_SPI_Init(void) {
|
||||
SPCTL = SSIG | SPEN | MSTR; /* 0xD0: SSIG=1, SPEN=1, MSTR=1, CPOL=0, CPHA=0, fosc/4 */
|
||||
SPSTAT = SPIF | WCOL; /* 清除标志 */
|
||||
}
|
||||
|
||||
uint8_t NRF_SPI_TransferByte(uint8_t dat) {
|
||||
SPDAT = dat;
|
||||
/* 等待传输完成 */
|
||||
while (!(SPSTAT & SPIF));
|
||||
/* 清除 SPIF (读 SPSTAT 再读 SPDAT 自动清除, 但这里直接写1清除更可靠) */
|
||||
SPSTAT = SPIF;
|
||||
return SPDAT;
|
||||
}
|
||||
|
||||
uint8_t NRF24L01_ReadReg(uint8_t reg) {
|
||||
uint8_t val;
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_R_REGISTER | reg);
|
||||
val = NRF_SPI_TransferByte(0xFF);
|
||||
NRF_CSN = 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
void NRF24L01_WriteReg(uint8_t reg, uint8_t value) {
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_W_REGISTER | reg);
|
||||
NRF_SPI_TransferByte(value);
|
||||
NRF_CSN = 1;
|
||||
}
|
||||
|
||||
void NRF24L01_ReadBuf(uint8_t reg, uint8_t *buf, uint8_t len) {
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_R_REGISTER | reg);
|
||||
for (uint8_t i = 0; i < len; i++)
|
||||
buf[i] = NRF_SPI_TransferByte(0xFF);
|
||||
NRF_CSN = 1;
|
||||
}
|
||||
|
||||
void NRF24L01_WriteBuf(uint8_t reg, const uint8_t *buf, uint8_t len) {
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_W_REGISTER | reg);
|
||||
for (uint8_t i = 0; i < len; i++)
|
||||
NRF_SPI_TransferByte(buf[i]);
|
||||
NRF_CSN = 1;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* NRF24L01 初始化与操作
|
||||
* ======================================================================== */
|
||||
|
||||
void NRF24L01_Init(void) {
|
||||
NRF_CE = 0;
|
||||
NRF_CSN = 1;
|
||||
|
||||
/* 初始化硬件 SPI */
|
||||
NRF_SPI_Init();
|
||||
|
||||
/* 延时等待上电 */
|
||||
for (volatile uint16_t d = 0; d < 5000; d++);
|
||||
|
||||
/* 配置寄存器 */
|
||||
NRF24L01_WriteReg(NRF_CONFIG, 0x0E); /* EN_CRC, CRC0, PWR_UP, PTX */
|
||||
NRF24L01_WriteReg(NRF_EN_AA, 0x01); /* Pipe0 auto ACK */
|
||||
NRF24L01_WriteReg(NRF_EN_RXADDR, 0x01); /* Pipe0 enable */
|
||||
NRF24L01_WriteReg(NRF_SETUP_AW, 0x03); /* 5字节地址 */
|
||||
NRF24L01_WriteReg(NRF_SETUP_RETR, 0x1A); /* 500us + 15次重试 */
|
||||
NRF24L01_WriteReg(NRF_RF_CH, rf_channel);
|
||||
NRF24L01_WriteReg(NRF_RF_SETUP, NRF_RATE_1M | NRF_PA_MAX);
|
||||
NRF24L01_WriteReg(NRF_RX_PW_P0, RF_PACKET_SIZE);
|
||||
NRF24L01_WriteReg(NRF_DYNPD, 0x00); /* 关闭动态负载 */
|
||||
NRF24L01_WriteReg(NRF_FEATURE, 0x00);
|
||||
|
||||
/* 设置地址 */
|
||||
NRF24L01_WriteBuf(NRF_TX_ADDR, tx_addr, NRF_ADDR_WIDTH);
|
||||
NRF24L01_WriteBuf(NRF_RX_ADDR_P0, tx_addr, NRF_ADDR_WIDTH);
|
||||
|
||||
/* 清空FIFO */
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_FLUSH_TX);
|
||||
NRF_CSN = 1;
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_FLUSH_RX);
|
||||
NRF_CSN = 1;
|
||||
|
||||
/* 清除状态 */
|
||||
NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT);
|
||||
|
||||
NRF_CE = 0;
|
||||
}
|
||||
|
||||
uint8_t NRF24L01_Check(void) {
|
||||
uint8_t buf[5] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
|
||||
uint8_t rx[5];
|
||||
NRF24L01_WriteBuf(NRF_TX_ADDR, buf, 5);
|
||||
NRF24L01_ReadBuf(NRF_TX_ADDR, rx, 5);
|
||||
for (uint8_t i = 0; i < 5; i++)
|
||||
if (rx[i] != 0xA5) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NRF24L01_SetChannel(uint8_t ch) {
|
||||
if (ch > NRF_MAX_CHANNEL) ch = NRF_MAX_CHANNEL;
|
||||
rf_channel = ch;
|
||||
NRF24L01_WriteReg(NRF_RF_CH, ch);
|
||||
}
|
||||
|
||||
void NRF24L01_SetRXAddr(uint8_t pipe, const uint8_t *addr) {
|
||||
if (pipe > 5) return;
|
||||
if (pipe < 2) {
|
||||
NRF24L01_WriteBuf(NRF_RX_ADDR_P0 + pipe, addr, NRF_ADDR_WIDTH);
|
||||
} else {
|
||||
NRF24L01_WriteReg(NRF_RX_ADDR_P0 + pipe, addr[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void NRF24L01_RXMode(void) {
|
||||
NRF_CE = 0;
|
||||
uint8_t cfg = NRF24L01_ReadReg(NRF_CONFIG);
|
||||
cfg |= 0x01; /* PRIM_RX = 1 */
|
||||
NRF24L01_WriteReg(NRF_CONFIG, cfg);
|
||||
NRF_CE = 1;
|
||||
}
|
||||
|
||||
void NRF24L01_TXMode(void) {
|
||||
NRF_CE = 0;
|
||||
uint8_t cfg = NRF24L01_ReadReg(NRF_CONFIG);
|
||||
cfg &= ~0x01; /* PRIM_RX = 0 */
|
||||
NRF24L01_WriteReg(NRF_CONFIG, cfg);
|
||||
NRF_CE = 1;
|
||||
}
|
||||
|
||||
uint8_t NRF24L01_IsDataReady(void) {
|
||||
uint8_t status = NRF24L01_ReadReg(NRF_STATUS);
|
||||
return (status & NRF_STATUS_RX_DR) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint8_t NRF24L01_RxPacket(uint8_t *data) {
|
||||
uint8_t status = NRF24L01_ReadReg(NRF_STATUS);
|
||||
if (!(status & NRF_STATUS_RX_DR)) return 0;
|
||||
|
||||
/* 读取payload */
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_R_RX_PAYLOAD);
|
||||
for (uint8_t i = 0; i < RF_PACKET_SIZE; i++)
|
||||
data[i] = NRF_SPI_TransferByte(0xFF);
|
||||
NRF_CSN = 1;
|
||||
|
||||
/* 清除 RX_DR */
|
||||
NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_RX_DR);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NRF24L01_FlushRX(void) {
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_FLUSH_RX);
|
||||
NRF_CSN = 1;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* NRF24L01 对频
|
||||
* ======================================================================== */
|
||||
|
||||
void NRF24L01_EnterBindMode(void) {
|
||||
/* 进入接收模式, 监听对频请求 */
|
||||
NRF_CE = 0;
|
||||
NRF24L01_WriteReg(NRF_CONFIG, 0x0F); /* PRX, PWR_UP, CRC */
|
||||
NRF24L01_WriteReg(NRF_EN_RXADDR, 0x01);
|
||||
NRF24L01_WriteReg(NRF_RX_PW_P0, RF_PACKET_SIZE);
|
||||
NRF24L01_WriteBuf(NRF_RX_ADDR_P0, tx_addr, NRF_ADDR_WIDTH);
|
||||
NRF24L01_WriteReg(NRF_STATUS, 0x70);
|
||||
NRF_CE = 1;
|
||||
}
|
||||
|
||||
void NRF_EnterBindMode(void) {
|
||||
rx_state = RX_STATE_BINDING;
|
||||
NRF24L01_EnterBindMode();
|
||||
}
|
||||
|
||||
uint8_t NRF_DoBindScan(void) {
|
||||
static uint8_t __xdata buf[RF_PACKET_SIZE];
|
||||
|
||||
/* 扫描所有通道 */
|
||||
for (uint8_t ch = 0; ch <= NRF_MAX_CHANNEL; ch++) {
|
||||
NRF24L01_SetChannel(ch);
|
||||
for (volatile uint16_t d = 0; d < 500; d++); /* 延时 */
|
||||
|
||||
if (NRF24L01_RxPacket(buf)) {
|
||||
/* 验证同步头 */
|
||||
if (buf[0] != RF_SYNC_BYTE0 || buf[1] != RF_SYNC_BYTE1)
|
||||
continue;
|
||||
|
||||
/* 验证对频短语 (6字节, 从偏移2开始) */
|
||||
uint8_t match = 1;
|
||||
for (uint8_t i = 0; i < RF_PHRASE_LEN; i++) {
|
||||
if (buf[2 + i] != bind_phrase[i]) {
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) continue;
|
||||
|
||||
/* 对频成功! 从包中提取地址 (偏移8开始, 5字节) */
|
||||
for (uint8_t i = 0; i < NRF_ADDR_WIDTH; i++) {
|
||||
tx_addr[i] = buf[8 + i];
|
||||
}
|
||||
|
||||
/* 保存配置到EEPROM */
|
||||
EEPROM_SaveConfig();
|
||||
|
||||
/* 重新初始化NRF */
|
||||
NRF24L01_Init();
|
||||
NRF24L01_RXMode();
|
||||
|
||||
rx_state = RX_STATE_DISCONNECTED;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* NRF24L01 数据包处理
|
||||
* ======================================================================== */
|
||||
|
||||
void NRF_ProcessPacket(void) {
|
||||
static uint8_t __xdata buf[RF_PACKET_SIZE];
|
||||
|
||||
if (!NRF24L01_RxPacket(buf))
|
||||
return;
|
||||
|
||||
/* 验证同步头 */
|
||||
if (buf[0] != RF_SYNC_BYTE0 || buf[1] != RF_SYNC_BYTE1)
|
||||
return;
|
||||
|
||||
/* 验证对频短语 */
|
||||
for (uint8_t i = 0; i < RF_PHRASE_LEN; i++) {
|
||||
if (buf[2 + i] != bind_phrase[i])
|
||||
return;
|
||||
}
|
||||
|
||||
/* 验证校验和 (XOR) */
|
||||
uint8_t checksum = 0;
|
||||
for (uint8_t i = 0; i < RF_PACKET_SIZE - 1; i++)
|
||||
checksum ^= buf[i];
|
||||
if (checksum != buf[RF_PACKET_SIZE - 1])
|
||||
return;
|
||||
|
||||
/* 提取通道数据 (8通道, 偏移8, 每通道2字节大端) */
|
||||
for (uint8_t i = 0; i < CHANNEL_COUNT; i++) {
|
||||
uint16_t raw = ((uint16_t)buf[8 + i * 2] << 8) | buf[8 + i * 2 + 1];
|
||||
/* raw: 0~2000, 映射到 PWM_MIN~PWM_MAX (250~500) */
|
||||
if (raw > 2000) raw = 2000;
|
||||
pwm_ch[i] = (uint16_t)((uint32_t)raw * (PWM_MAX - PWM_MIN) / 2000 + PWM_MIN);
|
||||
}
|
||||
|
||||
/* 更新 RSSI 估计: 从 NRF RPD 寄存器读取载波检测 */
|
||||
if (NRF24L01_ReadReg(NRF_RPD) & 0x01) {
|
||||
/* 有载波 = 信号强 */
|
||||
if (telem_rssi < 100) telem_rssi += 5;
|
||||
} else {
|
||||
if (telem_rssi > 10) telem_rssi -= 1;
|
||||
}
|
||||
if (telem_rssi > 100) telem_rssi = 100;
|
||||
|
||||
/* 更新丢包率: 基于 lost_packet_cnt 估算 */
|
||||
telem_packet_loss = 0; /* 收到包 = 当前不丢包, 累积值在外部计算 */
|
||||
|
||||
/* 更新状态 */
|
||||
lost_packet_cnt = 0;
|
||||
if (rx_state != RX_STATE_CONNECTED) {
|
||||
rx_state = RX_STATE_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* NRF24L01 回传发送
|
||||
* 包格式: 0xBB 0x44 + voltage(2B) + rssi(1B) + loss(1B) + temp(2B)
|
||||
* ======================================================================== */
|
||||
|
||||
static void NRF_SendTelemetry(void) {
|
||||
static uint8_t __xdata tbuf[8];
|
||||
|
||||
tbuf[0] = 0xBB; /* sync0 */
|
||||
tbuf[1] = 0x44; /* sync1 */
|
||||
tbuf[2] = (uint8_t)(bat_voltage_mv >> 8); /* voltage high */
|
||||
tbuf[3] = (uint8_t)(bat_voltage_mv & 0xFF); /* voltage low */
|
||||
tbuf[4] = telem_rssi; /* RSSI */
|
||||
tbuf[5] = telem_packet_loss; /* 丢包率 */
|
||||
tbuf[6] = 0; /* temp high (未实现) */
|
||||
tbuf[7] = 0; /* temp low */
|
||||
|
||||
/* 切到 TX 模式发送回传 */
|
||||
NRF24L01_TXMode();
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_FLUSH_TX);
|
||||
NRF_CSN = 1;
|
||||
NRF_CSN = 0;
|
||||
NRF_SPI_TransferByte(NRF_CMD_W_TX_PAYLOAD);
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
NRF_SPI_TransferByte(tbuf[i]);
|
||||
NRF_CSN = 1;
|
||||
NRF_CE = 1;
|
||||
for (volatile uint16_t d = 0; d < 100; d++);
|
||||
NRF_CE = 0;
|
||||
|
||||
/* 切回 RX 模式 */
|
||||
NRF24L01_RXMode();
|
||||
NRF24L01_FlushRX();
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* 串口命令解析
|
||||
* ======================================================================== */
|
||||
@@ -1304,8 +918,8 @@ void main(void) {
|
||||
telem_frame[0] = 0xEE;
|
||||
telem_frame[1] = 10; /* len */
|
||||
telem_frame[2] = 0x08; /* Battery sensor */
|
||||
telem_frame[3] = (uint8_t)(bat_voltage_mv >> 8); /* voltage high (mV*10) */
|
||||
telem_frame[4] = (uint8_t)(bat_voltage_mv & 0xFF); /* voltage low */
|
||||
telem_frame[3] = (uint8_t)((bat_voltage_mv / 10) >> 8); /* voltage high (10mV单位) */
|
||||
telem_frame[4] = (uint8_t)((bat_voltage_mv / 10) & 0xFF); /* voltage low */
|
||||
telem_frame[5] = 0; /* current high */
|
||||
telem_frame[6] = 0; /* current low */
|
||||
telem_frame[7] = 0; /* capacity */
|
||||
@@ -1370,9 +984,22 @@ void main(void) {
|
||||
static uint16_t last_adc_tick = 0;
|
||||
if (sys_tick - last_adc_tick >= 100) {
|
||||
last_adc_tick = sys_tick;
|
||||
bat_voltage_mv = ADC_Read();
|
||||
/* 粗略转换: 12位ADC, Vref=VCC, 分压比取决于硬件 */
|
||||
/* 这里保留原始ADC值, 上位机或飞控自行换算 */
|
||||
|
||||
/* 读取电池分压 ADC (P3.3/ADC11) */
|
||||
uint16_t bat_adc = ADC_Read();
|
||||
|
||||
/* 读取内部带隙基准 (通道14), 反算 VCC */
|
||||
uint16_t bg_adc = ADC_ReadBandgap();
|
||||
|
||||
/* VCC(mV) = 1190 * 4096 / bg_adc
|
||||
* V_bat(mV) = bat_adc * VCC / 4096 * 11 (分压比 1K:10K = 1/11)
|
||||
* 合并: V_bat(mV) = bat_adc * 1190 * 11 / bg_adc
|
||||
* = bat_adc * 13090 / bg_adc
|
||||
*/
|
||||
if (bg_adc > 0) {
|
||||
uint32_t tmp = (uint32_t)bat_adc * 13090UL / bg_adc;
|
||||
bat_voltage_mv = (uint16_t)tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* 更新LED */
|
||||
|
||||
Reference in New Issue
Block a user