mcuhost 发表于 2006-11-10 09:15:05

强烈推荐一款LCM12864(KS0108)的完整应用程序,感觉和“傻孩子”的1206程序有异曲同工之

其中,部分注释是本人注的,大家讨论一下这个程序吧。









/*

KS0108 128*64 LCD C语言驱动

参考ICCAVR资料和网上的资料改写

LCD引脚定义

1---GND

2---VCC

3---VLCD

4---D/I

5---R/W

6---E

7到14 D0-D7

15--CS1

16--CS2

17--RESET

18--VEE

19--SW

20--NC

*/

#include <iom16v.h>

#include <macros.h>



/* 当前行、列存储,行高16点,列宽8点 */

unsigned char CurOffset,CurRow,CurPage,CurCol;       



/*常量定义*/

#define LCD_STATUS_BUSY 0x80

#defineSTART_LINE0   0xc0

#defineDISPLAY_ON    0x3f

#defineDISPLAY_OFF   0x3e

#definePARA1         0x40

//PORTA---数据口PORTB----控制口

#define LCD_DIR_PORT        DDRA

#define LCD_IP_PORT                PINA

#define LCD_OP_PORT                PORTA



#define LCD_EN_PORT                PORTC

#define LCD_CS2_PORT        PORTC

#define LCD_CS1_PORT        PORTC

#define LCD_RW_PORT                PORTC

#define LCD_DI_PORT                PORTC



#define LCD_DI_BIT                BIT(7)//0x80

#define LCD_RW_BIT                BIT(6)//0x40

#define LCD_EN_BIT                BIT(5)//0x20

#define LCD_CS1_BIT                BIT(4)//0x10

#define LCD_CS2_BIT                BIT(3)//0x08



#define SET_LCD_E                LCD_EN_PORT |= LCD_EN_BIT    //LCD使能

#define CLEAR_LCD_E                LCD_EN_PORT &= ~LCD_EN_BIT   //LCD禁止



//以下可能出错,数据指令接口



#define SET_LCD_DATA        LCD_DI_PORT |= LCD_DI_BIT    //选择数据端口

#define SET_LCD_CMD                LCD_DI_PORT &= ~LCD_DI_BIT   //选择指令端口



#define SET_LCD_READ        LCD_RW_PORT |= LCD_RW_BIT    //读模式

#define SET_LCD_WRITE        LCD_RW_PORT &= ~LCD_RW_BIT   //写模式



#define SET_LCD_CS2   LCD_CS2_PORT |= LCD_CS2_BIT//右屏选择禁止

#define CLEAR_LCD_CS2   LCD_CS2_PORT &= ~LCD_CS2_BIT //右屏选择使能



#define SET_LCD_CS1   LCD_CS1_PORT |= LCD_CS1_BIT//左屏选择禁止

#define CLEAR_LCD_CS1   LCD_CS1_PORT &= ~LCD_CS1_BIT //左屏选择使能



#define LEFT 0

#define RIGHT 1

#define CMD 0

#define DATA 1



void LCD_BUSY(unsigned char lr) //判断忙标志。。

{

        unsigned char status;

    CLI();

        if(lr==LEFT)

        {

        //选择左半屏。。

          CLEAR_LCD_CS2; //cs2=0

                SET_LCD_CS1;   //cs1=1

        }

        else

        {

        //选择右半屏。。

                SET_LCD_CS2;   //cs2=1

            CLEAR_LCD_CS1; //cs1=0

        }       

        SET_LCD_CMD;//选择指令端口。。

    LCD_DIR_PORT = 0x00;//数据口方向设置。。

    LCD_OP_PORT = 0xff;//数据口输出高电平。。               

    SET_LCD_READ;//读模式。。

    SET_LCD_E;//LCD使能。。                                       

    asm("nop");        asm("nop");

    asm("nop");        asm("nop");

    while((LCD_IP_PORT) & LCD_STATUS_BUSY)//判断LCD是否忙。。

    {

      CLEAR_LCD_E;//LCD禁止。。                                  

                asm("nop");        asm("nop");

                asm("nop");        asm("nop");

                SET_LCD_E;//LCD使能。。       

                asm("nop");        asm("nop");

                asm("nop");        asm("nop");

    }

    CLEAR_LCD_E;

    SET_LCD_WRITE;//写模式。。

    LCD_OP_PORT = 0xff;//写入显示RAM

    SEI();

}



void write_LCD(unsigned char lr,unsigned char cd,unsigned char data) /*写入指令或数据*/

{       

    CLI();

        LCD_BUSY(lr);

        if(cd==CMD)        SET_LCD_CMD;

        else SET_LCD_DATA;

    SET_LCD_WRITE;

        SET_LCD_E;

    LCD_DIR_PORT = 0xff;

    LCD_OP_PORT = data;

    asm("nop");        asm("nop");

        asm("nop");        asm("nop");

    CLEAR_LCD_E;

    LCD_OP_PORT = 0xff;

    SEI();

}

unsigned char read_LCD(unsigned char lr)          /*读显示数据 */

{

        unsigned char data;



    CLI();

        LCD_BUSY(lr);

        SET_LCD_DATA;

    LCD_DIR_PORT = 0x00;

    LCD_OP_PORT = 0xff;

    SET_LCD_READ;

        SET_LCD_E;

        asm("nop");        asm("nop");

    asm("nop");        asm("nop");

    data=LCD_IP_PORT;

    CLEAR_LCD_E;

    SET_LCD_WRITE;



        LCD_BUSY(lr);

        SET_LCD_DATA;

    LCD_DIR_PORT = 0x00;

    LCD_OP_PORT = 0xff;

    SET_LCD_READ;

        SET_LCD_E;

    asm("nop");        asm("nop");

        asm("nop");        asm("nop");

    data=LCD_IP_PORT;

    CLEAR_LCD_E;

    SET_LCD_WRITE;



    SEI();

        return data;

}



void set_start_line_L(unsigned char line) /*设置显示起始行*/ //0-63

{

        write_LCD(LEFT,CMD,0xc0|line);

}



void set_start_line_R(unsigned char line) /*设置显示起始行*/ //0-63

{

        write_LCD(RIGHT,CMD,0xc0|line);

}



void set_page_L(unsigned char page)        /*设置X地址 设置页*///0-7

{

        write_LCD(LEFT,CMD,0xb8|page);                     

}

void set_page_R(unsigned char page)        /*设置X地址 设置页*/ //0-7

{

        write_LCD(RIGHT,CMD,0xb8|page);                     

}



void set_col_addr_L(unsigned char col) /*设置Y地址*/ //0-63

{

        write_LCD(LEFT,CMD,0x40|col);                     

}



void set_col_addr_R(unsigned char col) /*设置Y地址*/ //0-63

{

        write_LCD(RIGHT,CMD,0x40|col);                     

}



void init_lcd(void) /*初始化函数*/

{

        set_start_line_L(0); /*显示起始行为0*/

        set_start_line_R(0); /*显示起始行为0*/

        write_LCD(LEFT,CMD,DISPLAY_ON); /*开显示*/

        write_LCD(RIGHT,CMD,DISPLAY_ON); /*开显示*/

}



void clr_lcd(void) /*清屏函数*/

{

        unsigned char pages,i;

        for(pages=0;pages<8;pages++)

                {

                        set_page_L(pages);/* X 页地址 */

                        set_page_R(pages);/* X 页地址 */

                        for(i=0;i<64;i++)   

                                {

                                        set_col_addr_L(i);//Y

                                        set_col_addr_R(i);//Y

                                        write_LCD(LEFT,DATA,0x0);

                                        write_LCD(RIGHT,DATA,0x0);

                                }

                }

}



/*************************************/

/*             绘点函数            */

/*************************************/



void pixel(unsigned char xx,unsigned char yy,unsigned char flag)

{

        unsigned int y,ch;

        ch=yy%8;//余数



        y=1;

        for(;ch!=0;)

                {

                        y=y*2;

                        ch--;

                }

        if(xx<64)

                {

                        set_page_L(yy/8);

                        set_col_addr_L(xx);       

                        ch=read_LCD(LEFT);

                        set_col_addr_L(xx);

                        if(flag)

                                write_LCD(LEFT,DATA,ch|y);

                        else

                        {

                                y=~y;

                                ch&=y;

                                write_LCD(LEFT,DATA,ch|y);

                        }

                }

        else

                {

                        set_page_R(yy/8);

                        set_col_addr_R(xx-64);       

                        ch=read_LCD(RIGHT);

                        set_col_addr_R(xx-64);       

                        if(flag)

                                write_LCD(RIGHT,DATA,ch|y);

                        else

                        {

                                y=~y;

                                ch&=y;

                                write_LCD(RIGHT,DATA,ch|y);

                        }

                }

}



//ASCII 字模宽度及高度

#define ASC_CHR_WIDTH        8

#define ASC_CHR_HEIGHT        12



typedef struct typFNT_ASC16        /* 汉字字模显示数据结构 */

{

        char Index;

        char Msk;

};

struct typFNT_ASC16 const ASC_16[] = {        /* 显示为8*16Curier 10 常规*/

"1",0x00,0x00,0x08,0x08,0xFC,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x07,0x04,0x04,0x00,

"2",0x00,0x00,0x08,0x04,0x84,0x44,0x38,0x00,0x00,0x00,0x06,0x05,0x04,0x04,0x04,0x00,

"3",0x00,0x00,0x08,0x04,0x44,0x44,0xB8,0x00,0x00,0x00,0x02,0x04,0x04,0x04,0x03,0x00,

"4",0x00,0x00,0x80,0x60,0x18,0xFC,0x00,0x00,0x00,0x00,0x01,0x01,0x05,0x07,0x05,0x00,

"5",0x00,0x00,0x7C,0x44,0x44,0x44,0x84,0x00,0x00,0x00,0x02,0x04,0x04,0x04,0x03,0x00,

"6",0x00,0x00,0xF0,0x48,0x44,0x44,0x80,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x03,0x00,

"7",0x00,0x00,0x0C,0x04,0x84,0x64,0x1C,0x00,0x00,0x00,0x00,0x06,0x01,0x00,0x00,0x00,

"8",0x00,0x00,0xB8,0x44,0x44,0x44,0xB8,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x03,0x00,

"9",0x00,0x00,0x38,0x44,0x44,0x44,0xF8,0x00,0x00,0x00,0x00,0x04,0x04,0x02,0x01,0x00,

"0",0x00,0x00,0xF8,0x04,0x04,0x04,0xF8,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x03,0x00,

".",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00,

":",0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00,

" ",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

"(",0x00,0x00,0x00,0xE0,0x18,0x04,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x00,0x00,

")",0x00,0x00,0x00,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x00,0x10,0x0C,0x03,0x00,0x00,

};



#define ASC_HZ_WIDTH        12

//#define ASC_HZ_HEIGHT        12



typedef struct typFNT_GB16        /*12*16 汉字字模显示数据结构 */

{

        char Index;

        char Msk;

};

struct typFNT_GB16 const GB_16[] = {        /* 宋体 9小五 显示为12*16 */

"液",0x19,0xE2,0x14,0x42,0xF2,0x2E,0x72,0x8F,0xAA,0x7A,0x02,0x00,0x01,0x07,0x00,0x00,0x07,0x04,0x04,0x02,0x01,0x02,0x04,0x00,

"晶",0x00,0xC0,0x40,0x5F,0xD5,0x15,0xD5,0x55,0x5F,0x40,0xC0,0x00,0x00,0x07,0x05,0x05,0x07,0x00,0x07,0x05,0x05,0x05,0x07,0x00,

"显",0x00,0x40,0x9F,0x15,0xD5,0x15,0xD5,0x15,0x1F,0xC0,0x00,0x00,0x04,0x04,0x05,0x04,0x07,0x04,0x07,0x06,0x05,0x04,0x04,0x00,

"示",0x10,0x12,0x92,0x52,0x12,0xF2,0x12,0x12,0x53,0x92,0x10,0x00,0x02,0x01,0x00,0x04,0x04,0x07,0x00,0x00,0x00,0x00,0x03,0x00,

"的",0xFC,0x44,0x46,0x45,0xFC,0x10,0x2C,0xC7,0x04,0x04,0xFC,0x00,0x07,0x02,0x02,0x02,0x07,0x00,0x00,0x04,0x04,0x04,0x03,0x00,

"第",0x04,0xEA,0xAB,0xAE,0xAA,0xFC,0xAA,0xAB,0xAE,0xBA,0x82,0x00,0x04,0x04,0x02,0x01,0x00,0x07,0x00,0x02,0x02,0x02,0x01,0x00,

"一",0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

"行",0x48,0x24,0xF3,0x08,0x09,0x09,0x09,0x09,0xF9,0x09,0x08,0x00,0x00,0x00,0x07,0x00,0x00,0x04,0x04,0x04,0x07,0x00,0x00,0x00,

"二",0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x04,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,

"三",0x00,0x02,0x22,0x22,0x22,0x22,0x22,0x22,0x23,0x02,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x04,0x00,

"四",0x00,0xFF,0x81,0x41,0x3F,0x01,0x01,0xFF,0x81,0x81,0xFF,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x07,0x00,

"五",0x00,0x11,0x11,0x91,0x7F,0x11,0x11,0x11,0xF1,0x01,0x00,0x00,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x00,



};



unsigned char GetPage(void) /*得到当前页*/

{

        return CurPage;

}



unsigned char GetCol(void) /*得到当前列*/

{

        return CurCol;

}



void SetPageCol(unsigned char upage, unsigned char ucol) /* 设置液晶的页和列 */

{

        CurPage = upage;

        CurCol = ucol;

        if(ucol<64)

        {

                set_page_L(upage);

                set_col_addr_L(ucol);

        }

        else

        {

                set_page_R(upage);

                set_col_addr_R(ucol-64);

        }

}



/* 设置当前显示的页和列 */

void SetRowCol(unsigned char urow, unsigned char ucol)

{

        unsigned char page;

        CurRow = urow;

        CurCol = ucol;

       

        switch(urow)

        {

                case 1:

                        page=0;

                        CurOffset=1;

                        break;

                case 2:

                        page=1;

                        CurOffset=2;

                        break;

                case 3:

                        page=3;

                        CurOffset=1;

                        break;

                case 4:

                        page=4;

                        CurOffset=2;

                        break;

                case 5:

                        page=6;

                        CurOffset=1;

                        break;

        }

        SetPageCol(page,ucol);

}



void disp_char(unsigned char c)

{

        unsigned char k,j,uPage,uCol,ch_r,ch_w;

        unsigned char width;

        unsigned char len;

        uPage = GetPage();

        uCol = GetCol();

        len=sizeof(ASC_16)/sizeof(ASC_16);

        for(k=0;k<len;k++)

        {

                if(c == ASC_16.Index ) break;

        }

        if(k<len)

        {

               

                if(c=='-'||c==':')

                        width=ASC_CHR_WIDTH-2;

                else if(c=='|')

                        width=ASC_HZ_WIDTH-ASC_CHR_WIDTH;

                else

                        width=ASC_CHR_WIDTH;

               

                if(CurOffset==1) //下半部是写半个字节

                {

                        for(j=0;j<width;j++)

                        {

                                SetPageCol(uPage,uCol+j);

                                ch_w=ASC_16.Msk;

                                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                                else write_LCD(RIGHT,DATA,ch_w);

                        }

                        SetPageCol(uPage+1,uCol);

                       

                        for(j=0;j<width;j++)

                        {

                                SetPageCol(uPage+1,uCol+j);

                                if(uCol+j<64) ch_r=read_LCD(LEFT);

                                else ch_r=read_LCD(RIGHT);

                                ch_r&=0xf0;

                                ch_w=ASC_16.Msk&0x0f;

                                ch_w|=ch_r;

                                SetPageCol(uPage+1,uCol+j);

                                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                                else write_LCD(RIGHT,DATA,ch_w);

                        }

                }

                else //上半部是写半个字节

                {

                        for(j=0;j<width;j++)

                        {

                                SetPageCol(uPage,uCol+j);

                                if(uCol+j<64) ch_r=read_LCD(LEFT);

                                else ch_r=read_LCD(RIGHT);

                                ch_r&=0x0f;

                                ch_w=ASC_16.Msk;

                                ch_w=ch_w<<4;

                                ch_w|=ch_r;

                                SetPageCol(uPage,uCol+j);

                                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                                else write_LCD(RIGHT,DATA,ch_w);

                        }

                        SetPageCol(uPage+1,uCol);

                        for(j=0;j<width;j++)

                        {

                                SetPageCol(uPage+1,uCol+j);

                               

                                ch_r=ASC_16.Msk;

                                ch_w=ASC_16.Msk;

                                ch_r=ch_r>>4;

                                ch_w=ch_w<<4;

                                ch_w|=ch_r;

                                SetPageCol(uPage+1,uCol+j);

                                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                                else write_LCD(RIGHT,DATA,ch_w);

                        }

                }

        }

        SetPageCol(uPage,uCol+width);

}





void disp_hz(unsigned char const *hz)

{

        unsigned char k,j,uPage,uCol,ch_r,ch_w;

        uPage = GetPage();

        uCol = GetCol();

        for(k=0;k<sizeof(GB_16)/sizeof(GB_16);k++)

        {

                if(hz == GB_16.Index && hz == GB_16.Index)

                        break;

        }



        if(CurOffset==1)

        {

        for(j=0;j<ASC_HZ_WIDTH;j++)

        {

                SetPageCol(uPage,uCol+j);

                ch_w=GB_16.Msk;

                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                else write_LCD(RIGHT,DATA,ch_w);

        }

        SetPageCol(uPage+1,uCol);



        for(j=0;j<ASC_HZ_WIDTH;j++)

        {

                SetPageCol(uPage+1,uCol+j);

                if(uCol+j<64) ch_r=read_LCD(LEFT);

                else ch_r=read_LCD(RIGHT);

                ch_r&=0xf0;

                ch_w=GB_16.Msk&0x0f;

                ch_w|=ch_r;

                SetPageCol(uPage+1,uCol+j);

                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                else write_LCD(RIGHT,DATA,ch_w);

        }

        SetPageCol(uPage,uCol+ASC_HZ_WIDTH);

        }



        else //汉字上半部是写半个字节

        {

        for(j=0;j<ASC_HZ_WIDTH;j++)

        {

                SetPageCol(uPage,uCol+j);

                if(uCol+j<64) ch_r=read_LCD(LEFT);

                else ch_r=read_LCD(RIGHT);

                ch_r&=0x0f;

                ch_w=GB_16.Msk;

                ch_w=ch_w<<4;

                ch_w|=ch_r;

                SetPageCol(uPage,uCol+j);

                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                else write_LCD(RIGHT,DATA,ch_w);

        }

        SetPageCol(uPage+1,uCol);

        for(j=0;j<ASC_HZ_WIDTH;j++)

        {

                SetPageCol(uPage+1,uCol+j);



                ch_r=GB_16.Msk;

                ch_w=GB_16.Msk;

                ch_r=ch_r>>4;

                ch_w=ch_w<<4;

                ch_w|=ch_r;

                SetPageCol(uPage+1,uCol+j);

                if(uCol+j<64)        write_LCD(LEFT,DATA,ch_w);

                else write_LCD(RIGHT,DATA,ch_w);

        }

        SetPageCol(uPage,uCol+ASC_HZ_WIDTH);

        }

}



void disp_str(unsigned char const *p)

{

        unsigned char i=0;

        while(p>0)

        {

                if(p < 128)

                {        /* ASCII */

                        disp_char(p);

                }

                else

                {        /* 中文 */

                        disp_hz(&p);

                        i++;

                }

                i++;

        }

}

void main()

{

unsigned char i;

DDRC=0xff;

init_lcd();

clr_lcd();



SetRowCol(1,0);

disp_str("液晶显示的第一行1234");

SetRowCol(2,0);

disp_str("液晶显示的第二行2345");

SetRowCol(3,0);

disp_str("液晶显示的第三行3456");

SetRowCol(4,0);

disp_str("液晶显示的第四行5678");

SetRowCol(5,0);

disp_str("液晶显示的第五行6789");

for(i=0;i<64;i++) pixel(127,i,1);

for(i=0;i<64;i++) pixel(0,i,1);

for(i=0;i<128;i++) pixel(i,0,1);

for(i=0;i<128;i++) pixel(i,63,1);



while(1);



}
-----此内容被mcuhost于2006-11-10,09:31:24编辑过

mcuhost 发表于 2006-11-10 09:27:24

是不是认为程序太简单了??~~~~

mcuhost 发表于 2006-11-10 10:22:20

我疑惑!!

armok 发表于 2006-11-10 10:28:57

要用到才会有人认真研究 ....

mcuhost 发表于 2006-11-10 10:32:04

armok兄言之有理

fbnfbn 发表于 2006-12-6 09:16:14

请问这个液晶价格怎样,有没生产商或代理商的电话

谢谢!

Gorgon_Meducer 发表于 2006-12-6 09:20:29

发现自己名字……路过……

AVR-MEGA128 发表于 2006-12-6 09:30:50

ding 就一个字

fsclub 发表于 2006-12-31 12:23:48

刚刚以35米的价格买了个无字库的12864,正好是KS1008的,正好想配合GPS用来运动画轨迹..

下来研究一下...

fsclub 发表于 2006-12-31 12:35:55

//PORTA---数据口PORTB----控制口

--------

这个注释有问题吧?

我看PORTC才是控制口啊!

xuetwins 发表于 2007-3-30 17:12:05

to 楼主:



想在12864上做个反显示的程序,反显示的中文字数可以不限, 总是做不出,楼主能不能给个程序?? 或者给个思路也行



万分感谢!!



效果如下:



http://cache.amobbs.com/bbs_upload782111/files_6/armok01148622.jpg

hxke 发表于 2007-3-30 20:56:43

to: xuetwins

写汉字之前把字模取反就ok了。。。。(加个~符号就搞定)

:)./emotion/em078.gif

xuetwins 发表于 2007-3-31 09:50:05

比如最上面楼主的程序



在哪里加~   ???



麻烦你说清楚点,谢谢!!!

xuepeng2000 发表于 2007-3-31 10:29:14

if(uCol+j<64) ch_r=read_LCD(LEFT);

      else ch_r=read_LCD(RIGHT);

      ch_r=~ch_r;

   再write就可以了



这里就可以



感觉写汉字和写字母的不应该分开,反正一个扫八列,一个扫十六列

用一个标志来做汉字和字母的判断,

那样就可以用一个函数写出来.

xuepeng2000 发表于 2007-3-31 10:49:28

我把GUI贴上来



/****************************************************************************************

* 文件名:GUI.C

* 功能:GUI基本绘图函数。进行基本绘图运算,并调用相应的刷新程序更新LCD显示。

* 作者:黄绍斌

* 修改:冯建辉

* 日期:2006.09.13

* 备注:图形操作层,进行各种图形运算操作。

****************************************************************************************/

#include "gui.h"

#include <math.h>



/****************************************************************************

* 名称:GUI_HLine()

* 功能:画水平线。

* 入口参数:x0                水平线起点所在列的位置

*         y0                水平线起点所在行的位置

*         x1          水平线终点所在列的位置

*         color        显示颜色(对于黑白色LCM,为0时灭,为1时显示)

* 出口参数:无

* 说明:操作失败原因是指定地址超出缓冲区范围。

****************************************************************************/

voidGUI_HLine(unsigned int x0, unsigned char y0, unsigned int x1, TCOLOR color)

{

    unsigned charbak;

    if(x0>x1)                                 // 对x0、x1大小进行排列,以便画图

    {

      bak = x1;

      x1 = x0;

      x0 = bak;

    }   

    do

    {

      GUI_Point(x0, y0, color);        // 逐点显示,描出垂直线

      x0++;

    }

    while(x1>=x0);

}



/***********************************************************************

* 名称:GUI_RLine()

* 功能:画竖直线。根据硬件特点,实现加速。

* 入口参数:x0                垂直线起点所在列的位置

*         y0                垂直线起点所在行的位置

*         y1          垂直线终点所在行的位置

*         color        显示颜色(对于黑白色LCM,为0时灭,为1时显示)

* 出口参数:        无

* 说明:操作失败原因是指定地址超出缓冲区范围。

***********************************************************************/

voidGUI_RLine(unsigned int x0, unsigned char y0, unsigned char y1, TCOLOR color)

{

    unsigned charbak;

    if(y0>y1)                           // 对y0、y1大小进行排列,以便画图

    {

      bak = y1;

      y1 = y0;

      y0 = bak;

    }

    do

    {

      GUI_Point(x0, y0, color);        // 逐点显示,描出垂直线

      y0++;

    }

    while(y1>=y0);

}



/****************************************************************************

* 名称:GUI_Rectangle()

* 功能:画矩形。

* 入口参数:x0                矩形左上角的x坐标值

*         y0                矩形左上角的y坐标值

*         x1          矩形右下角的x坐标值

*         y1          矩形右下角的y坐标值

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Rectangle(uint16 x0, uint8 y0, uint16 x1, uint8 y1, TCOLOR color)

{

   GUI_HLine(x0, y0, x1, color);

   GUI_HLine(x0, y1, x1, color);

   GUI_RLine(x0, y0, y1, color);

   GUI_RLine(x1, y0, y1, color);

}



/****************************************************************************

* 名称:GUI_RectangleFill()

* 功能:填充矩形。画一个填充的矩形,填充色与边框色一样。

* 入口参数:x0                矩形左上角的x坐标值

*         y0                矩形左上角的y坐标值

*         x1          矩形右下角的x坐标值

*         y1          矩形右下角的y坐标值

*         color        填充颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_RectangleFill(uint16 x0, uint8 y0, uint16 x1, uint8 y1, TCOLOR color)

{

   uint32i;



   /* 先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1) */

   if(x0>x1)                                                 // 若x0>x1,则x0与x1交换

   {

      i = x0;

      x0 = x1;

      x1 = i;

   }

   if(y0>y1)                                                // 若y0>y1,则y0与y1交换

   {

      i = y0;

      y0 = y1;

      y1 = i;

   }

   

   /* 判断是否只是直线 */

   if(y0==y1)

   {

      GUI_HLine(x0, y0, x1, color);

      return;

   }

   if(x0==x1)

   {

      GUI_RLine(x0, y0, y1, color);

      return;

   }



   while(y0<=y1)                                               

   {

      GUI_HLine(x0, y0, x1, color);                                // 当前画水平线

      y0++;                                                        // 下一行

   }

}



/****************************************************************************

* 名称:GUI_Square()

* 功能:画正方形。

* 入口参数:x0                正方形左上角的x坐标值

*         y0                正方形左上角的y坐标值

*         with      正方形的边长

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Square(uint32 x0, uint32 y0, uint32with, TCOLORcolor)

{

   if(with==0)

      return;

   if( (x0+with) > GUI_LCM_XMAX )

      return;

   if( (y0+with) > GUI_LCM_YMAX )

      return;

   GUI_Rectangle(x0, y0, x0+with, y0+with, color);

}







/****************************************************************************

* 名称:GUI_Line()

* 功能:画任意两点之间的直线。

* 入口参数:x0                直线起点的x坐标值

*         y0                直线起点的y坐标值

*         x1          直线终点的x坐标值

*         y1          直线终点的y坐标值

*         color        显示颜色(对于黑白色LCM,为0时灭,为1时显示)

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Line(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)

{

   int32   dx;                                                // 直线x轴差值变量

   int32   dy;                                          // 直线y轴差值变量

   int8    dx_sym;                                        // x轴增长方向,为-1时减值方向,为1时增值方向

   int8    dy_sym;                                        // y轴增长方向,为-1时减值方向,为1时增值方向

   int32   dx_x2;                                        // dx*2值变量,用于加快运算速度

   int32   dy_x2;                                        // dy*2值变量,用于加快运算速度

   int32   di;                                                // 决策变量



   dx = x1-x0;                                                // 求取两点之间的差值

   dy = y1-y0;

   

   /* 判断增长方向,或是否为水平线、垂直线、点 */

   if(dx>0)                                                // 判断x轴方向

   {

      dx_sym = 1;                                        // dx>0,设置dx_sym=1

   }

   else

   {

      if(dx<0)

      {

         dx_sym = -1;                                        // dx<0,设置dx_sym=-1

      }

      else

      {// dx==0,画垂直线,或一点

         GUI_RLine(x0, y0, y1, color);

             return;

      }

   }

   

   if(dy>0)                                                // 判断y轴方向

   {

      dy_sym = 1;                                        // dy>0,设置dy_sym=1

   }

   else

   {

      if(dy<0)

      {

         dy_sym = -1;                                        // dy<0,设置dy_sym=-1

      }

      else

      {// dy==0,画水平线,或一点

         GUI_HLine(x0, y0, x1, color);

             return;

      }

   }

   

   /* 将dx、dy取绝对值 */

   dx = dx_sym * dx;

   dy = dy_sym * dy;



   /* 计算2倍的dx及dy值 */

   dx_x2 = dx*2;

   dy_x2 = dy*2;

   

   /* 使用Bresenham法进行画直线 */

   if(dx>=dy)                                                // 对于dx>=dy,则使用x轴为基准

   {

      di = dy_x2 - dx;

      while(x0!=x1)

      {

         GUI_Point(x0, y0, color);

         x0 += dx_sym;

         if(di<0)

         {

            di += dy_x2;                                // 计算出下一步的决策值

         }

         else

         {

            di += dy_x2 - dx_x2;

            y0 += dy_sym;

         }

      }

      GUI_Point(x0, y0, color);                              // 显示最后一点

   }

   else                                                        // 对于dx<dy,则使用y轴为基准

   {

      di = dx_x2 - dy;

      while(y0!=y1)

      {

         GUI_Point(x0, y0, color);

         y0 += dy_sym;

         if(di<0)

         {

            di += dx_x2;

         }

         else

         {

            di += dx_x2 - dy_x2;

            x0 += dx_sym;

         }

      }

      GUI_Point(x0, y0, color);                // 显示最后一点

   }

}





#if        GUI_LineWith_EN==1

/****************************************************************************

* 名称:GUI_LineWith()

* 功能:画任意两点之间的直线,并且可设置线的宽度。

* 入口参数:x0                直线起点的x坐标值

*         y0                直线起点的y坐标值

*         x1          直线终点的x坐标值

*         y1          直线终点的y坐标值

*         with      线宽(0-50)

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_LineWith(uint32 x0, uint32 y0, uint32 x1, uint32 y1, uint8 with, TCOLOR color)

{

   int32   dx;                                                // 直线x轴差值变量

   int32   dy;                                          // 直线y轴差值变量

   int8    dx_sym;                                        // x轴增长方向,为-1时减值方向,为1时增值方向

   int8    dy_sym;                                        // y轴增长方向,为-1时减值方向,为1时增值方向

   int32   dx_x2;                                        // dx*2值变量,用于加快运算速度

   int32   dy_x2;                                        // dy*2值变量,用于加快运算速度

   int32   di;                                                // 决策变量

   

   int32   wx, wy;                                        // 线宽变量

   int32   draw_a, draw_b;

   

   /* 参数过滤 */

   if(with==0)

      return;

   if(with>50)

      with = 50;

   

   dx = x1-x0;                                                // 求取两点之间的差值

   dy = y1-y0;

   

   wx = with/2;

   wy = with-wx-1;

   

   /* 判断增长方向,或是否为水平线、垂直线、点 */

   if(dx>0)                                                // 判断x轴方向

   {

      dx_sym = 1;                                        // dx>0,设置dx_sym=1

   }

   else

   {

      if(dx<0)

      {

         dx_sym = -1;                                        // dx<0,设置dx_sym=-1

      }

      else

      {/* dx==0,画垂直线,或一点 */

         wx = x0-wx;

         if(wx<0)

            wx = 0;

         wy = x0+wy;

         

         while(1)

         {

            x0 = wx;

            GUI_RLine(x0, y0, y1, color);

            if(wx>=wy)

               break;

            wx++;

         }

             return;

      }

   }

   

   if(dy>0)                                                // 判断y轴方向

   {

      dy_sym = 1;                                        // dy>0,设置dy_sym=1

   }

   else

   {

      if(dy<0)

      {

         dy_sym = -1;                                        // dy<0,设置dy_sym=-1

      }

      else

      {/* dy==0,画水平线,或一点 */

         wx = y0-wx;

         if(wx<0) wx = 0;

         wy = y0+wy;

         

         while(1)

         {

            y0 = wx;

            GUI_HLine(x0, y0, x1, color);

            if(wx>=wy)

               break;

            wx++;

         }

             return;

      }

   }

   

   /* 将dx、dy取绝对值 */

   dx = dx_sym * dx;

   dy = dy_sym * dy;



   /* 计算2倍的dx及dy值 */

   dx_x2 = dx*2;

   dy_x2 = dy*2;

   

   /* 使用Bresenham法进行画直线 */

   if(dx>=dy)                                                // 对于dx>=dy,则使用x轴为基准

   {

      di = dy_x2 - dx;

      while(x0!=x1)

      {/* x轴向增长,则宽度在y方向,即画垂直线 */

         draw_a = y0-wx;

         if(draw_a<0) draw_a = 0;

         draw_b = y0+wy;

         GUI_RLine(x0, draw_a, draw_b, color);

         

         x0 += dx_sym;                               

         if(di<0)

         {

            di += dy_x2;                                // 计算出下一步的决策值

         }

         else

         {

            di += dy_x2 - dx_x2;

            y0 += dy_sym;

         }

      }

      draw_a = y0-wx;

      if(draw_a<0)

         draw_a = 0;

      draw_b = y0+wy;

      GUI_RLine(x0, draw_a, draw_b, color);

   }

   else                                                        // 对于dx<dy,则使用y轴为基准

   {

      di = dx_x2 - dy;

      while(y0!=y1)

      {/* y轴向增长,则宽度在x方向,即画水平线 */

         draw_a = x0-wx;

         if(draw_a<0)

            draw_a = 0;

         draw_b = x0+wy;

         GUI_HLine(draw_a, y0, draw_b, color);

         

         y0 += dy_sym;

         if(di<0)

         {

            di += dx_x2;

         }

         else

         {

            di += dx_x2 - dy_x2;

            x0 += dx_sym;

         }

      }

      draw_a = x0-wx;

      if(draw_a<0)

         draw_a = 0;

      draw_b = x0+wy;

      GUI_HLine(draw_a, y0, draw_b, color);

   }

}

#endif



/****************************************************************************

* 名称:GUI_LineS()

* 功能:多个点之间的连续连线。从第一点连到第二点,再连到第三点...

* 入口参数:points      多个点坐标数据的指针,数据排列为(x0,y0)、(x1,y1)、(x2,y2)...

*         no          点数目,至少要大于1

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_LineS(uint32 const *points, uint8 no, TCOLOR color)

{

   uint32x0, y0;

   uint32x1, y1;

   uint8   i;



   /* 入口参数过滤 */

   if(0==no)

      return;

   if(1==no)                                                // 单点

   {

      x0 = *points++;

      y0 = *points;

      GUI_Point(x0, y0, color);

   }

   

   /* 画多条线条 */

   x0 = *points++;                                        // 取出第一点坐标值,作为原起点坐标值

   y0 = *points++;

   for(i=1; i<no; i++)

   {

      x1 = *points++;                                        // 取出下一点坐标值

      y1 = *points++;

      GUI_Line(x0, y0, x1, y1, color);

      x0 = x1;                                                // 更新原起点坐标

      y0 = y1;

   }

}



#ifGUI_CircleX_EN==1

/****************************************************************************

* 名称:GUI_Circle()

* 功能:指定圆心位置及半径,画圆。

* 入口参数:x0                圆心的x坐标值

*         y0                圆心的y坐标值

*         r         圆的半径

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Circle(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32draw_x0, draw_y0;                                // 刽图点坐标变量

   int32draw_x1, draw_y1;       

   int32draw_x2, draw_y2;       

   int32draw_x3, draw_y3;       

   int32draw_x4, draw_y4;       

   int32draw_x5, draw_y5;       

   int32draw_x6, draw_y6;       

   int32draw_x7, draw_y7;       

   int32xx, yy;                                        // 画圆控制变量



   int32di;                                                // 决策变量

   

   /* 参数过滤 */

   if(0==r)

      return;

   

   /* 计算出8个特殊点(0、45、90、135、180、225、270度),进行显示 */

   draw_x0 = draw_x1 = x0;

   draw_y0 = draw_y1 = y0 + r;

   if(draw_y0<GUI_LCM_YMAX)

      GUI_Point(draw_x0, draw_y0, color);                // 90度

       

   draw_x2 = draw_x3 = x0;

   draw_y2 = draw_y3 = y0 - r;

   if(draw_y2>=0)

      GUI_Point(draw_x2, draw_y2, color);                // 270度



   draw_x4 = draw_x6 = x0 + r;

   draw_y4 = draw_y6 = y0;

   if(draw_x4<GUI_LCM_XMAX)

      GUI_Point(draw_x4, draw_y4, color);                // 0度

   

   draw_x5 = draw_x7 = x0 - r;

   draw_y5 = draw_y7 = y0;

   if(draw_x5>=0)

      GUI_Point(draw_x5, draw_y5, color);                // 180度   

   if(1==r)

      return;                                                // 若半径为1,则已圆画完



   /* 使用Bresenham法进行画圆 */

   di = 3 - 2*r;                                        // 初始化决策变量

   

   xx = 0;

   yy = r;       

   while(xx<yy)

   {

      if(di<0)

      {

         di += 4*xx + 6;

      }

      else

      {

         di += 4*(xx - yy) + 10;

          

         yy--;

         draw_y0--;

         draw_y1--;

         draw_y2++;

         draw_y3++;

         draw_x4--;

         draw_x5++;

         draw_x6--;

         draw_x7++;

      }

          

      xx++;

      draw_x0++;

      draw_x1--;

      draw_x2++;

      draw_x3--;

      draw_y4++;

      draw_y5++;

      draw_y6--;

      draw_y7--;

       

      /* 要判断当前点是否在有效范围内 */

      if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )

      {

         GUI_Point(draw_x0, draw_y0, color);

      }

      if( (draw_x1>=0)&&(draw_y1>=0) )

      {

         GUI_Point(draw_x1, draw_y1, color);

      }

      if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x2, draw_y2, color);

      }

      if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x3, draw_y3, color);

      }

      if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )

      {

         GUI_Point(draw_x4, draw_y4, color);

      }

      if( (draw_x5>=0)&&(draw_y5>=0) )

      {

         GUI_Point(draw_x5, draw_y5, color);

      }

      if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x6, draw_y6, color);

      }

      if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x7, draw_y7, color);

      }

   }

}



/****************************************************************************

* 名称:GUI_CircleFill()

* 功能:指定圆心位置及半径,画圆并填充,填充色与边框色一样。

* 入口参数:x0                圆心的x坐标值

*         y0                圆心的y坐标值

*         r         圆的半径

*         color        填充颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_CircleFill(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32draw_x0, draw_y0;                                // 刽图点坐标变量

   int32draw_x1, draw_y1;       

   int32draw_x2, draw_y2;       

   int32draw_x3, draw_y3;       

   int32draw_x4, draw_y4;       

   int32draw_x5, draw_y5;       

   int32draw_x6, draw_y6;       

   int32draw_x7, draw_y7;       

   int32fill_x0, fill_y0;                                // 填充所需的变量,使用垂直线填充

   int32fill_x1;

   int32xx, yy;                                        // 画圆控制变量



   int32di;                                                // 决策变量

   

   /* 参数过滤 */

   if(0==r)

      return;

   

   /* 计算出4个特殊点(0、90、180、270度),进行显示 */

   draw_x0 = draw_x1 = x0;

   draw_y0 = draw_y1 = y0 + r;

   if(draw_y0<GUI_LCM_YMAX)

   {

      GUI_Point(draw_x0, draw_y0, color);        // 90度

   }

           

   draw_x2 = draw_x3 = x0;

   draw_y2 = draw_y3 = y0 - r;

   if(draw_y2>=0)

   {

      GUI_Point(draw_x2, draw_y2, color);        // 270度

   }

       

   draw_x4 = draw_x6 = x0 + r;

   draw_y4 = draw_y6 = y0;

   if(draw_x4<GUI_LCM_XMAX)

   {

      GUI_Point(draw_x4, draw_y4, color);        // 0度

      fill_x1 = draw_x4;

   }

   else

   {

      fill_x1 = GUI_LCM_XMAX;

   }

   fill_y0 = y0;                                                        // 设置填充线条起始点fill_x0

   fill_x0 = x0 - r;                                                // 设置填充线条结束点fill_y1

   if(fill_x0<0)

      fill_x0 = 0;

   GUI_HLine(fill_x0, fill_y0, fill_x1, color);

   

   draw_x5 = draw_x7 = x0 - r;

   draw_y5 = draw_y7 = y0;

   if(draw_x5>=0)

   {

      GUI_Point(draw_x5, draw_y5, color);        // 180度

   }

   if(1==r)

      return;

   

   

   /* 使用Bresenham法进行画圆 */

   di = 3 - 2*r;                                // 初始化决策变量

   

   xx = 0;

   yy = r;

   while(xx<yy)

   {

      if(di<0)

      {

         di += 4*xx + 6;

      }

      else

      {

         di += 4*(xx - yy) + 10;



         yy--;

         draw_y0--;

         draw_y1--;

         draw_y2++;

         draw_y3++;

         draw_x4--;

         draw_x5++;

         draw_x6--;

         draw_x7++;

      }

          

      xx++;

      draw_x0++;

      draw_x1--;

      draw_x2++;

      draw_x3--;

      draw_y4++;

      draw_y5++;

      draw_y6--;

      draw_y7--;

               

       

      /* 要判断当前点是否在有效范围内 */

      if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )

      {

         GUI_Point(draw_x0, draw_y0, color);

      }

      if( (draw_x1>=0)&&(draw_y1>=0) )

      {

         GUI_Point(draw_x1, draw_y1, color);

      }

          

      /* 第二点水直线填充(下半圆的点) */

      if(draw_x1>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x1;

      /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y1;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

      /* 设置填充线条结束点fill_x1 */

         fill_x1 = x0*2 - draw_x1;

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }



      if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x2, draw_y2, color);

      }

                    

      if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x3, draw_y3, color);

      }

          

      /* 第四点垂直线填充(上半圆的点) */

      if(draw_x3>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x3;

         /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y3;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

         /* 设置填充线条结束点fill_x1 */                                                                       

         fill_x1 = x0*2 - draw_x3;                               

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }



      if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )

      {

         GUI_Point(draw_x4, draw_y4, color);

      }

      if( (draw_x5>=0)&&(draw_y5>=0) )

      {

         GUI_Point(draw_x5, draw_y5, color);

      }

          

      /* 第六点垂直线填充(上半圆的点) */

      if(draw_x5>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x5;

         /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y5;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

         /* 设置填充线条结束点fill_x1 */                                                                       

         fill_x1 = x0*2 - draw_x5;                               

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }



      if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x6, draw_y6, color);

      }



      if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x7, draw_y7, color);

      }

          

      /* 第八点垂直线填充(上半圆的点) */

      if(draw_x7>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x7;

         /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y7;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

         /* 设置填充线条结束点fill_x1 */                                                                       

         fill_x1 = x0*2 - draw_x7;                               

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }

   }

}

#endif

xuepeng2000 发表于 2007-3-31 10:49:32

我把GUI贴上来



/****************************************************************************************

* 文件名:GUI.C

* 功能:GUI基本绘图函数。进行基本绘图运算,并调用相应的刷新程序更新LCD显示。

* 作者:黄绍斌

* 修改:冯建辉

* 日期:2006.09.13

* 备注:图形操作层,进行各种图形运算操作。

****************************************************************************************/

#include "gui.h"

#include <math.h>



/****************************************************************************

* 名称:GUI_HLine()

* 功能:画水平线。

* 入口参数:x0                水平线起点所在列的位置

*         y0                水平线起点所在行的位置

*         x1          水平线终点所在列的位置

*         color        显示颜色(对于黑白色LCM,为0时灭,为1时显示)

* 出口参数:无

* 说明:操作失败原因是指定地址超出缓冲区范围。

****************************************************************************/

voidGUI_HLine(unsigned int x0, unsigned char y0, unsigned int x1, TCOLOR color)

{

    unsigned charbak;

    if(x0>x1)                                 // 对x0、x1大小进行排列,以便画图

    {

      bak = x1;

      x1 = x0;

      x0 = bak;

    }   

    do

    {

      GUI_Point(x0, y0, color);        // 逐点显示,描出垂直线

      x0++;

    }

    while(x1>=x0);

}



/***********************************************************************

* 名称:GUI_RLine()

* 功能:画竖直线。根据硬件特点,实现加速。

* 入口参数:x0                垂直线起点所在列的位置

*         y0                垂直线起点所在行的位置

*         y1          垂直线终点所在行的位置

*         color        显示颜色(对于黑白色LCM,为0时灭,为1时显示)

* 出口参数:        无

* 说明:操作失败原因是指定地址超出缓冲区范围。

***********************************************************************/

voidGUI_RLine(unsigned int x0, unsigned char y0, unsigned char y1, TCOLOR color)

{

    unsigned charbak;

    if(y0>y1)                           // 对y0、y1大小进行排列,以便画图

    {

      bak = y1;

      y1 = y0;

      y0 = bak;

    }

    do

    {

      GUI_Point(x0, y0, color);        // 逐点显示,描出垂直线

      y0++;

    }

    while(y1>=y0);

}



/****************************************************************************

* 名称:GUI_Rectangle()

* 功能:画矩形。

* 入口参数:x0                矩形左上角的x坐标值

*         y0                矩形左上角的y坐标值

*         x1          矩形右下角的x坐标值

*         y1          矩形右下角的y坐标值

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Rectangle(uint16 x0, uint8 y0, uint16 x1, uint8 y1, TCOLOR color)

{

   GUI_HLine(x0, y0, x1, color);

   GUI_HLine(x0, y1, x1, color);

   GUI_RLine(x0, y0, y1, color);

   GUI_RLine(x1, y0, y1, color);

}



/****************************************************************************

* 名称:GUI_RectangleFill()

* 功能:填充矩形。画一个填充的矩形,填充色与边框色一样。

* 入口参数:x0                矩形左上角的x坐标值

*         y0                矩形左上角的y坐标值

*         x1          矩形右下角的x坐标值

*         y1          矩形右下角的y坐标值

*         color        填充颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_RectangleFill(uint16 x0, uint8 y0, uint16 x1, uint8 y1, TCOLOR color)

{

   uint32i;



   /* 先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1) */

   if(x0>x1)                                                 // 若x0>x1,则x0与x1交换

   {

      i = x0;

      x0 = x1;

      x1 = i;

   }

   if(y0>y1)                                                // 若y0>y1,则y0与y1交换

   {

      i = y0;

      y0 = y1;

      y1 = i;

   }

   

   /* 判断是否只是直线 */

   if(y0==y1)

   {

      GUI_HLine(x0, y0, x1, color);

      return;

   }

   if(x0==x1)

   {

      GUI_RLine(x0, y0, y1, color);

      return;

   }



   while(y0<=y1)                                               

   {

      GUI_HLine(x0, y0, x1, color);                                // 当前画水平线

      y0++;                                                        // 下一行

   }

}



/****************************************************************************

* 名称:GUI_Square()

* 功能:画正方形。

* 入口参数:x0                正方形左上角的x坐标值

*         y0                正方形左上角的y坐标值

*         with      正方形的边长

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Square(uint32 x0, uint32 y0, uint32with, TCOLORcolor)

{

   if(with==0)

      return;

   if( (x0+with) > GUI_LCM_XMAX )

      return;

   if( (y0+with) > GUI_LCM_YMAX )

      return;

   GUI_Rectangle(x0, y0, x0+with, y0+with, color);

}







/****************************************************************************

* 名称:GUI_Line()

* 功能:画任意两点之间的直线。

* 入口参数:x0                直线起点的x坐标值

*         y0                直线起点的y坐标值

*         x1          直线终点的x坐标值

*         y1          直线终点的y坐标值

*         color        显示颜色(对于黑白色LCM,为0时灭,为1时显示)

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Line(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)

{

   int32   dx;                                                // 直线x轴差值变量

   int32   dy;                                          // 直线y轴差值变量

   int8    dx_sym;                                        // x轴增长方向,为-1时减值方向,为1时增值方向

   int8    dy_sym;                                        // y轴增长方向,为-1时减值方向,为1时增值方向

   int32   dx_x2;                                        // dx*2值变量,用于加快运算速度

   int32   dy_x2;                                        // dy*2值变量,用于加快运算速度

   int32   di;                                                // 决策变量



   dx = x1-x0;                                                // 求取两点之间的差值

   dy = y1-y0;

   

   /* 判断增长方向,或是否为水平线、垂直线、点 */

   if(dx>0)                                                // 判断x轴方向

   {

      dx_sym = 1;                                        // dx>0,设置dx_sym=1

   }

   else

   {

      if(dx<0)

      {

         dx_sym = -1;                                        // dx<0,设置dx_sym=-1

      }

      else

      {// dx==0,画垂直线,或一点

         GUI_RLine(x0, y0, y1, color);

             return;

      }

   }

   

   if(dy>0)                                                // 判断y轴方向

   {

      dy_sym = 1;                                        // dy>0,设置dy_sym=1

   }

   else

   {

      if(dy<0)

      {

         dy_sym = -1;                                        // dy<0,设置dy_sym=-1

      }

      else

      {// dy==0,画水平线,或一点

         GUI_HLine(x0, y0, x1, color);

             return;

      }

   }

   

   /* 将dx、dy取绝对值 */

   dx = dx_sym * dx;

   dy = dy_sym * dy;



   /* 计算2倍的dx及dy值 */

   dx_x2 = dx*2;

   dy_x2 = dy*2;

   

   /* 使用Bresenham法进行画直线 */

   if(dx>=dy)                                                // 对于dx>=dy,则使用x轴为基准

   {

      di = dy_x2 - dx;

      while(x0!=x1)

      {

         GUI_Point(x0, y0, color);

         x0 += dx_sym;

         if(di<0)

         {

            di += dy_x2;                                // 计算出下一步的决策值

         }

         else

         {

            di += dy_x2 - dx_x2;

            y0 += dy_sym;

         }

      }

      GUI_Point(x0, y0, color);                              // 显示最后一点

   }

   else                                                        // 对于dx<dy,则使用y轴为基准

   {

      di = dx_x2 - dy;

      while(y0!=y1)

      {

         GUI_Point(x0, y0, color);

         y0 += dy_sym;

         if(di<0)

         {

            di += dx_x2;

         }

         else

         {

            di += dx_x2 - dy_x2;

            x0 += dx_sym;

         }

      }

      GUI_Point(x0, y0, color);                // 显示最后一点

   }

}





#if        GUI_LineWith_EN==1

/****************************************************************************

* 名称:GUI_LineWith()

* 功能:画任意两点之间的直线,并且可设置线的宽度。

* 入口参数:x0                直线起点的x坐标值

*         y0                直线起点的y坐标值

*         x1          直线终点的x坐标值

*         y1          直线终点的y坐标值

*         with      线宽(0-50)

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_LineWith(uint32 x0, uint32 y0, uint32 x1, uint32 y1, uint8 with, TCOLOR color)

{

   int32   dx;                                                // 直线x轴差值变量

   int32   dy;                                          // 直线y轴差值变量

   int8    dx_sym;                                        // x轴增长方向,为-1时减值方向,为1时增值方向

   int8    dy_sym;                                        // y轴增长方向,为-1时减值方向,为1时增值方向

   int32   dx_x2;                                        // dx*2值变量,用于加快运算速度

   int32   dy_x2;                                        // dy*2值变量,用于加快运算速度

   int32   di;                                                // 决策变量

   

   int32   wx, wy;                                        // 线宽变量

   int32   draw_a, draw_b;

   

   /* 参数过滤 */

   if(with==0)

      return;

   if(with>50)

      with = 50;

   

   dx = x1-x0;                                                // 求取两点之间的差值

   dy = y1-y0;

   

   wx = with/2;

   wy = with-wx-1;

   

   /* 判断增长方向,或是否为水平线、垂直线、点 */

   if(dx>0)                                                // 判断x轴方向

   {

      dx_sym = 1;                                        // dx>0,设置dx_sym=1

   }

   else

   {

      if(dx<0)

      {

         dx_sym = -1;                                        // dx<0,设置dx_sym=-1

      }

      else

      {/* dx==0,画垂直线,或一点 */

         wx = x0-wx;

         if(wx<0)

            wx = 0;

         wy = x0+wy;

         

         while(1)

         {

            x0 = wx;

            GUI_RLine(x0, y0, y1, color);

            if(wx>=wy)

               break;

            wx++;

         }

             return;

      }

   }

   

   if(dy>0)                                                // 判断y轴方向

   {

      dy_sym = 1;                                        // dy>0,设置dy_sym=1

   }

   else

   {

      if(dy<0)

      {

         dy_sym = -1;                                        // dy<0,设置dy_sym=-1

      }

      else

      {/* dy==0,画水平线,或一点 */

         wx = y0-wx;

         if(wx<0) wx = 0;

         wy = y0+wy;

         

         while(1)

         {

            y0 = wx;

            GUI_HLine(x0, y0, x1, color);

            if(wx>=wy)

               break;

            wx++;

         }

             return;

      }

   }

   

   /* 将dx、dy取绝对值 */

   dx = dx_sym * dx;

   dy = dy_sym * dy;



   /* 计算2倍的dx及dy值 */

   dx_x2 = dx*2;

   dy_x2 = dy*2;

   

   /* 使用Bresenham法进行画直线 */

   if(dx>=dy)                                                // 对于dx>=dy,则使用x轴为基准

   {

      di = dy_x2 - dx;

      while(x0!=x1)

      {/* x轴向增长,则宽度在y方向,即画垂直线 */

         draw_a = y0-wx;

         if(draw_a<0) draw_a = 0;

         draw_b = y0+wy;

         GUI_RLine(x0, draw_a, draw_b, color);

         

         x0 += dx_sym;                               

         if(di<0)

         {

            di += dy_x2;                                // 计算出下一步的决策值

         }

         else

         {

            di += dy_x2 - dx_x2;

            y0 += dy_sym;

         }

      }

      draw_a = y0-wx;

      if(draw_a<0)

         draw_a = 0;

      draw_b = y0+wy;

      GUI_RLine(x0, draw_a, draw_b, color);

   }

   else                                                        // 对于dx<dy,则使用y轴为基准

   {

      di = dx_x2 - dy;

      while(y0!=y1)

      {/* y轴向增长,则宽度在x方向,即画水平线 */

         draw_a = x0-wx;

         if(draw_a<0)

            draw_a = 0;

         draw_b = x0+wy;

         GUI_HLine(draw_a, y0, draw_b, color);

         

         y0 += dy_sym;

         if(di<0)

         {

            di += dx_x2;

         }

         else

         {

            di += dx_x2 - dy_x2;

            x0 += dx_sym;

         }

      }

      draw_a = x0-wx;

      if(draw_a<0)

         draw_a = 0;

      draw_b = x0+wy;

      GUI_HLine(draw_a, y0, draw_b, color);

   }

}

#endif



/****************************************************************************

* 名称:GUI_LineS()

* 功能:多个点之间的连续连线。从第一点连到第二点,再连到第三点...

* 入口参数:points      多个点坐标数据的指针,数据排列为(x0,y0)、(x1,y1)、(x2,y2)...

*         no          点数目,至少要大于1

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_LineS(uint32 const *points, uint8 no, TCOLOR color)

{

   uint32x0, y0;

   uint32x1, y1;

   uint8   i;



   /* 入口参数过滤 */

   if(0==no)

      return;

   if(1==no)                                                // 单点

   {

      x0 = *points++;

      y0 = *points;

      GUI_Point(x0, y0, color);

   }

   

   /* 画多条线条 */

   x0 = *points++;                                        // 取出第一点坐标值,作为原起点坐标值

   y0 = *points++;

   for(i=1; i<no; i++)

   {

      x1 = *points++;                                        // 取出下一点坐标值

      y1 = *points++;

      GUI_Line(x0, y0, x1, y1, color);

      x0 = x1;                                                // 更新原起点坐标

      y0 = y1;

   }

}



#ifGUI_CircleX_EN==1

/****************************************************************************

* 名称:GUI_Circle()

* 功能:指定圆心位置及半径,画圆。

* 入口参数:x0                圆心的x坐标值

*         y0                圆心的y坐标值

*         r         圆的半径

*         color        显示颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_Circle(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32draw_x0, draw_y0;                                // 刽图点坐标变量

   int32draw_x1, draw_y1;       

   int32draw_x2, draw_y2;       

   int32draw_x3, draw_y3;       

   int32draw_x4, draw_y4;       

   int32draw_x5, draw_y5;       

   int32draw_x6, draw_y6;       

   int32draw_x7, draw_y7;       

   int32xx, yy;                                        // 画圆控制变量



   int32di;                                                // 决策变量

   

   /* 参数过滤 */

   if(0==r)

      return;

   

   /* 计算出8个特殊点(0、45、90、135、180、225、270度),进行显示 */

   draw_x0 = draw_x1 = x0;

   draw_y0 = draw_y1 = y0 + r;

   if(draw_y0<GUI_LCM_YMAX)

      GUI_Point(draw_x0, draw_y0, color);                // 90度

       

   draw_x2 = draw_x3 = x0;

   draw_y2 = draw_y3 = y0 - r;

   if(draw_y2>=0)

      GUI_Point(draw_x2, draw_y2, color);                // 270度



   draw_x4 = draw_x6 = x0 + r;

   draw_y4 = draw_y6 = y0;

   if(draw_x4<GUI_LCM_XMAX)

      GUI_Point(draw_x4, draw_y4, color);                // 0度

   

   draw_x5 = draw_x7 = x0 - r;

   draw_y5 = draw_y7 = y0;

   if(draw_x5>=0)

      GUI_Point(draw_x5, draw_y5, color);                // 180度   

   if(1==r)

      return;                                                // 若半径为1,则已圆画完



   /* 使用Bresenham法进行画圆 */

   di = 3 - 2*r;                                        // 初始化决策变量

   

   xx = 0;

   yy = r;       

   while(xx<yy)

   {

      if(di<0)

      {

         di += 4*xx + 6;

      }

      else

      {

         di += 4*(xx - yy) + 10;

          

         yy--;

         draw_y0--;

         draw_y1--;

         draw_y2++;

         draw_y3++;

         draw_x4--;

         draw_x5++;

         draw_x6--;

         draw_x7++;

      }

          

      xx++;

      draw_x0++;

      draw_x1--;

      draw_x2++;

      draw_x3--;

      draw_y4++;

      draw_y5++;

      draw_y6--;

      draw_y7--;

       

      /* 要判断当前点是否在有效范围内 */

      if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )

      {

         GUI_Point(draw_x0, draw_y0, color);

      }

      if( (draw_x1>=0)&&(draw_y1>=0) )

      {

         GUI_Point(draw_x1, draw_y1, color);

      }

      if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x2, draw_y2, color);

      }

      if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x3, draw_y3, color);

      }

      if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )

      {

         GUI_Point(draw_x4, draw_y4, color);

      }

      if( (draw_x5>=0)&&(draw_y5>=0) )

      {

         GUI_Point(draw_x5, draw_y5, color);

      }

      if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x6, draw_y6, color);

      }

      if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x7, draw_y7, color);

      }

   }

}



/****************************************************************************

* 名称:GUI_CircleFill()

* 功能:指定圆心位置及半径,画圆并填充,填充色与边框色一样。

* 入口参数:x0                圆心的x坐标值

*         y0                圆心的y坐标值

*         r         圆的半径

*         color        填充颜色

* 出口参数:无

* 说明:操作失败原因是指定地址超出有效范围。

****************************************************************************/

voidGUI_CircleFill(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32draw_x0, draw_y0;                                // 刽图点坐标变量

   int32draw_x1, draw_y1;       

   int32draw_x2, draw_y2;       

   int32draw_x3, draw_y3;       

   int32draw_x4, draw_y4;       

   int32draw_x5, draw_y5;       

   int32draw_x6, draw_y6;       

   int32draw_x7, draw_y7;       

   int32fill_x0, fill_y0;                                // 填充所需的变量,使用垂直线填充

   int32fill_x1;

   int32xx, yy;                                        // 画圆控制变量



   int32di;                                                // 决策变量

   

   /* 参数过滤 */

   if(0==r)

      return;

   

   /* 计算出4个特殊点(0、90、180、270度),进行显示 */

   draw_x0 = draw_x1 = x0;

   draw_y0 = draw_y1 = y0 + r;

   if(draw_y0<GUI_LCM_YMAX)

   {

      GUI_Point(draw_x0, draw_y0, color);        // 90度

   }

           

   draw_x2 = draw_x3 = x0;

   draw_y2 = draw_y3 = y0 - r;

   if(draw_y2>=0)

   {

      GUI_Point(draw_x2, draw_y2, color);        // 270度

   }

       

   draw_x4 = draw_x6 = x0 + r;

   draw_y4 = draw_y6 = y0;

   if(draw_x4<GUI_LCM_XMAX)

   {

      GUI_Point(draw_x4, draw_y4, color);        // 0度

      fill_x1 = draw_x4;

   }

   else

   {

      fill_x1 = GUI_LCM_XMAX;

   }

   fill_y0 = y0;                                                        // 设置填充线条起始点fill_x0

   fill_x0 = x0 - r;                                                // 设置填充线条结束点fill_y1

   if(fill_x0<0)

      fill_x0 = 0;

   GUI_HLine(fill_x0, fill_y0, fill_x1, color);

   

   draw_x5 = draw_x7 = x0 - r;

   draw_y5 = draw_y7 = y0;

   if(draw_x5>=0)

   {

      GUI_Point(draw_x5, draw_y5, color);        // 180度

   }

   if(1==r)

      return;

   

   

   /* 使用Bresenham法进行画圆 */

   di = 3 - 2*r;                                // 初始化决策变量

   

   xx = 0;

   yy = r;

   while(xx<yy)

   {

      if(di<0)

      {

         di += 4*xx + 6;

      }

      else

      {

         di += 4*(xx - yy) + 10;



         yy--;

         draw_y0--;

         draw_y1--;

         draw_y2++;

         draw_y3++;

         draw_x4--;

         draw_x5++;

         draw_x6--;

         draw_x7++;

      }

          

      xx++;

      draw_x0++;

      draw_x1--;

      draw_x2++;

      draw_x3--;

      draw_y4++;

      draw_y5++;

      draw_y6--;

      draw_y7--;

               

       

      /* 要判断当前点是否在有效范围内 */

      if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )

      {

         GUI_Point(draw_x0, draw_y0, color);

      }

      if( (draw_x1>=0)&&(draw_y1>=0) )

      {

         GUI_Point(draw_x1, draw_y1, color);

      }

          

      /* 第二点水直线填充(下半圆的点) */

      if(draw_x1>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x1;

      /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y1;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

      /* 设置填充线条结束点fill_x1 */

         fill_x1 = x0*2 - draw_x1;

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }



      if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x2, draw_y2, color);

      }

                    

      if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x3, draw_y3, color);

      }

          

      /* 第四点垂直线填充(上半圆的点) */

      if(draw_x3>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x3;

         /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y3;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

         /* 设置填充线条结束点fill_x1 */                                                                       

         fill_x1 = x0*2 - draw_x3;                               

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }



      if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )

      {

         GUI_Point(draw_x4, draw_y4, color);

      }

      if( (draw_x5>=0)&&(draw_y5>=0) )

      {

         GUI_Point(draw_x5, draw_y5, color);

      }

          

      /* 第六点垂直线填充(上半圆的点) */

      if(draw_x5>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x5;

         /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y5;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

         /* 设置填充线条结束点fill_x1 */                                                                       

         fill_x1 = x0*2 - draw_x5;                               

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }



      if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x6, draw_y6, color);

      }



      if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )

      {

         GUI_Point(draw_x7, draw_y7, color);

      }

          

      /* 第八点垂直线填充(上半圆的点) */

      if(draw_x7>=0)

      {/* 设置填充线条起始点fill_x0 */

         fill_x0 = draw_x7;

         /* 设置填充线条起始点fill_y0 */

         fill_y0 = draw_y7;

         if(fill_y0>GUI_LCM_YMAX)

            fill_y0 = GUI_LCM_YMAX;

         if(fill_y0<0)

            fill_y0 = 0;

         /* 设置填充线条结束点fill_x1 */                                                                       

         fill_x1 = x0*2 - draw_x7;                               

         if(fill_x1>GUI_LCM_XMAX)

            fill_x1 = GUI_LCM_XMAX;

         GUI_HLine(fill_x0, fill_y0, fill_x1, color);

      }

   }

}

#endif

shaozh 发表于 2007-4-1 17:09:26

辛苦了,谢谢啦!

wagina 发表于 2007-8-4 14:16:06

请问你对数字取模用的什么取模软件?取模方式是什么?

imgxy 发表于 2007-8-6 16:30:57

请问你的是用ICC编译器吗?

转GCC怎么转呢?

dengxiaofeng 发表于 2009-3-14 11:42:13

呵呵 收下了哈!不错的哈!

lionliu 发表于 2009-3-20 21:15:15

JH

wear778899 发表于 2009-3-21 09:37:19

在多个画椭圆就好了 嘿嘿

guiltcool 发表于 2009-3-22 22:50:07

小弟有个TS12864A-2,管脚定义似乎跟楼主的一样,好像也没有字库的,
买的时候没看清楚,用了90大洋,我亏啊!收藏楼主的程序了!

lengqing1309 发表于 2009-3-23 15:59:24

MARK

cgbabc 发表于 2009-3-23 16:08:18

也顶一个

wangff2531 发表于 2009-3-23 20:17:59

好东西收下了

djl310 发表于 2009-3-24 13:32:40

标记~~~~~~~~~

lin638 发表于 2009-3-27 21:58:41

顶!做记号

ddaitt999 发表于 2009-3-27 22:40:36

一定有用~~!!

lgc-sdu 发表于 2009-5-11 15:48:30

顶!做记号

dpzc1234 发表于 2009-6-19 10:22:53

版主我想问一下关于IO口的设置问题的,我现在用飞思卡尔单片机不能显示,不知道为什么

ajoe 发表于 2009-6-19 12:53:47

留着侯用,谢谢

potatoES 发表于 2009-6-19 13:01:07

路过,好东西要珍藏

xiaobendan 发表于 2009-6-19 13:12:32

9楼在哪里买的啊,这么便宜?

0620221 发表于 2009-7-2 09:45:19

ddddddddddddddddddd

snail0204 发表于 2009-7-2 11:14:43

哈哈不错

0620221 发表于 2009-7-6 09:49:19

点击此处打开 ourdev_458799.jpg(文件大小:2.25M,只有400K以内的图片才能直接显示) (原文件名:12864.jpg)


这就是效果吗?

点击此处下载 ourdev_458800.rar(文件大小:78K) (原文件名:12864.rar)
protues 仿真效果

liudeee 发表于 2009-7-30 21:13:02

楼主用的什么字模提取软件?我试了好几个都不对。

chengtina 发表于 2009-7-31 15:50:11

mark

gdrc 发表于 2009-7-31 16:56:55

GUI写得不错,收藏了.

HONGXP0 发表于 2009-8-1 08:32:49

MARK

sinbord 发表于 2009-8-1 08:48:51

mark!收藏

yanjian 发表于 2009-8-1 12:22:01

收下,研究研究!

ouyangyong817 发表于 2009-8-6 19:22:50

收下先!

Alexkey 发表于 2009-8-6 19:51:38

这个是用在哪个MCU上的?我自己写了两个ARM的,STM32和LM3S,都挺好用的。

honami520 发表于 2009-8-6 20:05:24

这样也能加精?那我上次写的1500行的液晶驱动要是放上来,那不是也能拿精!

yunlong 发表于 2009-8-6 20:30:41

不是做广告,我也是刚开始用这个屏,昨晚才仿真了一下
http://www.gptlcm.cn/CN/list.asp?proname=OCM12864-3
这个网站的屏提供了详细的驱动代码。挺好用的。
ISIS 7 Professional里也有这个屏

qzzz 发表于 2009-8-6 20:40:29

好贴,谢谢了

hisun 发表于 2009-8-6 21:07:29

强贴留名中

xiaobendan 发表于 2009-8-7 13:01:29

我用了几种字模软件,字体都不如C51的字模III好看,可惜到期了,给自动加了一个横线。大家有没有发现其他比较好的字模软件啊?

xiaobendan 发表于 2009-8-7 13:03:42

还有那个GUI是用在KS0108上面的吗?

yanghuagui 发表于 2009-8-24 19:17:38

好贴,研究研究!

xhero 发表于 2009-9-25 20:17:12

研究

zhuzi1441 发表于 2009-9-30 03:22:39

在我的显示模块上,画线正常,字符不正常呀,楼上的同志有调通的吗,给指点一下吧,谢谢了!

cgbabc 发表于 2009-9-30 09:33:51

支持一下

kebaojun305 发表于 2009-9-30 09:36:49

收藏GUI程序。

mountaintop 发表于 2009-9-30 10:46:23

mark,留用!

yangyi 发表于 2009-9-30 10:51:21

没有字库,刷屏慢点

gxy508 发表于 2009-9-30 10:59:37

mark

firs_avr 发表于 2009-10-4 09:02:31

cain.lee 发表于 2009-10-4 12:40:03

先顶一个···话说我的lcd还不知道是不是好的呢···

yunlong 发表于 2009-10-4 19:04:51

zhc7302 发表于 2009-10-4 21:57:58

mark

xczxwy 发表于 2009-10-28 16:12:44

那个GUI的程序不知道有人用过没有呢?看上去挺牛的

382383706 发表于 2009-11-7 17:32:28

mark

Dream_catcher 发表于 2009-11-13 14:16:14

学习

i387DX 发表于 2009-11-27 22:54:18

正好刚收了几片白菜KS0108 12864,有空试试看……

realize 发表于 2009-11-28 09:28:08

mark

eduhf_123 发表于 2009-11-28 22:03:43

MARK GUI

smtgg 发表于 2009-11-28 22:47:11

mark

DirkHo 发表于 2010-1-25 14:42:12

mark too

king2009 发表于 2010-1-25 18:56:56

无图无真相

zooky 发表于 2010-1-25 22:20:37

mark

ringan865 发表于 2010-1-26 17:06:17

mark

xinzhi1986 发表于 2010-1-26 17:13:36

汗,我之前也自己写了个驱动的,原来大家都有了,拿来参考参考,改进改进~

rayingpx 发表于 2010-1-28 08:36:24

mark

jiangping_hbhm 发表于 2010-2-7 23:22:48

MARK

hisun 发表于 2010-2-8 20:28:41

紧跟在后马克

gdourf 发表于 2010-2-9 10:42:10

mark

skyxjh 发表于 2010-2-21 14:36:07

mark

chinamanzhong 发表于 2010-2-21 14:51:02

mark

taiwentaotwt 发表于 2010-2-27 09:08:56

学习了,我的屏是MD12864A,驱动器好像就是这一个

gxy508 发表于 2010-2-27 12:48:36

mark

sonna 发表于 2010-4-1 01:14:54

又是个古董贴啊

liuhongyu 发表于 2010-6-21 22:55:33

mark

ljt8015 发表于 2010-6-22 10:40:43

mark!~~

wbanng 发表于 2010-7-22 11:56:56

mark

pursuer99 发表于 2010-7-22 23:18:39

我看了这个帖子 ,很好 ,比较通用 但是,其中有些地方不明白,希望有人给程序注释一下啊,


if(CurOffset==1) //下半部是写半个字节
{
for(j=0;j<width;j++)
{
SetPageCol(uPage,uCol+j);
ch_w=ASC_16.Msk;
if(uCol+j<64) write_LCD(LEFT,DATA,ch_w);
else write_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage+1,uCol);

for(j=0;j<width;j++)
{
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64) ch_r=read_LCD(LEFT);
else ch_r=read_LCD(RIGHT);
ch_r&=0xf0;
ch_w=ASC_16.Msk&0x0f;
ch_w|=ch_r;
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64) write_LCD(LEFT,DATA,ch_w);
else write_LCD(RIGHT,DATA,ch_w);
}
}
else //上半部是写半个字节
{
for(j=0;j<width;j++)
{
SetPageCol(uPage,uCol+j);
if(uCol+j<64) ch_r=read_LCD(LEFT);
else ch_r=read_LCD(RIGHT);
ch_r&=0x0f;
ch_w=ASC_16.Msk;
ch_w=ch_w<<4;
ch_w|=ch_r;
SetPageCol(uPage,uCol+j);
if(uCol+j<64) write_LCD(LEFT,DATA,ch_w);
else write_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage+1,uCol);
for(j=0;j<width;j++)
{
SetPageCol(uPage+1,uCol+j);

ch_r=ASC_16.Msk;
ch_w=ASC_16.Msk;
ch_r=ch_r>>4;
ch_w=ch_w<<4;
ch_w|=ch_r;
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64) write_LCD(LEFT,DATA,ch_w);
else write_LCD(RIGHT,DATA,ch_w);
}
}
}
SetPageCol(uPage,uCol+width);
}

hbzhangy 发表于 2010-8-13 16:18:10

好帖啊,顶之~

poet_lee 发表于 2010-8-13 20:43:49

谢谢分享~

KevinLee 发表于 2010-8-13 20:54:11

mark

120908069 发表于 2010-8-20 02:32:56

GOOD

739797340 发表于 2010-9-21 21:34:40

mark

myworkmail 发表于 2010-9-21 23:01:37

mark

8s209 发表于 2010-10-19 23:10:05

mark

wenfeiexe 发表于 2010-10-19 23:21:04

mark

allenjwb 发表于 2010-10-26 23:19:14

mark

bmagui 发表于 2010-10-27 08:29:01

mark

myworkmail 发表于 2010-10-27 09:04:03

mark

youpeng 发表于 2010-11-28 21:40:03

GOOD!必须MARK!
页: [1] 2
查看完整版本: 强烈推荐一款LCM12864(KS0108)的完整应用程序,感觉和“傻孩子”的1206程序有异曲同工之