#include "lcd.h" #include "lcd_init.h" #include "lcdfont.h" #include "spi.h" #include "cmsis_os.h" extern osSemaphoreId_t DMA_SemaphoreHandle; /****************************************************************************** 函数说明:在指定区域填充颜色 入口数据:xsta,ysta 起始坐标 xend,yend 终止坐标 color 要填充的颜色 返回值: 无 ******************************************************************************/ void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color) { u16 i,j; LCD_Address_Set(xsta, ysta,xend-1, yend-1);//设置显示范围 for(i=ysta;iCR1 |= SPI_CR1_DFF; // 置位 DFF,启用 16 位数据帧 __HAL_SPI_ENABLE(&hspi2); // 3. 启动 DMA 传输 HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)color_p, count); } static void *lcd_ready_cb = NULL; // 设置通知的回调函数 void LCD_Set_Flush_Complete_Callback(void *cb) { // 保存回调指针 lcd_ready_cb = cb; } // DMA 传输完成中断回调 void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI2) { // 1. 死等 SPI 总线发完最后 1 bit while (hspi->Instance->SR & SPI_FLAG_BSY); // 2. 安全切回 8-bit 模式 (为下一次发送命令做准备) __HAL_SPI_DISABLE(hspi); hspi->Instance->CR1 &= ~SPI_CR1_DFF; // 清除 DFF,回退到 8 位 __HAL_SPI_ENABLE(hspi); // 3. 通知 LVGL 渲染结束,执行回调函数 if (lcd_ready_cb) { LCD_CallbackFunc_t func = (LCD_CallbackFunc_t)lcd_ready_cb; func(); } } } /****************************************************************************** 函数说明:在指定位置画点 入口数据:x,y 画点坐标 color 点的颜色 返回值: 无 ******************************************************************************/ void LCD_DrawPoint(u16 x,u16 y,u16 color) { LCD_Address_Set(x,y,x,y);//设置光标位置 LCD_WR_DATA(color); } /****************************************************************************** 函数说明:画线 入口数据:x1,y1 起始坐标 x2,y2 终止坐标 color 线的颜色 返回值: 无 ******************************************************************************/ void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color) { u16 t; int xerr=0,yerr=0,delta_x,delta_y,distance; int incx,incy,uRow,uCol; delta_x=x2-x1; //计算坐标增量 delta_y=y2-y1; uRow=x1;//画线起点坐标 uCol=y1; if(delta_x>0)incx=1; //设置单步方向 else if (delta_x==0)incx=0;//垂直线 else {incx=-1;delta_x=-delta_x;} if(delta_y>0)incy=1; else if (delta_y==0)incy=0;//水平线 else {incy=-1;delta_y=-delta_y;} if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 else distance=delta_y; for(t=0;tdistance) { xerr-=distance; uRow+=incx; } if(yerr>distance) { yerr-=distance; uCol+=incy; } } } /****************************************************************************** 函数说明:画矩形 入口数据:x1,y1 起始坐标 x2,y2 终止坐标 color 矩形的颜色 返回值: 无 ******************************************************************************/ void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color) { LCD_DrawLine(x1,y1,x2,y1,color); LCD_DrawLine(x1,y1,x1,y2,color); LCD_DrawLine(x1,y2,x2,y2,color); LCD_DrawLine(x2,y1,x2,y2,color); } /****************************************************************************** 函数说明:画圆 入口数据:x0,y0 圆心坐标 r 半径 color 圆的颜色 返回值: 无 ******************************************************************************/ void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color) { int a,b; a=0;b=r; while(a<=b) { LCD_DrawPoint(x0-b,y0-a,color); //3 LCD_DrawPoint(x0+b,y0-a,color); //0 LCD_DrawPoint(x0-a,y0+b,color); //1 LCD_DrawPoint(x0-a,y0-b,color); //2 LCD_DrawPoint(x0+b,y0+a,color); //4 LCD_DrawPoint(x0+a,y0-b,color); //5 LCD_DrawPoint(x0+a,y0+b,color); //6 LCD_DrawPoint(x0-b,y0+a,color); //7 a++; if((a*a+b*b)>(r*r))//判断要画的点是否过远 { b--; } } } /****************************************************************************** 函数说明:显示汉字串 入口数据:x,y显示坐标 *s 要显示的汉字串 fc 字的颜色 bc 字的背景色 sizey 字号 可选 16 24 32 mode: 0非叠加模式 1叠加模式 返回值: 无 ******************************************************************************/ void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode) { while(*s!=0) { if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode); else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode); else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode); else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode); else return; s+=2; x+=sizey; } } /****************************************************************************** 函数说明:显示单个12x12汉字 入口数据:x,y显示坐标 *s 要显示的汉字 fc 字的颜色 bc 字的背景色 sizey 字号 mode: 0非叠加模式 1叠加模式 返回值: 无 ******************************************************************************/ void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode) { u8 i,j,m=0; u16 k; u16 HZnum;//汉字数目 u16 TypefaceNum;//一个字符所占字节大小 u16 x0=x; TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey; HZnum=sizeof(tfont12)/sizeof(typFNT_GB12); //统计汉字数目 for(k=0;k