⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphic.c

📁 AVR控制12864液晶画圆弧,在AVR单片机的控制下完成圆弧的绘制。
💻 C
字号:
//*****************************************************************
//本头文件实现了用于液晶显示的缓冲区和基本的图形函数
//包括了画点,画线,画圆,画矩形等函数,每种函数都有三种方式画
//即 LCD_MODE_CLEAR, LCD_MODE_SET, LCD_MODE_XOR(清除,置位,异或)
//             ---北京交通大学电气学院 杨罡 2008.8
//*****************************************************************
#include  "graphic.h"

 unsigned char l_mask_array[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
 unsigned char l_display_array[LCD_Y_BYTES][LCD_X_BYTES]={0,0,0};
 /* TODO: avoid or PROGMEM */
 /* fill buffer and LCD with pattern */
void lcd_fill( unsigned char pattern)
 { unsigned char page, col;

   for (page=0; page<LCD_Y_BYTES; page++) 
    { for (col=0; col<LCD_X_BYTES; col++) 
         l_display_array[page][col]=pattern;
    }
   lcd_update_all();
 }


void lcd_erase(void)
 { lcd_fill(0x00);
   lcd_update_all();
 }

/*
**
** Updates area of the display. Writes data from "framebuffer" 
** RAM to the lcd display controller RAM.
** 
** Arguments Used:
**    top     top line of area to update.
**    bottom  bottom line of area to update.
**    from MJK-Code
**
*/
void lcd_update( unsigned char top,  unsigned char bottom)
 { unsigned char x;
   unsigned char y;
   unsigned char yt;
   unsigned char yb;
   unsigned char *colptr;
  
   /* setup bytes of range */
   yb = bottom >> 3;
   yt = top >> 3;		

   for(y = yt; y <= yb; y++)
    {lcd_out_ctl(LCD_SET_PAGE+y,3);	    /* set page */
                                       //     lcd_out_ctl(LCD_SET_COL+LCD_STARTCOL_REVERSE,3);
     lcd_out_ctl(LCD_SET_COL+0,3);
	 
     colptr = &l_display_array[y][0];

      for (x=0; x < LCD_X_BYTES; x++)
       { if ( x <LCD_X_BYTES/2 ) 
            lcd_out_dat_l(*colptr++);
         else 
            lcd_out_dat_r(*colptr++);
       }
 
    }
 }



void lcd_update_all(void)
 { lcd_update(SCRN_TOP,SCRN_BOTTOM);
 }



/* sets/clears/switchs(XOR) dot at (x,y) */
void lcd_dot( unsigned char x,  unsigned char y,  unsigned char mode) 
 { unsigned char bitnum, bitmask, yByte;
   unsigned char *pBuffer; /* pointer used for optimisation */

   if ( ( x > SCRN_RIGHT ) || ( y > SCRN_BOTTOM ) ) return;

   yByte   = y >> 3; 
   bitnum  = y & 0x07;
   bitmask = l_mask_array[bitnum]; // bitmask = ( 1 << (y & 0x07) );
   pBuffer = &(l_display_array[yByte][x]);
   switch (mode) 
    { case LCD_MODE_SET:
         *pBuffer |= bitmask;
         break;
      case LCD_MODE_CLEAR:
         *pBuffer &= ~bitmask;
         break;
      case LCD_MODE_XOR:
         *pBuffer ^= bitmask;
         break;
      default: break;
    }         
 }


/* line- and circle-function from a KS0108-library by F. Thiele */

void lcd_line( uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2,  uint8_t mode ) 
 { uint8_t length, xTmp, yTmp, i, y, yAlt;
   int16_t m;
   
   if(x1 == x2) 
    { // vertical line
      // x1|y1 must be the upper point
      if(y1 > y2) 
       { xTmp = x1;
         yTmp = y1;
         x1 = x2;
         y1 = y2;
         x2 = xTmp;
         y2 = yTmp;
       }
      length = y2-y1;
      for(i=0; i<=length; i++) 
         lcd_dot(x1, y1+i, mode);
    } 
   else if(y1 == y2) 
    { // horizontal line
      // x1|y1 must be the left point
      if(x1 > x2) 
       { xTmp = x1;
         yTmp = y1;
         x1 = x2;
         y1 = y2;
         x2 = xTmp;
         y2 = yTmp;
       }

      length = x2-x1;
      for(i=0; i<=length; i++) 
         lcd_dot(x1+i, y1, mode);
       
    } 
   else 
    { // x1 must be smaller than x2
      if(x1 > x2) 
       { xTmp = x1;
         yTmp = y1;
         x1 = x2;
         y1 = y2;
         x2 = xTmp;
         y2 = yTmp;
       }
		
      if((y2-y1) >= (x2-x1) || (y1-y2) >= (x2-x1)) 
       { // angle larger or equal 45?
         length = x2-x1;								// not really the length :)
         m = ((y2-y1)*200)/length;
         yAlt = y1;
         for(i=0; i<=length; i++) 
          { y = ((m*i)/200)+y1;
            if((m*i)%200 >= 100)
               y++;
            else if((m*i)%200 <= -100)
               y--;
				
            lcd_line(x1+i, yAlt, x1+i, y, mode ); /* wuff wuff recurs. */
            if(length<=(y2-y1) && y1 < y2)
               yAlt = y+1;
            else if(length<=(y1-y2) && y1 > y2)
               yAlt = y-1;
            else
               yAlt = y;
          }
       } 
      else
       { // angle smaller 45?
         // y1 must be smaller than y2
         if(y1 > y2)
          { xTmp = x1;
            yTmp = y1;
            x1 = x2;
            y1 = y2;
            x2 = xTmp;
            y2 = yTmp;
          }
         length = y2-y1;
         m = ((x2-x1)*200)/length;
         yAlt = x1;
         for(i=0; i<=length; i++)
          { y = ((m*i)/200)+x1;

            if((m*i)%200 >= 100)
               y++;
            else if((m*i)%200 <= -100)
               y--;

            lcd_line(yAlt, y1+i, y, y1+i, mode); /* wuff */
            if(length<=(x2-x1) && x1 < x2)
               yAlt = y+1;
            else if(length<=(x1-x2) && x1 > x2)
               yAlt = y-1;
            else
               yAlt = y;
          }
       }
    }
 }


void lcd_circle( uint8_t xCenter, uint8_t yCenter, 
                 uint8_t radius,  uint8_t mode) 
 {  int tSwitch, y, x = 0;
   uint8_t d;
   
   d = yCenter - xCenter;
   y = radius;
   tSwitch = 3 - 2 * radius;

   while (x <= y) 
    { lcd_dot(xCenter + x, yCenter + y, mode);
      lcd_dot(xCenter + x, yCenter - y, mode);
	
      lcd_dot(xCenter - x, yCenter + y, mode);
      lcd_dot(xCenter - x, yCenter - y, mode);
	
      lcd_dot(yCenter + y - d, yCenter + x, mode);
      lcd_dot(yCenter + y - d, yCenter - x, mode);
   
      lcd_dot(yCenter - y - d, yCenter + x, mode);
      lcd_dot(yCenter - y - d, yCenter - x, mode);

      if (tSwitch<0) 
         tSwitch += (4 * x + 6);
      else 
       { tSwitch += (4 * (x - y) + 10);
         y--;
       }
      x++;
    }
 }


void lcd_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t mode) 
 { width--;
   height--;
   lcd_line(x, y, x+width, y, mode);	// top
   lcd_line(x, y, x, y+height, mode);	// left
   lcd_line(x, y+height, x+width, y+height, mode);	// bottom
   lcd_line(x+width, y, x+width, y+height, mode);		// right
 }

void lcd_box( uint8_t x, uint8_t y, uint8_t width,  uint8_t height,  uint8_t mode) 
 { uint8_t i;
   if (!width) return; 

   width--;
	
   for (i=y;i<y+height;i++) 
      lcd_line(x, i, x+width, i, mode);
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -