Code:
/************************************************************************
* *
* Project: Nokia_Fonts *
* Source: Nokia_Main.c *
* Author: Mike McLaren, K8LH *
* (C)2013: Micro Application Consultants *
* Date: 25-May-2018 *
* *
* Experimental Nokia 5110 LCD display driver demo using a 96 *
* character packed 2.5-word-per-character 5x7 font table on a *
* PIC16F1823. *
* *
* IDE: MPLABX v4.05 *
* Lang: XC8 v1.45, Lite/Free version *
* *
************************************************************************/
/* CONFIG1 */
#pragma config FOSC = INTOSC // INTOSC oscillator: I/O on CLKIN pin
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR/VPP pin function is MCLR
#pragma config CP = OFF // Code protection is disabled
#pragma config CPD = OFF // Data memory code protection disabled
#pragma config BOREN = ON // Brown-out Reset Enable
#pragma config CLKOUTEN = OFF // Clock Out Enable (off)
#pragma config IESO = OFF // Internal/External Switchover (off)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (off)
/* CONFIG2 */
#pragma config WRT = OFF // Write protection off
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable
#pragma config BORV = LO // Brown-out Reset Low Trip Point
#pragma config LVP = ON // Low-Voltage Programming Enable
#include <xc.h>
#define _XTAL_FREQ 8000000
/************************************************************************
* *
************************************************************************/
#define rst RA0 // 5110 'reset'
#define dat RA1 // 5110 'din'
#define clk RA2 // 5110 'clk'
#define ce RC0 // 5110 'ce'
#define dc RC1 // 5110 'dc'
/************************************************************************
* *
************************************************************************/
void putwreg() // send byte, msb first
{ char work; //
asm("movwf putwreg@work "); //
ce = 0; // spi enable on
for(char n=0; n<8; n++) //
{ clk = 0; dat = 0; // "
if(work & 128) dat = 1; // "
clk = 1; work <<= 1; // "
} //
ce = 1; // spi enable off
} //
/************************************************************************
* *
************************************************************************/
void putcmd(char cmd) // bank 0 (inserted by compiler) |00
{ dc = 0; // command mode |00
asm("call _putwreg "); // |00
}
/************************************************************************
* *
************************************************************************/
void rdflash() //
{ asm("banksel EECON1 "); // bank 3 |03
asm("bcf EECON1,6 "); // CFGS = 0 (not config) |03
asm("bsf EECON1,7 "); // EEPGD = 1 (program memory) |03
asm("bsf EECON1,0 "); // RD = 1 (initiate read) |03
asm("nop "); // required nop |03
asm("nop "); // " |03
asm("incf EEADRL,F "); // bump EEADR |03
asm("rlf EEDATL,W "); // move b7 into Carry |03
asm("rlf EEDATH,W "); // wreg = the 7 bit hi byte |03
asm("bcf EEDATL,7 "); // eedatl = the 7 bit lo byte |03
} //
/************************************************************************
* *
************************************************************************/
void wrchar(char ascii) //
{ dc = 1; // set lcd 'data' mode |00
asm("movlw -32 "); // ascii 32..127 minus offset |00
asm("addwf wrchar@ascii,F "); // font array index, 0..95 |00
asm("lsrf wrchar@ascii,W "); // int(ascii *= 2.5) -> 0..237 |00
asm("addwf wrchar@ascii,W "); // " |00
asm("addwf wrchar@ascii,W "); // " |00
asm("movlb 3 "); // bank 3 |00
asm("movwf EEADRL "); // flash address lo |00
asm("movlw Font5x7/256 "); // |00
asm("movwf EEADRH "); // flash address hi |00
/* *
* Extract five bytes of pattern data from three memory words. An *
* even character uses word 0 hi + lo, 1 hi + lo, and 2 hi while *
* odd characters use word 0 lo, 1 hi + lo, and 2 hi + lo. A 6th *
* blank (zero) byte is sent for inter-character spacing. *
* */
asm("call _rdflash "); // read 1st word (2 bytes) |03
asm("banksel wrchar@ascii "); // bank 0 |00
asm("btfss wrchar@ascii,0 "); // odd char? yes, skip, else |00
asm("call _putwreg "); // send hi byte (even character) |00
asm("banksel EEDATL "); // bank 3 |03
asm("movf EEDATL,W "); // |03
asm("call _putwreg "); // send lo byte |00
asm("call _rdflash "); // read 2nd word (2 bytes) |03
asm("call _putwreg "); // send hi byte |00
asm("banksel EEDATL "); // bank 3 |03
asm("movf EEDATL,W "); // |03
asm("call _putwreg "); // send lo byte |00
asm("call _rdflash "); // read 3rd word (2 bytes) |03
asm("call _putwreg "); // send hi byte |00
asm("banksel EEDATL "); // bank 3 |03
asm("movf EEDATL,W "); // |03
asm("banksel wrchar@ascii "); // bank 0 |00
asm("btfsc wrchar@ascii,0 "); // even char? yes, skip, else |00
asm("call _putwreg "); // send lo byte (odd characters) |00
asm("movlw 0 "); // |00
asm("call _putwreg "); // send blank 6th column |00
}
/************************************************************************
* *
************************************************************************/
void putstr(const char *str) // put 'ROM' strings
{ char n = 0; //
while(str[n++]) //
{ asm("call _putwreg "); //
}
}
/************************************************************************
* main setup *
************************************************************************/
void main(void)
{ ANSELA = 0; // Analog off (digital I/O)
ANSELC = 0; // "
TRISA = 0; //
TRISC = 0; //
OSCCON = 0b01110000; // set INTOSC to 8-MHz
/* *
* initialize Nokia 5110 LCD display *
* */
__delay_ms(30); //
rst = 0; rst = 1; // 5110 'reset' pulse
putcmd(0x20+0x01); // function set: ext instructions
putcmd(0x80+0x30); // set Vop (contrast), 0..127
putcmd(0x04+0x02); // set temperature coefficient, 0..3
putcmd(0x10+0x03); // Set bias system, 0..7
putcmd(0x20+0x00); // function set: std instructions
putcmd(0x08+0x04); // display control: normal mode
/* *
* test the lcd print functions *
* */
putcmd(0x80+0x20); // set DDRAM X address, 0..83
putcmd(0x40+0x02); // set DDRAM Y address, 0..5
wrchar('R'); //
putstr("eady"); //
/************************************************************************
* main loop *
************************************************************************/
while(1)
{ //
} //
} //
/************************************************************************
* Packed 96 character 5x7 Font, 2.5-words-per-character, 240 words *
************************************************************************/
#asm
PSECT myFonts, class=CODE, abs, space=0, delta=2
ORG 700h
Font5x7:
dw 0x0000, 0x0000, 0x0000, 0x005F, 0x0000 ; 32 ' ' '!'
dw 0x0007, 0x0007, 0x0014, 0x3F94, 0x3F94 ; 34 '"' '#'
dw 0x122A, 0x3FAA, 0x0923, 0x0988, 0x3262 ; 36 '$' '%'
dw 0x1B49, 0x2AA2, 0x2800, 0x0283, 0x0000 ; 38 '&' '''
dw 0x001C, 0x1141, 0x0000, 0x20A2, 0x0E00 ; 40 '(' ')'
dw 0x0A08, 0x1F08, 0x0A08, 0x043E, 0x0408 ; 42 '*' '+'
dw 0x0050, 0x1800, 0x0008, 0x0408, 0x0408 ; 44 ',' '-'
dw 0x0060, 0x3000, 0x0020, 0x0808, 0x0202 ; 46 '.' '/'
dw 0x1F51, 0x24C5, 0x1F00, 0x217F, 0x2000 ; 48 '0' '1'
dw 0x2161, 0x28C9, 0x2321, 0x20C5, 0x25B1 ; 50 '2' '3'
dw 0x0C14, 0x097F, 0x0827, 0x22C5, 0x22B9 ; 52 '4' '5'
dw 0x1E4A, 0x24C9, 0x1801, 0x3889, 0x0283 ; 54 '6' '7'
dw 0x1B49, 0x24C9, 0x1B06, 0x24C9, 0x149E ; 56 '8' '9'
dw 0x0036, 0x1B00, 0x0000, 0x2B36, 0x0000 ; 58 ':' ';'
dw 0x0414, 0x1141, 0x0014, 0x0A14, 0x0A14 ; 60 '<' '='
dw 0x0041, 0x1114, 0x0402, 0x00D1, 0x0486 ; 62 '>' '?'
dw 0x1949, 0x3CC1, 0x1F7E, 0x0891, 0x08FE ; 64 '@' 'A'
dw 0x3FC9, 0x24C9, 0x1B3E, 0x20C1, 0x20A2 ; 66 'B' 'C'
dw 0x3FC1, 0x20A2, 0x0E7F, 0x24C9, 0x24C1 ; 68 'D' 'E'
dw 0x3F89, 0x0489, 0x00BE, 0x20C9, 0x24FA ; 70 'F' 'G'
dw 0x3F88, 0x0408, 0x3F80, 0x20FF, 0x2080 ; 72 'H' 'I'
dw 0x1040, 0x20BF, 0x00FF, 0x0414, 0x1141 ; 74 'J' 'K'
dw 0x3FC0, 0x2040, 0x207F, 0x010C, 0x017F ; 76 'L' 'M'
dw 0x3F84, 0x0410, 0x3FBE, 0x20C1, 0x20BE ; 78 'N' 'O'
dw 0x3F89, 0x0489, 0x033E, 0x20D1, 0x10DE ; 80 'P' 'Q'
dw 0x3F89, 0x0CA9, 0x2346, 0x24C9, 0x24B1 ; 82 'R' 'S'
dw 0x0081, 0x3F81, 0x00BF, 0x2040, 0x203F ; 84 'T' 'U'
dw 0x0FA0, 0x2020, 0x0FBF, 0x2038, 0x203F ; 86 'V' 'W'
dw 0x3194, 0x0414, 0x3187, 0x0470, 0x0407 ; 88 'X' 'Y'
dw 0x30D1, 0x24C5, 0x2180, 0x3FC1, 0x2080 ; 90 'Z' '['
dw 0x0104, 0x0410, 0x1000, 0x20C1, 0x3F80 ; 92 '\' ']'
dw 0x0202, 0x0082, 0x0240, 0x2040, 0x2040 ; 94 '^' '_'
dw 0x0001, 0x0104, 0x0020, 0x2A54, 0x2A78 ; 96 '`' 'a'
dw 0x3FC8, 0x2244, 0x1C38, 0x2244, 0x2220 ; 98 'b' 'c'
dw 0x1C44, 0x2248, 0x3FB8, 0x2A54, 0x2A18 ; 100 'd' 'e'
dw 0x047E, 0x0481, 0x010C, 0x2952, 0x293E ; 102 'f' 'g'
dw 0x3F88, 0x0204, 0x3C00, 0x227D, 0x2000 ; 104 'h' 'i'
dw 0x1040, 0x223D, 0x007F, 0x0828, 0x2200 ; 106 'j' 'k'
dw 0x0041, 0x3FC0, 0x007C, 0x0218, 0x0278 ; 108 'l' 'm'
dw 0x3E08, 0x0204, 0x3C38, 0x2244, 0x2238 ; 110 'n' 'o'
dw 0x3E14, 0x0A14, 0x0408, 0x0A14, 0x0C7C ; 112 'p' 'q'
dw 0x3E08, 0x0204, 0x0448, 0x2A54, 0x2A20 ; 114 'r' 's'
dw 0x023F, 0x2240, 0x103C, 0x2040, 0x107C ; 116 't' 'u'
dw 0x0E20, 0x2020, 0x0E3C, 0x2030, 0x203C ; 118 'v' 'w'
dw 0x2228, 0x0828, 0x220C, 0x2850, 0x283C ; 120 'x' 'y'
dw 0x2264, 0x2A4C, 0x2200, 0x0436, 0x2080 ; 122 'z' '{'
dw 0x0000, 0x3F80, 0x0000, 0x20B6, 0x0400 ; 124 '|' '}'
dw 0x0808, 0x0410, 0x0478, 0x2341, 0x2378 ; 126 '~' ''
#endasm
/************************************************************************/
Bookmarks