原创 强烈推荐一款LCM12864(KS0108)的完整应用程序,(转贴自ouravr)

2007-4-2 13:17 5684 5 6 分类: MCU/ 嵌入式


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




/*
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编辑过
__________________________
天天进步,天天成长,天天快乐,天天健康!!
zhaoxibo1980@126.com
QQ:39787535
技术交流群:28625733
pixel.GIF2006-11-10,09:15:05
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【2楼】 mcuhost 波波
armok01132655.gif
积分:156
派别:
等级:------
来自:天津
是不是认为程序太简单了??~~~~
__________________________
天天进步,天天成长,天天快乐,天天健康!!
zhaoxibo1980@126.com
QQ:39787535
技术交流群:28625733
pixel.GIF2006-11-10,09:27:24
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【3楼】 mcuhost 波波
armok01132655.gif
积分:156
派别:
等级:------
来自:天津
我疑惑!!
__________________________
天天进步,天天成长,天天快乐,天天健康!!
zhaoxibo1980@126.com
QQ:39787535
技术交流群:28625733
pixel.GIF2006-11-10,10:22:20
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【4楼】 armok 阿莫
armok01110386.jpg
积分:20336
派别:
等级:------
来自:OurAVR.com 站长
要用到才会有人认真研究 ....
__________________________
There's something good in this world. And it's worth fighting for ……
我的手机为:13433056000,如果本网站不正常,请用手机短信通知我。
我不用QQ,我用MSN:armokarmok@hotmail. 技术问题请在论坛发贴,否则我会忙不过来,谢谢。
pixel.GIF2006-11-10,10:28:57
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【5楼】 mcuhost 波波
armok01132655.gif
积分:156
派别:
等级:------
来自:天津
armok兄言之有理
__________________________
天天进步,天天成长,天天快乐,天天健康!!
zhaoxibo1980@126.com
QQ:39787535
技术交流群:28625733
pixel.GIF2006-11-10,10:32:04
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【6楼】 fbnfbn
积分:131
派别:
等级:------
来自:广州番禺
请问这个液晶价格怎样,有没生产商或代理商的电话
谢谢!
__________________________

MSN: fbnfbnfbn@21cn.com

pixel.GIF2006-12-06,09:16:14
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【7楼】 Gorgon Meducer 傻孩子
armok0111022.jpg
积分:693
派别:
等级:------
来自:祖国的大西南
发现自己名字……路过……
 
pixel.GIF2006-12-06,09:20:29
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【8楼】 AVR-MEGA128 安步当车
armok01145721.jpg
积分:564
派别:
等级:------
来自:http://www.ouravr.com/bbs/bbs_upload5678234990515/files_unde
ding 就一个字
__________________________
QQ:315716395
pixel.GIF2006-12-06,09:30:50
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【9楼】 fsclub
armok0120882.gif
积分:1505
派别:
等级:------
来自:
刚刚以35米的价格买了个无字库的12864,正好是KS1008的,正好想配合GPS用来运动画轨迹..
下来研究一下...
__________________________
欢迎光临俺的网站:

http://www.mp3-cn.com
pixel.GIF2006-12-31,12:23:48
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【10楼】 fsclub
armok0120882.gif
积分:1505
派别:
等级:------
来自:
//PORTA---数据口  PORTB----控制口 
--------
这个注释有问题吧?
我看PORTC才是控制口啊!
__________________________
欢迎光临俺的网站:

http://www.mp3-cn.com
pixel.GIF2006-12-31,12:35:55
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【11楼】 xuetwins
积分:3
派别:
等级:------
来自:
to 楼主: 

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

万分感谢!!

效果如下:

armok01148622.jpg
 
pixel.GIF2007-03-30,17:12:05
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【12楼】 hxke
积分:22
派别:
等级:------
来自:
to: xuetwins
写汉字之前把字模取反就ok了。。。。(加个~符号就搞定)
em078.gif
 
pixel.GIF2007-03-30,20:56:43
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【13楼】 xuetwins
积分:3
派别:
等级:------
来自:
比如最上面楼主的程序

在哪里加~   ???

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

 
pixel.GIF2007-03-31,09:50:05
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【14楼】 xuepeng2000
积分:164
派别:
等级:------
来自:
if(uCol+j<64) ch_r=read_LCD(LEFT); 
      else ch_r=read_LCD(RIGHT); 
      ch_r=~ch_r;
   再write就可以了

这里就可以

感觉写汉字和写字母的不应该分开,反正一个扫八列,一个扫十六列
用一个标志来做汉字和字母的判断,
那样就可以用一个函数写出来.
 
 
pixel.GIF2007-03-31,10:29:14
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【15楼】 xuepeng2000
积分:164
派别:
等级:------
来自:
if(uCol+j<64) ch_r=read_LCD(LEFT); 
      else ch_r=read_LCD(RIGHT); 
      ch_r=~ch_r;
   再write就可以了

这里就可以

感觉写汉字和写字母的不应该分开,反正一个扫八列,一个扫十六列
用一个标志来做汉字和字母的判断,
那样就可以用一个函数写出来.
 
我把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
 
pixel.GIF2007-03-31,10:49:28
pixel.GIF资料 pixel.GIF邮件 pixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIFpixel.GIF编辑 pixel.GIF删除 pixel.GIFpixel.GIF

【16楼】 xuepeng2000
积分:164
派别:
等级:------
来自:
if(uCol+j<64) ch_r=read_LCD(LEFT); 
      else ch_r=read_LCD(RIGHT); 
      ch_r=~ch_r;
   再write就可以了

这里就可以

感觉写汉字和写字母的不应该分开,反正一个扫八列,一个扫十六列
用一个标志来做汉字和字母的判断,
那样就可以用一个函数写出来.
 
我把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我把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

文章评论1条评论)

登录后参与讨论

guoxingye159gxy_443316930 2011-4-6 14:41

这是用在MP3上的吗?
相关推荐阅读
fpga2006 2008-11-13 09:16
步进电机。。(转载)
虽然步进电机已被广泛地应用,但步进电机并不能象普通的直流电机,交流电机在常规下使用。它必须由双环形脉冲信号、功率驱动电路等组成控制系统方可使用。因此用好步进电机却非易事,它涉及到机械、电机、电子及计算...
fpga2006 2008-07-22 14:17
转载 3V与5V混合系统中逻辑器接口问题
3V与5V混合系统中逻辑器接口问题  3V与5V混合系统中逻辑器接口问题1 引言近年来,随着便携式数字电子产品棗笔记本计算机、数字式移动电话、寻呼机、手持式测试仪表等的迅速发展,要求使用体积小、功耗低...
fpga2006 2008-07-03 15:16
GB ma
GB码 GB 即"国标"的汉语拼音缩写,为中华人民共和国国家标准的意思. 国标编码就是中华人民共和国信息交换汉字编码标准(GB2312-80), 在此标准中制定了每一个汉字及非汉字符号的编码。规定将汉...
fpga2006 2008-06-30 14:21
俄文866编码及其与ANSI编码的转换
АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщыьэюяёъ(俄文866编码,用一个字节表示,在WORD中用西里尔文(DOS))80...
fpga2006 2008-05-07 16:15
液晶扫描一帧的行数N的倒数叫占空比,半选择点和选择点的电压比叫偏压。
液晶扫描一帧的行数N的倒数叫占空比,半选择点和选择点的电压比叫偏压。很抽象?具体的说液晶是n行的(com端的数目),占空比就是1/n,在电压一定的情况下,行数的增加意味着占空比下降,使液晶的显示质量下...
fpga2006 2008-03-21 09:30
区位码和国标码转换
国标与机内码的转换   国标码并不等于区位码,它是由区位码稍作转换得到,其转换方法为:先将十进制区码和位码转换为十六进制的区码和位码,;这样就得了一个与国标码有一个相对位置差的代码,;再将这个代码的第...
我要评论
1
5
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /4 下一条