STM32F4制作一個電腦(二) 界面
1.窗體
雖然用UCGUI之類會更友善,但為了友善移植,自己寫了個簡單的
#include "MYGUI.h"
void GUI_SetPColor(u16 c)
{
POINT_COLOR = c;
}
void GUI_SetBColor(u16 c)
{
BACK_COLOR = c;
}
void GUI_DrawHLine(u16 y,u16 x0,u16 x1)
{
LCD_Fill(x0,y,x1,y,POINT_COLOR);
}
void GUI_DrawVLine(u16 x,u16 y0,u16 y1)
{
LCD_Fill(x,y0,x,y1,POINT_COLOR);
}
void GUI_DrawRect(u16 x0, u16 y0, u16 x1,u16 y1)
{
LCD_Fill(x0,y0,x0,y1,POINT_COLOR);
LCD_Fill(x1,y0,x1,y1,POINT_COLOR);
LCD_Fill(x0,y0,x1,y0,POINT_COLOR);
LCD_Fill(x0,y1,x1,y1,POINT_COLOR);
}
void GUI_DrawZoomRect(const GUI_RECT *r ,const s16 dh,const s16 dv)
{
GUI_DrawRect(r->x0-dh, r->y0-dv,r->x1+dh,r->y1+dv);
}
void GUI_FocusRect( const GUI_RECT *r ,const u16 d)
{
GUI_DrawRect(r->x0-d, r->y0-d,r->x1+d,r->y1+d);
}
void GUI_MoveRect( const GUI_RECT *r ,const s16 dh,const s16 dv)
{
GUI_DrawRect(r->x0+dh, r->y0+dv,r->x1+dh,r->y1+dv);
}
void GUI_GradualRect( const GUI_RECT *r ,const u16 d,u16 scolor ,u16 ecolor)
{
// u8 i=d;
// u8 sr=((scolor>>11)<<3),sg=(((scolor&0x07e0)>>5)<<2),sb=((scolor&0x001f)<<3);
// u8 er=((ecolor>>11)<<3),eg=(((ecolor&0x07e0)>>5)<<2),eb=((ecolor&0x001f)<<3);
// while(i)
// {
// //GUI_SetPColor( )
// GUI_DrawZoomRect( r ,i,i);
// i--;
// }
}
void GUIX_ZoomRect(GUI_RECT *r ,const s16 dh,const s16 dv )
{
r->x0-=dh,r->x1+=dh;
r->y0-=dv,r->y1+=dv;
}
void GUIX_MoveRect(GUI_RECT *r ,const s16 dh,const s16 dv )
{
r->x0+=dh,r->x1+=dh;
r->y0+=dv,r->y1+=dv;
}
void GUI_ShowWindow( const GUI_RECT *r,const u16 c)
{
LCD_Fill(r->x0, r->y0, r->x1, r->y1,c);
GUI_SetPColor(0x0000);
GUI_DrawRect(r->x0, r->y0, r->x1, r->y1); /* Draw rectangle around it */
/* Draw the bright sides */
GUI_SetPColor(0xffff);
GUI_DrawHLine(r->y0 + 1, r->x0 + 1, r->x1 - 2); /* Draw top line */
GUI_DrawVLine(r->x0 + 1, r->y0 + 1, r->y1 - 2);
/* Draw the dark sides */
GUI_SetPColor(RGB888TO565(0X666666));
GUI_DrawHLine(r->y1-1, r->x0 + 1, r->x1 - 1);
GUI_DrawVLine(r->x1-1, r->y0 + 1, r->y1 - 2);
}
上面都是基本函數,其實效果就像一個按鈕。
//畫背景
static void cDrawBackground( )
{
#define _GRAPH (C_HPSIZE-C_ZTSIZE/2)/2
#define _GRAPV (C_VPSIZE-C_ZTSIZE)/2
GUI_RECT r;
u16 x0=g_CalcUI.x0 ;
u16 y0=g_CalcUI.y0 ;
r.x0=x0;r.y0 =y0;r.x1 = x0+C_HWSIZE;r.y1=y0+C_VWSIZE;
GUI_ShowWindow(&r,g_CalcUI.wcolor );
//grap
GUI_SetPColor( TORGB565(230,233,230) );
GUI_DrawHLine(y0+C_VPSIZE*2, x0 + 2, r.x1 - 2);
GUI_DrawHLine(y0+C_VPSIZE*3, x0 + 2, r.x1 - 2);
GUI_DrawHLine(y0+C_VPSIZE*4, x0 + 2, r.x1 - 2);
GUI_DrawHLine(y0+C_VPSIZE*5, x0 + 2, r.x1 - 2);
GUI_DrawHLine(y0+C_VPSIZE*6, x0 + 2, r.x1 - 2-C_HPSIZE);
GUI_DrawVLine(x0+C_HPSIZE*1, y0 + C_VPSIZE*2 +1, r.y1-2-C_VPSIZE);
GUI_DrawVLine(x0+C_HPSIZE*2, y0 + C_VPSIZE*3 +1, r.y1-2);
GUI_DrawVLine(x0+C_HPSIZE*3, y0 + C_VPSIZE*2 +1, r.y1-2);
GUI_DrawVLine(x0+C_HPSIZE*4, y0 + C_VPSIZE*2 +1, r.y1-2);
cDrawTextbox( &r );
GUI_SetPColor( g_CalcUI.wfcolor);
LCD_ShowChar( x0+ _GRAPH -C_ZTSIZE/4 , y0+ _GRAPV + (C_VPSIZE*2),'<',24,1);LCD_ShowChar( x0+ _GRAPH+C_ZTSIZE/4 , y0+ _GRAPV + (C_VPSIZE*2),'-',24,1);
LCD_ShowChar( x0+ _GRAPH , y0+ _GRAPV + (C_VPSIZE*3),'7',24,1);
LCD_ShowChar( x0+ _GRAPH , y0+ _GRAPV + (C_VPSIZE*4),'4',24,1);
LCD_ShowChar( x0+ _GRAPH , y0+ _GRAPV + (C_VPSIZE*5),'1',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE/2 , y0+ _GRAPV + (C_VPSIZE*6),'0',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE/2+ C_HPSIZE , y0+ _GRAPV + (C_VPSIZE*2),'C',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE , y0+ _GRAPV + (C_VPSIZE*3),'8',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE , y0+ _GRAPV + (C_VPSIZE*4),'5',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE , y0+ _GRAPV + (C_VPSIZE*5),'2',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*2 , y0+ _GRAPV + (C_VPSIZE*3),'9',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*2 , y0+ _GRAPV + (C_VPSIZE*4),'6',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*2 , y0+ _GRAPV + (C_VPSIZE*5),'3',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*2 , y0+ _GRAPV + (C_VPSIZE*6),'.',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*3 , y0+ _GRAPV + (C_VPSIZE*2) + C_ZTSIZE/4 , '-',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*3 , y0+ _GRAPV + (C_VPSIZE*2) - C_ZTSIZE/8 ,'+',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*3 , y0+ _GRAPV + (C_VPSIZE*3),'/',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*3 , y0+ _GRAPV + (C_VPSIZE*4),'*',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*3 , y0+ _GRAPV + (C_VPSIZE*5),'-',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*3 , y0+ _GRAPV + (C_VPSIZE*6),'+',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*4 , y0+ _GRAPV + (C_VPSIZE*3),'%',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*4 - C_ZTSIZE/2 , y0+ _GRAPV + (C_VPSIZE*4) ,'1',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*4 , y0+ _GRAPV + (C_VPSIZE*4) ,'/',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*4 + C_ZTSIZE/2 , y0+ _GRAPV + (C_VPSIZE*4) ,'x',24,1);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*4 , y0+ _GRAPV + (C_VPSIZE*5) + C_VPSIZE/2,'=',24,1);
//X号
GUI_SetPColor( RED);
LCD_ShowChar( x0+ _GRAPH + C_HPSIZE*4 , y0+ _GRAPV + (C_VPSIZE*2),'X',24,1);
}
//畫文本框
static void cDrawTextbox(const GUI_RECT *r)
{
u16 x0=r->x0+6;
u16 x1=r->x0+C_HWSIZE-6;
u16 y0=r->y0+6;
u16 y1=r->y0 + C_VPSIZE*2-12;
LCD_Fill(x0,y0,x1,y1, g_CalcUI.tcolor);
GUI_SetPColor( g_CalcUI.tfcolor);
GUI_DrawRect(x0+2, y0+2, x1-2, y1-2);
LCD_ShowChar(x0+8,y0+2+ (C_VPSIZE-C_ZTSIZE)/2 -3-6 + (C_VPSIZE-3),'0',24,0);
}
//文本框清0
static void cClearTextbox(const u16 x0,const u16 y0)
{
u16 x=x0+6;
u16 x1=x0+C_HWSIZE-6;
u16 y=y0+6;
u16 y1=y0 + C_VPSIZE*2-12;
LCD_Fill(x+4,y+4,x1-4,y1-4, g_CalcUI.tcolor);
GUI_SetPColor( g_CalcUI.tfcolor);
LCD_ShowChar(x+8,y+2+ (C_VPSIZE-C_ZTSIZE)/2 -3-6 + (C_VPSIZE-3),'0',24,0);
}
//在文本框顯示單個字元
void txtbox_showChar(u8 kcode,u8 idx,u8 upORdown) //UP -0,DOWN-1
{
u8 code=kcode;
u16 x0=g_CalcUI.x0+8+6,y0=g_CalcUI.y0+2+ (C_VPSIZE-C_ZTSIZE)/2 -3 + (C_VPSIZE-3)*upORdown;
LCD_ShowChar(x0 + idx *C_ZTSIZE/2,y0,code ,24,0);
}
還有訓示按下焦點的函數
// x,y 位置
//isTouch 是否按下
static u8 cplay_touchFocus( const u16 x,const u16 y,u8 isTouch)
{
u16 x0 = g_CalcUI.x0 , y0 = g_CalcUI.y0;
u8 keyval=0xff;
if( x>x0 && x<x0+C_HWSIZE-2 && y>y0+C_VPSIZE*2 && y<y0+C_VWSIZE-2 )
{
u8 xy=0;
u16 xt = (x-x0+1)/C_HPSIZE,yt=(y-y0+1-C_VPSIZE*2)/C_VPSIZE;
xy= (yt<<4)+xt ;
switch(xy)
{
case 0 + 0 : //<-
keyval=17;
break ;
case (1<<4)+0:
keyval=7;
break;
case (2<<4)+0:
keyval=4;
break;
case (3<<4)+0:
keyval=1;
break;
case (4<<4)+0:
keyval=0;
break;
case 0+ 1:
keyval=18;
break ;
case (1<<4)+1:
keyval=8;
break;
case (2<<4)+1:
keyval=5;
break;
case (3<<4)+1:
keyval=2;
break;
case (4<<4)+1:
keyval=0;
break;
case 0+ 2:
keyval=18;//c
break ;
case (1<<4)+2:
keyval=9;
break;
case (2<<4)+2:
keyval=6;
break;
case (3<<4)+2:
keyval=3;
break;
case (4<<4)+2:
keyval=10;// .
break;
case 0+ 3: //+-
keyval=19;
break ;
case (1<<4)+3: // /
keyval=14;
break;
case (2<<4)+3: //*
keyval=13;
break;
case (3<<4)+3: // -
keyval=12;
break;
case (4<<4)+3:// +
keyval=11;
break;
case 0+ 4: // x 退出
keyval=21;
break ;
case (1<<4)+4://%
keyval=16;
break;
case (2<<4)+4:// 1/x
keyval=15;
break;
case (3<<4)+4://=
case (4<<4)+4:
keyval=20;
break;
}
if(xt<=4 && yt<=4)
{
GUI_RECT r;
r.x0= x0+2,r.y0=y0+2+C_VPSIZE*2,r.x1=r.x0+C_HPSIZE-3,r.y1=r.y0+C_VPSIZE-3;
if( isTouch )
GUI_SetPColor( FOCUS_COLOR );
else
GUI_SetPColor( g_CalcUI.wcolor );
if( keyval == 0 )
{
r.x1+=C_HPSIZE;
xt=0;
}
else if( keyval == 18 )
{
r.x1+=C_HPSIZE;
xt=1;
}
else if( keyval == 20 )
{
r.y1+=C_VPSIZE;
yt=3;
}
//
GUIX_MoveRect(&r , xt * (C_HPSIZE), yt* (C_VPSIZE) ) ;
GUI_DrawZoomRect(&r , 0, 0 );
GUI_DrawZoomRect(&r , -1, -1 );
GUI_DrawZoomRect(&r , -2, -2 );
GUI_DrawZoomRect(&r , -3, -3 );
}
}
return keyval ;
}
2.效果
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9QzVZ5GbtlFcwNjW1ZkMkZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DO5UTMzYTMzIjNyEDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
注:這個是原子的STM32F4闆子,我記得這個屏的觸摸代碼是有問題的。原子的程式需要改一下。
u8 GT9147_Scan(u8 modex)這個函數要修改一下:
//if(mode&0X80&&((mode&0XF)<6))
{
temp=0;
GT9147_WR_Reg(GT_GSTID_REG,&temp,1);//清标志
}
注釋掉那個條件判斷。詳細看IC的手冊,清标志是不應該做條件判斷的。我一步步跟蹤,調試了很久很久才找到這個根源。