一、迪文屏通信协议封装
// 帧头定义
#define DWIN_HEAD1 0x5A
#define DWIN_HEAD2 0xA5
// 发送数据到指定地址(写变量存储器)
void DWIN_WriteData(uint16_t addr, uint8_t *data, uint8_t len)
{
uint8_t tx_buf[256];
uint8_t pos = 0;
tx_buf[pos++] = DWIN_HEAD1; // 帧头1
tx_buf[pos++] = DWIN_HEAD2; // 帧头2
tx_buf[pos++] = len + 3; // 数据长度(命令+地址+数据)
tx_buf[pos++] = 0x82; // 写变量存储器命令
tx_buf[pos++] = (addr >> 8) & 0xFF; // 地址高字节
tx_buf[pos++] = addr & 0xFF; // 地址低字节
for(uint8_t i = 0; i < len; i++) {
tx_buf[pos++] = data[i];
}
HAL_UART_Transmit(&huart1, tx_buf, pos, 100);
}
// 发送16位数据(单通道曲线数据)
void DWIN_WriteWord(uint16_t addr, uint16_t data)
{
uint8_t buf[2];
buf[0] = (data >> 8) & 0xFF; // 高字节在前
buf[1] = data & 0xFF;
DWIN_WriteData(addr, buf, 2);
}
// 发送32位数据(双精度或长整型)
void DWIN_WriteLong(uint16_t addr, uint32_t data)
{
uint8_t buf[4];
buf[0] = (data >> 24) & 0xFF;
buf[1] = (data >> 16) & 0xFF;
buf[2] = (data >> 8) & 0xFF;
buf[3] = data & 0xFF;
DWIN_WriteData(addr, buf, 4);
}
二、曲线数据发送(实时曲线方式)
迪文屏的实时曲线通常使用 0x9010-0x9FFF 区域作为通道缓冲区:
// 通道地址定义(根据DGUS工程设置调整)
#define CURVE_CH0_ADDR 0x9010 // 通道0基地址
#define CURVE_CH1_ADDR 0x9020 // 通道1基地址
#define CURVE_CH2_ADDR 0x9030 // 通道2基地址
#define CURVE_CH3_ADDR 0x9040 // 通道3基地址
// 发送曲线数据(Y轴数值,范围0-65535或根据量程调整)
void DWIN_SendCurveData(uint8_t channel, uint16_t value)
{
uint16_t addr;
switch(channel) {
case 0: addr = CURVE_CH0_ADDR; break;
case 1: addr = CURVE_CH1_ADDR; break;
case 2: addr = CURVE_CH2_ADDR; break;
case 3: addr = CURVE_CH3_ADDR; break;
default: return;
}
DWIN_WriteWord(addr, value);
}
// 批量发送曲线数据(提高刷新率)
void DWIN_SendCurveBatch(uint8_t channel, uint16_t *data, uint8_t count)
{
uint16_t addr;
switch(channel) {
case 0: addr = CURVE_CH0_ADDR; break;
case 1: addr = CURVE_CH1_ADDR; break;
case 2: addr = CURVE_CH2_ADDR; break;
case 3: addr = CURVE_CH3_ADDR; break;
default: return;
}
// 批量发送(迪文屏支持连续地址写入)
uint8_t tx_buf[256];
uint8_t pos = 0;
uint8_t len = count * 2; // 每个数据2字节
tx_buf[pos++] = 0x5A;
tx_buf[pos++] = 0xA5;
tx_buf[pos++] = len + 3; // 长度
tx_buf[pos++] = 0x82; // 写命令
tx_buf[pos++] = (addr >> 8) & 0xFF;
tx_buf[pos++] = addr & 0xFF;
for(uint8_t i = 0; i < count; i++) {
tx_buf[pos++] = (data[i] >> 8) & 0xFF;
tx_buf[pos++] = data[i] & 0xFF;
}
HAL_UART_Transmit(&huart1, tx_buf, pos, 100);
}
三、实际应用示例(ADC数据采集显示)
// ADC值转换为曲线Y坐标(假设ADC 12位,曲线高度300像素)
uint16_t ADC_To_CurveY(uint16_t adc_val)
{
// 映射:0-4095 -> 0-300(根据实际曲线控件高度调整)
return (uint16_t)((uint32_t)adc_val * 300 / 4096);
}
// 主循环中定时发送
void main_loop(void)
{
static uint32_t last_tick = 0;
uint16_t adc_val, curve_y;
if(HAL_GetTick() - last_tick >= 50) { // 20Hz刷新率
last_tick = HAL_GetTick();
// 读取ADC
adc_val = HAL_ADC_GetValue(&hadc1);
// 转换为曲线坐标
curve_y = ADC_To_CurveY(adc_val);
// 发送到迪文屏通道0
DWIN_SendCurveData(0, curve_y);
// 同时发送数值显示(假设显示地址0x1000)
DWIN_WriteWord(0x1000, adc_val);
}
}
四、DGUS屏软件配置要点
添加曲线控件:在DGUS Tool中选择"趋势图"或"实时曲线"控件
设置通道数:1-4通道可选
设置Y轴范围:匹配STM32发送的数据范围(如0-300)
设置数据地址:
实时曲线:使用0x9010+(通道号×0x10)
历史曲线:使用自定义变量地址(如0x1000)