feat: add STM8 mesh relay firmware
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file adc_current.h
|
||||
* @brief ACS712 电流采样服务接口。
|
||||
*
|
||||
* PC4 接收经过 R3/R4 1:1 分压后的 ACS712 VIOUT。业务层只能读取经过
|
||||
* 零点校准、RMS 计算和比例换算后的实际 mA 值,不得直接把 ADC 原始值
|
||||
* 当作电流上报。
|
||||
*/
|
||||
#ifndef ADC_CURRENT_H
|
||||
#define ADC_CURRENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化 PC4 ADC 和采样服务状态。 */
|
||||
void Current_Init(void);
|
||||
|
||||
/** 执行一次后台采样任务。 */
|
||||
void Current_Task(void);
|
||||
|
||||
/** 返回最近一次计算得到的实际电流,单位为 mA。 */
|
||||
uint16_t Current_GetMilliAmpere(void);
|
||||
|
||||
/** 返回零点和 RMS 窗口是否已经准备完成。 */
|
||||
uint8_t Current_IsReady(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file app_config.h
|
||||
* @brief STM8 蓝牙 Mesh 继电器固件的统一配置入口。
|
||||
*
|
||||
* 本文件集中保存当前已经确认的协议和业务常量,避免在多个 C 文件中
|
||||
* 重复定义相同数字。后续接入真实寄存器时,硬件相关宏也应优先放在此处
|
||||
* 或独立的 board_config.h 中,便于人工维护和更换 PCB。
|
||||
*/
|
||||
#ifndef APP_CONFIG_H
|
||||
#define APP_CONFIG_H
|
||||
|
||||
/** 系统节拍周期,单位为毫秒。 */
|
||||
#define SYSTEM_TICK_MS 1u
|
||||
/** JDY-28M 与 STM8 固定通信波特率。 */
|
||||
#define JDY28M_UART_BAUDRATE 9600ul
|
||||
/** PWRC 拉低后进入 AT 指令窗口的等待时间。 */
|
||||
#define JDY28M_AT_ENTRY_WAIT_MS 10ul
|
||||
/** JDY-28M RESET 低电平脉冲时间。 */
|
||||
#define JDY28M_RESET_PULSE_MS 500ul
|
||||
/** 释放 RESET 后等待模块启动完成的时间。 */
|
||||
#define JDY28M_RESET_STARTUP_WAIT_MS 1500ul
|
||||
|
||||
/** 默认电流阈值,单位为 mA。 */
|
||||
#define DEFAULT_CURRENT_THRESHOLD_MA 100u
|
||||
|
||||
/** 电流故障产生和恢复的连续确认时间,单位为毫秒。 */
|
||||
#define CURRENT_FAULT_CONFIRM_MS 10000ul
|
||||
|
||||
/** Mesh 状态连续确认时间,单位为毫秒。 */
|
||||
#define MESH_STATUS_CONFIRM_MS 3000ul
|
||||
|
||||
/** 蓝牙初始化故障 LED 的亮灭周期,单位为毫秒。 */
|
||||
#define LED_INIT_FAULT_PERIOD_MS 300ul
|
||||
|
||||
/** 未组网 LED 的亮灭周期,单位为毫秒。 */
|
||||
#define LED_NOT_JOINED_PERIOD_MS 1000ul
|
||||
|
||||
/** ACS712 采样建议使用的 RMS 窗口,单位为毫秒。 */
|
||||
#define CURRENT_RMS_WINDOW_MS 100ul
|
||||
|
||||
/** 业务协议帧头第一个字节。 */
|
||||
#define BUSINESS_FRAME_HEAD_0 0x55u
|
||||
|
||||
/** 业务协议帧头第二个字节。 */
|
||||
#define BUSINESS_FRAME_HEAD_1 0xAAu
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @file bluetooth_manager.h
|
||||
* @brief JDY-28M 上电初始化、短地址查询和 LED 状态管理接口。
|
||||
*/
|
||||
#ifndef BLUETOOTH_MANAGER_H
|
||||
#define BLUETOOTH_MANAGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化蓝牙管理状态机。 */
|
||||
void BluetoothManager_Init(void);
|
||||
|
||||
/** 执行一次非阻塞蓝牙初始化和 LED 状态任务。 */
|
||||
void BluetoothManager_Task(void);
|
||||
|
||||
/** 返回蓝牙初始化是否成功。 */
|
||||
uint8_t BluetoothManager_IsReady(void);
|
||||
|
||||
/** 返回蓝牙初始化故障状态。 */
|
||||
uint8_t BluetoothManager_IsFault(void);
|
||||
|
||||
/** 返回最近一次查询到的短地址。 */
|
||||
uint16_t BluetoothManager_GetShortAddress(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief 蓝牙 Mesh 继电器硬件板级接口定义。
|
||||
*
|
||||
* 本阶段先提供稳定的硬件抽象接口,不在业务层直接操作 GPIO 寄存器。
|
||||
* PA1 的有效电平已经确认:高电平吸合、低电平断开;PD3 高电平点亮 LED3。
|
||||
*/
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化 GPIO、时钟和板级默认安全状态。 */
|
||||
void Board_Init(void);
|
||||
|
||||
/** 设置继电器目标输出状态,1 表示吸合,0 表示断开。 */
|
||||
void Board_SetRelay(uint8_t on);
|
||||
|
||||
/** 读取当前继电器控制输出状态,1 表示吸合,0 表示断开。 */
|
||||
uint8_t Board_GetRelay(void);
|
||||
|
||||
/** 读取 JDY-28M STAT 状态,1 表示模块报告已组网。 */
|
||||
uint8_t Board_ReadMeshJoined(void);
|
||||
|
||||
/** 设置 LED3 点亮状态,1 表示点亮,0 表示熄灭。 */
|
||||
void Board_SetLed3(uint8_t on);
|
||||
|
||||
/** 设置 PWRC:1 表示拉低进入 AT 窗口,0 表示恢复高电平通信。 */
|
||||
void Board_SetBluetoothAtWindow(uint8_t enabled);
|
||||
|
||||
/** 设置 RESET:1 表示拉低复位,0 表示释放复位。 */
|
||||
void Board_SetBluetoothReset(uint8_t reset_active);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file business_protocol.h
|
||||
* @brief STM8 业务帧协议接口。
|
||||
*
|
||||
* 业务帧格式:0x55 0xAA | CMD | LEN | DATA | CRC16。
|
||||
* CRC 使用 CRC-16/MODBUS,计算范围为 CMD 至 DATA,低字节在前。
|
||||
*/
|
||||
#ifndef BUSINESS_PROTOCOL_H
|
||||
#define BUSINESS_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 业务帧最大 DATA 长度,需为 JDY-28M 外层 20 字节限制预留空间。 */
|
||||
#define BUSINESS_MAX_DATA_LENGTH 4u
|
||||
|
||||
/** 业务帧头长度。 */
|
||||
#define BUSINESS_FRAME_HEADER_LENGTH 2u
|
||||
|
||||
/** 业务命令:继电器控制。 */
|
||||
#define CMD_RELAY_CONTROL 0x01u
|
||||
|
||||
/** 业务命令:查询继电器状态。 */
|
||||
#define CMD_RELAY_QUERY 0x02u
|
||||
|
||||
/** 业务命令:查询实际电流。 */
|
||||
#define CMD_CURRENT_QUERY 0x03u
|
||||
|
||||
/** 业务命令:故障/恢复上报。 */
|
||||
#define CMD_FAULT_REPORT 0x04u
|
||||
|
||||
/** 业务命令:短地址查询。 */
|
||||
#define CMD_ADDRESS_QUERY 0x05u
|
||||
|
||||
/** 业务命令:电流阈值配置。 */
|
||||
#define CMD_THRESHOLD_CONFIG 0x06u
|
||||
|
||||
/** 应答命令基值,具体应答为请求命令加 0x80。 */
|
||||
#define CMD_RESPONSE_FLAG 0x80u
|
||||
|
||||
/** 通用错误应答命令。 */
|
||||
#define CMD_ERROR_RESPONSE 0xE0u
|
||||
|
||||
/** CRC 校验失败时静默丢弃,不生成业务错误应答。 */
|
||||
#define BUSINESS_PARSE_CRC_ERROR 0x01u
|
||||
|
||||
/** 业务帧解析结果:没有完整帧。 */
|
||||
#define BUSINESS_PARSE_INCOMPLETE 0x00u
|
||||
|
||||
/** 业务帧解析结果:收到并通过 CRC 校验。 */
|
||||
#define BUSINESS_PARSE_FRAME_READY 0x01u
|
||||
|
||||
/** 业务帧解析器初始化。 */
|
||||
void BusinessProtocol_Init(void);
|
||||
|
||||
/** 处理 UART 输入和待发送业务帧。 */
|
||||
void BusinessProtocol_Task(void);
|
||||
|
||||
/**
|
||||
* 向解析器输入一个字节。
|
||||
*
|
||||
* 该接口只负责解析内层业务帧,不执行继电器动作,也不负责 JDY-28M
|
||||
* 外层 Mesh 封装。外层模块应在确认 `F1 DD 09 00 0A ... 0D 0A` 后,
|
||||
* 将其中的业务数据逐字节送入本接口。
|
||||
*
|
||||
* @param value 输入字节。
|
||||
* @return 1 表示刚刚形成一帧合法业务帧,0 表示尚未形成完整帧。
|
||||
*/
|
||||
uint8_t BusinessProtocol_InputByte(uint8_t value);
|
||||
|
||||
/** 读取最近一帧合法业务帧的命令字。 */
|
||||
uint8_t BusinessProtocol_GetCommand(void);
|
||||
|
||||
/** 读取最近一帧合法业务帧的数据长度。 */
|
||||
uint8_t BusinessProtocol_GetDataLength(void);
|
||||
|
||||
/** 读取最近一帧合法业务帧的数据区;返回 0 表示下标越界。 */
|
||||
uint8_t BusinessProtocol_GetDataByte(uint8_t index, uint8_t *value);
|
||||
|
||||
/** 执行最近一帧已经通过校验的业务命令,并向源地址返回应答。 */
|
||||
void BusinessProtocol_HandleFrame(uint16_t source_address);
|
||||
|
||||
/** CRC-16/MODBUS 计算函数,输入范围不包含业务帧头。 */
|
||||
uint16_t BusinessProtocol_Crc16Modbus(const uint8_t *data, uint16_t length);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file fault_manager.h
|
||||
* @brief 继电器状态与 ACS712 电流状态的故障判定接口。
|
||||
*
|
||||
* 本模块只依据“继电器控制输出状态”和“ACS712 已换算后的实际电流值”
|
||||
* 做软件诊断,不声称能够证明继电器机械触点一定闭合。因为当前硬件没有
|
||||
* 触点反馈,继电器吸合失败最终只能通过“吸合后没有有效电流”间接发现。
|
||||
*/
|
||||
#ifndef FAULT_MANAGER_H
|
||||
#define FAULT_MANAGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化故障判定状态机。 */
|
||||
void FaultManager_Init(void);
|
||||
|
||||
/** 周期性执行电流故障确认、恢复确认和未确认重发。 */
|
||||
void FaultManager_Task(void);
|
||||
|
||||
/** 收到主机对故障/恢复上报的 ACK 后调用。 */
|
||||
void FaultManager_OnReportAck(uint8_t fault_code);
|
||||
|
||||
/** 设置运行期电流阈值;单位 mA。 */
|
||||
uint8_t FaultManager_SetThreshold(uint16_t threshold_ma);
|
||||
|
||||
/** 获取当前电流阈值;单位 mA。 */
|
||||
uint16_t FaultManager_GetThreshold(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file mesh_frame.h
|
||||
* @brief JDY-28M Mesh 外层帧解析和发送接口。
|
||||
*/
|
||||
#ifndef MESH_FRAME_H
|
||||
#define MESH_FRAME_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** JDY-28M 外层完整帧最大长度,包含帧头、地址、数据和 0D 0A。 */
|
||||
#define JDY_MESH_FRAME_MAX_LENGTH 20u
|
||||
|
||||
/** 初始化 JDY-28M 外层帧状态机。 */
|
||||
void MeshFrame_Init(void);
|
||||
|
||||
/** 从 UART 接收并解析 JDY-28M 外层帧。 */
|
||||
void MeshFrame_Task(void);
|
||||
|
||||
/** 返回最近一帧合法数据的源短地址。 */
|
||||
uint16_t MeshFrame_GetLastSourceAddress(void);
|
||||
|
||||
/**
|
||||
* 封装并发送一帧 Mesh 业务数据。
|
||||
*
|
||||
* @param target_address 目标短地址,0xFFFF 表示广播。
|
||||
* @param command 业务命令。
|
||||
* @param data 业务数据,可为 NULL(此时 length 必须为 0)。
|
||||
* @param length 业务数据长度,当前不能超过 4 字节。
|
||||
* @return 1 表示已发送,0 表示参数超出 20 字节外层限制。
|
||||
*/
|
||||
uint8_t MeshFrame_SendBusiness(uint16_t target_address,
|
||||
uint8_t command,
|
||||
const uint8_t *data,
|
||||
uint8_t length);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @file nonvolatile_config.h
|
||||
* @brief STM8 Data EEPROM 中的设备配置接口。
|
||||
*/
|
||||
#ifndef NONVOLATILE_CONFIG_H
|
||||
#define NONVOLATILE_CONFIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化 EEPROM 配置访问状态。 */
|
||||
void NonvolatileConfig_Init(void);
|
||||
|
||||
/** 读取保存的电流阈值;无效时返回 0。 */
|
||||
uint16_t NonvolatileConfig_ReadThreshold(void);
|
||||
|
||||
/** 保存电流阈值;返回 1 表示写入并回读校验成功。 */
|
||||
uint8_t NonvolatileConfig_WriteThreshold(uint16_t threshold_ma);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file stm8s003_registers.h
|
||||
* @brief STM8S003F3 常用外设寄存器的最小定义集。
|
||||
*
|
||||
* 本工程暂不引入完整厂商库,先使用经过数据手册地址核对的最小寄存器集。
|
||||
* 后续如果切换到 ST 标准外设库,只应替换本文件和 drivers 层,不改变业务层接口。
|
||||
*/
|
||||
#ifndef STM8S003_REGISTERS_H
|
||||
#define STM8S003_REGISTERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* GPIO 端口寄存器布局:ODR、IDR、DDR、CR1、CR2。 */
|
||||
#define GPIOA_ODR_ADDR 0x5000u
|
||||
#define GPIOA_IDR_ADDR 0x5001u
|
||||
#define GPIOA_DDR_ADDR 0x5002u
|
||||
#define GPIOA_CR1_ADDR 0x5003u
|
||||
#define GPIOA_CR2_ADDR 0x5004u
|
||||
#define GPIOC_ODR_ADDR 0x500Au
|
||||
#define GPIOC_IDR_ADDR 0x500Bu
|
||||
#define GPIOC_DDR_ADDR 0x500Cu
|
||||
#define GPIOC_CR1_ADDR 0x500Du
|
||||
#define GPIOC_CR2_ADDR 0x500Eu
|
||||
#define GPIOD_ODR_ADDR 0x500Fu
|
||||
#define GPIOD_IDR_ADDR 0x5010u
|
||||
#define GPIOD_DDR_ADDR 0x5011u
|
||||
#define GPIOD_CR1_ADDR 0x5012u
|
||||
#define GPIOD_CR2_ADDR 0x5013u
|
||||
|
||||
/* UART1 寄存器地址。 */
|
||||
#define UART1_SR_ADDR 0x5230u
|
||||
#define UART1_DR_ADDR 0x5231u
|
||||
#define UART1_BRR1_ADDR 0x5232u
|
||||
#define UART1_BRR2_ADDR 0x5233u
|
||||
#define UART1_CR1_ADDR 0x5234u
|
||||
#define UART1_CR2_ADDR 0x5235u
|
||||
#define UART1_CR3_ADDR 0x5236u
|
||||
#define UART1_CR4_ADDR 0x5237u
|
||||
#define UART1_CR5_ADDR 0x5238u
|
||||
|
||||
/* ADC1 寄存器地址。 */
|
||||
#define ADC1_CSR_ADDR 0x5400u
|
||||
#define ADC1_CR1_ADDR 0x5401u
|
||||
#define ADC1_CR2_ADDR 0x5402u
|
||||
#define ADC1_CR3_ADDR 0x5403u
|
||||
#define ADC1_DRH_ADDR 0x5404u
|
||||
#define ADC1_DRL_ADDR 0x5405u
|
||||
|
||||
/* TIM4 低功耗 8 位定时器寄存器地址。 */
|
||||
#define TIM4_CR1_ADDR 0x5340u
|
||||
#define TIM4_IER_ADDR 0x5343u
|
||||
#define TIM4_SR1_ADDR 0x5344u
|
||||
#define TIM4_EGR_ADDR 0x5345u
|
||||
#define TIM4_CNTR_ADDR 0x5346u
|
||||
#define TIM4_PSCR_ADDR 0x5347u
|
||||
#define TIM4_ARR_ADDR 0x5348u
|
||||
|
||||
/* 独立看门狗寄存器。 */
|
||||
#define IWDG_KR_ADDR 0x50E0u
|
||||
#define IWDG_PR_ADDR 0x50E1u
|
||||
#define IWDG_RLR_ADDR 0x50E2u
|
||||
|
||||
#define REG8(address) (*((volatile uint8_t *)(address)))
|
||||
|
||||
#define PA1_MASK 0x02u
|
||||
#define PC3_MASK 0x08u
|
||||
#define PC4_MASK 0x10u
|
||||
/** PC4 在 STM8S003F3P6 上对应 ADC1 的 AIN2 通道。 */
|
||||
#define ADC1_CHANNEL_PC4 2u
|
||||
#define PD3_MASK 0x08u
|
||||
#define PD5_MASK 0x20u
|
||||
#define PD6_MASK 0x40u
|
||||
#define PC5_MASK 0x20u
|
||||
#define PC6_MASK 0x40u
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @file system_tick.h
|
||||
* @brief 1 ms 系统节拍接口。
|
||||
*/
|
||||
#ifndef SYSTEM_TICK_H
|
||||
#define SYSTEM_TICK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化系统节拍定时器。 */
|
||||
void SystemTick_Init(void);
|
||||
|
||||
/** 返回系统启动后经过的毫秒数。 */
|
||||
uint32_t SystemTick_NowMs(void);
|
||||
|
||||
/** 在定时器中断服务程序中递增系统节拍。 */
|
||||
void SystemTick_InterruptHandler(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @file uart1.h
|
||||
* @brief JDY-28M 使用的 UART1 抽象接口。
|
||||
*/
|
||||
#ifndef UART1_H
|
||||
#define UART1_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化 UART1。具体波特率和寄存器配置在底层阶段接入。 */
|
||||
void Uart1_Init(void);
|
||||
|
||||
/** 轮询 UART1 硬件状态并把收到的字节放入环形缓冲区。 */
|
||||
void Uart1_Task(void);
|
||||
|
||||
/** 向 UART1 发送一个字节。 */
|
||||
void Uart1_WriteByte(uint8_t value);
|
||||
|
||||
/** 尝试读取一个接收字节,返回 1 表示读取成功。 */
|
||||
uint8_t Uart1_ReadByte(uint8_t *value);
|
||||
|
||||
/** 返回接收环形缓冲区中尚未读取的字节数。 */
|
||||
uint8_t Uart1_Available(void);
|
||||
|
||||
/** UART1 接收中断处理入口。 */
|
||||
void Uart1_InterruptHandler(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
/** @file watchdog.h @brief STM8 独立看门狗接口。 */
|
||||
#ifndef WATCHDOG_H
|
||||
#define WATCHDOG_H
|
||||
|
||||
/** 初始化约 5 秒独立看门狗。 */
|
||||
void Watchdog_Init(void);
|
||||
|
||||
/** 在主循环中刷新看门狗计数器。 */
|
||||
void Watchdog_Refresh(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user