以下是基于HC32L130F8UA和PAN3029的无线温湿度传感器设计方案,包含完整硬件驱动实现及Python数据解析代码:
HC32L130F8UA硬件驱动实现
// 系统时钟配置(使用内部低速时钟降低功耗)
void SystemClock_Config(void) {
stc_clock_xtal_init_t stcXtalInit;
MEM_ZERO_STRUCT(stcXtalInit);
CLOCK_XtalStructInit(&stcXtalInit);
CLOCK_XtalInit(&stcXtalInit);
CLOCK_SetClockDiv(ClkDiv1, ClkDiv1_1);
CLOCK_SetClockDiv(ClkDivSys, ClkDiv1_1);
CLOCK_HrcCmd(Enable);
CLOCK_SetSysClockSrc(ClkSysSrcHRC);
}
// PAN3029 SPI初始化
void PAN3029_SPI_Init(void) {
stc_spi_init_t stcSpiInit;
MEM_ZERO_STRUCT(stcSpiInit);
stcSpiInit.enClkDiv = SpiClkDiv8;
stcSpiInit.enDataWidth = SpiDataWidth8;
stcSpiInit.enTransDir = SpiTransDirFullDuplex;
stcSpiInit.enMsbFirst = SpiMsbFirst;
stcSpiInit.enSampleMode = SpiSampleModeOddEdge;
SPI_Init(M4_SPI1, &stcSpiInit);
SPI_Cmd(M4_SPI1, Enable);
}
// 温湿度传感器I2C初始化(以SHT30为例)
void SHT30_I2C_Init(void) {
stc_i2c_init_t stcI2cInit;
MEM_ZERO_STRUCT(stcI2cInit);
stcI2cInit.u32ClockDiv = I2cClockDiv16;
stcI2cInit.u32Baudrate = 100000;
I2C_Init(M4_I2C1, &stcI2cInit);
I2C_Cmd(M4_I2C1, Enable);
}
// ADC初始化(PTC/NTC采集)
void ADC_Init(void) {
stc_adc_init_t stcAdcInit;
MEM_ZERO_STRUCT(stcAdcInit);
stcAdcInit.u16ScanMode = AdcModeContinuous;
stcAdcInit.u16Resolution = AdcResolution12Bit;
ADC_Init(M4_ADC1, &stcAdcInit);
ADC_Cmd(M4_ADC1, Enable);
}
// 读取SHT30温湿度数据
int32_t SHT30_ReadData(float *temp, float *humi) {
uint8_t cmd[2] = {0x2C, 0x06};
uint8_t data[6] = {0};
I2C_WriteRead(M4_I2C1, SHT30_ADDR, cmd, 2, data, 6);
uint16_t tempRaw = (data[0] << 8) | data[1];
uint16_t humiRaw = (data[3] << 8) | data[4];
*temp = -45 + 175.0f * (tempRaw / 65535.0f);
*humi = 100.0f * (humiRaw / 65535.0f);
return 0;
}
// 读取PTC/NTC电阻值
void Read_PTC_NTC(uint16_t *ptcVal, uint16_t *ntcVal) {
ADC_ChannelCmd(M4_ADC1, AdcExInputCh8, Enable);
*ptcVal = ADC_GetConversionValue(M4_ADC1);
ADC_ChannelCmd(M4_ADC1, AdcExInputCh9, Enable);
*ntcVal = ADC_GetConversionValue(M4_ADC1);
}
// 数据帧打包
void PackSensorData(uint8_t *buf, uint16_t hostId, uint16_t netId,
float temp, float humi, uint16_t ptc, uint16_t ntc) {
uint8_t *p = buf;
uint16_t crc = 0;
*p++ = 0x68; // 帧头
*p++ = hostId >> 8;
*p++ = hostId & 0xFF;
*p++ = netId >> 8;
*p++ = netId & 0xFF;
uint8_t lenPos = p - buf;
*p++ = 0; // 长度占位
int16_t tempInt = (int16_t)(temp * 100);
int16_t humiInt = (int16_t)(humi * 100);
*p++ = tempInt >> 8;
*p++ = tempInt & 0xFF;
*p++ = humiInt >> 8;
*p++ = humiInt & 0xFF;
*p++ = ptc >> 8;
*p++ = ptc & 0xFF;
*p++ = ntc >> 8;
*p++ = ntc & 0xFF;
memset(p, 0, 32); // 预留数据
p += 32;
buf[lenPos] = p - buf - lenPos - 1; // 填充长度
crc = CRC16_Calculate(buf, p - buf);
*p++ = crc >> 8;
*p++ = crc & 0xFF;
*p++ = 0x16; // 结束符
}
// 主任务循环
void MainTask(void) {
float temp, humi;
uint16_t ptc, ntc;
uint8_t txBuf[64];
while(1) {
SHT30_ReadData(&temp, &humi);
Read_PTC_NTC(&ptc, &ntc);
PackSensorData(txBuf, 0x1234, 0x0001, temp, humi, ptc, ntc);
PAN3029_SendData(txBuf, p - txBuf);
LowPower_Sleep(1000); // 低功耗休眠1秒
}
}
Python串口数据采集实现
import serial
import time
import struct
from crcmod import mkCrcFun
class SensorCollector:
def __init__(self, port, baudrate=115200):
self.ser = serial.Serial(port, baudrate, timeout=1)
self.crc16 = mkCrcFun(0x18005, rev=True, initCrc=0xFFFF)
def parse_frame(self, data):
if len(data) < 12:
return None
if data[0] != 0x68 or data[-1] != 0x16:
return None
length = data[5]
if len(data) != 7 + length + 3: # 头5+长度1+数据+CRC2+尾1
return None
crc = self.crc16(data[:-3])
if crc != (data[-3] << 8) | data[-2]:
return None
host_id = (data[1] << 8) | data[2]
net_id = (data[3] << 8) | data[4]
temp = struct.unpack('>h', data[6:8])[0] / 100.0
humi = struct.unpack('>h', data[8:10])[0] / 100.0
ptc = (data[10] << 8) | data[11]
ntc = (data[12] << 8) | data[13]
return {
'host_id': host_id,
'net_id': net_id,
'temperature': temp,
'humidity': humi,
'ptc': ptc,
'ntc': ntc
}
def read_data(self):
buffer = bytearray()
while True:
byte = self.ser.read(1)
if not byte:
continue
buffer += byte
if len(buffer) > 0 and buffer[0] != 0x68:
buffer = bytearray()
continue
if len(buffer) > 5: # 已读取长度字段
expected_len = 7 + buffer[5] + 3
if len(buffer) >= expected_len:
frame = bytes(buffer[:expected_len])
buffer = buffer[expected_len:]
result = self.parse_frame(frame)
if result:
return result
if __name__ == "__main__":
collector = SensorCollector('COM3')
while True:
data = collector.read_data()
if data:
print(f"Host:{data['host_id']:04X} Net:{data['net_id']:04X} "
f"Temp:{data['temperature']:.2f}C Humi:{data['humidity']:.2f}% "
f"PTC:{data['ptc']} NTC:{data['ntc']}")
关键设计要点
- 低功耗实现策略
- 使用HC32L130的内置低功耗模式
- 传感器采集间隔期间进入STOP模式
- PAN3029采用休眠唤醒机制
- 数据采集精度处理
- SHT30采用16bit数据格式
- ADC采用12bit分辨率
- 温度数据放大100倍传输避免浮点
- 无线传输优化
- 数据包长度固定为50字节
- 采用CRC16校验保证可靠性
- PAN3029配置为透明传输模式
- Python解析工具特性
- 自动帧同步处理
- CRC校验验证
- 实时数据显示
- 支持多设备ID识别
完整工程需要根据实际硬件连接调整GPIO配置,PTC/NTC需要设计合适的分压电路,温度转换需根据具体传感器规格实现。
701

被折叠的 条评论
为什么被折叠?



