1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

A 'packed' 5x7 Font Table (for Nokia 5110)

Discussion in 'Microcontrollers' started by Mike - K8LH, May 18, 2018.

  1. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,679
    Likes:
    122
    Location:
    Michigan, USA
    Anyone want to take a peek at example code to implement a 'packed' font array (table)? I borrowed the idea from a Gentleman over on the PicBasicPro forum.

    My old 96 character 5x7 font table used 5 words of program memory to store 5 (7-bit) bytes of pattern data for each character and the entire table used 480 words of program memory. My new table packs two 7-bit patterns in each 14-bit memory word and uses three words per character for a total of 288 words of program memory.

    This is a demo program for a 16F1823 and a Nokia 5110 display written in BoostC. I haven't tested it on hardware yet but it simulates ok. It's reasonably tight code (452 words total) but it's also pretty rude-n'-crude with only the simplest functions to write commands, data, ascii characters, and ascii strings to the display. I haven't even had a chance to add a clear-screen function.

    If I have time I'll try to make an XC8 version of the program.

    Cheerful regards, Mike

    Code (C):

      /********************************************************************
       *                                                                  *
       *  Project: Nokia 5110 16F1823 Demo                                *
       *   Source: Nokia_5110_16F1823_Demo.c                              *
       *   Author: Mike McLaren, K8LH                                     *
       *  (C)2013: Micro Application Consultants                          *
       *     Date: 29-Nov-2013, Revised: 18-May-2018                      *
       *                                                                  *
       *   First experiment driving a Nokia 5110 LCD display.  revised    *
       *   to use a packed 14-bit 'word' size font table/array.           *
       *                                                                  *
       *                                                                  *
       *      IDE: MPLAB 8.84 (tabs = 4)                                  *
       *     Lang: SourceBoost BoostC v7.05, Lite/Free version            *
       *                                                                  *
       ********************************************************************/

     
       #include <system.h>
       #pragma DATA _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _MCLRE_ON
       #pragma DATA _CONFIG2, _PLLEN_OFF & _LVP_OFF
       #pragma CLOCK_FREQ 8000000       // 8 MHz INTOSC

      /********************************************************************
       *  function prototypes                                             *
       ********************************************************************/


      /********************************************************************
       *  typedef and defines                                             *
       ********************************************************************/


       #define rst porta.0          // RA0 = 5110 'reset'
       #define dat porta.1          // RA1 = 5110 'din'
       #define clk porta.2          // RA2 = 5110 'clk'
       #define ce  portc.0          // RC0 = 5110 'ce'
       #define dc  portc.1          // RC1 = 5110 'dc'

      /********************************************************************
       *  variables and the Nokia 5110 packed 5x7 font array              *
       ********************************************************************/


       #pragma DATA 1024,           // packed 96 character 5x7 font array
         0x0000, 0x0000, 0x0000,    // 20 ' '
         0x0000, 0x2F80, 0x0000,    // 21 '!'
         0x0007, 0x0007, 0x0000,    // 22 '"'
         0x0A7F, 0x0A7F, 0x0A00,    // 23 '#'
         0x122A, 0x3FAA, 0x0900,    // 24 '$'
         0x1193, 0x0464, 0x3100,    // 25 '%'
         0x1B49, 0x2AA2, 0x2800,    // 26 '&'
         0x0005, 0x0180, 0x0000,    // 27 '''
         0x001C, 0x1141, 0x0000,    // 28 '(' fixed
         0x0041, 0x111C, 0x0000,    // 29 ')' fixed
         0x0A08, 0x1F08, 0x0A00,    // 2A '*'
         0x0408, 0x1F08, 0x0400,    // 2B '+'
         0x0050, 0x1800, 0x0000,    // 2C ','
         0x0408, 0x0408, 0x0400,    // 2D '-'
         0x0060, 0x3000, 0x0000,    // 2E '.' fixed
         0x1010, 0x0404, 0x0100,    // 2F '/'
         0x1F51, 0x24C5, 0x1F00,    // 30 '0'
         0x0042, 0x3FC0, 0x0000,    // 31 '1'
         0x2161, 0x28C9, 0x2300,    // 32 '2'
         0x10C1, 0x22CB, 0x1880,    // 33 '3'
         0x0C14, 0x097F, 0x0800,    // 34 '4'
         0x13C5, 0x22C5, 0x1C80,    // 35 '5'
         0x1E4A, 0x24C9, 0x1800,    // 36 '6'
         0x00F1, 0x0485, 0x0180,    // 37 '7'
         0x1B49, 0x24C9, 0x1B00,    // 38 '8'
         0x0349, 0x24A9, 0x0F00,    // 39 '9'
         0x0036, 0x1B00, 0x0000,    // 3A ':'
         0x0056, 0x1B00, 0x0000,    // 3B ';'
         0x0414, 0x1141, 0x0000,    // 3C '<'
         0x0A14, 0x0A14, 0x0A00,    // 3D '='
         0x0041, 0x1114, 0x0400,    // 3E '>'
         0x0101, 0x2889, 0x0300,    // 3F '?'
         0x1949, 0x3CC1, 0x1F00,    // 40 '@'
         0x3F11, 0x0891, 0x3F00,    // 41 'A'
         0x3FC9, 0x24C9, 0x1B00,    // 42 'B'
         0x1F41, 0x20C1, 0x1100,    // 43 'C'
         0x3FC1, 0x20A2, 0x0E00,    // 44 'D'
         0x3FC9, 0x24C9, 0x2080,    // 45 'E'
         0x3F89, 0x0489, 0x0080,    // 46 'F'
         0x1F41, 0x24C9, 0x3D00,    // 47 'G'
         0x3F88, 0x0408, 0x3F80,    // 48 'H'
         0x0041, 0x3FC1, 0x0000,    // 49 'I'
         0x1040, 0x20BF, 0x0080,    // 4A 'J'
         0x3F88, 0x0A22, 0x2080,    // 4B 'K'
         0x3FC0, 0x2040, 0x2000,    // 4C 'L'
         0x3F82, 0x0602, 0x3F80,    // 4D 'M'
         0x3F84, 0x0410, 0x3F80,    // 4E 'N'
         0x1F41, 0x20C1, 0x1F00,    // 4F 'O'
         0x3F89, 0x0489, 0x0300,    // 50 'P'
         0x1F41, 0x28A1, 0x2F00,    // 51 'Q'
         0x3F89, 0x0CA9, 0x2300,    // 52 'R'
         0x2349, 0x24C9, 0x1880,    // 53 'S'
         0x0081, 0x3F81, 0x0080,    // 54 'T'
         0x1FC0, 0x2040, 0x1F80,    // 55 'U'
         0x0FA0, 0x2020, 0x0F80,    // 56 'V'
         0x1FC0, 0x1C40, 0x1F80,    // 57 'W'
         0x3194, 0x0414, 0x3180,    // 58 'X'
         0x0388, 0x3808, 0x0380,    // 59 'Y'
         0x30D1, 0x24C5, 0x2180,    // 5A 'Z'
         0x007F, 0x20C1, 0x0000,    // 5B '['
         0x0104, 0x0410, 0x1000,    // 5C '\'
         0x0041, 0x20FF, 0x0000,    // 5D ']'
         0x0202, 0x0082, 0x0200,    // 5E '^'
         0x2040, 0x2040, 0x2000,    // 5F '_'
         0x0001, 0x0104, 0x0000,    // 60 '`'
         0x1054, 0x2A54, 0x3C00,    // 61 'a'
         0x3FC8, 0x2244, 0x1C00,    // 62 'b'
         0x1C44, 0x2244, 0x1000,    // 63 'c'
         0x1C44, 0x2248, 0x3F80,    // 64 'd'
         0x1C54, 0x2A54, 0x0C00,    // 65 'e'
         0x047E, 0x0481, 0x0100,    // 66 'f'
         0x0652, 0x2952, 0x1F00,    // 67 'g'
         0x3F88, 0x0204, 0x3C00,    // 68 'h'
         0x0044, 0x3EC0, 0x0000,    // 69 'i'
         0x1040, 0x223D, 0x0000,    // 6A 'j'
         0x3F90, 0x1444, 0x0000,    // 6B 'k'
         0x0041, 0x3FC0, 0x0000,    // 6C 'l'
         0x3E04, 0x0C04, 0x3E00,    // 6D 'm' ????
         0x3E08, 0x0204, 0x3E00,    // 6E 'n' ????
         0x1C44, 0x2244, 0x1C00,    // 6F 'o'
         0x3E14, 0x0A14, 0x0400,    // 70 'p'
         0x0414, 0x0A18, 0x3E00,    // 71 'q'
         0x3E08, 0x0204, 0x0400,    // 72 'r'
         0x2454, 0x2A54, 0x1000,    // 73 's'
         0x023F, 0x2240, 0x1000,    // 74 't'
         0x1E40, 0x2020, 0x3E00,    // 75 'u'
         0x0E20, 0x2020, 0x0E00,    // 76 'v'
         0x1E40, 0x1840, 0x1E00,    // 77 'w'
         0x2228, 0x0828, 0x2200,    // 78 'x'
         0x0650, 0x2850, 0x1E00,    // 79 'y'
         0x2264, 0x2A4C, 0x2200,    // 7A 'z'
         0x0008, 0x1B41, 0x0000,    // 7B '{'
         0x0000, 0x3F80, 0x0000,    // 7C '|'
         0x0041, 0x1B08, 0x0000,    // 7D '}'
         0x0808, 0x0410, 0x0400,    // 7E '~'
         0x3C46, 0x20C6, 0x3C00     // 7F ' '


      /********************************************************************
       *  functions                                                       *
       ********************************************************************/

       void putlcd(char data)       //
       { unsigned char n = 8;       //
         ce = 0;                    // spi enable
         do                         //
         { clk = 0; dat = 0;        //
           if(data.7) dat = 1;      //
           clk = 1; data <<= 1;     //
         } while(--n);              //
         ce = 1;                    // spi enable off
       }                            //

      /********************************************************************
       *                                                                  *
       ********************************************************************/

       void RdFlash()               // bank 3 (inserted by compiler)
       { asm bcf     _eecon1,CFGS   // not 'config' memory            |03
         asm bsf     _eecon1,EEPGD  // select 'program' memory        |03
         asm bsf     _eecon1,RD     // initiate read operation        |03
         asm nop                    // required nop                   |03
         asm nop                    //  "                             |03
         asm incf    _eeadrl,F      // bump EEADR                     |03
         asm btfsc   _status,Z      //  "                             |03
         asm incf    _eeadrh,F      //  "                             |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)      // WrChar() for packed 5x7 font
       { asm movf    _ascii,W       // ascii char value, 32..127      |00
         asm addlw   -32            // minus table offset             |00
         asm movwf   _ascii         // font array index, 0..95        |00
     /*                                                                   *
      *  multiply index by 3 (0..95 -> 0..285), add table base address,   *
      *  and stuff the result in the EEADR register pair.                 *
      *                                                                   */

         asm lslf    _wreg,W        // wreg = (ascii-32)*2            |00
         asm addwf   _ascii,W       // wreg = (ascii-32)*3            |00
      // asm movlb   3              // bank 3 (inserted by compiler)  |03
         asm movwf   _eeadrl        // flash address lo               |03
         asm movlw   1024/256       // table address hi               |03
         asm btfsc   _status,C      // overflow? no, skip, else       |03
         asm addlw   1              // bump value                     |03
         asm movwf   _eeadrh        // flash address hi               |03
     /*                                                                   *
      *  read 3 words (6 bytes) of font pattern data from the packed      *
      *  5x7 font array and write them to the Nokia 5110 LCD.             *
      *                                                                   */

         for(char i=0; i<3; i++)    //
         { RdFlash();               // read one word (2 bytes)
           putlcd(wreg);            // send hi byte
           putlcd(eedatl);          // send lo byte
         }                          //
       }                            //

      /********************************************************************
       *                                                                  *
       ********************************************************************/

       void WrChar(rom char *data)  // overload function for strings
       { char ndx = 0;              //
         while(data[ndx++])         // while not end-of-string
           WrChar(wreg);            //
       }                            //

      /********************************************************************
       *  main init                                                       *
       ********************************************************************/

       void main()
       { ansela = 0;                // adc off for digital I/O
         anselc = 0;                //  "
         trisa = 0;                 // porta all outputs except RA3/MCLR
         trisc = 0;                 // portc all outputs
         ce = 1;                    // 5110 'ce' off
         rst = 1;                   // 5110 'rst' off
         osccon = 0b01110000;       // set INTOSC to 8 MHz
     /*                                                                   *
      *  initialize Nokia 5110 LCD display                                *
      *                                                                   */

         delay_ms(30);              //
         rst = 0;                   // 5110 'reset' pulse
         rst = 1;                   //
         dc = 0;                    // command mode
         putlcd(0x20+0x01);         // function set: extended instructions
         putlcd(0x80+0x48);         // set Vop (contrast), 0..127
         putlcd(0x04+0x02);         // set temperature coefficient, 0..3
         putlcd(0x10+0x03);         // Set bias system, 0..7
         putlcd(0x20+0x00);         // function set: standard instructions
         putlcd(0x08+0x04);         // display control: normal mode
         putlcd(0x80+0x20);         // set DDRAM X address, 0..83
         putlcd(0x40+0x02);         // set DDRAM Y address, 0..5
         dc = 1;                    // data mode

         WrChar("Hello");           // test string overload function

      /********************************************************************
       *  main loop                                                       *
       ********************************************************************/

         while(1)                   //
         {
         }
       }
     
    Last edited: Jun 14, 2018
    • Like Like x 2
    • Thanks Thanks x 1
  2. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,679
    Likes:
    122
    Location:
    Michigan, USA
    I also created a spreadsheet to convert my old 5-byte-per-character font table to the 'packed' 3 word format and added a crude single character viewer/editor, if anyone is interested. The packed output file can be formatted for assembler or C. I also added a 'Font Viewer' sheet to the workbook that renders the character set directly from the 5-byte-per-character input table.

    Cheerful regards, Mike

    5x7 Font Packer #2.png

    Font Viewer 5x7.png
     
    Last edited: Jun 15, 2018
  3. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,679
    Likes:
    122
    Location:
    Michigan, USA
    Here's a version written for XC8 (and 16F1823). Much like the BoostC program in post #1, the low level drivers are assembly code. The program uses 370 words of program memory, including the font table. Some differences from the BoostC example in post #1;

    () This version uses a smaller 240 word 96 character font table that packs 5 bytes per character of font data into 2.5 words of program memory.
    () This version includes a clear screen function.
    () This version drives the Nokia 5110 display using hardware SPI.

    Cheerful regards, Mike
     

    Attached Files:

    Last edited: Jun 16, 2018
    • Like Like x 3
  4. dave miyares

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    2
    Likes:
    -10


     
  5. gophert

    gophert Active Member

    Joined:
    Jan 17, 2015
    Messages:
    473
    Likes:
    73
    Location:
    Western, PA (USA)
    Do you have a 5110 display to try this out?
     
  6. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,679
    Likes:
    122
    Location:
    Michigan, USA
    Yes, I have a 5110 display and both the BoostC program in post #1 and the XC8 program in post #3 have been tested on the display (Vcc = 3.3v). Here's the XC8 program running;

    5110 #1.png
     
    • Like Like x 1
  7. gophert

    gophert Active Member

    Joined:
    Jan 17, 2015
    Messages:
    473
    Likes:
    73
    Location:
    Western, PA (USA)
    Looks good. I read the first few posts that you simulated it - nice to see you built a working version.
    I also read that Nokia re-released the 3310. Maybe 5110 is next (Ha).
     
  8. dave miyares

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    2
    Likes:
    -10


     
  9. granddad

    granddad Active Member

    Joined:
    Jan 18, 2015
    Messages:
    838
    Likes:
    89
    Location:
    Worcestershire UK
    So I just got a 5110 display, but not got time to play at the moment. any suggestions for a hookup to a PIC24 circuit wise please.
     
  10. gophert

    gophert Active Member

    Joined:
    Jan 17, 2015
    Messages:
    473
    Likes:
    73
    Location:
    Western, PA (USA)
    I just used a simple bit bang spi so you just need one output pin to each 5110 pin. I used a small npn Transistor to power the LED backlight and controlled the backlight from another output pin on the micro (to npn base pin). My project was only a proof of concept so nothing fancy (yet)
     
    • Thanks Thanks x 1
  11. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,679
    Likes:
    122
    Location:
    Michigan, USA
    Hi, granddad... I bit-banged an SPI driver in my original BoostC demo and I used the hardware SPI peripheral on the XC8 demo. Both demos were for a 16F1823 running at 8-MHz on 3.3 volts.

    Now I'm trying to bring up a 0.91-inch 128x32 OLED display with integrated SSD1306 driver IC and an I2C interface. After studying the datasheet and looking at some examples on the internet, it seems I might be able to use my packed 5x7 font with this display but it's so darned tiny I think I may have to resort to using it as a 2-line display with a larger 10x14 font. Perhaps something similar to the font below...

    Cheerful regards, Mike

    Font Viewer 10x14 (small).png
     
    • Thanks Thanks x 1

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice