陶晶驰串口屏
资料
陶晶驰串口屏是本质是一个MCU,屏幕是MCU的模块,一般是一块TFT屏幕。在串口屏厂商提供的软件上面编写界面,然后通过串口直接烧到串口屏的MCU上,然后在屏幕上展示出来。
串口屏资料中心传送门入口
使用方法
串口屏资料中心传送门入口(详细使用方法请关注资料中心)
YXY通信
YXY通信是专门为串口屏开发的一种通信方法
YXY通信把数据分为了三个部分,分别是数据id、数据、数据尾,没错就这三个简单吧,甚至没有打包解包的过程,比市面上的一众通信原理都简单。
数据id是用来区分是哪个模块,发过来的数据,比如我要做一个智能家居,智能家居,要做空调,要做窗帘,要做扫地机器人,那我就分别给他定义数据id,比如空调是0x11,风扇是0x12,扫地机器人是0x13,当串口屏给外部MCU发送0x11时,我就知道,用户在串口屏上操作了空调部分,获取了操作后的数据,我再到对应的地方去编写对应的代码,就可以实现由串口屏到模块的直接控制。
串口屏软件上数据发送部分
直接上例子
就这几个例子吧,后面之恶极上工程
cubemx配置
1.开一个串口(开串口中断)
代码部分
我是直接把我之前做的工程的代码拿过来了,最后面附上整个工程的源码,这里仅供参考。
UART_Screen.c
#include "UART_Screen.h"
#include "O_redirect.h"
#include "yxy_delay.h"
#include "usart.h"
#include "string.h"
#include "stdbool.h"
#include "UserHand.h"
#include "esp8266.h"
#include "errorType.h"
HMI_Struct HMI_InitStr;
HMI_SetTime hmiSetTime;
/*发送数字或字符串给串口屏*/
// ConData是串口屏的控制命令格式
// Data是对该命令格式赋予的数据
// DataType是发送的是字符数字还是字符串 0是数字,1是字符串
void HMI_SendData(uint8_t *ConData, uint8_t DataType, void * Data)
{
U_Printf(HMI_print, "%s", ConData);
// U_Printf(U_UART1, "%s\r\n", ConData);
switch(DataType)
{
case HMI_NUM:
{
uint16_t Num = *((uint16_t *)Data);
U_Printf(HMI_print, "%d", Num);
// U_Printf(U_UART1, "Num : %d\r\n", Num);
}break;
case HMI_STRING:
{
uint8_t * text = (uint8_t *)Data;
uint8_t sz = 0;
while(*(text+sz) != 255)
{
sz++;
}
U_Printf(U_UART1, "sz : %d\r\n", sz);
U_Printf(HMI_print, "\"");
for(int i=0; i<sz; i++)
{
U_Printf(HMI_print, "%c", text[i]);
}
U_Printf(HMI_print, "\"");
}break;
}
U_Printf(HMI_print, "\xff\xff\xff");
}
/* 串口屏跳转页面函数 */
// Data 是要跳转的页面名字
void HMI_SendData(uint8_t* Data)
{
U_Printf(HMI_print, "page %s\xff\xff\xff", Data);
}
/* * 函数名:HMI_Init * 描述 :串口屏数据与串口初始化 * 输入 :无 * 返回 :无 * 调用 :无 */
void HMI_Init(void)
{
HMI_InitStr.HMI_cnt = 0;
HMI_InitStr.a_HMI_buf=0;
HMI_InitStr.HMI_cntPre=0;
memset(HMI_InitStr.HMI_buf, 0, sizeof(HMI_InitStr.HMI_buf));
HAL_UART_Receive_IT(&HMI_huart, (uint8_t *)&(HMI_InitStr.a_HMI_buf), 1);//开启接收中断
}
/* * 函数名:HMI_Clear * 描述 :清空缓冲区,以及接收计数 * 输入 :无 * 返回 :无 * 调用 :无 */
void HMI_Clear(void)
{
memset(HMI_InitStr.HMI_buf, 0, sizeof(HMI_InitStr.HMI_buf));//清空缓冲区,全部填0
HMI_InitStr.a_HMI_buf = 0;
HMI_InitStr.HMI_cnt = 0;//清空缓存区计数
HMI_InitStr.HMI_cntPre = 0;//清空
}
/*内部函数声明*/
static void LoginDataProcess(void);
static void M_C_DataProcess(void);
static void DisinfectDataProcess(void);
static void CurtainDataProcess(void);
static void InternetDataProcess(void);
/*串口屏解包函数*/
void HMI_UnPack(void)
{
switch(HMI_InitStr.HMI_buf[0])
{
case HMI_MAIN:
U_Printf(U_UART1, "这里是main界面\r\n");
break;
case HMI_LOGIN:
U_Printf(U_UART1, "这里是login界面\r\n");
LoginDataProcess();
break;
case HMI_PASS_CHANGE:
U_Printf(U_UART1, "这里是password change界面\r\n");
LoginDataProcess();
break;
case HMI_LOGIN_SUCC:
U_Printf(U_UART1, "这里是login succeed界面\r\n");
break;
case HMI_LOGIN_FAIL:
U_Printf(U_UART1, "这里是login fail界面\r\n");
break;
case HMI_MEDICINE_CHEST:
U_Printf(U_UART1, "这里是mediciness chest界面\r\n");
M_C_DataProcess();
break;
case HMI_DISINFECT:
U_Printf(U_UART1, "这里是disinfect界面\r\n");
DisinfectDataProcess();
break;
case HMI_CURTAIN:
U_Printf(U_UART1, "这里是curtain界面\r\n");
CurtainDataProcess();
break;
case HMI_INTERNET:
U_Printf(U_UART1, "这里是internet界面\r\n");
InternetDataProcess();
break;
default:
break;
}
HMI_Clear(); //清空缓存
}
/*密码数据处理函数*/
static void LoginDataProcess(void)
{
uint8_t tx[] = "va0.txt=";
uint8_t UserPass[PASS_LENG_MAX+1];
uint8_t i = 2;
memset(UserPass, 255, sizeof(UserPass));
switch(HMI_InitStr.HMI_buf[1])
{
case Get_PASS: //获取单片机上存储的密码
{
U_Printf(U_UART1, "login中 的 Get_PASS\r\n");
UserGetPassword(UserPass);
UserPass[PASS_LENG_MAX] = '\0';
U_Printf(U_UART1, "UserPass:%s\r\n", UserPass);
HMI_SendData(tx, HMI_STRING, (void *)(UserPass));
}break;
case CHANGE_PASS: //修改单片机上存储的密码
{
U_Printf(U_UART1, "login中 的 CHANGE_PASS\r\n");
curPassLen=0;
while(*(HMI_InitStr.HMI_buf + i) != 0xff)
{
curPassLen++;
i++;
}
Wrinte_EEPOM(PASS_LEN, curPassLen); //密码长度存储
U_Printf(U_UART1, "UserPass:%s, Cnt : %d \r\n", HMI_InitStr.HMI_buf+2, curPassLen);
UserSetPassword(((uint8_t *)(HMI_InitStr.HMI_buf+2)), curPassLen); //cnt减去一级id,二级id 和 包尾
}break;
case RESET_PASS: //重置单片机上的密码为1111
{
U_Printf(U_UART1, "login中 的 RESET_PASS\r\n");
uint8_t ResPass[] = "1111";
UserSetPassword((uint8_t *)ResPass, 4);
curPassLen = 4;
Wrinte_EEPOM(PASS_LEN, curPassLen); //密码长度存储
}break;
default:
U_Printf(U_UART1, "0x%x\r\n", HMI_InitStr.HMI_buf[1]);
break;
}
}
/*药箱数据处理函数*/
static void M_C_DataProcess(void)
{
switch(HMI_InitStr.HMI_buf[1])
{
case MC_SW_ON_OFF:
U_Printf(U_UART1, "mediciness chest 的 MC_SW_ON_OFF\r\n");
switch(HMI_InitStr.HMI_buf[2])
{
case 1:
U_Printf(U_UART1, "va0 : %d\r\n", HMI_InitStr.HMI_buf[3]);
if(HMI_InitStr.HMI_buf[3] == MC_Close)
{
SG90_Ch_Degrees(sg90_Ch1, Degrees135);
}
else if(HMI_InitStr.HMI_buf[3] == MC_Open)
{
SG90_Ch_Degrees(sg90_Ch1, Degrees0);
}
break;
case 2:
U_Printf(U_UART1, "va1 : %d\r\n", HMI_InitStr.HMI_buf[3]);
if(HMI_InitStr.HMI_buf[3] == MC_Close)
{
SG90_Ch_Degrees(sg90_Ch2, Degrees135);
}
else if(HMI_InitStr.HMI_buf[3] == MC_Open)
{
SG90_Ch_Degrees(sg90_Ch2, Degrees0);
}
break;
default:
break;
}
break;
case Get_MC_Val:
{
U_Printf(U_UART1, "mediciness chest 的 Get_MC_Val\r\n");
uint8_t tx0[] = "va0.val=";
uint16_t Num = MC_Close;
if(Get_MC_flag(sg90_Ch1) == MC_Open)
{
Num = MC_Open;
}
HMI_SendData(tx0, HMI_NUM, &Num); // 获取药箱数据
// 获取吃药时间数据
uint8_t tx2[] = "h0.val=";
uint8_t tx3[] = "h1.val=";
uint8_t tx4[] = "h2.val=";
uint8_t tx5[] = "t5.txt=";
uint8_t tx6[30];
sprintf((char *)tx6, "定时时间:%2d:%2d:%2d", hmiSetTime.hmi_hour[HMI_MC_Num],
hmiSetTime.hmi_min[HMI_MC_Num],
hmiSetTime.hmi_sec[HMI_MC_Num]);
HMI_SendData(tx2, HMI_NUM, &hmiSetTime.hmi_hour[HMI_MC_Num]);
HMI_SendData(tx3, HMI_NUM, &hmiSetTime.hmi_min[HMI_MC_Num]);
HMI_SendData(tx4, HMI_NUM, &hmiSetTime.hmi_sec[HMI_MC_Num]);
HMI_SendData(tx5, HMI_STRING, (void *)tx6);
}break;
case Set_Med_Time:
{
U_Printf(U_UART1, "mediciness chest 的 Set_Med_Time\r\n");
hmiSetTime.hmi_hour[HMI_MC_Num] = HMI_InitStr.HMI_buf[2];
hmiSetTime.hmi_min[HMI_MC_Num] = HMI_InitStr.HMI_buf[3];
hmiSetTime.hmi_sec[HMI_MC_Num] = HMI_InitStr.HMI_buf[4];
hmiSetTime.hmi_flag &= ~(1<<(HMI_MC_Num)); // 清除标志位
U_Printf(U_UART1, "Set_Med_Time: %d:%d:%d\r\n", hmiSetTime.hmi_hour[HMI_MC_Num],
hmiSetTime.hmi_min[HMI_MC_Num], hmiSetTime.hmi_sec[HMI_MC_Num]);
}break;
case In_Med_Interface:
{
U_Printf(U_UART1, "mediciness chest 的 In_Med_Interface\r\n");
// U_Printf(U_UART1, "HMI_InitStr.HMI_buf[2] : %d\r\n", HMI_InitStr.HMI_buf[2]);
switch(HMI_InitStr.HMI_buf[2])
{
case 0x01:
BeepRing(1);
yxy_delay_ms(200);
BeepRing(0);
break;
case 0x02:
hmiSetTime.hmi_flag |= 1<<(HMI_MC_Num); // 闹铃消除标志位
hmiSetTime.hmi_lastTime = esp_time.esp_hour*60 + esp_time.esp_min; // 一定时间不响闹铃
break;
}
}break;
default:
break;
}
}
/*紫外线消毒数据处理函数*/
static void DisinfectDataProcess(void)
{
switch(HMI_InitStr.HMI_buf[1])
{
case D_SW_ON_OFF:
switch(HMI_InitStr.HMI_buf[2])
{
case 0x00:
No_Disinfection;
TIM5->CCR1 = 10000;
break;
case 0x01:
LowDisinfection;
TIM5->CCR1 = 6666;
break;
case 0x02:
ModDisinfection;
TIM5->CCR1 = 3333;
break;
case 0x03:
HigDisinfection;
TIM5->CCR1 = 0;
break;
default:
No_Disinfection;
TIM5->CCR1 = 0;
break;
}
break;
case Get_LED_Val:
{
uint8_t tx[] = "h0.val=";
uint16_t Num;
Num = UV2_State();
HMI_SendData(tx, HMI_NUM, &Num);
}break;
default:
break;
}
}
/*窗帘数据处理函数*/
static void CurtainDataProcess(void)
{
switch(HMI_InitStr.HMI_buf[1])
{
case C_SW_ON_OFF:
{
U_Printf(U_UART1, "curtain 的 C_SW_ON_OFF\r\n");
switch(HMI_InitStr.HMI_buf[2])
{
case 0x01:
uln2003_MotorRotation(FORWARD);
uln_flag = 1;
break;
case 0x02:
uln2003_MotorRotation(REVERSE);
uln_flag = 2;
break;
default:
uln2003_MotorRotation(STOP_IT);
uln_flag = 0;
break;
}
}break;
case Get_Cur_Val:
{
U_Printf(U_UART1, "curtain 的 Get_Cur_Val\r\n");
uint8_t tx2[] = "h0.val=";
uint8_t tx3[] = "h1.val=";
uint8_t tx4[] = "h2.val=";
uint8_t tx5[] = "t5.txt=";
uint8_t tx6[30];
sprintf((char *)tx6, "定时时间:%2d:%2d:%2d", hmiSetTime.hmi_hour[HMI_Cur_Num],
hmiSetTime.hmi_min[HMI_Cur_Num], hmiSetTime.hmi_sec[HMI_Cur_Num]);
HMI_SendData(tx2, HMI_NUM, &hmiSetTime.hmi_hour[HMI_Cur_Num]);
HMI_SendData(tx3, HMI_NUM, &hmiSetTime.hmi_min[HMI_Cur_Num]);
HMI_SendData(tx4, HMI_NUM, &hmiSetTime.hmi_sec[HMI_Cur_Num]);
HMI_SendData(tx5, HMI_STRING, (void *)tx6);
}break;
case Set_Cur_Time:
{
U_Printf(U_UART1, "curtain 的 Set_Cur_Time\r\n");
hmiSetTime.hmi_hour[HMI_Cur_Num] = HMI_InitStr.HMI_buf[2];
hmiSetTime.hmi_min[HMI_Cur_Num] = HMI_InitStr.HMI_buf[3];
hmiSetTime.hmi_sec[HMI_Cur_Num] = HMI_InitStr.HMI_buf[4];
// hmiSetTime.hmi_flag &= ~(1<<(HMI_Cur_Num)); // 清除标志位
U_Printf(U_UART1, "Set_Cur_Time: %d:%d:%d\r\n", hmiSetTime.hmi_hour[HMI_Cur_Num],
hmiSetTime.hmi_min[HMI_Cur_Num], hmiSetTime.hmi_sec[HMI_Cur_Num]);
U_Printf(HMI_print, "page Curtain\xff\xff\xff");
}break;
default:
break;
}
}
/*联网数据处理函数*/
static void InternetDataProcess(void)
{
uint16_t Len = 0;
uint8_t ssid[20];
uint8_t wifiPassword[20];
switch(HMI_InitStr.HMI_buf[1])
{
case NETWORKING:
{
uint8_t tx[] = "main.p0.pic=";
uint16_t Num = 40;
ESP_flag &= ~ESP_IN_NETWORK; // 清空联网标志位
HMI_SendData(tx, HMI_NUM, &Num);// 显示未联网
while(Len < HMI_InitStr.HMI_buf[2])
{
ssid[Len] = HMI_InitStr.HMI_buf[3+Len];
Len++;
}
ssid[Len] = '\0'; // 字符串结尾符号
Len = 0;
while(Len < HMI_InitStr.HMI_buf[3 + HMI_InitStr.HMI_buf[2]])
{
wifiPassword[Len] = HMI_InitStr.HMI_buf[4 + HMI_InitStr.HMI_buf[2] + Len];
Len++;
}
wifiPassword[Len] = '\0'; // 字符串结尾符号
U_Printf(U_UART1, "ssidLen : %d password : %d\r\n", HMI_InitStr.HMI_buf[2], HMI_InitStr.HMI_buf[3 + HMI_InitStr.HMI_buf[2]]);
U_Printf(U_UART1, "ssid : %s\r\npassword : %s\r\n", ssid, wifiPassword);
ssidPass_wifi(ssid, wifiPassword); // 配置esp 并联网
U_Printf(HMI_print, "page main\xff\xff\xff"); // 联网成功后跳转到main界面
if((ESP_flag&ESP_IN_NETWORK) == ESP_IN_NETWORK) // 判断是否联网成功
{
Num = 41;
}
else
{
Num = 40;
}
HMI_SendData(tx, HMI_NUM, &Num);
}break;
default:
break;
}
}
/*HMI、esp8266串口中断函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == HMI_UART)
{
if(HMI_InitStr.HMI_cnt >= HMI_BUF_SIZE)//溢出判断
{
HMI_InitStr.HMI_cnt = 0;
memset(HMI_InitStr.HMI_buf, 0, sizeof(HMI_InitStr.HMI_buf)); //清零字符串
U_Printf(U_UART1, "HMI data overflow\r\n");
}
else
{
//数据存入
HMI_InitStr.HMI_buf[HMI_InitStr.HMI_cnt] = HMI_InitStr.a_HMI_buf;
HMI_InitStr.HMI_cnt++;
if(HMI_InitStr.a_HMI_buf == HMI_PackTail) //检测到包尾
HMI_flag = 1; // 解包函数准备启动
}
HAL_UART_Receive_IT(&HMI_huart, (uint8_t *)&(HMI_InitStr.a_HMI_buf), 1); //再开启接收中断
}
}
UART_Screen.h
#ifndef __UART_SCREEN_H_
#define __UART_SCREEN_H_
#include "stdint.h"
/*宏定义区*/
#define HMI_BUF_SIZE 127 //缓冲区大小
#define HMI_huart huart2
#define HMI_UART USART2
#define HMI_print U_UART2
#define HMI_PackTail 0xff // 包尾
#define TimeNumber 16
#define TimeRInit 0x70
/*枚举区*/
//页面id合集
typedef enum
{
HMI_MAIN = 0x01, //主页面id
HMI_LOGIN = 0x70, //密码登入页面id
HMI_PASS_CHANGE = 0x71, //密码修改页面id
HMI_LOGIN_SUCC = 0x72, //登入后界面id
HMI_LOGIN_FAIL = 0x73, //登入失败界面id
HMI_MEDICINE_CHEST = 0x74, //药箱界面id
HMI_DISINFECT = 0x75, //紫外线界面id
HMI_CURTAIN = 0x76, //床帘界面id
HMI_INTERNET = 0x77, //联网页面
MAX_MODULE_ID = 0x80
}EnumPackID;
#define HMI_MC_Num (HMI_MEDICINE_CHEST - TimeRInit)
#define HMI_Cur_Num (HMI_CURTAIN - TimeRInit)
/*主页面数据与命令*/
//typedef enum
//{
//
//}MainID;
/*修改密码界面操作命令*/
typedef enum
{
Get_PASS = 0x11, //获取密码值
CHANGE_PASS = 0x12, //修改密码
RESET_PASS = 0x13 //重置密码为1111
}PasswordChangeID;
/*药箱界面操作*/
typedef enum
{
MC_SW_ON_OFF = 0x11, //药箱开关信号
Get_MC_Val = 0x12, //获取当前单片机上的药箱数值情况
Set_Med_Time = 0x13, //设置用药时间
In_Med_Interface= 0x14 //在吃药界面
}MedicineChestID;
/*紫外灯界面操作*/
typedef enum
{
D_SW_ON_OFF = 0x11, //紫外灯开关信号
Get_LED_Val = 0x12 //获取当前单片机上的紫外线数值情况
}DisinfectID;
/*窗帘界面操作*/
typedef enum
{
C_SW_ON_OFF = 0x11, //床帘开关信号
Get_Cur_Val = 0x12, //获取当前单片机上的上窗帘时间数值
Set_Cur_Time= 0x13, //设置晚上睡觉时间
}CurtainID;
/*联网界面操作*/
typedef enum
{
NETWORKING = 0x11 //联网信号
}InternetID;
/*给串口屏数据类型*/
typedef enum
{
HMI_NUM = 0, //数字类型
HMI_STRING //字符串类型
}HMI_Data_Type;
/*结构体部分*/
/*单片机接收串口屏数据类型*/
typedef struct HMI_struct
{
uint8_t HMI_buf[HMI_BUF_SIZE]; //数据缓冲存取区
uint8_t a_HMI_buf; //缓冲区元素暂存位置
uint16_t HMI_cnt; //当前接收计数
uint8_t HMI_cntPre; //上次计数
}HMI_Struct;
/* //包 typedef struct { uint8_t packPageId; //用户自定义页面Id uint8_t packDataId; //二级页面内数据Id uint8_t arrData[10]; //10个数据元素 uint8_t packtail; //数据尾 }StructPackType; */
typedef struct hmiSet_Time
{
uint8_t hmi_hour[TimeNumber];
uint8_t hmi_min[TimeNumber];
uint8_t hmi_sec[TimeNumber];
uint16_t hmi_flag;
uint16_t hmi_lastTime;
}HMI_SetTime;
extern HMI_SetTime hmiSetTime;
/*函数区*/
/*串口屏初始化以及数据接收处理部分*/
void HMI_Init(void); //串口屏初始化
void HMI_UnPack(void); //串口屏数据解包,并执行相应解包函数
/*单片机发送数据到串口屏部分*/ /*发送数字或字符串给串口屏*/
void HMI_SendData(uint8_t *ConData, uint8_t DataType, void * Data);
/* //函数用法 1、单片机发送数据到串口屏函数使用方法 uint8_t tx[] = "123"; uint8_t str[] = "12345"; uint16_t Num = 0; HMI_SendData(tx, HMI_STRING, (void *)(str)); HMI_SendData(tx, HMI_STRING, (void *)(&Num)); */
/*全局变量*/
#endif /* __UART_SCREEN_H_ */
初始化
HMI_Init();
效果展示
串口屏的智能家居
源码
链接:https://pan.baidu.com/s/1FYY1S2K6p81wKKVA_KCcxg?pwd=nkxs
提取码:nkxs
今天的文章cubemx stm32 陶晶驰 串口屏 基于YXY通信原理的串口屏驱动代码分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/60025.html