//_______________________________________________________________________________________________________
// PIC to Nokia 3310 LCD (PCD8544) driving routines written Hi-Tech C
// written by Ramandeep Singh ©2004
// with help from Michel Bavin's EEPROM to 3310 LCD routines
// www.spiralbrain.tk or http://67.15.78.55/~spiral/
// spiralbrain@yahoo.com
// Date: 21 Nov 2004
//
// Usage : Include 3310.c in the main project file, include delay.h and delay.c
// in the main file, define the PIC pins to be used in this file, in the main
// code file call init_nokia(); to initialise the LCD
// nokia_gotoxy(0,0);
// nokia_printchar('D');
// nokia_printmessage("hello can you really read this?");
//
//_______________________________________________________________________________________________________
#include <pic.h>
#define _XTAL_FREQ 8000000
// define PIC <> LCD ports here
#define nok_sclk RB3 // nokia lcd sclk pin 2
#define nok_sda RB4 // nokia lcd sda pin 3
#define nok_dc RB5 // nokia lcd d/c pin 4
#define nok_cs RB6 // nokia lcd cs pin 5
#define nok_res RB7 // nokia lcd res pin 8
typedef unsigned char BYTE; /* Unsigned 8-bit */
typedef unsigned char byte; /* Unsigned 8-bit */
unsigned char charsel,i,c;
unsigned char bytefornokia,testbyte;
static byte LcdCache [ 5 ];
char LcdCacheIdx;
//functions
void init_nokia(void); // initialisation
void nokia_write_command(void); // nokia lcd subroutines
void nokia_write_dorc(void);
void nokia_build_DDRAM(void); //Build DDRAM
void nokia_write_data(void); //write Data
void nokia_gotoxy(byte xnokia, byte ynokia); // go to x,y on the LCD
void nokia_printchar(byte c); // print a char at the current position
void nokia_printmessage(const char* message); // print a string at the current position
void table_to_nokialcd(void); // write from table to nokia lcd
//__________________________________________________________________________________________________________________________
// ASCII lookup table
static const byte FontLookup [][5] =
{
{ 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 }, // [
{ 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55
{ 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
};
//__________________________________________________________________________________________________________________________
void init_nokia(void)
{
// nokia LCD init
nok_dc=1; // bytes are stored in the display data ram, address counter, incremented automatically
nok_cs=1; // chip disabled
__delay_ms(10);
nok_res=0; // reset chip during 250ms
__delay_ms(250);
nok_res=1;
bytefornokia=0x21; // set extins extended instruction set
nokia_write_command();
bytefornokia=0xc5; // Vop was 0xc5 // better is 0xa0
nokia_write_command();
bytefornokia=0x13; // bias
nokia_write_command();
bytefornokia=0x20; // horizontal mode from left to right, X axe are incremented automatically , 0x22 for vertical addressing ,back on normal instruction set too 0x20 for horizontal
nokia_write_command();
bytefornokia=0x09; // all on
nokia_write_command();
__delay_ms(250);
__delay_ms(250);
nokia_build_DDRAM(); // reset DDRAM, otherwise the lcd is blurred with random pixels
__delay_ms(10);
bytefornokia=0x08; // mod control blank change (all off)
nokia_write_command();
__delay_ms(10);
bytefornokia=0x0c; // mod control normal change
nokia_write_command();
nokia_gotoxy(0,0);
}
//__________________________________________________________________________________________________________________________
void nokia_write_command(void)
{
nok_dc=0; // byte is a command it is read with the eight SCLK pulse
nok_cs=0; // chip enabled
nokia_write_dorc();
nok_cs=1; // chip disabled
}
//__________________________________________________________________________________________________________________________
void nokia_write_data(void)
{
nok_dc=1;
nok_cs=0; // chip enabled
nokia_write_dorc();
nok_cs=1; // chip disabled
}
//__________________________________________________________________________________________________________________________
void nokia_write_dorc(void) // serial write data or command subroutine
{
for (c=8;c>0;c--) {
nok_sclk=0;
if ((bytefornokia&0x80)==0){
nok_sda=0;
}
else {
nok_sda=1;
}
nok_sclk=1;
bytefornokia=bytefornokia<<1;
}
}
//__________________________________________________________________________________________________________________________
void nokia_build_DDRAM(void) // clear all DDRAM (set all bits to zero)
{
signed char ch, cm, cl;
nok_sda=0;
nok_dc=1;
nok_cs=0;
for (ch=6;ch>0;ch--){ // 6 rows
for (cm=84;cm>0;cm--){ // 84 columns
for (cl=8;cl>0;cl--){ // 8 pixels
nok_sclk=0;
nok_sclk=1;
}
}
}
nok_cs=1;
}
//__________________________________________________________________________________________________________________________
void nokia_gotoxy (byte xnokia, byte ynokia) // Nokia LCD Position cursor
{
bytefornokia=(0x40|(ynokia&0x07)); // Y axe initialisation: 0100 0yyy
nokia_write_command();
bytefornokia=(0x80|(xnokia&0x7f)); // X axe initialisation: 1xxx xxxx
nokia_write_command();
}
//__________________________________________________________________________________________________________________________
void nokia_printmessage(const char* message) // Write message to LCD (C string type)
{
while (*message) // Look for end of string
nokia_printchar(*message++); //
}
//__________________________________________________________________________________________________________________________
void nokia_printchar(byte c) // Write 1 character to LCD
{
charsel=c;
table_to_nokialcd();
}
//__________________________________________________________________________________________________________________________
void menu_nokia_printmessage(const char* message) // Write message to LCD (C string type)
{
nokia_gotoxy (0,5);
while (*message) // Look for end of string
nokia_printchar(*message++); //
}
//__________________________________________________________________________________________________________________________
void table_to_nokialcd(void) //
{
for ( i = 0; i < 5; i++ )
{
LcdCache[i] = FontLookup[charsel - 32][i] << 1;
bytefornokia=LcdCache[i]; // Write D at 30,0
nokia_write_data(); // send data to nokia
// DelayMs(15);
}
bytefornokia=0x00;
nokia_write_data(); // send data to nokia
}
|