天天看點

STM32F4制作一個電腦(二) 界面

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.效果

STM32F4制作一個電腦(二) 界面

注:這個是原子的STM32F4闆子,我記得這個屏的觸摸代碼是有問題的。原子的程式需要改一下。

u8 GT9147_Scan(u8 modex)這個函數要修改一下:

//if(mode&0X80&&((mode&0XF)<6))
          {
             temp=0;
             GT9147_WR_Reg(GT_GSTID_REG,&temp,1);//清标志         
          } 
           

注釋掉那個條件判斷。詳細看IC的手冊,清标志是不應該做條件判斷的。我一步步跟蹤,調試了很久很久才找到這個根源。

繼續閱讀