前言
经过上一次的串口屏学习,实现了单个页面的控件操作显示,但依旧还存在着许多需要解决的问题和优化的地方。
这次呢,主要实现串口屏多页面显示,及对应UI组件的控制。
上一篇串口屏链接:
合泰HT32 & 淘晶驰TJC–T0串口屏学习笔记(一)
指令
指令 | 说明 |
---|---|
page x | 跳转到x页面 |
sendme | 串口发送页面ID |
covx | 变量类型转换 |
指令详解
以下指令如果从单片机发送到串口屏都需要加上结束符
0XFF 0XFF 0XFF
一、page x 刷新页面
语法
page pageid
pageid:页面ID或页面名称
实例1:page 0 (刷新ID为0的页面)
实例2:page main (刷新名称为main的页面)
备注:
1.设备上电自动刷新第0页。
2.也可以对系统变量dp赋值来实现跳转页面(如dp=0),系统变量dp可以设置可以读取,具体请参看系统变量列表。
3.page 指令是跳转指令。写在page指令后面的代码将被忽略没机会执行。
二、sendme
语法
sendme
(直接发送sendme这条字符串即可)
备注
设备收到此指令会立刻把当前页面的ID号发送到串口,如果想要每次刷新页面自动发送页面ID,需要在页面的初始化事件里写上sendme语句。
三、covx 变量类型转换
语法
covx att1,att2,lenth,format
att1:源变量
att2:目标变量
lenth:字符串的长度(0为自动长度,非0为固定长度)
format:申明数值类型(0-数字;1-货币;2-Hex)
备注
实例1:covx h0.val,t0.txt,0,0 (把滑块h0的val数值变量转换成10进制数字字符串并赋值给文本t0的txt变量,长度为自动)
实例2:covx t0.txt,h0.val,0,0 (把文本t0的txt十进制数字字符串变量转换为数值并赋值给滑块h0的val数值变量,长度为自动)
串口屏多页面设计
首先我们需要在“页面”栏创建新的页面;然后在主页面那里把背景换成图片(图片上面已经设计好UI图标了)。
至于UI设计嘛,我们这是以学习为目标哈,因此可以在网上找几个好看的图标,用PS弄进图片里面就行。
图片的分辨率必须要改成自己屏幕对应的分辨率,不然的话显示会有问题的。
然后添加几个按钮,将按钮的“sta”属性换成“切图”,换成切图之后,按钮就变成透明的了,这时候记得要在“属性”栏将切图的“picc”“picc2”设置成对应的图片!
按钮属性设置完成之后,在对应按钮的“弹起事件”写上需要转的页面即可,如果想返回主页面也是一样,写上page “页面ID”指令就可以跳转到对应的页面了。
对了记得在页面的前初始化事件那里把波特率改成和单片机串口的波特率一样。
程序
查找当前的页面
我们要知道当前是什么页面才能对,对应的组件进行修改,这里主要有两种方法。
第一、主动发送
在每个页面的初始化事件那里写上sendme指令,那么在进入这个页面的时候串口屏就会主动发送当前页面的ID给单片机了。
第二、被动查询
这种方法主要通过单片机发送sendme指令给串口屏,串口屏接收到这条指令之后就会把页面ID发送到单片机了。
比如当前的页面为第0页,单片机发送sendme,串口屏就会回复
0X66 0X00 0XFF 0XFF 0XFF,其中0x66 为固定的前字节,0x00为当前的页面ID,后面的三个就是结束符了
。
实现函数:
查询当前的页面ID
unsigned char search_page()
//=================检查当前页面============//
// 用debug串口将信息打印输出
//并返回对应的页面ID
u8 search_page()
{
unsigned char timeOut=200;
tjc_sendstring("sendme");
USART_SEND_END(COM0_PORT);
while(timeOut--)
{
if(USART0_WaitRecive()==0)
{
hexStr2Str((char *)gRx_Buffer);
if(strstr((const char *)gRx_Buffer, "6600") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 0");
return 0;
}
else if(strstr((const char *)gRx_Buffer, "6601") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 1");
return 1;
}
else if(strstr((const char *)gRx_Buffer, "6602") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 2");
return 2;
}
else if(strstr((const char *)gRx_Buffer, "6603") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 3");
return 3;
}
else if(strstr((const char *)gRx_Buffer, "6604") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 4");
return 4;
}
}
}return NULL;
}
因为串口屏给我们发送的是十六进制数,因此我们可以把它转换为字符串,感觉这样更直观一点,下面为十六进制转换为字符串的实现程序。
uint8_t HexToChar(uint8_t temp)
{
uint8_t dst;
if (temp < 10){
dst = temp + '0';
}else{
dst = temp -10 +'A';
}
return dst;
}
//==================16进制转为字符串====================//
//@ *data 用指针输入需要转换十六进制数的buffer
void hexStr2Str(char *data)
{
int i = 0;
uint8_t str[10];
uint8_t dst[10];
for(i = 0; i<5;i++)
{
str[2*i] = data[i]>>4;
str[2*i+1] = data[i]&0xf;
}
for(i = 0; i<10;i++)
{
dst[i] = HexToChar(str[i]);
}
for(i=0;i<10;i++)
{
data[i]=dst[i];
}
}
通过上面的程序我们就可以知道,现在处于哪个页面了,接下来就是对页面组件的操作,这个请参考串口屏的第一篇笔记博文。
串口屏相关的一些函数
#include "tjc.h"
#include "delay.h"
#include "usart.h"
//C库
#include <string.h>
#include <stdio.h>
extern u8 gRx_Buffer[128];
extern vu32 gURRx_Length;
//page 1组件参数存放,光谱仪
#define MAX_VAL 1000 //最大值,到时候需要修改
unsigned int page1_NUM[10]={95,78,140,355,888,643,85,98,987,666};
//char page1_TXT[8][4]={"富强","民主","文明","和谐","自由","平等","公正","法治"};
//page 2组件参数存放,灯光检测
unsigned int page2_NUM[2]={1118,4000};
unsigned char page2_TXT[4]={"黄色"};
//page 3组件参数存放,大棚
unsigned int page3_NUM[2]={500,480};
//page 4组件参数存放,PH值检测
unsigned char page4_TXT[2][4]={"8.8","偏蓝"};
uint8_t HexToChar(uint8_t temp)
{
uint8_t dst;
if (temp < 10){
dst = temp + '0';
}else{
dst = temp -10 +'A';
}
return dst;
}
//==================16进制转为字符串====================//
void hexStr2Str(char *data)
{
int i = 0;
uint8_t str[10];
uint8_t dst[10];
for(i = 0; i<5;i++)
{
str[2*i] = data[i]>>4;
str[2*i+1] = data[i]&0xf;
}
for(i = 0; i<10;i++)
{
dst[i] = HexToChar(str[i]);
}
for(i=0;i<10;i++)
{
data[i]=dst[i];
}
}
//===========发送字符串给串口屏================//
void tjc_sendstring(char *buf)
{
Usart_SendStr(COM0_PORT,buf);
}
//**************将进度条数值发送给串口屏***************//
//入口参数:
//max_val 最大值,因为进度条最多显示100,需要归100化
//j_x 进度条标识,需要修改的进度条标号,比如修改j.0,那么j_x=0
//j_val 需要显示的数值
//*****************************************************//
void tjcSend_jdt(float max_val,unsigned char j_x,float j_val)
{
unsigned char jdt_va;
jdt_va=(100/max_val)*j_val;
Usart_SendStr(COM0_PORT,"j");
Usart_Sendbyte(COM0_PORT,j_x+48);// 把整数 int i 转为字符码并发送
Usart_SendStr(COM0_PORT,".val=");
Int2Char_Send(COM0_PORT,jdt_va);
USART_SEND_END(COM0_PORT);
}
//****************将文本组件字符发送给串口屏*************//
//入口参数:
//t_x 文本标识,第几条文本
//t_txt 文本的内容
//=======================================================//
void tjcSend_txt(unsigned char t_x, unsigned char *t_txt)
{
Usart_SendStr(COM0_PORT,"t");
Usart_Sendbyte(COM0_PORT,t_x+48);// 把整数 int i 转为字符码并发送
Usart_SendStr(COM0_PORT,".txt=");
Usart_Sendbyte(COM0_PORT,34);//引号
Usart_SendString(COM0_PORT,t_txt,4);//默认为4个字节,如果超过需要修改
Usart_Sendbyte(COM0_PORT,34);//引号
USART_SEND_END(COM0_PORT);
}
//****************将数字组件数值发送给串口屏*************//
//入口参数:
void tjcSend_num(unsigned char n_x,unsigned int n_val)
{
Usart_SendStr(COM0_PORT,"n");
Usart_Sendbyte(COM0_PORT,n_x+48);// 把整数 int i 转为字符码并发送
Usart_SendStr(COM0_PORT,".val=");
Int2Char_Send(COM0_PORT,n_val);
USART_SEND_END(COM0_PORT);
}
//=================检查当前页面============//
u8 search_page()
{
unsigned char timeOut=200;
tjc_sendstring("sendme");
USART_SEND_END(COM0_PORT);
while(timeOut--)
{
if(USART0_WaitRecive()==0)
{
hexStr2Str((char *)gRx_Buffer);
if(strstr((const char *)gRx_Buffer, "6600") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 0");
return 0;
}
else if(strstr((const char *)gRx_Buffer, "6601") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 1");
return 1;
}
else if(strstr((const char *)gRx_Buffer, "6602") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 2");
return 2;
}
else if(strstr((const char *)gRx_Buffer, "6603") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 3");
return 3;
}
else if(strstr((const char *)gRx_Buffer, "6604") != NULL) //如果检索到关键词
{
memset(gRx_Buffer, 0, sizeof(gRx_Buffer));
gURRx_Length = 0;
UsartPrintf (COM1_PORT ,"page 4");
return 4;
}
}
}return NULL;
}
void tjc_show(void)
{
unsigned char page,i;
page=search_page();
switch(page)
{
case 0:
{break;}
//第一页,光谱仪
case 1:
{
for(i=0;i<10;i++)
{
if(i<8)
{
tjcSend_jdt (MAX_VAL,i,page1_NUM[i]);
}
tjcSend_num(i,page1_NUM[i]);
}
break;
}
//第二页,灯光检测
case 2:
{
for(i=0;i<2;i++)
{
tjcSend_num(i,page2_NUM[i]);
}
tjcSend_txt(0,page2_TXT);
break;
}
//第三页,大棚
case 3:
{
for(i=0;i<2;i++)
{
tjcSend_num(i,page3_NUM[i]);
}
break;
}
//第四页,PH值
case 4:
{
for(i=0;i<2;i++)
{
tjcSend_txt(i,page4_TXT[i]);
}
break;
}
}
}