• 專注電子技術學習與研究
    當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

    ST7920 12864 經典函數

    作者:佚名   來源:不詳   點擊數:  更新時間:2014年08月17日   【字體:

     void  LCD12864Init(void)           //LCD12864字庫初始化程序

    {
     Delay_nms(100); //大于40MS的延時程序             
     PSB = 1;  //設置為8BIT并口工作模式
     Delay_nus(1);
     RST = 0;
     Delay_nms(100); //大于40MS的延時程序              
     RST = 1;  //復位置高
     Delay_nms(100);
     
     
     Delay_nms(50);
     LCD12864_Write(COMMAND,0x30);  //Extended Function Set :8BIT設置,RE=0: basic instruction set, G=0 :graphic display OFF
     Delay_nms(120);         //大于100uS的延時程序
     LCD12864_Write(COMMAND,0x30);  //Function Set
     Delay_nms(40);          //大于37uS的延時程序
     LCD12864_Write(COMMAND,0xC0);  //Display on Control
     Delay_nms(120);         //大于100uS的延時程序
     LCD12864_Write(COMMAND,0x10);  //Cursor Display Control光標設置
     Delay_nms(120);         //大于100uS的延時程序
     LCD12864_Write(COMMAND,0x0C);  //Display Control,D=1,顯示開
     Delay_nms(120);         //大于100uS的延時程序
     LCD12864_Write(COMMAND,0x01);  //Display Clear
     Delay_nms(15);          //大于10mS的延時程序
     LCD12864_Write(COMMAND,0x06);  //Enry Mode Set,光標從右向左加1位移動
     Delay_nms(120);         //大于100uS的延時程序
     
     
    }
     
    void LCD12864WaitForReady(void)
    {
        unsigned char temp;
    #ifdef _Use_LCD12864OnlyWrite
     Delay_nus(30);
    #else
     LCD12864_SetReadData;
     LCD12864_RS = 0;
     LCD12864_RW = 1;
       
     do
     {
            LCD12864_EN = Enable;
      Delay_nus(1); 
      temp = LCD12864_Data_PIN;
      Delay_nus(1);
      LCD12864_EN = Disable;
     }while (temp & 0x80);  //RW=1,讀PD7,為0表示空閑;
      
        LCD12864_EN = Disable;
     LCD12864_SetWriteData;
     
    #endif
    }
     
    void LCD12864_Write(unsigned char cmdordata,unsigned char Data)  //傳送數據或者命令,當cmdordata=0是,傳送命令,當cmdordata=1,傳送數據.
    {
        LCD12864WaitForReady();
     LCD12864_EN = 0;
     LCD12864_RW = 0;
     Delay_nus(1);
     if(cmdordata == 0)
     {
      LCD12864_RS = 0;
     }
     else
     {
      LCD12864_RS = 1;
     }
     Delay_nus(1);
     LCD12864_Data_Port = Data;
     LCD12864_EN = 1;
     Delay_nus(1);
     LCD12864_EN = 0;
    }
     
    unsigned char LCD12864_Read(void)
    {
     unsigned char data;
        LCD12864WaitForReady();
     LCD12864_SetReadData;
     LCD12864_RS = 1;
     Delay_nus(1);
     LCD12864_RW = 1;
        Delay_nus(1);
     LCD12864_EN = 1;
     Delay_nus(1);
     data = LCD12864_Data_PIN;
     LCD12864_EN = 0;
     LCD12864_SetWriteData;
     return data;
    }
    void LCD12864_Clean(void)
    {
        unsigned char x,y;
        LCD12864_Write(COMMAND,GRAPH_ON);
        LCD12864Init();     //設置擴展指令集,按手冊說明,僅設置了繪圖位,
        LCD12864_Write(COMMAND,GRAPH_ON); //需要兩次,本次設置擴展指令集。
     
        for (y=0;y<32;y++)
        {
            LCD12864_Write(COMMAND,0x80+y); //設置y=0000+000x,y+1則往下一行
            LCD12864_Write(COMMAND,0x80); //設置x=0000 0000
            for (x=0;x<16;x++)
            {
                LCD12864_Write(DATA,0x00);   //高字節數據
                LCD12864_Write(DATA,0x00); //低字節數據
            }
        }
    }
    void Serial_DDRAM_Address_Set(unsigned char ucDDramAdd)
    {
     LCD12864_Write(COMMAND,BASIC_FUNCTION);   //基本指令集
     LCD12864_Write(COMMAND,ucDDramAdd);    //設定DDRAM地址到地址計數器AC
    }
    void Overturn_Char(unsigned char x,unsigned char y,unsigned char wide,unsigned char cor)
    {
        unsigned char i,base_x,colour;
     if(cor == 1) colour = 0xFF;
     if(cor == 0) colour = 0x00;
     LCD12864_Write(COMMAND,GRAPH_OFF);
     if(y == 1 || y == 2)    base_x = 0x80;
     if(y == 3 || y == 4)    base_x = 0x88;
        if(x % 2)
     {
         for(i = 0;i < wide; i ++)
      {
             LCD12864_Write(COMMAND,0X80 - 16 + y * 16 + i);
             LCD12864_Write(COMMAND,base_x+(x/2));
          LCD12864_Write(DATA,colour);
          LCD12864_Write(DATA,0x00);
      }
     }
     else
     {
         for(i = 0;i < wide; i ++)
      {
             LCD12864_Write(COMMAND,0X80 - 16 + y * 16 + i);
             LCD12864_Write(COMMAND,base_x+(x/2)-1);
          LCD12864_Write(DATA,0x00);
          LCD12864_Write(DATA,colour);
      }
     } 
     LCD12864_Write(COMMAND,GRAPH_ON);  
    }
    void Overturn_Font(unsigned char x,unsigned char y,unsigned char wide,unsigned char cor)
    {
        unsigned char i,base_x,colour;
     if(cor == 1) colour = 0xFF;
     if(cor == 0) colour = 0x00;
     LCD12864_Write(COMMAND,GRAPH_OFF);
     if(y == 1 || y == 2)    base_x = 0x80;
     if(y == 3 || y == 4)    base_x = 0x88;
     
        for(i = 0;i < wide;i ++)
     {
         LCD12864_Write(COMMAND,0X80 - 16 + y * 16 + i); //- 16 + y * 16 + i);
         LCD12864_Write(COMMAND,base_x+x-1);
      LCD12864_Write(DATA,colour);
      LCD12864_Write(DATA,colour);
     }
     LCD12864_Write(COMMAND,GRAPH_ON);
    }
    void GUI_Point(unsigned char y,unsigned char x,unsigned colour)
    {
        unsigned char GDRAM_hbit,GDRAM_lbit;
        unsigned char x_Dyte,x_byte;                 //定義列地址的字節位,及在字節中的哪1位
        unsigned char y_Dyte,y_byte;       
        x--;y--;          //定義為上下兩個屏(取值為0,1),行地址(取值為0~31)
       
        x_Dyte=y/16;                                         //計算在16個字節中的哪一個
        x_byte=y&0x0f;                                     //計算在該字節中的哪一位
        y_Dyte=x/32;                                         //0為上半屏,1為下半屏
        y_byte=x&0x1f;                                     //計算在0~31當中的哪一行
       
        LCD12864_Write(COMMAND,0x80+y_byte);                     //設定行地址(y坐標)
        LCD12864_Write(COMMAND,0x80+x_Dyte+8*y_Dyte);         //設定列地址(x坐標),并通過8*y_Dyte選定上下屏
                               
        LCD12864_Read();
        GDRAM_hbit=LCD12864_Read();                         //讀取當前顯示高8位數據
        GDRAM_lbit=LCD12864_Read();                         //讀取當前顯示低8位數據
        Delay_nus(1);
       
        if(colour==1)
        {
      LCD12864_Write(COMMAND,0x80+y_byte);                     //設定行地址(y坐標)
      LCD12864_Write(COMMAND,0x80+x_Dyte+8*y_Dyte);         //設定列地址(x坐標),并通過8*y_Dyte選定上下屏
      Delay_nus(1);
     
            if(x_byte<8)                                             //判斷其在高8位,還是在低8位
      {
       LCD12864_Write(DATA,GDRAM_hbit|(0X01<<(7-x_byte)));     //顯示GDRAM區高8位數據
       LCD12864_Write(DATA,GDRAM_lbit);                             //顯示GDRAM區低8位數據
            }
            else
            {
       LCD12864_Write(DATA,GDRAM_hbit);
       LCD12864_Write(DATA,GDRAM_lbit|(0x01<<(15-x_byte)));
            }
        }
        else
        {
      LCD12864_Write(COMMAND,0x80+y_byte);                     //設定行地址(y坐標)
      LCD12864_Write(COMMAND,0x80+x_Dyte+8*y_Dyte);         //設定列地址(x坐標),并通過8*y_Dyte選定上下屏
      Delay_nus(1);
     
            if(x_byte<8)                                             //判斷其在高8位,還是在低8位
      {
       LCD12864_Write(DATA,GDRAM_hbit & ~(0X01<<(7-x_byte)));     //顯示GDRAM區高8位數據
       LCD12864_Write(DATA,GDRAM_lbit);                             //顯示GDRAM區低8位數據
            }
            else
            {
       LCD12864_Write(DATA,GDRAM_hbit);
       LCD12864_Write(DATA,GDRAM_lbit & ~(0x01<<(15-x_byte)));
            }
     }
     
    }
     
    void GUI_Line(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char colour)
    {
        int temp;
        int dx,dy;               //定義起點到終點的橫、縱坐標增加值
        int s1,s2,status,i;
        int Dx,Dy,sub;
     
        dx = x1 - x0;
        if(dx >= 0)                 //X的方向是增加的
            s1 = 1;
        else                     //X的方向是降低的
            s1 = -1;    
        dy = y1 - y0;                 //判斷Y的方向是增加還是降到的
        if(dy >= 0)
            s2 = 1;
        else
            s2 =- 1;
     
        Dx = abs(x1-x0);             //計算橫、縱標志增加值的絕對值
        Dy = abs(y1-y0);
          
        if(Dy > Dx)                             
        {                     //以45度角為分界線,靠進Y軸是status=1,靠近X軸是status=0
            temp = Dx;
            Dx = Dy;
            Dy = temp;
        status = 1;
        }
        else
            status = 0;
     
     
     
        sub = Dy + Dy - Dx;                 //第1次判斷下個點的位置
        for(i = 0;i < Dx;i ++)
        {
            GUI_Point(x0,y0,colour);           //畫點
            if(sub >= 0)                              
            {
                if(status == 1)               //在靠近Y軸區,x值加1
                    x0 += s1;
                else                     //在靠近X軸區,y值加1              
                    y0 += s2;
                sub -= (Dx + Dx);                 //判斷下下個點的位置
            }
            if(status == 1)
                y0 += s2;
            else      
                x0 += s1;
            sub += Dy + Dy;
           
        }
    }
     
    void plotC(int x,int y,int xc,int yc,unsigned char colour)
    {
        GUI_Point(xc+x,yc+y,colour);
        GUI_Point(xc+x,yc-y,colour);
        GUI_Point(xc-x,yc+y,colour);
        GUI_Point(xc-x,yc-y,colour);
        GUI_Point(xc+y,yc+x,colour);
        GUI_Point(xc+y,yc-x,colour);
        GUI_Point(xc-y,yc+x,colour);
        GUI_Point(xc-y,yc-x,colour);
    }
     
    void GUI_Circle(int xc,int yc,int r,unsigned char colour)
    {
        int x,y,d;
        y = r;
        d = 3 - (r + r);
        x = 0;
        while(x <= y)
        {
            plotC(x,y,xc,yc,colour);
            if(d < 0)
                d += (x + x + x + x) + 6;
            else
            {
                d+=((x - y) + (x - y) + (x - y) + (x - y)) + 10;
                y = y - 1;
            }
            x = x + 1;
        }
    }
    void GUI_Full(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char colour)
    {
        unsigned char i,j;
     for(j = y0;j <= y1;j ++)
         for(i = x0;i <= x1;i ++)
          GUI_Point(i,j,colour);
    }
     
     
     
     
    關閉窗口
    亚洲一区二区制服在线|在绩专区欧美自拍日韩|青春娱乐网97超碰人人射|在线观看国产网址你懂的