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

📄 sed1520.c

📁 AVR单片机的EW12A03GLY液晶显示代码
💻 C
字号:
/**************************************************************************
 *                                                                         
 *   sed1520.c                                                             
 *   LCD display controller interface routines for graphics modules        
 *   with onboard SED1520 controller(s) in "write-only" setup              
 *                                                                         
 *   Version 1.02 (20051031)                                               
 *                                                                         
 *   For Atmel AVR controllers with avr-gcc/avr-libc                       
 *   Copyright (c) 2005                                                    
 *     Martin Thomas, Kaiserslautern, Germany                              
 *     <eversmith@heizung-thomas.de>                                       
 *     http://www.siwawi.arubi.uni-kl.de/avr_projects                      
 *
 *   Permission to use in NON-COMMERCIAL projects is herbey granted. For
 *   a commercial license contact the author.
 *
 *   The above copyright notice and this permission notice shall be included in all
 *   copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 *   FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 *   COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 *   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *                                                                         
 *
 *   partly based on code published by:                                    
 *   Michael J. Karas and Fabian "ape" Thiele
 *
 *
 ***************************************************************************/

/* 
   An Emerging Display EW12A03LY 122x32 Graphics module has been used
   for testing. This module only supports "write". There is no option
   to read data from the SED1520 RAM. The SED1520 R/W line on the 
   module is bound to GND according to the datasheet. Because of this 
   Read-Modify-Write using the LCD-RAM is not possible with the 12A03 
   LCD-Module. So this library uses a "framebuffer" which needs 
   ca. 500 bytes of the AVR's SRAM. The libray can of cause be used 
   with read/write modules too.
*/

/* tab-width: 4 */

#include <avr/io.h>
#include <avr/delay.h>
#include <stdint.h>
#include "sed1520.h"
#include "fonts.h"
#include "bmp.h"

/* pixel level bit masks for display */
/* this array is setup to map the order */
/* of bits in a byte to the vertical order */
/* of bits at the LCD controller */
const unsigned char l_mask_array[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; /* TODO: avoid or PROGMEM */

/* the LCD display image memory */
/* buffer arranged so page memory is sequential in RAM */
unsigned char l_display_array[LCD_Y_BYTES][LCD_X_BYTES];

/* control-lines hardware-interface (only "write") */
#define LCD_CMD_MODE()     LCDCTRLPORT &= ~(1<<LCDCMDPIN)
#define LCD_DATA_MODE()    LCDCTRLPORT |=  (1<<LCDCMDPIN)
#define LCD_ENABLE_E1()    LCDCTRLPORT &= ~(1<<LCDE1PIN)
#define LCD_DISABLE_E1()   LCDCTRLPORT |=  (1<<LCDE1PIN)
#define LCD_ENABLE_E2()    LCDCTRLPORT &= ~(1<<LCDE2PIN)
#define LCD_DISABLE_E2()   LCDCTRLPORT |=  (1<<LCDE2PIN)

/* 
**
** Low level LCD Controller Interface Support Routines
**
*/

static void lcd_strobe_delay(void)
 { //
#ifndef LCD_SIM
   _delay_us(1);
#endif
 }

static void lcd_long_delay(void)
 {
#ifndef LCD_SIM
   _delay_ms(100);
#endif
 }

static void lcd_strobe_e(const unsigned char ncontr)
 { lcd_strobe_delay();

   if ( ncontr & 0x01 ) 
      LCD_ENABLE_E1();

   if ( ncontr & 0x02 ) 
      LCD_ENABLE_E2();

   lcd_strobe_delay();

   LCD_DISABLE_E1();
   LCD_DISABLE_E2();
 }


/* 
**
** low level routine to send a byte value 
** to the LCD controller control register. 
** entry argument is the data to output 
** and the controller to use
** 1: IC 1, 2: IC 2, 3: both ICs
**
*/
void lcd_out_ctl(const unsigned char cmd, const unsigned char ncontr)
 { LCD_CMD_MODE();
   LCDDATAPORT = cmd;
   lcd_strobe_e(ncontr);
 }

/* 
**
** low level routine to send a byte value 
** to the LCD controller data register. entry argument
** is the data to output and the controller-number
**
*/
void lcd_out_dat(const unsigned char dat, const unsigned char ncontr)
 { LCD_DATA_MODE();
   LCDDATAPORT = dat;
   lcd_strobe_e(ncontr);
 }


/*
** 
** routine to initialize the operation of the LCD display subsystem
**
*/
void lcd_init(void)
 { LCDDATADDR = 0xff; /* all output */
   LCDCTRLDDR |= ( (1<<LCDCMDPIN) | (1<<LCDE1PIN) | (1<<LCDE2PIN) );

   lcd_out_ctl(0,3);
   lcd_out_ctl(LCD_RESET,3);
   lcd_long_delay();
   
   lcd_out_ctl(LCD_DISP_ON,3);
   lcd_out_ctl(LCD_SET_ADC_REV,3); // !
   lcd_out_ctl(LCD_SET_LINE+0,3);
   lcd_out_ctl(LCD_SET_PAGE+0,3);
   lcd_out_ctl(LCD_SET_COL+LCD_STARTCOL_REVERSE,3);
 } 


#ifdef LCD_DEBUG

/* fills complete area with pattern - direct to LCD-RAM */
void lcd_test(const unsigned char pattern)
 { unsigned char page, col;

	for (page=0; page<LCD_Y_BYTES; page++) 
    { lcd_out_ctl(LCD_SET_PAGE+page,3);
      lcd_out_ctl(LCD_SET_COL+LCD_STARTCOL_REVERSE,3); // !
      for (col=0; col<LCD_X_BYTES/2; col++) 
         lcd_out_dat(pattern,3);
		 
    }
 }

/* raw write to LCD-RAM - used for debugging */
void lcd_raw(const unsigned char page, const unsigned char col, const unsigned char nctrl, const unsigned char pattern)
 { lcd_out_ctl(LCD_SET_PAGE+page,nctrl);
   lcd_out_ctl(LCD_SET_COL+col,nctrl);	
   lcd_out_dat(pattern,nctrl);
 }

#endif /* LCD_DEBUG */


/* fill buffer and LCD with pattern */
void lcd_fill(const 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(const unsigned char top, const 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(*colptr++,1);
         else 
            lcd_out_dat(*colptr++,2);
       }
    }
 }



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



/* sets/clears/switchs(XOR) dot at (x,y) */
void lcd_dot(const unsigned char x, const unsigned char y, const 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, const 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

⌨️ 快捷键说明

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