338 lines
8.7 KiB
C
338 lines
8.7 KiB
C
/* USER CODE BEGIN Header */
|
||
/**
|
||
******************************************************************************
|
||
* @file screen.c
|
||
* @brief 串口屏驱动实现(JC系列),使用 USART1
|
||
******************************************************************************
|
||
*/
|
||
/* USER CODE END Header */
|
||
|
||
#include "screen.h"
|
||
#include "cmsis_os2.h"
|
||
#include "main.h"
|
||
#include "usart.h"
|
||
#include "cmsis_os.h"
|
||
#include <string.h>
|
||
#include <stdint.h>
|
||
#include "gbk_text.h"
|
||
#include "elog.h"
|
||
|
||
/* 发送缓冲 */
|
||
static uint8_t txbuf[512];
|
||
|
||
/* =========================================================
|
||
内部工具函数(替代 sprintf)
|
||
========================================================= */
|
||
|
||
/* 将字符串复制到发送缓冲区 */
|
||
static uint16_t buf_str(uint16_t p,const char *s)
|
||
{
|
||
while(*s) txbuf[p++]=*s++;
|
||
return p;
|
||
}
|
||
|
||
/* 将32位无符号整数转换为字符串并复制到发送缓冲区 */
|
||
static uint16_t buf_u32(uint16_t p,uint32_t v)
|
||
{
|
||
char tmp[12];
|
||
int i=0;
|
||
if(v==0){ txbuf[p++]='0'; return p; }
|
||
while(v){ tmp[i++]=v%10+'0'; v/=10; }
|
||
while(i--) txbuf[p++]=tmp[i];
|
||
return p;
|
||
}
|
||
|
||
/* 发送指定长度的数据 */
|
||
static void send_buf(uint16_t len)
|
||
{
|
||
HAL_UART_Transmit(&huart1,txbuf,len,HAL_MAX_DELAY);
|
||
osDelay(100);
|
||
}
|
||
|
||
/* =========================================================
|
||
基础接口
|
||
========================================================= */
|
||
|
||
/* 发送数据缓冲区 */
|
||
int Screen_SendBuf(const uint8_t *buf,uint16_t len)
|
||
{
|
||
if(!buf||!len) return -1;
|
||
HAL_StatusTypeDef st=HAL_UART_Transmit(&huart1,(uint8_t*)buf,len,HAL_MAX_DELAY);
|
||
osDelay(20);
|
||
return (st==HAL_OK)?0:-2;
|
||
}
|
||
|
||
/* 发送命令字符串 */
|
||
int Screen_SendCmd(const char *cmd)
|
||
{
|
||
if(!cmd) return -1;
|
||
return Screen_SendBuf((uint8_t*)cmd,strlen(cmd));
|
||
}
|
||
|
||
/* 发送命令并等待确认(当前未实现超时机制) */
|
||
int Screen_SendCmdWaitOK(const char *cmd,uint32_t timeout_ms)
|
||
{
|
||
(void)timeout_ms;
|
||
return Screen_SendCmd(cmd);
|
||
}
|
||
|
||
/* =========================================================
|
||
初始化
|
||
========================================================= */
|
||
|
||
/* 屏幕初始化函数 */
|
||
void Screen_Init(void)
|
||
{
|
||
osDelay(1000);
|
||
Screen_Clear(BG_COLOR);
|
||
osDelay(200);
|
||
Screen_SetBGColor(BG_COLOR);
|
||
Screen_SetBrightness(0);
|
||
osDelay(200);
|
||
Screen_Box(0,0,127,127,TEXT_COLOR);
|
||
Screen_DrawText24_GBK(5,1,text_device_name,text_device_name_LEN,TEXT_COLOR);
|
||
Screen_Line(0, 27, 127, 27, TEXT_COLOR);
|
||
}
|
||
|
||
/* =========================================================
|
||
基础命令(全部保留)
|
||
========================================================= */
|
||
|
||
/* 清除指定图层 */
|
||
void Screen_Clear(uint8_t layer)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"DIR(1);CLR(");
|
||
p=buf_u32(p,layer);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 显示指定地址的图片 */
|
||
void Screen_DisplayImage(uint32_t addr)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"DIR(1);FSIMG(");
|
||
p=buf_u32(p,addr);
|
||
p=buf_str(p,",0,0,128,128,0);\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 设置屏幕亮度 */
|
||
void Screen_SetBrightness(uint8_t val)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"BL(");
|
||
p=buf_u32(p,val);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 设置屏幕旋转方向 */
|
||
void Screen_SetRotation(uint8_t dir)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"DIR(");
|
||
p=buf_u32(p,dir);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 设置串口波特率 */
|
||
void Screen_SetBaud(uint32_t baud)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"BPS(");
|
||
p=buf_u32(p,baud);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 在指定位置显示图片 */
|
||
void Screen_DisplayImageAtAddr(uint32_t addr,uint16_t x,uint16_t y,uint16_t w,uint16_t h,uint8_t mode)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"FSIMG(");
|
||
p=buf_u32(p,addr); txbuf[p++]=',';
|
||
p=buf_u32(p,x); txbuf[p++]=',';
|
||
p=buf_u32(p,y); txbuf[p++]=',';
|
||
p=buf_u32(p,w); txbuf[p++]=',';
|
||
p=buf_u32(p,h); txbuf[p++]=',';
|
||
p=buf_u32(p,mode);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 通过索引显示图片 */
|
||
void Screen_DisplayImageByIndex(uint32_t index,uint16_t x,uint16_t y,uint16_t w,uint16_t h,uint8_t mode)
|
||
{
|
||
Screen_DisplayImageAtAddr(index,x,y,w,h,mode);
|
||
}
|
||
|
||
/* 绘制单个像素点 */
|
||
void Screen_Pixel(uint16_t x,uint16_t y,uint8_t color)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"PS(");
|
||
p=buf_u32(p,x); txbuf[p++]=',';
|
||
p=buf_u32(p,y); txbuf[p++]=',';
|
||
p=buf_u32(p,color);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 绘制直线 */
|
||
void Screen_Line(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint8_t color)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"PL(");
|
||
p=buf_u32(p,x1); txbuf[p++]=',';
|
||
p=buf_u32(p,y1); txbuf[p++]=',';
|
||
p=buf_u32(p,x2); txbuf[p++]=',';
|
||
p=buf_u32(p,y2); txbuf[p++]=',';
|
||
p=buf_u32(p,color);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 绘制矩形框 */
|
||
void Screen_Box(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint8_t color)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"BOX(");
|
||
p=buf_u32(p,x1); txbuf[p++]=',';
|
||
p=buf_u32(p,y1); txbuf[p++]=',';
|
||
p=buf_u32(p,x2); txbuf[p++]=',';
|
||
p=buf_u32(p,y2); txbuf[p++]=',';
|
||
p=buf_u32(p,color);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 绘制填充矩形 */
|
||
void Screen_BoxFill(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint8_t color)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"BOXF(");
|
||
p=buf_u32(p,x1); txbuf[p++]=',';
|
||
p=buf_u32(p,y1); txbuf[p++]=',';
|
||
p=buf_u32(p,x2); txbuf[p++]=',';
|
||
p=buf_u32(p,y2); txbuf[p++]=',';
|
||
p=buf_u32(p,color);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 绘制圆形 */
|
||
void Screen_Circle(uint16_t x,uint16_t y,uint16_t r,uint8_t color)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"CIR(");
|
||
p=buf_u32(p,x); txbuf[p++]=',';
|
||
p=buf_u32(p,y); txbuf[p++]=',';
|
||
p=buf_u32(p,r); txbuf[p++]=',';
|
||
p=buf_u32(p,color);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 绘制填充圆形 */
|
||
void Screen_CircleFill(uint16_t x,uint16_t y,uint16_t r,uint8_t color)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"CIRF(");
|
||
p=buf_u32(p,x); txbuf[p++]=',';
|
||
p=buf_u32(p,y); txbuf[p++]=',';
|
||
p=buf_u32(p,r); txbuf[p++]=',';
|
||
p=buf_u32(p,color);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 设置背景颜色 */
|
||
void Screen_SetBGColor(uint8_t color)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"SBC(");
|
||
p=buf_u32(p,color);
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* =========================================================
|
||
GBK核心(所有字号)
|
||
========================================================= */
|
||
|
||
/* 绘制GBK文本的核心函数 */
|
||
static void draw_gbk(const char *cmd,
|
||
uint16_t x,uint16_t y,
|
||
const uint8_t *gbk,uint16_t len,
|
||
uint8_t color,
|
||
uint8_t extra,
|
||
uint8_t has_extra)
|
||
{
|
||
uint16_t p=0;
|
||
|
||
p=buf_str(p,cmd);
|
||
txbuf[p++]='(';
|
||
p=buf_u32(p,x); txbuf[p++]=',';
|
||
p=buf_u32(p,y); txbuf[p++]=',';
|
||
txbuf[p++]='\'';
|
||
|
||
memcpy(&txbuf[p],gbk,len);
|
||
p+=len;
|
||
|
||
txbuf[p++]='\'';
|
||
txbuf[p++]=',';
|
||
p=buf_u32(p,color);
|
||
|
||
if(has_extra){
|
||
txbuf[p++]=',';
|
||
p=buf_u32(p,extra);
|
||
}
|
||
|
||
p=buf_str(p,");\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/* 16号字体GBK文本绘制 */
|
||
void Screen_DrawText16_GBK(uint16_t x,uint16_t y,const uint8_t *g,uint16_t l,uint8_t c){draw_gbk("DC16",x,y,g,l,c,0,0);}
|
||
void Screen_DrawText16V_GBK(uint16_t x,uint16_t y,const uint8_t *g,uint16_t l,uint8_t c){draw_gbk("DCV16",x,y,g,l,c,0,0);}
|
||
|
||
/* 24号字体GBK文本绘制 */
|
||
void Screen_DrawText24_GBK(uint16_t x,uint16_t y,const uint8_t *g,uint16_t l,uint8_t c){draw_gbk("DC24",x,y,g,l,c,0,0);}
|
||
void Screen_DrawText24V_GBK(uint16_t x,uint16_t y,const uint8_t *g,uint16_t l,uint8_t c){draw_gbk("DCV24",x,y,g,l,c,0,0);}
|
||
|
||
/* 32号字体GBK文本绘制 */
|
||
void Screen_DrawText32_GBK(uint16_t x,uint16_t y,const uint8_t *g,uint16_t l,uint8_t c){draw_gbk("DC32",x,y,g,l,c,0,0);}
|
||
void Screen_DrawText32V_GBK(uint16_t x,uint16_t y,const uint8_t *g,uint16_t l,uint8_t c){draw_gbk("DCV32",x,y,g,l,c,0,0);}
|
||
|
||
/* 48号字体GBK文本绘制 */
|
||
void Screen_DrawText48_GBK(uint16_t x,uint16_t y,const uint8_t *g,uint16_t l,uint8_t c,uint8_t t)
|
||
{draw_gbk("DC48",x,y,g,l,c,t,1);}
|
||
|
||
/* =========================================================
|
||
版本查询
|
||
========================================================= */
|
||
|
||
/* 查询屏幕版本信息 */
|
||
void Screen_Ver(void)
|
||
{
|
||
uint16_t p=0;
|
||
p=buf_str(p,"VER();\r\n");
|
||
send_buf(p);
|
||
}
|
||
|
||
/**
|
||
* @brief 清除内容区(保留标题和边框)
|
||
* @note 假设屏幕分辨率 128x128,标题高度28像素,边框占1像素
|
||
*/
|
||
void Screen_ClearContent(void)
|
||
{
|
||
elog_i("Screen", "Clearing screen content...");
|
||
// 内容区域坐标:
|
||
// 左上角 x=1, y=28(标题下方一行)
|
||
// 右下角 x=126, y=127(屏幕右下角)
|
||
Screen_BoxFill(1, 28, 126, 127, BG_COLOR);
|
||
}
|