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

📄 lcd128x64.c

📁 embedded graphics library for avr
💻 C
📖 第 1 页 / 共 2 页
字号:
#pragma CODE

#include <c8051f020.h>                 // SFR declarations
#include "lcd128x64.h"
#include "fonts.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 code l_mask_array[8] =
         {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

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

/* 
**
** Low level LCD Controller Interface Support Routines
** The LCD Controller interfaces to the microcontroller
** using the connections as shown below. 
**
**		P3^0  LCD Controller Reset (RST/) signal
**		P3^1  LCD Controller Chip Select (CS/) signal
**		P3^2  LCD Controller Ctl/Data Select (C/D) signal
**		P3^2  LCD Controller Serial Clcok (SCLK) signal
**		P3^3  LCD Controller Serial Data (SDAT) signal
**
**
*/

void lcd_init(void)
{
	int i;

	/* initialize the port control lines to the LCD module */
	LCD_RST = 1;					/* set RST signal high off output */

	LCD_CS = 1;						/* set chip select high off output */
	
	LCD_CD = 0;						/* set the CD line low as output */
	
	LCD_SCLK = 1;					/* set SCLK line high */

	LCD_SDAT = 0;		   			/* set SDAT line low */

	/* reset the LCD controller chip */
	LCD_RST = 0;					/* set the reset line low */
	for(i=0; i<1000; i++)			/* delay for the reset time */
	{
	}
	LCD_RST = 1;					/* release reset to back high */

	/* program the controller operational state */
	lcd_out_ctl(LCD_SET_ADC_REV);	/* set ADC reverse */
	lcd_out_ctl(LCD_SET_SHL_NOR);	/* set SHL normal */
	lcd_out_ctl(LCD_SET_BIAS_0);	/* set for the low bias mode */
	lcd_out_ctl(LCD_PWR_CTL+5);		/* turn on the VC bit */
	for(i=0; i<1000; i++)			/* delay for the converter on */
	{
	}
	lcd_out_ctl(LCD_PWR_CTL+6);		/* now turn on VC+VR bits */
	for(i=0; i<1000; i++)			/* delay for the regulator on */
	{
	}
	lcd_out_ctl(LCD_PWR_CTL+7);		/* now turn on the VC+VR+VF */
	lcd_out_ctl(LCD_REG_RESISTOR+4); /* set default resistor ratio */
	lcd_out_ctl(LCD_REF_VOLT_MODE);	 /* prime for the reference voltage */
	lcd_out_ctl(LCD_REF_VOLT_REG+42);	 /* set default reference voltage select */
	for(i=0; i<1000; i++)			 /* delay for power stabilize */
	{
	}
	lcd_out_ctl(LCD_DISP_ON);		/* put the display on */

	lcd_out_ctl(LCD_SET_LINE+0);	/* set line for row 0 of display */
	lcd_out_ctl(LCD_SET_PAGE+0);	/* set page 0 */
	lcd_out_ctl(LCD_SET_COL_HI+0);	/* set column 0 */
	lcd_out_ctl(LCD_SET_COL_LO+0);
/*
** 
** program test loop to find right resistor ratio 0-8
** (use by break pointing at each loop step)
**
*/

#if 0
	for(p=0; p<7; p++)
	{
		lcd_out_ctl(LCD_REG_RESISTOR+p); /* set resistor ratio */
	}
#endif

/*
** 
** program test loop to find reference voltage setting 0-63
** (use by break pointing at each loop step)
**
*/

#if 0
	for(p=0; p<63; p++)
	{
		lcd_out_ctl(LCD_REF_VOLT_MODE);	 	 /* prime for the reference voltage */
		lcd_out_ctl(LCD_REF_VOLT_REG+p);	 /* set reference voltage select */
	}
#endif
} 

/* 
**
** low level routine to send a byte value out the serial bus
** to the LCD controller data register. entry argument
** is the data to output.
**
*/

void lcd_out_dat(char dat)
{
	unsigned char i=8;				/* serial bit counter */

	EA = 0;							/* disable interrupts */
	
	LCD_CD = 1;						/* select register for data port */
	LCD_CS = 0;						/* enable interface via chip select */

	while(i--)
	{
		LCD_SDAT = (dat & 0x80 ? 1 : 0);  /* transmit data from MSB */
		LCD_SCLK = 0;				/* turn the clock on */
		dat <<= 1;					/* shift data left 1 place */
		LCD_SCLK = 1;				/* clock back off */	
	}

	LCD_CD = 1;						/* force chip select back off */

	/* re-establish the exit interrupt state */
	EA = 1;
} 

/* 
**
** low level routine to send a byte value out the serial bus
** to the LCD controller control register. entry argument is
** the data to output.
**
*/

void lcd_out_ctl(char dat)
{
	unsigned char i=8;				/* serial bit counter */

	EA = 0;							/* disable interrupts */
	
	LCD_CD = 0;						/* select register for command port */
	LCD_CS = 0;						/* enable interface via chip select */

	while(i--)
	{
		LCD_SDAT = (dat & 0x80 ? 1 : 0);  /* transmit data from MSB */
		LCD_SCLK = 0;				/* turn the clock on */
		dat <<= 1;					/* shift data left 1 place */
		LCD_SCLK = 1;				/* clock back off */	
	}

	LCD_CD = 1;						/* force chip select back off */

	/* re-establish the exit interrupt state */
	EA = 1;
} 
 
/* 
**
** routine to erase the LCD screen, This erases whole
** display memory of the S6B0724 LCD controller.
**
*/

void lcd_erase(void)
{
	unsigned char p;
	unsigned char i;

	for(p=0; p<9; p++)
	{
		lcd_out_ctl(LCD_SET_PAGE+p);	/* set page */
		lcd_out_ctl(LCD_SET_COL_HI+0);	/* set column 0 */
		lcd_out_ctl(LCD_SET_COL_LO+0);
		for(i=0; i<132; i++)
		{
			lcd_out_dat(0);				/* clear the data */
		}
	}
}

/* 
**
** routine to display a test pattern on the LCD screen,
**
*/

unsigned char code testpat[4][8]={
				   {0x0F,0x0F,0x0F,0x0F,0xF0,0xF0,0xF0,0xF0},
				   {0xF0,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x0F},
	               {0xFF,0x81,0xBD,0xBD,0xBD,0xBD,0x81,0xFF},
				   {0x00,0x7E,0x42,0x42,0x42,0x42,0x7E,0x00}
				  };

void lcd_test(unsigned char pattern)
{
	unsigned char p;
	unsigned char i;

	for(p=0; p<7; p++)
	{
		lcd_out_ctl(LCD_SET_PAGE+p);	/* set page */
		lcd_out_ctl(LCD_SET_COL_HI+26/16);	/* set column 0 */
		lcd_out_ctl(LCD_SET_COL_LO+26%16);
		for(i=0; i<106; i++)
		{
			lcd_out_dat(testpat[pattern][i%8]);
		}
	}
}

/*
**
** 	Clears the display memory starting at the left/top  and going to
**  the right/bottom . No runtime error checking is performed. It is 
**  assumed that left is less than right and that top is less than 
**  bottom
**
*/

void lcd_clear_area(unsigned char left,  unsigned char top,    
			        unsigned char right, unsigned char bottom)
{
	unsigned char bit_pos;
	unsigned char x;
	unsigned char byte_offset;
	unsigned char y_bits;
	unsigned char remaining_bits;
	unsigned char mask;

	bit_pos = top & 0x07;					/* get starting bit offset into byte */

	for(x = left; x <= right; x++)
	{
		byte_offset = top >> 3;				/* get byte offset into y direction */
		y_bits = (bottom - top) + 1;		/* get length in the y direction to write */
		remaining_bits = 8 - bit_pos;		/* number of bits left in byte */
		mask = l_mask_array[bit_pos];		/* get mask for this bit */

		while(y_bits)						/* while there are still bits to write */
		{
			if((remaining_bits == 8) && (y_bits > 7))
			{
				/* here if we are byte aligned and have at least 1 byte to write */
				/* do the entire byte at once instead of bit by bit */
				while(y_bits > 7)			/* while there are at least 8 more bits to do */
				{
					l_display_array[byte_offset][x] = 0x00;
					byte_offset++;
					y_bits -= 8;
				}
			}
			else
			{
				/* here if not byte aligned or an entire byte does not need written */
				/* thus do bit by bit */
				l_display_array[byte_offset][x] &= ~mask;
				if(l_mask_array[0] & 0x80)
				{
					mask >>= 1;
				}
				else
				{
					mask <<= 1;
				}
				y_bits--;
				remaining_bits--;
				if(remaining_bits == 0)
				{
					/* might have bust gotton byte aligned */
					/* so reset for beginning of a byte */
					remaining_bits = 8;
					byte_offset++;
					mask = l_mask_array[0];
				}
			}
		}
	}
}

/*
**
** Inverts the display memory starting at the left/top and going to
** the right/bottom. No runtime error checking is performed. It is 
** assumed that left is less than right and that top is less than 
** bottom 
** 
*/

void lcd_invert_area(unsigned char left,  unsigned char top,    
			         unsigned char right, unsigned char bottom)
{
	unsigned char bit_pos;
	unsigned char x;
	unsigned char byte_offset;
	unsigned char y_bits;
	unsigned char remaining_bits;
	unsigned char mask;

	bit_pos = top & 0x07;					/* get starting bit offset into byte */

	for(x = left; x <= right; x++)
  	{
		byte_offset = top >> 3;				/* get byte offset into y direction */
		y_bits = (bottom - top) + 1;		/* get length in the x direction to write */
		remaining_bits = 8 - bit_pos;		/* number of bits left in byte */
		mask = l_mask_array[bit_pos];		/* get mask for this bit */

		while(y_bits)						/* while there are still bits to write */
    	{
			if((remaining_bits == 8) && (y_bits > 7))
			{
				/* here if we are byte aligned and have at least 1 byte to write */
				/* do the entire byte at once instead of bit by bit */
				while(y_bits > 7)			/* while there are at least 8 more bits to do */
				{
					l_display_array[byte_offset][x] ^= 0xFF;
					byte_offset++;
					y_bits -= 8;
				}
      		}
      		else
      		{
				/* here if not byte aligned or an entire byte does not need written */
				/* thus do bit by bit */
				l_display_array[byte_offset][x] ^= mask;
				if(l_mask_array[0] & 0x80)
				{
					mask >>= 1;
				}
				else
				{
					mask <<= 1;
				}
				y_bits--;
				remaining_bits--;
				if(remaining_bits == 0)
				{
					/* might have bust gotton byte aligned */
					/* so reset for beginning of a byte */
					remaining_bits = 8;
					byte_offset++;
					mask = l_mask_array[0];
				}
			}
		}
	}
}

/*
**
** Draws a line into the display memory starting at left going to
** right, on the given row. No runtime error checking is performed.  
** It is assumed that left is less than right.
**
*/

void lcd_horz_line(unsigned char left, unsigned char right,
		           unsigned char row)
{
	unsigned char bit_pos;
	unsigned char byte_offset;
	unsigned char mask;
	unsigned char col;

  	bit_pos = row & 0x07;			/* get the bit offset into a byte */
  	byte_offset = row >> 3;		    /* get the byte offset into x array */
  	mask = l_mask_array[bit_pos]; 	/* get the mask for this bit */

  	for(col = left; col <= right; col++)
  	{
    	l_display_array[byte_offset][col] |= mask;
  	}
}

/*
**
** Draws a vertical line into display memory starting at the top
** going to the bottom in the given column. No runtime error checking 
** is performed. It is assumed that top is less than bottom and that 

⌨️ 快捷键说明

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