422 lines
15 KiB
C
422 lines
15 KiB
C
/*--------------------------------------------------------------------------------------------------
|
|
|
|
Name : nokia_5110.c
|
|
|
|
Description : This is a driver for the Nokia 84x48 graphic LCD.
|
|
|
|
Author : 2014-01-08 - Paolo Iocco
|
|
|
|
History : 2014-01-08 - Date of creation
|
|
2014-02-03 - First release (non buffered)
|
|
|
|
Info : Max RAM - xx byte
|
|
: Max Stack - xx byte
|
|
|
|
--------------------------------------------------------------------------------------------------*/
|
|
#include "nokia_5110.h"
|
|
|
|
static const unsigned char font5x7 [][5] PROGMEM =
|
|
{
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp
|
|
{ 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !
|
|
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
|
|
{ 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
|
|
{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
|
|
{ 0xc4, 0xc8, 0x10, 0x26, 0x46 }, // %
|
|
{ 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
|
|
{ 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
|
|
{ 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
|
|
{ 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
|
|
{ 0x14, 0x08, 0x3E, 0x08, 0x14 }, // *
|
|
{ 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +
|
|
{ 0x00, 0x00, 0x50, 0x30, 0x00 }, // ,
|
|
{ 0x10, 0x10, 0x10, 0x10, 0x10 }, // -
|
|
{ 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 }, // ;
|
|
{ 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
|
|
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
|
|
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
|
|
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
|
|
{ 0x32, 0x49, 0x59, 0x51, 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, 0x09, 0x01 }, // F
|
|
{ 0x3E, 0x41, 0x49, 0x49, 0x7A }, // 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, 0x0C, 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
|
|
{ 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W
|
|
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
|
|
{ 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
|
|
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
|
|
{ 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [
|
|
{ 0x02, 0x04, 0x08, 0x10, 0x20 }, // back slash
|
|
{ 0x00, 0x41, 0x41, 0x7f, 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
|
|
{ 0x0C, 0x52, 0x52, 0x52, 0x3E }, // g
|
|
{ 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h
|
|
{ 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i
|
|
{ 0x20, 0x40, 0x44, 0x3D, 0x00 }, // j
|
|
{ 0x7F, 0x10, 0x28, 0x44, 0x00 }, // 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 }, // }
|
|
{ 0x04, 0x02, 0x04, 0x08, 0x04 }, // ~
|
|
{ 0x00, 0x00, 0x36, 0x00, 0x00 }, // free (chr 127)
|
|
{ 0x0e, 0x51, 0x31, 0x11, 0x08 }, // free (chr 128)
|
|
{ 0x3c, 0x41, 0x40, 0x21, 0x7c }, // free (chr 129)
|
|
{ 0x38, 0x54, 0x56, 0x55, 0x18 }, // free (chr 130)
|
|
{ 0x20, 0x56, 0x55, 0x56, 0x78 }, // free (chr 131)
|
|
{ 0x20, 0x55, 0x54, 0x55, 0x78 }, // free (chr 132)
|
|
{ 0x20, 0x55, 0x56, 0x54, 0x78 }, // free (chr 133)
|
|
{ 0x08, 0x08, 0x2a, 0x1c, 0x08 }, // Right Arrow (chr 134)
|
|
{ 0x0e, 0x51, 0x31, 0x11, 0x08 }, // free (chr 135)
|
|
{ 0x38, 0x56, 0x55, 0x56, 0x18 }, // free (chr 136)
|
|
};
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------
|
|
Function Definitions
|
|
--------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_write_byte: write data to LCD
|
|
argument(s): dat -> operand
|
|
command -> command (0) /data (1)
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_write_byte(unsigned char dat, unsigned char command) {
|
|
unsigned char i;
|
|
|
|
LCD_CE_clr;
|
|
if (command == CMD)
|
|
LCD_DC_clr;
|
|
else
|
|
LCD_DC_set;
|
|
for(i=0;i<8;i++) {
|
|
if(dat&0x80)
|
|
SDIN_set;
|
|
else
|
|
SDIN_clr;
|
|
SCLK_clr;
|
|
dat = dat << 1;
|
|
SCLK_set;
|
|
}
|
|
LCD_CE_set;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_Char: Displays a character
|
|
argument(s): c -> char to display
|
|
return: none
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_Char(unsigned char c) {
|
|
unsigned char line;
|
|
|
|
c -= 32;
|
|
LCD_write_byte(0x00,1);
|
|
for (line=0; line<5; line++)
|
|
LCD_write_byte(pgm_read_byte(&(font5x7[c][line])), DATA);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_clear: clears the LCD
|
|
argument(s): none.
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_Cls(void) {
|
|
unsigned int i;
|
|
|
|
LCD_write_byte(0x0c, 0);
|
|
LCD_write_byte(0x80, 0);
|
|
for (i=0; i<504; i++)
|
|
LCD_write_byte(0, DATA);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_DrawBmp: Bitmap drawing function
|
|
argument(s): X,Y -> starting point X (0..84),Y (0..5)
|
|
h -> height
|
|
w -> width
|
|
*map -> bitmap data
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_DrawBmp(unsigned char X,unsigned char Y, unsigned char w,unsigned char h, const unsigned char *map){
|
|
unsigned int i,n;
|
|
unsigned char row;
|
|
|
|
if (h%8==0)
|
|
row=h/8; //calculate how many lines are needed
|
|
else
|
|
row=h/8+1;
|
|
for (n=0;n<row;n++) {
|
|
LCD_GotoXY(X,Y);
|
|
for(i=0; i<w; i++)
|
|
LCD_write_byte(map[i+n*w], DATA);
|
|
Y++; // next line
|
|
}
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_DrawCircle: Draws a circle
|
|
argument(s): x,y -> center
|
|
radius -> radius
|
|
mode -> empty (0), full (1)
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_DrawCircle (unsigned char x1, unsigned char y1, unsigned char radius, unsigned char mode){
|
|
/*
|
|
* to be defined
|
|
* // only with Video-Ram support (504 bytes)
|
|
*/
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------
|
|
LCD_Drawline: Draws a line between two points on the display.
|
|
Argument(s): x1, y1 -> Absolute pixel coordinates for line origin.
|
|
x2, y2 -> Absolute pixel coordinates for line end.
|
|
mode -> Off, On or Xor. See enum.
|
|
return: none.
|
|
created date 2014-01-08
|
|
--------------------------------------------------------------------------------------------------*/
|
|
void LCD_DrawLine (unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) {
|
|
/*
|
|
// only with Video-Ram support (504 bytes)
|
|
int dx, dy, stepx, stepy, fraction;
|
|
|
|
dy = y2 - y1;
|
|
dx = x2 - x1;
|
|
if ( dy < 0 ) {
|
|
dy = -dy;
|
|
stepy = -1;
|
|
}
|
|
else
|
|
stepy = 1;
|
|
if ( dx < 0 ){
|
|
dx = -dx;
|
|
stepx = -1;
|
|
}
|
|
else
|
|
stepx = 1;
|
|
dx <<= 1;
|
|
dy <<= 1;
|
|
LcdPixel( x1, y1, mode );
|
|
if ( dx > dy ) {
|
|
fraction = dy - (dx >> 1);
|
|
while ( x1 != x2 ) {
|
|
if ( fraction >= 0 ) {
|
|
y1 += stepy;
|
|
fraction -= dx;
|
|
}
|
|
x1 += stepx;
|
|
fraction += dy;
|
|
LcdPixel( x1, y1, mode );
|
|
}
|
|
}
|
|
else {
|
|
fraction = dx - (dy >> 1);
|
|
while ( y1 != y2 ) {
|
|
if ( fraction >= 0 ) {
|
|
x1 += stepx;
|
|
fraction -= dy;
|
|
}
|
|
y1 += stepy;
|
|
fraction += dx;
|
|
LcdPixel( x1, y1, mode );
|
|
}
|
|
}
|
|
UpdateLcd = TRUE;
|
|
*/
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_DrawRect: Draws a rectangle
|
|
argument(s): x,y -> upper left corner
|
|
w -> width
|
|
h -> height
|
|
mode -> empty (0), full (1)
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_DrawRect (unsigned char x1, unsigned char y1, unsigned char w, unsigned char h, unsigned char mode) {
|
|
/*
|
|
* to be defined
|
|
* // only with Video-Ram support (504 bytes)
|
|
*/
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_GotoXY: Set the LCD coordinate functions
|
|
argument(s): X -> 0..83
|
|
Y -> 0..5
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_GotoXY(unsigned char X, unsigned char Y) {
|
|
LCD_write_byte(0x40 | Y, CMD); // column
|
|
LCD_write_byte(0x80 | X, CMD); // row
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_init: LCD initialization
|
|
argument(s): none.
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_Init(void) {
|
|
LCD_DDR |= BIT(SCLK_PIN); //PIN Port DDR
|
|
LCD_DDR |= BIT(SDIN_PIN);
|
|
LCD_DDR |= BIT(LCD_DC_PIN);
|
|
LCD_DDR |= BIT(LCD_CE_PIN);
|
|
LCD_DDR |= BIT(LCD_RST_PIN);
|
|
LCD_RST_clr; // very first reset
|
|
delay_1us;
|
|
LCD_RST_set;
|
|
LCD_CE_clr; // chip Enable
|
|
delay_1us;
|
|
LCD_CE_set; // chip disable for the first initialization
|
|
delay_1us;
|
|
LCD_write_byte(0x21, CMD); // set LCD mode:PDown=0, Vaddr=0, Hext=1
|
|
LCD_write_byte(0xC8, CMD); // set bias voltage, 0b(1)100.1000 (0x48)
|
|
LCD_write_byte(0x06, CMD); // temperature correction=0b(0000.01)10
|
|
LCD_write_byte(0x13, CMD); // set bias system: 0b(0001.0)011 --> 1:48
|
|
LCD_write_byte(0x20, CMD); // set LCD mode:PDown=0, Vaddr=0, Hext=0
|
|
LCD_write_byte(0x0c, CMD); // set LCD config, 0b(0000.1)100 --> normal mode
|
|
LCD_CE_clr; // chip enable
|
|
LCD_Cls(); // clear the LCD
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------
|
|
LCD_Pixel: Displays a pixel at given absolute (x, y) location.
|
|
Argument(s): x, y -> Absolute pixel coordinates
|
|
mode -> Off, On or Xor. See enum.
|
|
return: none.
|
|
created date 2014-01-08
|
|
--------------------------------------------------------------------------------------------------*/
|
|
void LCD_Pixel (unsigned char x, unsigned char y) {
|
|
/*
|
|
// only with Video-Ram support (504 bytes)
|
|
unsigned int index;
|
|
unsigned char offset;
|
|
unsigned char data;
|
|
|
|
if ( x > 84 ) return;
|
|
if ( y > 48 ) return;
|
|
index = ((y / 8) * 84) + x;
|
|
offset = y - ((y / 8) * 8);
|
|
data = LcdCache[index];
|
|
if ( mode == PIXEL_OFF )
|
|
data &= (~(0x01 << offset));
|
|
else if ( mode == PIXEL_ON )
|
|
data |= (0x01 << offset);
|
|
else if ( mode == PIXEL_XOR )
|
|
data ^= (0x01 << offset);
|
|
LcdCache[index] = data;
|
|
if ( index < LoWaterMark )
|
|
LoWaterMark = index; // Update low marker.
|
|
if ( index > HiWaterMark )
|
|
HiWaterMark = index; // Update high marker.
|
|
UpdateLcd = TRUE;
|
|
*/
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_SetContrast: Sets the contrast
|
|
argument(s): contrast -> contrast
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_SetContrast(unsigned char contrast) {
|
|
LCD_write_byte( 0x21, CMD ); // LCD Extended Commands.
|
|
LCD_write_byte( 0x80 | contrast, CMD ); // Set LCD Vop (Contrast).
|
|
LCD_write_byte( 0x20, CMD ); // LCD Standard Commands, horizontal addressing mode.
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_String_P: Display strings stored in Flash Memory
|
|
argument(s): X -> 0..83
|
|
Y -> 0..5
|
|
s -> String to display
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_String_P(unsigned char X,unsigned char Y, char *characters) {
|
|
LCD_GotoXY(X,Y);
|
|
while (pgm_read_byte(characters))
|
|
LCD_Char(pgm_read_byte(characters++));
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------
|
|
LCD_WriteXY: Displays a strings in x,y
|
|
argument(s): X -> 0..83
|
|
Y -> 0..5
|
|
characters -> String to display
|
|
return: none.
|
|
created date 2014-01-08
|
|
-----------------------------------------------------------------------*/
|
|
void LCD_WriteXY(unsigned char X,unsigned char Y, char *characters) {
|
|
LCD_GotoXY(X,Y);
|
|
while (*characters) {
|
|
LCD_Char(*characters);
|
|
characters++;
|
|
}
|
|
}
|