LCD 160x80 (LC7981)

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
MagnusE
Posts: 3
Joined: 03 Jul 2009 13:36

LCD 160x80 (LC7981)

#1 Post by MagnusE » 01 Oct 2010 09:23

I´m trying to get this code to work!!!! Code from frozeneskimo.com it´s for atmel but i use pic18f452. I changed the ports but there are many errors i cant work out.

Code: Select all

//lc7981.h file

/* AVR clock speed */
//#define F_CPU	8000000

//#include <avr/io.h>
//#include <util/delay.h>

/* Hardware setup */
//#define LCD_DATA_DDR	DDRA
#define LCD_DATA_PORT	PORTD
//#define LCD_DATA_PIN	PINA

//#define LCD_CTRL_DDR	DDRB
//#define LCD_CTRL_PORT	PORTB

#define LCD_CTRL_RS	PORTB.F0
#define LCD_CTRL_RW	PORTB.F1
#define LCD_CTRL_E	PORTB.F2

#define LCD_WIDTH	160
#define LCD_HEIGHT	80

/* Convenient macros to toggle RS, RW, and E control pins */
#define lcd_rs_high() (PORTB.F0 = 1)         // wonder if this work
#define lcd_rs_low() (PORTB.F0 = 0)         // wonder if this work

#define lcd_rw_high() (PORTB.F1 = 1)         // wonder if this work
#define lcd_rw_low() (PORTB.F1 = 0)          // wonder if this work

#define lcd_enable_high() (PORTB.F2 = 1)     // wonder if this work
#define lcd_enable_low() (PORTB.F2 = 0)     // wonder if this work

/* All possible instructions for the LCD Instruction Register */
#define	LCD_CMD_MODE			0x00
#define LCD_CMD_CHAR_PITCH		0x01
#define LCD_CMD_NUM_CHARS		0x02
#define LCD_CMD_TIME_DIVISION		0x03
#define LCD_CMD_CURSOR_POS		0x04

#define LCD_CMD_DISPLAY_START_LA	0x08
#define LCD_CMD_DISPLAY_START_HA	0x09
#define LCD_CMD_CURSOR_LA		0x0A
#define LCD_CMD_CURSOR_HA		0x0B

#define LCD_CMD_WRITE_DATA		0x0C
#define LCD_CMD_READ_DATA		0x0D

#define LCD_CMD_CLEAR_BIT		0x0E
#define LCD_CMD_SET_BIT			0x0F

/* Bits of the LCD Mode Control Register (DB5-DB0) */
#define LCD_MODE_ON_OFF		32
#define LCD_MODE_MASTER_SLAVE	16
#define LCD_MODE_BLINK		8
#define LCD_MODE_CURSOR		4
#define LCD_MODE_MODE		2
#define LCD_MODE_EXTERNAL	1

/* Possible settings of the character pitch register */
/* Horizontal character pitches of 6, 7, and 8 */
#define LCD_CHAR_PITCH_HP_6	0x05
#define LCD_CHAR_PITCH_HP_7	0x06
#define LCD_CHAR_PITCH_HP_8	0x07

/* To indicate the state of a pixel */
#define PIXEL_ON	0xFF
#define PIXEL_OFF	0x00

/* Low-level LCD interface functions */
void lcd_strobe_enable(void);
void lcd_write_command(unsigned char command, unsigned char data);
void lcd_wait_busy(void);

/* LCD Graphics interface */
void lcd_graphics_init(void);
void lcd_graphics_clear(void);
void lcd_graphics_move(unsigned short x, unsigned short y);
void lcd_graphics_draw_byte(unsigned char data);
void lcd_graphics_plot_byte(unsigned short x, unsigned short y, unsigned char data);
void lcd_graphics_plot_pixel(unsigned short x, unsigned short y, unsigned char state);

Code: Select all

// lc7981.c file
 
#include "lc7981.h"
#include "graphics.c"
//#include "draw_penguin.c"

/** 
 * Strobes the Enable control line to trigger the lcd to process the
 * transmitted instruction.
 */
void lcd_strobe_enable(void) {
	lcd_enable_high();
	__asm("nop;"); __asm("nop;"); __asm("nop;");
	lcd_enable_low();
	__asm("nop;"); __asm("nop;"); __asm("nop;");
}

/**
 * Waits for the busy flag to clear, which should take
 * around the maximum time for an instruction to complete.
 * Note, LCD operation is kind of sensitive to this configuration. If the delay
 * is too fast, the LCD will miss some pixels when it is really put through
 * a stress test. This dela time seems to work great.
 */
void lcd_wait_busy(void) {
	Delay_us(3);
}
/**
 * Writes a raw instruction to the LCD. 
 * @param command The 4-bit instruction code.
 * @param data The 8-bit paramater/data to the specified instruction.
 */
void lcd_write_command(unsigned char command, unsigned char data) {
	/* Wait for the busy flag to clear */
	lcd_wait_busy();
	
	/* Set RW low, RS high to write the instruction command */
	lcd_rw_low();
	lcd_rs_high();
	/* Instruction commands are a maximum of 4 bits long, so 
	 * just mask off the rest. */
	LCD_DATA_PORT = (command&0x0F);
	__asm("nop;"); __asm("nop;"); __asm("nop;");
	__asm("nop;"); __asm("nop;"); __asm("nop;");
	lcd_strobe_enable();
	__asm("nop;"); __asm("nop;"); __asm("nop;");
	__asm("nop;"); __asm("nop;"); __asm("nop;");

	/* Set RW low, RW low to write the instruction data */
	lcd_rw_low();
	lcd_rs_low();
	LCD_DATA_PORT = data;
	__asm("nop;"); __asm("nop;"); __asm("nop;");
	__asm("nop;"); __asm("nop;"); __asm("nop;");
	lcd_strobe_enable();
	__asm("nop;"); __asm("nop;"); __asm("nop;");
	__asm("nop;"); __asm("nop;"); __asm("nop;");
}

/**
 * Initializes the LCD in graphics mode.
 * Uses a character pitch of 8 (8 bits are plotted whenever a byte is drawn)
 */ 
void lcd_graphics_init(void) {
	unsigned char commandData;
             /* Set the data direction registers apprioriately */
             TRISD = 0;
             TRISB = 0;

	/* Assert all control lines to low */
	lcd_rw_low();
	lcd_rs_low();
	lcd_enable_low();

	/* Send mode configuration command with
	 * Toggle Display On, Master, Mode Graphics bits set */
	commandData = LCD_MODE_ON_OFF | LCD_MODE_MASTER_SLAVE | LCD_MODE_MODE;
	lcd_write_command(LCD_CMD_MODE, commandData);

	/* Send the set character pitch command with horizontal
 	 * character pitch of 8 (so 8 pixels are painted when we draw) */	
	commandData = LCD_CHAR_PITCH_HP_8;
	lcd_write_command(LCD_CMD_CHAR_PITCH, commandData);
	
	/* Send the number of characters command with the total
	 * number of graphics bytes that can be painted horizontally 
	 * (width/8) */
	commandData = (LCD_WIDTH/8)-1;
	lcd_write_command(LCD_CMD_NUM_CHARS, commandData);

	/* Set the time division */
	commandData = 128-1;
	lcd_write_command(LCD_CMD_TIME_DIVISION, commandData);
	
	/* Set the display low/high start address to 0x00 (left corner) */
	commandData = 0x00;
	lcd_write_command(LCD_CMD_DISPLAY_START_LA, commandData);
	lcd_write_command(LCD_CMD_DISPLAY_START_HA, commandData);

	/* Reset the cursor to home 0x00 (left corner) */
	commandData = 0x00;
	lcd_write_command(LCD_CMD_CURSOR_LA, commandData);
	lcd_write_command(LCD_CMD_CURSOR_HA, commandData);
}

/**
 * Moves the LCD cursor to the specified coordinates. 
 * @param x The new x coordinante of the cursor.
 * @param y The new y coordinante of the cursor.
 */
void lcd_graphics_move(unsigned short x, unsigned short y) {
	unsigned short pos;

	/* Calculate the raw address in terms of bytes on the screen */
	pos = ((y*LCD_WIDTH)+x)/8;

	/* Move the cursor to the new address */
	lcd_write_command(LCD_CMD_CURSOR_LA, pos&0xFF);
	lcd_write_command(LCD_CMD_CURSOR_HA, pos>>8);
}

/**
 * Draws a byte to the LCD at the current LCD's cursor location.
 * @param data The byte to draw. The pixels are drawn MSB to LSB.
 */
void lcd_graphics_draw_byte(unsigned char data) {
	lcd_write_command(LCD_CMD_WRITE_DATA, data);
}

/**
 * Plots a byte at the specified coordinates. 
 * @param x The x coordinante of the byte to be drawn.
 * @param y The y coordinante of the byte to be drawn.
 * @param data The byte to draw. The pixels are drawn MSB to LSB.
 */
void lcd_graphics_plot_byte(unsigned short x, unsigned short y, unsigned char data) {
	lcd_graphics_move(x, y);
	lcd_graphics_draw_byte(data);
}

/**
 * Plots a pixel at the specified coordinates.
 * @param x The x coordinante of the pixel.
 * @param y The y coordinante of the pixel.
 * @param state PIXEL_ON to set the pixel, otherwise pixel will be cleared.
 */
void lcd_graphics_plot_pixel(unsigned short x, unsigned short y, unsigned char state) {
	unsigned char pos;
	
	lcd_graphics_move(x, y);
	/* Since lcd_graphics_move() moves the cursor to a particular
	 * byte, not bit, we need the relative distance to the specified 
	 * bit we are going to set/clear. */
	pos = x%8;

	if (state == PIXEL_ON) 
		lcd_write_command(LCD_CMD_SET_BIT, pos);
	else 
		lcd_write_command(LCD_CMD_CLEAR_BIT, pos);
}

/**
 * Clears the LCD screen 
 */
void lcd_graphics_clear(void) {
	unsigned short i;
	/* Move cursor to home (top left corner) */
	lcd_graphics_move(0, 0);
	/* Draw empty bytes to ocucpy the entire screen */
	for (i = 0; i < ((LCD_WIDTH*LCD_HEIGHT)/8); i++) 
		lcd_graphics_draw_byte(0x00);
}

/**
 * Delay in milliseconds.
 * An extension of _delay_ms() so we can delay for longer periods of time.
 * @param ms Milliseconds to delay.
 */
void delay_ms_long(unsigned short ms) {
	for (; ms > 0; ms--)
		Delay_ms(1);
}

int main(void) {
	lcd_graphics_init();
	lcd_graphics_clear();
	g_draw_rectangle(6, 5, 100, 30);
	g_draw_rectangle(8, 7, 100, 30);
	g_draw_rectangle(10, 9, 100, 30);
	g_draw_rectangle(12, 11, 100, 30);
	g_draw_string(17, 15, "Graphics Demo!\nHello World!"); 
	//draw_penguin(); // this i removed it´s not in the project
	g_draw_string(22, 44, "!\"#$%&'=\n()*+,-./\n:;<>?@\[\n]^_`|{}");
	while (1) ;
	return 0;
}

Code: Select all

// graphics.h 
 
#include "font5x7.h"

#define FONT_WIDTH	5
#define FONT_HEIGHT	7

void g_draw_horizontal_line(unsigned short x, unsigned short y, unsigned short length);
void g_draw_vertical_line(unsigned short x, unsigned short y, unsigned short length);
void g_draw_rectangle(unsigned short x, unsigned short y, unsigned short width, unsigned short height);
void g_draw_char(unsigned short x, unsigned short y, char character);
void g_draw_string(unsigned short x, unsigned short y, const char *str);


Code: Select all

//graphics.c 
 
#include "graphics.h"

/**
 * Draws a horizontal line, left to right, at the specified coordinates and of
 * the specified length.
 * @param x The x coordinante of the line's origin.
 * @param y The y coordinante of the line's origin.
 * @param length The length of the line, in pixels.
 */
void g_draw_horizontal_line(unsigned short x, unsigned short y, unsigned short length) {
	unsigned short i;
	for (i = x; i <= x+length; i++)
		lcd_graphics_plot_pixel(i, y, PIXEL_ON);
}

/**
 * Draws a vertical line, top to bottom, at the specified coordinates and of 
 * the specified length.
 * @param x The x coordinante of the line's origin.
 * @param y The y coordinante of the line's origin.
 * @param length The length of the line, in pixels.
 */
void g_draw_vertical_line(unsigned short x, unsigned short y, unsigned short length) {
	unsigned short i;
	for (i = y; i < y+length; i++)
		lcd_graphics_plot_pixel(x, i, PIXEL_ON);
}

/**
 * Draws a rectangle. The coordinantes specify the top left corner of the 
 * rectangle.
 * @param x The x coordinante of the rectangle's origin.
 * @param y The y coordinante of the rectangle's origin.
 * @param width The width of the rectangle, in pixels.
 * @param height The height of the rectangle, in pixels.
 */ 
void g_draw_rectangle(unsigned short x, unsigned short y, unsigned short width, unsigned short height) {
	/* Adjust width and height because x and y coordinates start on 0,0 */
	width--;
	height--;
	g_draw_horizontal_line(x, y, width);
	g_draw_vertical_line(x, y, height);
	g_draw_vertical_line(x+width, y, height);
	g_draw_horizontal_line(x, y+height, width);
}

/**
 * Draws a 5x7 character to the screen. The coordinantes specify the top left 
 * corner of the character.
 * Characters outside the character set will not be drawn (function will return
 * immediately).
 * @param x The x coordinate of the character's origin.
 * @param y The y coordinate of the character's origin.
 * @param character The ASCII character to draw.
 */
void g_draw_char(unsigned short x, unsigned short y, char character) {
	unsigned char fontIndex, i, j;

	/* The 5x7 character set starts at the '!' character (ASCII index 
 	 * number 33) so we subtract 32 from the ASCII character to find the 
 	 * index in the 5x7 font table. */	
	fontIndex = character-32;
	/* If the index is out of bounds, bail out */
	if (fontIndex > 94)
		return;
	
	for (i = 0; i < FONT_WIDTH; i++) {
		for (j = 0; j < FONT_HEIGHT; j++) {
			/* Check if the bit/pixel is set, paint accoringly to 
 			 * the screen */
			if (Font5x7[FONT_WIDTH*fontIndex+i] & (1<<j))
				lcd_graphics_plot_pixel(x, y+j, PIXEL_ON);
			else	
				lcd_graphics_plot_pixel(x, y+j, PIXEL_OFF);
		}
		/* Move the LCD cursor through the font width as well */
		x++;
	}
}

/**
 * Draws a string of characters to the screen. The characters will be drawn in i
 * 5x7 font.
 * The coordinantes specify the top left corner of the first character in the 
 * string.
 * Characters will be wrapped. The newline character is supported.
 * Characters outside the 5x7 character set will not be drawn.
 * @param x The x coordinate of the string's first character's origin.
 * @param y The y coordinate of the string's first character's origin.
 * @param str The null-terminated ASCII string of characters.
 */
void g_draw_string(unsigned short x, unsigned short y, const char *str) {
	unsigned short origin_X;

	/* Preserve the origin X, in case of a new line */
	origin_X = x;

	/* Continue through the string until we encounter a null character */
	while (*str != '\0') {
		/* If the character is a newline, then prepare our x and y
		 * coordinates for the next character on the new line. */
		if (*str == '\n') {
			/* Reset x to its origin */
			x = origin_X;
			/* Move y one character down */
			y += FONT_HEIGHT+1;
		
			str++;
			continue;
		}
		g_draw_char(x, y, *str++);
		
		/* Add a 1-pixel spacing between the characters */
		x += FONT_WIDTH+1;

		/* In case we are putting this character out of bounds,
		 * move the character to the next line on the display */
		if ((x+FONT_WIDTH) > LCD_WIDTH) {
			/* Reset x to its origin */
			x = origin_X;
			/* Move y one character down */
			y += FONT_HEIGHT+1;
		}
	}
}

Code: Select all

//font5x7.h files

#ifndef FONT5X7_H
#define FONT5X7_H

// standard ascii 5x7 font
// defines ascii characters 0x20-0x7F (32-127)
//static unsigned char __attribute__ ((progmem)) Font5x7[] = {
static unsigned char  Font5x7[] = {
	0x00, 0x00, 0x00, 0x00, 0x00,// (space)
	0x00, 0x00, 0x5F, 0x00, 0x00,// !
	0x00, 0x07, 0x00, 0x07, 0x00,// "
	0x14, 0x7F, 0x14, 0x7F, 0x14,// #
	0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
	0x23, 0x13, 0x08, 0x64, 0x62,// %
	0x36, 0x49, 0x55, 0x22, 0x50,// &
	0x00, 0x05, 0x03, 0x00, 0x00,// '
	0x00, 0x1C, 0x22, 0x41, 0x00,// (
	0x00, 0x41, 0x22, 0x1C, 0x00,// )
	0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
	0x08, 0x08, 0x3E, 0x08, 0x08,// +
	0x00, 0x50, 0x30, 0x00, 0x00,// ,
	0x08, 0x08, 0x08, 0x08, 0x08,// -
	0x00, 0x60, 0x60, 0x00, 0x00,// .
	0x20, 0x10, 0x08, 0x04, 0x02,// /
	0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
	0x00, 0x42, 0x7F, 0x40, 0x00,// 1
	0x42, 0x61, 0x51, 0x49, 0x46,// 2
	0x21, 0x41, 0x45, 0x4B, 0x31,// 3
	0x18, 0x14, 0x12, 0x7F, 0x10,// 4
	0x27, 0x45, 0x45, 0x45, 0x39,// 5
	0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
	0x01, 0x71, 0x09, 0x05, 0x03,// 7
	0x36, 0x49, 0x49, 0x49, 0x36,// 8
	0x06, 0x49, 0x49, 0x29, 0x1E,// 9
	0x00, 0x36, 0x36, 0x00, 0x00,// :
	0x00, 0x56, 0x36, 0x00, 0x00,// ;
	0x00, 0x08, 0x14, 0x22, 0x41,// <
	0x14, 0x14, 0x14, 0x14, 0x14,// =
	0x41, 0x22, 0x14, 0x08, 0x00,// >
	0x02, 0x01, 0x51, 0x09, 0x06,// ?
	0x32, 0x49, 0x79, 0x41, 0x3E,// @
	0x7E, 0x11, 0x11, 0x11, 0x7E,// A
	0x7F, 0x49, 0x49, 0x49, 0x36,// B
	0x3E, 0x41, 0x41, 0x41, 0x22,// C
	0x7F, 0x41, 0x41, 0x22, 0x1C,// D
	0x7F, 0x49, 0x49, 0x49, 0x41,// E
	0x7F, 0x09, 0x09, 0x01, 0x01,// F
	0x3E, 0x41, 0x41, 0x51, 0x32,// G
	0x7F, 0x08, 0x08, 0x08, 0x7F,// H
	0x00, 0x41, 0x7F, 0x41, 0x00,// I
	0x20, 0x40, 0x41, 0x3F, 0x01,// J
	0x7F, 0x08, 0x14, 0x22, 0x41,// K
	0x7F, 0x40, 0x40, 0x40, 0x40,// L
	0x7F, 0x02, 0x04, 0x02, 0x7F,// M
	0x7F, 0x04, 0x08, 0x10, 0x7F,// N
	0x3E, 0x41, 0x41, 0x41, 0x3E,// O
	0x7F, 0x09, 0x09, 0x09, 0x06,// P
	0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
	0x7F, 0x09, 0x19, 0x29, 0x46,// R
	0x46, 0x49, 0x49, 0x49, 0x31,// S
	0x01, 0x01, 0x7F, 0x01, 0x01,// T
	0x3F, 0x40, 0x40, 0x40, 0x3F,// U
	0x1F, 0x20, 0x40, 0x20, 0x1F,// V
	0x7F, 0x20, 0x18, 0x20, 0x7F,// W
	0x63, 0x14, 0x08, 0x14, 0x63,// X
	0x03, 0x04, 0x78, 0x04, 0x03,// Y
	0x61, 0x51, 0x49, 0x45, 0x43,// Z
	0x00, 0x00, 0x7F, 0x41, 0x41,// [
	0x02, 0x04, 0x08, 0x10, 0x20,// "\"
	0x41, 0x41, 0x7F, 0x00, 0x00,// ]
	0x04, 0x02, 0x01, 0x02, 0x04,// ^
	0x40, 0x40, 0x40, 0x40, 0x40,// _
	0x00, 0x01, 0x02, 0x04, 0x00,// `
	0x20, 0x54, 0x54, 0x54, 0x78,// a
	0x7F, 0x48, 0x44, 0x44, 0x38,// b
	0x38, 0x44, 0x44, 0x44, 0x20,// c
	0x38, 0x44, 0x44, 0x48, 0x7F,// d
	0x38, 0x54, 0x54, 0x54, 0x18,// e
	0x08, 0x7E, 0x09, 0x01, 0x02,// f
	0x08, 0x14, 0x54, 0x54, 0x3C,// g
	0x7F, 0x08, 0x04, 0x04, 0x78,// h
	0x00, 0x44, 0x7D, 0x40, 0x00,// i
	0x20, 0x40, 0x44, 0x3D, 0x00,// j
	0x00, 0x7F, 0x10, 0x28, 0x44,// k
	0x00, 0x41, 0x7F, 0x40, 0x00,// l
	0x7C, 0x04, 0x18, 0x04, 0x78,// m
	0x7C, 0x08, 0x04, 0x04, 0x78,// n
	0x38, 0x44, 0x44, 0x44, 0x38,// o
	0x7C, 0x14, 0x14, 0x14, 0x08,// p
	0x08, 0x14, 0x14, 0x18, 0x7C,// q
	0x7C, 0x08, 0x04, 0x04, 0x08,// r
	0x48, 0x54, 0x54, 0x54, 0x20,// s
	0x04, 0x3F, 0x44, 0x40, 0x20,// t
	0x3C, 0x40, 0x40, 0x20, 0x7C,// u
	0x1C, 0x20, 0x40, 0x20, 0x1C,// v
	0x3C, 0x40, 0x30, 0x40, 0x3C,// w
	0x44, 0x28, 0x10, 0x28, 0x44,// x
	0x0C, 0x50, 0x50, 0x50, 0x3C,// y
	0x44, 0x64, 0x54, 0x4C, 0x44,// z
	0x00, 0x08, 0x36, 0x41, 0x00,// {
	0x00, 0x00, 0x7F, 0x00, 0x00,// |
	0x00, 0x41, 0x36, 0x08, 0x00,// }
	0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
	0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
};

#endif
This is all files i have in my project but it dont work.
Please help!!!!

Thanks MagnusE

Post Reply

Return to “mikroC PRO for PIC General”