Nokia lcd include , small footprint to suit pic16's


Closed Thread
Results 1 to 40 of 111

Hybrid View

  1. #1
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    Richard... Would you be interested in seeing my driver code for font tables with 2.5 word-per-character packing instead of 3 word-per-character packing? The new '2.5' font tables use 240 words of memory (down from 288 words) and my little single file ~225 line (non-PBP) demo program now weighs in at ~406 words total memory...

    Cheerful regards, Mike
    Last edited by Mike, K8LH; - 24th May 2018 at 10:35.

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,696


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    Richard... Would you be interested in seeing my driver code for font tables
    yes please, I had considered doing that but could not find a method that preserved the gain
    my attempts used half the saved space up doing the unpacking
    Warning I'm not a teacher

  3. #3
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    First, here's how I'm packing font pattern data into 2-1/2 words within groups of 5 words;

    Name:  font pack 25.png
Views: 6715
Size:  77.2 KB

    In the first part of my WrChar() routine I calculate the table address by first subtracting the font table offset (32) from the ASCII character value (32..127). Then I multiply the resulting font table index (0..95) by 2.5 and add the integer result (0..237) to the font table base address. In my case, I'm using a fixed 0x0400 address for the font table so I don't need to perform the addition. I simply stuff the 0..237 value directly into EEADRL and the hi byte of the font table address into EEADRH.

    In the other half of my WrChar() routine, if the font table index is even I print the 1st word hi & lo bytes, the 2nd word hi & lo bytes, and the 3rd word hi byte. If the font table index is odd I print the 1st word lo byte, the 2nd word hi & lo bytes, and the 3rd word hi & lo bytes. You'll notice the logic is relatively simple and unrolling the print loop to accommodate the logic doesn't seem to have incurred additional program overhead.

    The new demo program (attached below) is 50 words smaller than the old (3-word-per-character) program (406 words total) so it seems I've realized the full 48 word savings from the new packed font table format.

    I hope this example provides some useful ideas and I'm sorry I can't help with PBP...

    Have fun... Cheerful regards, Mike

    Code:
      /********************************************************************
       *                                                                  *
       *  Project: Nokia 5110 16F1823 Demo                                *
       *   Source: Nokia_5110_Packed_v2.c                                 *
       *   Author: Mike McLaren, K8LH                                     *
       *  (C)2013: Micro Application Consultants                          *
       *     Date: 23-May-2018                                            *
       *                                                                  *
       *   Experimental Nokia 5110 LCD display driver demo using a 96     *
       *   character packed 2.5-word-per-character 5x7 font table.        *
       *                                                                  *
       *      IDE: MPLAB 8.92 (tabs = 4)                                  *
       *     Lang: SourceBoost BoostC v7.30, 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, defines, and macros                                    *
       ********************************************************************/
    
       #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'
       
       #define putlcd(x)  asm movlw x      \
                          asm call putwreg()
    
       #define putcmd(x)  dc = 0;          \
                          asm movlw x      \
                          asm call putwreg()
    
      /********************************************************************
       *  variables & packed 2.5-word-per-character 5x7 font table/array  *
       ********************************************************************/
    
       #pragma DATA 1024,
         0x0000, 0x0000, 0x0000, 0x005F, 0x0000,    //  32 ' '  '!'
         0x0007, 0x0007, 0x0014, 0x3F94, 0x3F94,    //  34 '"'  '#'
         0x122A, 0x3FAA, 0x0923, 0x0988, 0x3262,    //  36 '$'  '%'
         0x1B49, 0x2AA2, 0x2800, 0x0283, 0x0000,    //  38 '&'  '''
         0x001C, 0x1141, 0x0000, 0x20A2, 0x0E00,    //  40 '('  ')'
         0x0A08, 0x1F08, 0x0A08, 0x043E, 0x0408,    //  42 '*'  '+'
         0x0050, 0x1800, 0x0008, 0x0408, 0x0408,    //  44 ','  '-'
         0x0060, 0x3000, 0x0020, 0x0808, 0x0202,    //  46 '.'  '/'
         0x1F51, 0x24C5, 0x1F00, 0x217F, 0x2000,    //  48 '0'  '1'
         0x2161, 0x28C9, 0x2321, 0x20C5, 0x25B1,    //  50 '2'  '3'
         0x0C14, 0x097F, 0x0827, 0x22C5, 0x22B9,    //  52 '4'  '5'
         0x1E4A, 0x24C9, 0x1801, 0x3889, 0x0283,    //  54 '6'  '7'
         0x1B49, 0x24C9, 0x1B06, 0x24C9, 0x149E,    //  56 '8'  '9'
         0x0036, 0x1B00, 0x0000, 0x2B36, 0x0000,    //  58 ':'  ';'
         0x0414, 0x1141, 0x0014, 0x0A14, 0x0A14,    //  60 '<'  '='
         0x0041, 0x1114, 0x0402, 0x00D1, 0x0486,    //  62 '>'  '?'
         0x1949, 0x3CC1, 0x1F7E, 0x0891, 0x08FE,    //  64 '@'  'A'
         0x3FC9, 0x24C9, 0x1B3E, 0x20C1, 0x20A2,    //  66 'B'  'C'
         0x3FC1, 0x20A2, 0x0E7F, 0x24C9, 0x24C1,    //  68 'D'  'E'
         0x3F89, 0x0489, 0x00BE, 0x20C9, 0x24FA,    //  70 'F'  'G'
         0x3F88, 0x0408, 0x3F80, 0x20FF, 0x2080,    //  72 'H'  'I'
         0x1040, 0x20BF, 0x00FF, 0x0414, 0x1141,    //  74 'J'  'K'
         0x3FC0, 0x2040, 0x207F, 0x010C, 0x017F,    //  76 'L'  'M'
         0x3F84, 0x0410, 0x3FBE, 0x20C1, 0x20BE,    //  78 'N'  'O'
         0x3F89, 0x0489, 0x033E, 0x20D1, 0x10DE,    //  80 'P'  'Q'
         0x3F89, 0x0CA9, 0x2346, 0x24C9, 0x24B1,    //  82 'R'  'S'
         0x0081, 0x3F81, 0x00BF, 0x2040, 0x203F,    //  84 'T'  'U'
         0x0FA0, 0x2020, 0x0FBF, 0x2038, 0x203F,    //  86 'V'  'W'
         0x3194, 0x0414, 0x3187, 0x0470, 0x0407,    //  88 'X'  'Y'
         0x30D1, 0x24C5, 0x2180, 0x3FC1, 0x2080,    //  90 'Z'  '['
         0x0104, 0x0410, 0x1000, 0x20C1, 0x3F80,    //  92 '\'  ']'
         0x0202, 0x0082, 0x0240, 0x2040, 0x2040,    //  94 '^'  '_'
         0x0001, 0x0104, 0x0020, 0x2A54, 0x2A78,    //  96 '`'  'a'
         0x3FC8, 0x2244, 0x1C38, 0x2244, 0x2220,    //  98 'b'  'c'
         0x1C44, 0x2248, 0x3FB8, 0x2A54, 0x2A18,    // 100 'd'  'e'
         0x047E, 0x0481, 0x010C, 0x2952, 0x293E,    // 102 'f'  'g'
         0x3F88, 0x0204, 0x3C00, 0x227D, 0x2000,    // 104 'h'  'i'
         0x1040, 0x223D, 0x007F, 0x0828, 0x2200,    // 106 'j'  'k'
         0x0041, 0x3FC0, 0x007C, 0x0218, 0x0278,    // 108 'l'  'm'
         0x3E08, 0x0204, 0x3C38, 0x2244, 0x2238,    // 110 'n'  'o'
         0x3E14, 0x0A14, 0x0408, 0x0A14, 0x0C7C,    // 112 'p'  'q'
         0x3E08, 0x0204, 0x0448, 0x2A54, 0x2A20,    // 114 'r'  's'
         0x023F, 0x2240, 0x103C, 0x2040, 0x107C,    // 116 't'  'u'
         0x0E20, 0x2020, 0x0E3C, 0x2030, 0x203C,    // 118 'v'  'w'
         0x2228, 0x0828, 0x220C, 0x2850, 0x283C,    // 120 'x'  'y'
         0x2264, 0x2A4C, 0x2200, 0x0436, 0x2080,    // 122 'z'  '{'
         0x0000, 0x3F80, 0x0000, 0x20B6, 0x0400,    // 124 '|'  '}'
         0x0808, 0x0410, 0x0478, 0x2341, 0x2378     // 126 '~'  ''
    
      /********************************************************************
       *                                                                  *
       ********************************************************************/
       void putwreg()               // send byte, msb first (15 words)
       { char work;                 //
         asm movwf   _work          //
         char n = 0; ce = 0;        // spi enable on
         do                         // send 8 bits
         { clk = 0; dat = 0;        //  "
           if(work.7) dat = 1;      //  "
           clk = 1; work <<= 1;     //  "
           n++;                     //  "
         } while(n.3 == 0);         //  "
         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 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)      // for packed 2.5 word 5x7 font
       { dc = 1;                    // set lcd 'data' mode
         asm movlw   -32            // ascii 32..127 minus offset     |00
         asm addwf   _ascii,F       // font array index, 0..95        |00
         asm lsrf    _ascii,W       // int(ascii *= 2.5) -> 0..237    |00
         asm addwf   _ascii,W       //  "                             |00
         asm addwf   _ascii,W       //  "                             |00
      // asm movlb   3              // bank 3 (inserted by compiler)  |03
         asm movwf   _eeadrl        // flash address lo, 0..237       |03
         asm movlw   1024/256       // table address hi               |03
         asm movwf   _eeadrh        // flash address hi               |03
     /*                                                                   *
      *  Extract five bytes of pattern data from three memory words.      *
      *  Odd characters use word 0 lo, 1 hi + lo, and 2 hi + lo while     *
      *  even characters use word 0 hi + lo, 1 hi + lo, and 2 hi.  A      *
      *  sixth blank (zero) byte is sent for inter-character spacing.     *
      *                                                                   */
         asm call    RdFlash()      // read 1st word                  |03
      // asm movlb   0              // bank 0 (inserted by compiler)  |00
         asm btfss   _ascii,0       // odd char? yes, skip, else      |00
         asm call    putwreg()      // send hi byte (even character)  |00
      // asm movlb   3              // bank 3                         |03
         asm movf    _eedatl,W      //                                |03
         asm call    putwreg()      // send lo byte                   |00
         asm call    RdFlash()      // read 2nd word                  |03
         asm call    putwreg()      // send hi byte                   |00
      // asm movlb   3              // bank 3                         |03
         asm movf    _eedatl,W      //                                |03
         asm call    putwreg()      // send lo byte                   |00
         asm call    RdFlash()      // read 3rd word                  |03
         asm call    putwreg()      // send hi byte                   |00
      // asm movlb   3              // bank 3                         |03
         asm movf    _eedatl,W      //                                |03
      // asm movlb   0              // bank 0                         |00
         asm btfsc   _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 WrChar(rom char *data)  // overload function for strings
       { char ndx = 0;              //
         while(data[ndx++])         // while not end-of-string
           WrChar(wreg);            //
       }                            //
    
      /********************************************************************
       *  main setup                                                      *
       ********************************************************************/
    
       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; rst = 1;          // 5110 'reset' pulse
         putcmd(0x20+0x01);         // function set: extended 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: standard instructions
         putcmd(0x08+0x04);         // display control: normal mode
     /*                                                                   *
      *  test the LCD and the print string overload function.             *
      *                                                                   */
         putcmd(0x80+0x20);         // set DDRAM X address, 0..83
         putcmd(0x40+0x02);         // set DDRAM Y address, 0..5
         WrChar('H');               // write ascii character
         WrChar("ello");            // write ascii string
    
      /********************************************************************
       *  main loop                                                       *
       ********************************************************************/
    
         while(1)                   //
         {                          //
         }                          //
       }                            //
    Last edited by Mike, K8LH; - 25th May 2018 at 03:26.

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,696


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    thanks mike , the concept works nicely

    xc8 version (393)+240 words , uses mssp1

    Code:
    #include "mcc_generated_files/mcc.h"
    #include "FONT.c"
    void putwreg(char work);
    void putcmd(char x);
    void WrChar(char ascii);
    void WrStr(char *);
    void main(void) {
        // initialize the device
        SYSTEM_Initialize();
        /*                                                                   *
         *  initialize Nokia 5110 LCD display                                *
         *                                                                   */
        __delay_ms(30); //
        LCD_RST_SetLow(); // 5110 'reset' pulse
        __delay_ms(1);
        LCD_RST_SetHigh(); // 5110 'reset' pulse
        __delay_ms(1);
        putcmd(0x20 + 0x01); // function set: extended instructions
        putcmd(0xc8);        // 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: standard instructions
        putcmd(0x08 + 0x04); // display control: normal mode
        putcmd(0x80 + 0x20); // set DDRAM X address, 0..83
        putcmd(0x40 + 0x02); // set DDRAM Y address, 0..5
        WrChar('R'); // write ascii character
        WrStr("eady");
        while (1) {
        }
    }
    /**
     End of File
     */
     
    void putwreg(char work) // send byte, msb first (15 words)
    {
        LCD_CE_LAT = 0; // spi enable on
        SPI1_Exchange8bit(work);
        while (!PIR1bits.SSP1IF);
        LCD_CE_LAT = 1; // spi enable off
    } //
    void WrChar(char ascii) // for packed 2.5 word 5x7 font
    {
        unsigned int dat, inx = 0x1f00;
        char i = 5;
        // char fd[6],i=5,*pt;
        //pt=fd;
        inx += ((ascii - 32)*5) >> 1;
        dat = FLASH_ReadWord(inx++);
        if (!(ascii & 1))putwreg(dat >> 7); //  *pt++=dat>>7;
        putwreg(dat & 0x7f);
        //*pt++ =(char)dat&0x7f;     
        dat = FLASH_ReadWord(inx++);
        putwreg(dat >> 7);
        putwreg(dat & 0x7f);
        //*pt++=dat>>7;   
        //*pt++=(char)dat&0x7f;   
        dat = FLASH_ReadWord(inx);
        //*pt++=dat>>7;
        putwreg(dat >> 7);
        if (ascii & 1) putwreg(dat & 0x7f); //*pt++=(char)dat&0x7f;
        //pt=fd;
        // while(i--){
        //    putwreg(*pt++); 
        // }
        putwreg(0);
    }
    void putcmd(char x) {
        LCD_DC_SetLow();
        putwreg(x);
        LCD_DC_SetHigh();
    }
    void WrStr(char *buff) {
        { //
            while (*buff) // while not end-of-string
                WrChar(*buff++); //
        }
    }

    font
    Code:
    #include <xc.h>
    #asm
    PSECT strings,class=CODE,abs,delta=2
    ORG 0x1f00 
    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
    Last edited by richard; - 25th May 2018 at 11:42.
    Warning I'm not a teacher

  5. #5
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    Nice to see an XC8 example excerpt...

    May I ask where I can find information for placing DW data in XC8 at an absolute address, please? I haven't found it so far, nor can I get your example working in a 16F1823 XC8 project...

    I'm also struggling with MCC (Microsoft Code Configurator)...

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    2,696


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    May I ask where I can find information for placing DW data in XC8 at an absolute address
    all my knowledge came from google" xc8 psect" , i have not found a good reference yet
    the xc8 use rguide/manual is severely lacking in that respect

    key elements
    PSECT strings,class=CODE,abs,delta=2
    ORG 0x1f00

    my example uses an asm segment in a c include file, it may be better to place the data in an asm file and include that instead
    because i have terrible trouble getting "labels" to work properly my way. [ still learning]

    mcc is a splendid thing once you get the hang of it, for the chips it supports.
    once i have created the standalone project i use mcc to set the osc and create the main.c and mcc files
    then you can add the pins/hw modules
    Attached Images Attached Images     

  7. #7
    Join Date
    May 2013
    Location
    australia
    Posts
    2,696


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    a saner way is, and let the linker locate the font for you

    font .c file

    Code:
    #include <xc.h>
    #asm
    psect FONT_table,class=CODE,local,delta=2
      GLOBAL _FNT
    _FNT
            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 '&'  '''
       ................
    in main.c

    extern const char FNT;
    int addr=&FNT;


    in wrChar()
    unsigned int dat, inx = addr;
    char i = 5;
    Warning I'm not a teacher

  8. #8
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Nokia lcd include , small footprint to suit pic16's

    Ah... Thank you for the PSECT search term. Got it. I also discovered that I could use a label in the font table and access that address in my code... Very exciting stuff (grin)...

    I still need to double-check and simulate my XC8 version but so far it uses 381 words (141 code + 240 font). I didn't use MCC (Microchip Code Configurator) so it's a single file, about 235 lines, including the font table (see below).

    MCC doesn't seem to support the MSSP module on my 16F1823 so I still need to consult the datasheet before I can implement the SPI driver.

    Cheerful regards, Mike, K8LH

    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
    /************************************************************************/
    Last edited by Mike, K8LH; - 26th May 2018 at 08:42.

Similar Threads

  1. Using Nokia LCD
    By BobP in forum mel PIC BASIC Pro
    Replies: 300
    Last Post: - 3rd May 2018, 05:47
  2. 16F946 pcb footprint (64 tqfp)
    By nomad in forum Schematics
    Replies: 2
    Last Post: - 8th September 2009, 12:14
  3. small 2X16 LCD
    By Ron Marcus in forum Off Topic
    Replies: 2
    Last Post: - 26th October 2007, 21:37
  4. Nokia 3310 LCD
    By barkerben in forum General
    Replies: 3
    Last Post: - 10th December 2005, 20:08
  5. Small LCD module,character
    By Ron Marcus in forum Off Topic
    Replies: 6
    Last Post: - 27th November 2005, 19:13

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts