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

📄 lcd.c

📁 COP8 CPU的一个解释型BASIC源码
💻 C
字号:
////////////////////////////////////////////////////////////////
//
//                S C R I P T H E R M
//             A SCRIPTABLE THERMOMETER
// 
// entry of the National Semiconductor COP8FLASH Design Contest
//        submitted by Alberto Ricci Bitti (C) 2001
//              a.riccibitti@ra.nettuno.it
//
//--------------------------------------------------------------
//       FOR A BETTER VIEW SET TAB SIZE=4, INDENT SIZE=4
//--------------------------------------------------------------
// FILE   : lcd.c
// PURPOSE: very portable LCD display driver. Just change the 
//          #defines for pin assignment and display size 
//          and check the non-critical wait() delay.
//          Works with LCD modules based on the T6963 controller.
//
////////////////////////////////////////////////////////////////

#include <ioc8cdr.h>
#include "lcd.h"



/////////////////////////////////////////////////////////////////////
//vary these according to your display size
/////////////////////////////////////////////////////////////////////

#define PIXELS_X        128
#define PIXELS_Y        64
#define CHAR_WIDTH      6
#define DISPLAY_RAM     8192

/////////////////////////////////////////////////////////////////////
//vary these according to your display connection
/////////////////////////////////////////////////////////////////////

#define SET_LCD_RESET   (__PORTDD_bit.bit0 = 1)
#define CLEAR_LCD_RESET (__PORTDD_bit.bit0 = 0)

#define SET_LCD_CD      (__PORTDD_bit.bit1 = 1)
#define CLEAR_LCD_CD    (__PORTDD_bit.bit1 = 0)

#define SET_LCD_CE      (__PORTDD_bit.bit2 = 1)
#define CLEAR_LCD_CE    (__PORTDD_bit.bit2 = 0)

#define SET_LCD_RD      (__PORTDD_bit.bit3 = 1)
#define CLEAR_LCD_RD    (__PORTDD_bit.bit3 = 0)

#define SET_LCD_WR      (__PORTDD_bit.bit4 = 1)
#define CLEAR_LCD_WR    (__PORTDD_bit.bit4 = 0)

#define BUSDATI_OUT     (__PORTBD)
#define BUSDATI_IN      (__PORTBP)

#define BUSDATI_OUTPUT  (__PORTBC = 0xFF)
#define BUSDATI_INPUT   (__PORTBC = 0x00)

/////////////////////////////////////////////////////////////////////
//don't touch these!!!
/////////////////////////////////////////////////////////////////////
#define ROWS            (PIXELS_Y / 8)
#define COLUMNS         (PIXELS_X / CHAR_WIDTH)
#define CHARS_ROW       ((PIXELS_X + CHAR_WIDTH -1) / CHAR_WIDTH)

#define GRAPHICS_HOME   (DISPLAY_RAM   - CHARS_ROW * ROWS * 8)
#define TEXT_HOME       (GRAPHICS_HOME - CHARS_ROW * ROWS)
#define USER_RAM        (DISPLAY_RAM   - TEXT_HOME)


//current text cursor coordinates
unsigned char cursor_row = 0;
unsigned char cursor_col = 0;



//very quick & dirty wait routine
static void wait(unsigned int x)
{	unsigned int i;
	x = x*10;
	while (x > 0)
	{
		for (i=0; i<1000; i++)
		{
		};;
		x--;
	}
}



static void LCD_check_status(unsigned char mask)
{       
	BUSDATI_INPUT;
	SET_LCD_CD;
	CLEAR_LCD_RD;
	CLEAR_LCD_CE;
	/*wait 150 nS*/
	asm("NOP");
	
    while  ( (BUSDATI_IN & mask) != mask)
	{ 
       	SET_LCD_CE;
    	CLEAR_LCD_CE;
    	asm("NOP");
    };
   	SET_LCD_CE;
	SET_LCD_RD;
}



void LCD_data(unsigned char D1)
{       
	LCD_check_status(3);
	BUSDATI_OUTPUT;
	BUSDATI_OUT = D1;
	CLEAR_LCD_CD;
	CLEAR_LCD_WR;
	CLEAR_LCD_CE;
    /*implicit wait: 80nS*/
	SET_LCD_CE;
	SET_LCD_WR;
}



unsigned char LCD_read(void)
{   unsigned char retval;
	
	LCD_check_status(3);
	BUSDATI_INPUT;
	CLEAR_LCD_CD;
	CLEAR_LCD_RD;
	CLEAR_LCD_CE;
    /*implicit wait: 80nS*/
	asm("NOP");
    retval = BUSDATI_IN;
	SET_LCD_CE;
	SET_LCD_RD;
	return retval;
}


 
void LCD_command(unsigned char command, unsigned char D1, unsigned char D2)
{       
	LCD_data(D1);
	LCD_data(D2);
  	LCD_check_status(3);
    
	BUSDATI_OUTPUT;
	BUSDATI_OUT = command;
	SET_LCD_CD;
	CLEAR_LCD_WR;
	CLEAR_LCD_CE;
    /*implicit wait: 80nS*/
	SET_LCD_CE;
	SET_LCD_WR;
}
       

       
void LCD_initialize(void)
{        
   	BUSDATI_INPUT;
	SET_LCD_WR;
	SET_LCD_RD;
	SET_LCD_CD;
  	CLEAR_LCD_CE;
	CLEAR_LCD_RESET;
	// wait at least 10mS
	wait(1);
	SET_LCD_RESET;
  	SET_LCD_CE;
	// wait at least 1 uS
    wait(1);

	LCD_command( SET_GRAPHIC_HOME_ADDRESS,  GRAPHICS_HOME & 0xFF,   GRAPHICS_HOME >> 8);
	LCD_command( SET_GRAPHIC_COLUMNS,       CHARS_ROW,              0);
	LCD_command( SET_TEXT_HOME_ADDRESS,     TEXT_HOME & 0xFF,       TEXT_HOME >> 8);
	LCD_command( SET_TEXT_COLUMNS,          CHARS_ROW,              0);
	LCD_command( SET_XOR_TEXT_GRAPHICS,     0,                      0);
	LCD_command( DISPLAY_ALL_ON,            0,                      0);
    LCD_clear_text();
    LCD_clear_graphics();
}



void LCD_locate(unsigned char row, unsigned char col)
{   unsigned int address;
    if (row >= ROWS)      row = 0;
    if (col >= CHARS_ROW) col = 0;
    address = TEXT_HOME + row * CHARS_ROW + col;
	LCD_command(SET_ADDRESS_POINTER, address & 0xFF, address >> 8);
	cursor_row = row; cursor_col = col;
}



void LCD_putchar(unsigned char c)
{
	LCD_locate(cursor_row, cursor_col);
	switch(c)
	{
	case '\n':	//on newline, clear to end of row
	case '\r':
		do
		{
			LCD_putchar(' ');
		} while (cursor_col != 0);
		break;

	default:
        LCD_command( DATA_WRITE_INCREMENT, 0, c - ' ');
		if(++cursor_col == COLUMNS)
		{
			cursor_col = 0;
			if (++cursor_row == ROWS)
				cursor_row = 0;
			LCD_locate(cursor_row, cursor_col);
		};
		break;
	};
}



void LCD_puts(char * s)
{	
	while (*s)
		LCD_putchar(*s++);
}



void LCD_clear_text(void)
{ 	unsigned char i;      
	LCD_command( SET_ADDRESS_POINTER, TEXT_HOME & 0xFF, TEXT_HOME >> 8);
	for (i=0; i < ROWS * CHARS_ROW; i++)
	{
        LCD_command( DATA_WRITE_INCREMENT, 0, 0);
	};     
	LCD_locate(0,0);
}



void LCD_clear_graphics(void)
{
    unsigned int i;
	LCD_command( SET_ADDRESS_POINTER, GRAPHICS_HOME & 0xFF, GRAPHICS_HOME >> 8);
	for (i=0; i < ROWS * CHARS_ROW * 8; i++)
	{
        LCD_command( DATA_WRITE_INCREMENT, 0, 0);
	};     
}



// sets or clears the pixel at x,y according to 'command' (0=clear pixel) 
void LCD_pset(unsigned char x, unsigned char y, unsigned char command)
{
    unsigned int address = GRAPHICS_HOME +  (unsigned int)(PIXELS_Y - y) * CHARS_ROW + x / CHAR_WIDTH;
    command = ( command == 0 ? RESET_BIT : SET_BIT );
	LCD_command( SET_ADDRESS_POINTER, address& 0xFF, address >> 8);
	/*the bit position, left-to-right,  is x % CHAR_WIDTH; 
	  it is then subtracted from CHAR_WIDTH-1 to reverse direction to right-to-left*/
    LCD_command( command | (CHAR_WIDTH - 1 - (x % CHAR_WIDTH)), 0, 0 );
}



void LCD_move_cursor(unsigned char row, unsigned char col)
{
	LCD_command( SET_CURSOR_POSITION, col, row);
}

⌨️ 快捷键说明

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