Files
SmartMassager_STM32/Core/Src/screen.c

338 lines
8.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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);
}