基于HMI串口屏的协议(STM32)
提示: 硬件:STM32H750VBT6、USART_HMI(3.5寸基本型)(TJC4832T035_011X) 官方资料网站:HMI
前言
一、协议
提示:此处仅作为演示,完整版在文章末尾会有下载方式
注:一帧完整的数据一共有7Byte ,所以在发送功能类数据时需要把其他位用0x00 补全。 数据的缩放等级有0x00 、0x01 、0x02 三个等级,分别对应数据扩大0倍 、数据扩大10倍 、数据扩大100倍 。数据采用低端模式,即低字节在地址的低地址中,(例如:发送0x43AA ,则协议中的数据位的顺序是AA 43 ,所以在单片机解析数据中需要注意)。STM32 也是采用小端模式。
二、协议示例
在调试的时候可以把这些数据采用上位机的形式发送给单片机。
三、协议程序
1、Hmi_Agreements.c
代码如下(示例):
#include "hmi_agreement.h"
#include "stdlib.h"
#include "stdio.h"
_usarthmi UHMI;
void HMI_Usart_Rest(void)
{
uint8_t End_Bit[3] = {0xff,0xff,0xff};
uint8_t Rest[4] = "rest";
HAL_UART_Transmit(&uart, (uint8_t*)&Rest, 4, 0xffff);
HAL_UART_Transmit(&uart, (uint8_t*)&End_Bit, 3, 0xffff);
}
void HMI_Usart_Refresh(uint8_t *Page)
{
uint8_t End_Bit[3] = {0xff,0xff,0xff};
uint8_t Head[5] = "page ";
uint8_t *str;
uint16_t size = strlen((char*)Page);
str = (uint8_t*)malloc(size + 5);
if(str != NULL)
{
memcpy(str,Head,5);
memcpy(str + 5,Page,size);
HAL_UART_Transmit(&uart, (uint8_t*)str, size + 5, 0xffff);
HAL_UART_Transmit(&uart, (uint8_t*)&End_Bit, 3, 0xffff);
free(str);
}
}
void HMI_Usart_ShowHideobj(uint8_t *Obj,uint8_t State)
{
uint8_t End_Bit[3] = {0xff,0xff,0xff};
uint8_t Sho[4] = "vis ";
uint8_t *str;
uint16_t size = sizeof(Obj);
str = (uint8_t*)malloc(size + 6);
if(str != NULL)
{
memcpy(str,Sho,4);
memcpy(str + 4,Obj,size);
memcpy(str + 4 + size,(uint8_t*)",",1);
if(State)
memcpy(str + 5 + size,(uint8_t*)"1",1);
else
memcpy(str + 5 + size,(uint8_t*)"0",1);
HAL_UART_Transmit(&uart, (uint8_t*)str, size + 6, 0xffff);
HAL_UART_Transmit(&uart, (uint8_t*)&End_Bit, 3, 0xffff);
free(str);
}
}
void HMI_Usart_SendDataText(uint8_t *Head, uint8_t *SData)
{
uint8_t End_Bit[3] = {0xff,0xff,0xff};
uint8_t *str;
uint16_t size1 = strlen((char*)Head);
uint16_t size2 = strlen((char*)SData);
str = (uint8_t*)malloc(size1 + size2 + 3);
if(str != NULL)
{
memcpy(str,Head,size1);
memcpy(str + size1,(uint8_t*)"=",1);
memcpy(str + size1 + 1,(uint8_t*)"\"",1);
memcpy(str + size1 + 2,SData,size2);
memcpy(str + size1 + size2 + 2,(uint8_t*)"\"",1);
HAL_UART_Transmit(&uart, (uint8_t*)str, size1 + size2 + 3, 0xffff);
HAL_UART_Transmit(&uart, (uint8_t*)&End_Bit, 3, 0xffff);
free(str);
}
}
void HMI_Usart_SendDataValue(uint8_t *Head, int16_t data)
{
uint8_t End_Bit[3] = {0xff,0xff,0xff};
uint8_t buf[10];
uint8_t *str;
uint16_t size1 = strlen((char*)Head);
sprintf((char*)&buf,"%d",data);
uint16_t size2 = strlen((char*)buf);
str = (uint8_t*)malloc(size1 + 1);
if(str != NULL)
{
memcpy(str,Head,size1);
memcpy(str + size1,(uint8_t*)"=",1);
str = (uint8_t*)realloc(str,size1 + 1 + size2);
memcpy(str + size1 + 1, buf,size2);
HAL_UART_Transmit(&uart, (uint8_t*)str, size1 + size2 + 1, 0xffff);
HAL_UART_Transmit(&uart, (uint8_t*)&End_Bit, 3, 0xffff);
free(str);
}
}
static float ResolvingData(uint8_t *_DA)
{
int16_t DataBUf = 0;
switch (_DA[2])
{
case _1E_0:
DataBUf = *((int16_t*)(&_DA[3]));
return (float)DataBUf;
case _1E_1:
DataBUf = *((int16_t*)(&_DA[3]));
return (float)DataBUf / 10.f;
case _1E_2:
DataBUf = *((int16_t*)(&_DA[3]));
return (float)DataBUf / 100.f;
default:
return -1.f;
}
}
static void Acceptance_Data(uint8_t *_DA)
{
float DataBuf = 0;
DataBuf = ResolvingData(_DA);
if(DataBuf != -1)
{
UHMI.ID = _DA[1];
switch (_DA[1])
{
case _INT_VAID1: UHMI._IntRecData->_Data01 = (int16_t)DataBuf; break;
case _INT_VAID2: UHMI._IntRecData->_Data02 = (int16_t)DataBuf; break;
case _INT_VAID3: UHMI._IntRecData->_Data03 = (int16_t)DataBuf; break;
case _INT_VAID4: UHMI._IntRecData->_Data04 = (int16_t)DataBuf; break;
case _INT_VAID5: UHMI._IntRecData->_Data05 = (int16_t)DataBuf; break;
case _FLO_VAID1: UHMI._FloatRecData->_Data10 = DataBuf; break;
case _FLO_VAID2: UHMI._FloatRecData->_Data20 = DataBuf; break;
case _FLO_VAID3: UHMI._FloatRecData->_Data30 = DataBuf; break;
case _FLO_VAID4: UHMI._FloatRecData->_Data40 = DataBuf; break;
case _FLO_VAID5: UHMI._FloatRecData->_Data50 = DataBuf; break;
}
}
}
void HMI_Usart_ReciveData(uint8_t *RData,uint8_t size)
{
if(size == 7)
{
if(RData[0] == 0xCC)
Acceptance_Data(RData);
else if(RData[0] == 0xDD)
HMI_Usart_FunctionSelect(&RData[1]);
}
}
void HMI_Usart_FunctionSelect(uint8_t *Rfun)
{
switch (*Rfun)
{
case Start: UHMI.StartFlag = 1; break;
case Stop: UHMI.StartFlag = 0; break;
case mode1: UHMI.Mode = 1; break;
case mode2: UHMI.Mode = 2; break;
case mode3: UHMI.Mode = 3; break;
case mode4: UHMI.Mode = 4; break;
case mode5: UHMI.Mode = 5; break;
default: UHMI.Mode = 0; UHMI.StartFlag = 0; break;
}
}
2、Hmi_Agreements.h
代码如下(示例):
#ifndef __HMI_AGREEMENT_H
#define __HMI_AGREEMENT_H
#include "stm32h7xx.h"
#include "stdio.h"
#include "string.h"
#include "usart.h"
#define uart huart2
#define _DataNum 5
enum _Var
{
Start = 0x00,
Stop = 0x01,
mode1 = 0x11,
mode2 = 0x12,
mode3 = 0x13,
mode4 = 0x14,
mode5 = 0x15,
_1E_0 = 0,
_1E_1,
_1E_2,
_INT_VAID1 = 0x01,
_INT_VAID2,
_INT_VAID3,
_INT_VAID4,
_INT_VAID5,
_FLO_VAID1 = 0x10,
_FLO_VAID2,
_FLO_VAID3,
_FLO_VAID4,
_FLO_VAID5,
};
struct IntRecData
{
int16_t _Data01;
int16_t _Data02;
int16_t _Data03;
int16_t _Data04;
int16_t _Data05;
};
struct FloatRecData
{
float _Data10;
float _Data20;
float _Data30;
float _Data40;
float _Data50;
};
typedef struct
{
uint8_t StartFlag;
uint8_t ID;
uint8_t Mode;
struct IntRecData _IntRecData[_DataNum/5];
struct FloatRecData _FloatRecData[_DataNum/5];
}_usarthmi;
extern _usarthmi UHMI;
void HMI_Usart_Rest(void);
void HMI_Usart_Refresh(uint8_t *Page);
void HMI_Usart_SendDataValue(uint8_t *Head, int16_t data);
void HMI_Usart_SendDataText(uint8_t *Head, uint8_t *SData);
void HMI_Usart_ShowHideobj(uint8_t *Obj,uint8_t State);
static float ResolvingData(uint8_t *_DA);
static void Acceptance_Data(uint8_t *_DA);
void HMI_Usart_ReciveData(uint8_t *RData,uint8_t size);
void HMI_Usart_FunctionSelect(uint8_t *Rfun);
#endif
四、使用说明
1、接收数据
本程序暂未采用DMA 形式发送接收数据,只需在串口回调函数中调用数据接收处理函数
void HMI_Usart_ReciveData(uint8_t *RData,uint8_t size)
接收的数据会分为两类:整型和浮点型的数据,整型数据保存在以下结构体中:
struct IntRecData
{
int16_t _Data01;
int16_t _Data02;
int16_t _Data03;
int16_t _Data04;
int16_t _Data05;
};
浮点型数据保存在以下结构体中:
struct FloatRecData
{
float _Data10;
float _Data20;
float _Data30;
float _Data40;
float _Data50;
};
他们的ID 与HMI 发送的数据的ID 相同(注:发送时整型和浮点型数据开始的ID 不一样) 而他们都在以下结构体中:
typedef struct
{
uint8_t StartFlag;
uint8_t ID;
uint8_t Mode;
struct IntRecData _IntRecData[_DataNum/5];
struct FloatRecData _FloatRecData[_DataNum/5];
}_usarthmi;
2、发送数据
发送数据可使用以下函数:
void HMI_Usart_SendDataValue(uint8_t *Head, int16_t data);
void HMI_Usart_SendDataText(uint8_t *Head, uint8_t *SData);
五、下载方式
有积分的同学可以用csdn 下载哦,没积分的同学可以去我GitHub 仓库下载
|