/* 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 #include #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); }