搜索
bottom↓
回复: 155

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

[复制链接]

出0入0汤圆

发表于 2006-11-10 09:15:05 | 显示全部楼层 |阅读模式
其中,部分注释是本人注的,大家讨论一下这个程序吧。









/*

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

#define  START_LINE0   0xc0

#define  DISPLAY_ON    0x3f

#define  DISPLAY_OFF   0x3e

#define  PARA1         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[1];

        char Msk[16];

};

struct typFNT_ASC16 const ASC_16[] = {        /* 显示为8*16  Curier 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[2];

        char Msk[24];

};

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[0]);

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

        {

                if(c == ASC_16[k].Index[0] ) 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[k].Msk[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);

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

                                else ch_r=read_LCD(RIGHT);

                                ch_r&=0xf0;

                                ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j]&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[k].Msk[j];

                                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[k].Msk[j];

                                ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j];

                                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[0]);k++)

        {

                if(hz[0] == GB_16[k].Index[0] && hz[1] == GB_16[k].Index[1])

                        break;

        }



        if(CurOffset==1)

        {

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

        {

                SetPageCol(uPage,uCol+j);

                ch_w=GB_16[k].Msk[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);

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

                else ch_r=read_LCD(RIGHT);

                ch_r&=0xf0;

                ch_w=GB_16[k].Msk[ASC_HZ_WIDTH+j]&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[k].Msk[j];

                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[k].Msk[j];

                ch_w=GB_16[k].Msk[ASC_HZ_WIDTH+j];

                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编辑过

出0入0汤圆

 楼主| 发表于 2006-11-10 09:27:24 | 显示全部楼层
是不是认为程序太简单了??~~~~

出0入0汤圆

 楼主| 发表于 2006-11-10 10:22:20 | 显示全部楼层
我疑惑!!
头像被屏蔽

出0入0汤圆

发表于 2006-11-10 10:28:57 | 显示全部楼层
要用到才会有人认真研究 ....

出0入0汤圆

 楼主| 发表于 2006-11-10 10:32:04 | 显示全部楼层
armok兄言之有理

出0入0汤圆

发表于 2006-12-6 09:16:14 | 显示全部楼层
请问这个液晶价格怎样,有没生产商或代理商的电话

谢谢!

出0入296汤圆

发表于 2006-12-6 09:20:29 | 显示全部楼层
发现自己名字……路过……

出0入0汤圆

发表于 2006-12-6 09:30:50 | 显示全部楼层
ding 就一个字

出0入0汤圆

发表于 2006-12-31 12:23:48 | 显示全部楼层
刚刚以35米的价格买了个无字库的12864,正好是KS1008的,正好想配合GPS用来运动画轨迹..

下来研究一下...

出0入0汤圆

发表于 2006-12-31 12:35:55 | 显示全部楼层
//PORTA---数据口  PORTB----控制口

--------

这个注释有问题吧?

我看PORTC才是控制口啊!

出0入0汤圆

发表于 2007-3-30 17:12:05 | 显示全部楼层
to 楼主:



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



万分感谢!!



效果如下:



出0入0汤圆

发表于 2007-3-30 20:56:43 | 显示全部楼层
to: xuetwins

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

:)

出0入0汤圆

发表于 2007-3-31 09:50:05 | 显示全部楼层
比如最上面楼主的程序



在哪里加~   ???



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

出0入0汤圆

发表于 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就可以了



这里就可以



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

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

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

出0入0汤圆

发表于 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时显示)

* 出口参数:无

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

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

void  GUI_HLine(unsigned int x0, unsigned char y0, unsigned int x1, TCOLOR color)

{

    unsigned char  bak;

    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时显示)

* 出口参数:        无

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

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

void  GUI_RLine(unsigned int x0, unsigned char y0, unsigned char y1, TCOLOR color)

{

    unsigned char  bak;

    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        显示颜色

* 出口参数:无

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

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

void  GUI_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        填充颜色

* 出口参数:无

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

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

void  GUI_RectangleFill(uint16 x0, uint8 y0, uint16 x1, uint8 y1, TCOLOR color)

{

   uint32  i;



   /* 先找出矩形左上角与右下角的两个点,保存在(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        显示颜色

* 出口参数:无

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

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

void  GUI_Square(uint32 x0, uint32 y0, uint32  with, TCOLOR  color)

{

   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时显示)

* 出口参数:无

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

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

void  GUI_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        显示颜色

* 出口参数:无

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

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

void  GUI_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        显示颜色

* 出口参数:无

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

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

void  GUI_LineS(uint32 const *points, uint8 no, TCOLOR color)

{

   uint32  x0, y0;

   uint32  x1, 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;

   }

}



#if  GUI_CircleX_EN==1

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

* 名称:GUI_Circle()

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

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

*           y0                圆心的y坐标值

*           r           圆的半径

*           color        显示颜色

* 出口参数:无

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

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

void  GUI_Circle(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32  draw_x0, draw_y0;                                // 刽图点坐标变量

   int32  draw_x1, draw_y1;       

   int32  draw_x2, draw_y2;       

   int32  draw_x3, draw_y3;       

   int32  draw_x4, draw_y4;       

   int32  draw_x5, draw_y5;       

   int32  draw_x6, draw_y6;       

   int32  draw_x7, draw_y7;       

   int32  xx, yy;                                        // 画圆控制变量



   int32  di;                                                // 决策变量

   

   /* 参数过滤 */

   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        填充颜色

* 出口参数:无

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

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

void  GUI_CircleFill(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32  draw_x0, draw_y0;                                // 刽图点坐标变量

   int32  draw_x1, draw_y1;       

   int32  draw_x2, draw_y2;       

   int32  draw_x3, draw_y3;       

   int32  draw_x4, draw_y4;       

   int32  draw_x5, draw_y5;       

   int32  draw_x6, draw_y6;       

   int32  draw_x7, draw_y7;       

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

   int32  fill_x1;

   int32  xx, yy;                                        // 画圆控制变量



   int32  di;                                                // 决策变量

   

   /* 参数过滤 */

   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

出0入0汤圆

发表于 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时显示)

* 出口参数:无

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

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

void  GUI_HLine(unsigned int x0, unsigned char y0, unsigned int x1, TCOLOR color)

{

    unsigned char  bak;

    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时显示)

* 出口参数:        无

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

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

void  GUI_RLine(unsigned int x0, unsigned char y0, unsigned char y1, TCOLOR color)

{

    unsigned char  bak;

    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        显示颜色

* 出口参数:无

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

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

void  GUI_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        填充颜色

* 出口参数:无

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

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

void  GUI_RectangleFill(uint16 x0, uint8 y0, uint16 x1, uint8 y1, TCOLOR color)

{

   uint32  i;



   /* 先找出矩形左上角与右下角的两个点,保存在(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        显示颜色

* 出口参数:无

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

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

void  GUI_Square(uint32 x0, uint32 y0, uint32  with, TCOLOR  color)

{

   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时显示)

* 出口参数:无

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

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

void  GUI_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        显示颜色

* 出口参数:无

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

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

void  GUI_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        显示颜色

* 出口参数:无

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

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

void  GUI_LineS(uint32 const *points, uint8 no, TCOLOR color)

{

   uint32  x0, y0;

   uint32  x1, 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;

   }

}



#if  GUI_CircleX_EN==1

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

* 名称:GUI_Circle()

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

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

*           y0                圆心的y坐标值

*           r           圆的半径

*           color        显示颜色

* 出口参数:无

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

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

void  GUI_Circle(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32  draw_x0, draw_y0;                                // 刽图点坐标变量

   int32  draw_x1, draw_y1;       

   int32  draw_x2, draw_y2;       

   int32  draw_x3, draw_y3;       

   int32  draw_x4, draw_y4;       

   int32  draw_x5, draw_y5;       

   int32  draw_x6, draw_y6;       

   int32  draw_x7, draw_y7;       

   int32  xx, yy;                                        // 画圆控制变量



   int32  di;                                                // 决策变量

   

   /* 参数过滤 */

   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        填充颜色

* 出口参数:无

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

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

void  GUI_CircleFill(uint32 x0, uint32 y0, uint32 r, TCOLOR color)

{

   int32  draw_x0, draw_y0;                                // 刽图点坐标变量

   int32  draw_x1, draw_y1;       

   int32  draw_x2, draw_y2;       

   int32  draw_x3, draw_y3;       

   int32  draw_x4, draw_y4;       

   int32  draw_x5, draw_y5;       

   int32  draw_x6, draw_y6;       

   int32  draw_x7, draw_y7;       

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

   int32  fill_x1;

   int32  xx, yy;                                        // 画圆控制变量



   int32  di;                                                // 决策变量

   

   /* 参数过滤 */

   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

出0入0汤圆

发表于 2007-4-1 17:09:26 | 显示全部楼层
辛苦了,谢谢啦!

出0入0汤圆

发表于 2007-8-4 14:16:06 | 显示全部楼层
请问你对数字取模用的什么取模软件?取模方式是什么?

出0入0汤圆

发表于 2007-8-6 16:30:57 | 显示全部楼层
请问你的是用ICC编译器吗?

转GCC怎么转呢?

出0入18汤圆

发表于 2009-3-14 11:42:13 | 显示全部楼层
呵呵 收下了哈!不错的哈!

出0入0汤圆

发表于 2009-3-20 21:15:15 | 显示全部楼层
JH

出0入0汤圆

发表于 2009-3-21 09:37:19 | 显示全部楼层
在多个画椭圆就好了 嘿嘿

出0入0汤圆

发表于 2009-3-22 22:50:07 | 显示全部楼层
小弟有个TS12864A-2,管脚定义似乎跟楼主的一样,好像也没有字库的,
买的时候没看清楚,用了90大洋,我亏啊!收藏楼主的程序了!

出10入8汤圆

发表于 2009-3-23 15:59:24 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-3-23 16:08:18 | 显示全部楼层
也顶一个

出0入0汤圆

发表于 2009-3-23 20:17:59 | 显示全部楼层
好东西  收下了

出0入0汤圆

发表于 2009-3-24 13:32:40 | 显示全部楼层
标记~~~~~~~~~

出0入0汤圆

发表于 2009-3-27 21:58:41 | 显示全部楼层
顶!做记号

出0入0汤圆

发表于 2009-3-27 22:40:36 | 显示全部楼层
一定有用~~!!

出0入0汤圆

发表于 2009-5-11 15:48:30 | 显示全部楼层
顶!做记号

出0入0汤圆

发表于 2009-6-19 10:22:53 | 显示全部楼层
版主我想问一下关于IO口的设置问题的,我现在用飞思卡尔单片机不能显示,不知道为什么

出0入0汤圆

发表于 2009-6-19 12:53:47 | 显示全部楼层
留着侯用,谢谢

出0入0汤圆

发表于 2009-6-19 13:01:07 | 显示全部楼层
路过,好东西要珍藏

出0入0汤圆

发表于 2009-6-19 13:12:32 | 显示全部楼层
9楼在哪里买的啊,这么便宜?

出0入0汤圆

发表于 2009-7-2 09:45:19 | 显示全部楼层
ddddddddddddddddddd

出0入0汤圆

发表于 2009-7-2 11:14:43 | 显示全部楼层
哈哈不错

出0入0汤圆

发表于 2009-7-6 09:49:19 | 显示全部楼层
点击此处打开 ourdev_458799.jpg(文件大小:2.25M,只有400K以内的图片才能直接显示) (原文件名:12864.jpg)


这就是效果吗?

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

出0入0汤圆

发表于 2009-7-30 21:13:02 | 显示全部楼层
楼主用的什么字模提取软件?  我试了好几个都不对。

出0入10汤圆

发表于 2009-7-31 15:50:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-7-31 16:56:55 | 显示全部楼层
GUI写得不错,收藏了.

出0入0汤圆

发表于 2009-8-1 08:32:49 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-8-1 08:48:51 | 显示全部楼层
mark!收藏

出0入0汤圆

发表于 2009-8-1 12:22:01 | 显示全部楼层
收下,研究研究!

出0入0汤圆

发表于 2009-8-6 19:22:50 | 显示全部楼层
收下先!

出0入0汤圆

发表于 2009-8-6 19:51:38 | 显示全部楼层
这个是用在哪个MCU上的?我自己写了两个ARM的,STM32和LM3S,都挺好用的。

出0入90汤圆

发表于 2009-8-6 20:05:24 | 显示全部楼层
这样也能加精?那我上次写的1500行的液晶驱动要是放上来,那不是也能拿精!

出0入0汤圆

发表于 2009-8-6 20:30:41 | 显示全部楼层
不是做广告,我也是刚开始用这个屏,昨晚才仿真了一下
http://www.gptlcm.cn/CN/list.asp?proname=OCM12864-3
这个网站的屏提供了详细的驱动代码。挺好用的。
ISIS 7 Professional里也有这个屏

出0入0汤圆

发表于 2009-8-6 20:40:29 | 显示全部楼层
好贴,谢谢了

出0入0汤圆

发表于 2009-8-6 21:07:29 | 显示全部楼层
强贴留名中

出0入0汤圆

发表于 2009-8-7 13:01:29 | 显示全部楼层
我用了几种字模软件,字体都不如C51的字模III好看,可惜到期了,给自动加了一个横线。大家有没有发现其他比较好的字模软件啊?

出0入0汤圆

发表于 2009-8-7 13:03:42 | 显示全部楼层
还有那个GUI是用在KS0108上面的吗?

出0入0汤圆

发表于 2009-8-24 19:17:38 | 显示全部楼层
好贴,研究研究!

出0入0汤圆

发表于 2009-9-25 20:17:12 | 显示全部楼层
研究

出0入0汤圆

发表于 2009-9-30 03:22:39 | 显示全部楼层
在我的显示模块上,画线正常,字符不正常呀,楼上的同志有调通的吗,给指点一下吧,谢谢了!

出0入0汤圆

发表于 2009-9-30 09:33:51 | 显示全部楼层
支持一下

出0入8汤圆

发表于 2009-9-30 09:36:49 | 显示全部楼层
收藏GUI程序。

出0入0汤圆

发表于 2009-9-30 10:46:23 | 显示全部楼层
mark,留用!

出10入10汤圆

发表于 2009-9-30 10:51:21 | 显示全部楼层
没有字库,刷屏慢点

出0入0汤圆

发表于 2009-9-30 10:59:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-4 09:02:31 | 显示全部楼层

出0入0汤圆

发表于 2009-10-4 12:40:03 | 显示全部楼层
先顶一个···话说我的lcd还不知道是不是好的呢···

出0入0汤圆

发表于 2009-10-4 19:04:51 | 显示全部楼层

出0入0汤圆

发表于 2009-10-4 21:57:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-28 16:12:44 | 显示全部楼层
那个GUI的程序不知道有人用过没有呢?看上去挺牛的

出0入0汤圆

发表于 2009-11-7 17:32:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-13 14:16:14 | 显示全部楼层
学习

出0入0汤圆

发表于 2009-11-27 22:54:18 | 显示全部楼层
正好刚收了几片白菜KS0108 12864,有空试试看……

出0入0汤圆

发表于 2009-11-28 09:28:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-28 22:03:43 | 显示全部楼层
MARK GUI

出0入0汤圆

发表于 2009-11-28 22:47:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-25 14:42:12 | 显示全部楼层
mark too

出0入0汤圆

发表于 2010-1-25 18:56:56 | 显示全部楼层
无图无真相

出0入0汤圆

发表于 2010-1-25 22:20:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-26 17:06:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-26 17:13:36 | 显示全部楼层
汗,我之前也自己写了个驱动的,原来大家都有了,拿来参考参考,改进改进~

出0入0汤圆

发表于 2010-1-28 08:36:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-7 23:22:48 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-2-8 20:28:41 | 显示全部楼层
紧跟在后马克

出0入0汤圆

发表于 2010-2-9 10:42:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-21 14:36:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-21 14:51:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-27 09:08:56 | 显示全部楼层
学习了,我的屏是MD12864A,驱动器好像就是这一个

出0入0汤圆

发表于 2010-2-27 12:48:36 | 显示全部楼层
mark

出0入59汤圆

发表于 2010-4-1 01:14:54 | 显示全部楼层
又是个古董贴啊

出0入0汤圆

发表于 2010-6-21 22:55:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-22 10:40:43 | 显示全部楼层
mark!~~

出0入0汤圆

发表于 2010-7-22 11:56:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-22 23:18:39 | 显示全部楼层
我看了这个帖子 ,很好 ,比较通用 但是,其中有些地方不明白,希望有人给程序注释一下啊,


if(CurOffset==1) //下半部是写半个字节
{
for(j=0;j<width;j++)
{
SetPageCol(uPage,uCol+j);
ch_w=ASC_16[k].Msk[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);
if(uCol+j<64) ch_r=read_LCD(LEFT);
else ch_r=read_LCD(RIGHT);
ch_r&=0xf0;
ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j]&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[k].Msk[j];
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[k].Msk[j];
ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j];
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);
}

出0入0汤圆

发表于 2010-8-13 16:18:10 | 显示全部楼层
好帖啊,顶之~

出0入0汤圆

发表于 2010-8-13 20:43:49 | 显示全部楼层
谢谢分享~

出0入0汤圆

发表于 2010-8-13 20:54:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-20 02:32:56 | 显示全部楼层
GOOD

出0入0汤圆

发表于 2010-9-21 21:34:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-21 23:01:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-19 23:10:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-19 23:21:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-26 23:19:14 | 显示全部楼层
mark

出350入8汤圆

发表于 2010-10-27 08:29:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-27 09:04:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-28 21:40:03 | 显示全部楼层
GOOD!必须MARK!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 06:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表