PDA

View Full Version : Nokia lcd include , small footprint to suit pic16's



richard
- 16th May 2018, 11:06
Entire demo is 872 words ,its less than 1/3 size of other attempts and has same features and a full alpha-numeric font

Ioannis
- 16th May 2018, 15:37
Amazing work Richard.

5*

Ioannis

wjsmarine
- 17th May 2018, 10:10
Well done Richard, Ioannis almost got it right - put a star up against your name and let's call it 6*.

Regards,
Bill

Mike, K8LH
- 18th May 2018, 09:24
I agree... nicely done, Richard. I can't tell you how much I enjoy studying and learning from your code.

I was inspired by how you compressed a 96 character 5x7 font table down to something like 288 words and I spent most of the day implementing something similar on an old 5110 demo program written in C for a 16F1823. With just basic INIT, CMD, DAT, and STR functions, the program now uses less than 500 words of program memory. I'm pretty geeked about it! Thank you...

Take care. Have fun. Cheerful regards, Mike

richard
- 18th May 2018, 09:50
if you really want to geek it up


changing the output routine to use the mssp module shaves another 10% off the code size
and speeds the thing up by a factor of 10x

din and clk need to be on sdo and sck

this

PAUSEUS 150
SHiftOUT LCD_DIN,LCD_CLK,1,[LcdData]

becomes

PIR1.3=0
SSP1BUF = LcdData
WHILE !PIR1.3 : wend


and this is added to init routine

SSP1CON1=$21 ;$22,21,20 all work @32mhz 20 is fastest
SSP1STAT=$40

Mike, K8LH
- 18th May 2018, 15:40
Yes, I already thought about using the SPI module. The current bit-bang driver uses 14 words of memory and runs at ~190-kb/s (with 8-MHz clock). An SPI driver and its init code shouldn't be any bigger. I hope to work on an SPI driver later today. I just need to refresh my memory on the SPI modes. Looks like you're using CKE = 1 and CKP = 0, yes?

8650

Implementing the 'packed' font table and extracting data was surprisingly simple, though I'm coding pretty close to the metal and the results are nothing as agile or elegant as your use of the 'readcode' function. Here's an excerpt, if you're interested;


/************************************************** ******************
* *
************************************************** ******************/
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 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); //
} //

/* *
* 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+0x30); // 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


Thank you again for sharing your work. Mike

wjsmarine
- 19th May 2018, 02:30
Hi Richard,

Just taking a quick look at your Include demo and I can only write 13 characters per line successfully... if 14 then the result is a wrap around and overwriting of the first char. Example below:




looper:
LCDCLR
; LCDSTR 6,0,"-Nokia-Demo-" ; Line 0, position 6.
LCDSTR 0,0,"I wonder what happens if the string is large?" ; = Rubbish on first line and "missing quote" error message.
; LCDSTR 0,0,"I wonder what?" ; = "? wonder what" [14 chars]
LCDSTR 0,0,"I wonder what" ; = "I wonder what" [13 chars only]
LCDC 0,4,"'" ; Line 4, position 0.
LCDC 25,5,"8" ; Line 5, position 25.
PAUSE 1000
GOTO looper


I'll test more later today and let you know if I find anything else needing a tweak. Again, great job.

Regards,
Bill

richard
- 19th May 2018, 03:17
yes probably, but here is a new version with double size chr capability and mssp and font unpacking in asm [like in my ks0108 code]

its not been texted on a pic18 , but its blisteringly fast on the 16f1847, and will fill screen fully

thanks go to blll [wjsmarine] for donation of hardware for this project, enjoy

wjsmarine
- 19th May 2018, 09:56
That's impressive, Richard.

Can you explain how your font table works and how you derived those values in each column please? What limits the size of the table one can create?

I'd like to learn from it and maybe if I can get my head around the process find a way to smooth out the double size characters (particularly 0-9, the degree symbol and C) - I'm guessing you are working your magic to achieve double size by math so it probably means making a larger table to accommodate these.

An indication of smooth characters is shown in the pic attached, made with the previous lookup table style, which consumed 4 normal sized chars' area per big one and 2 lines (as does yours) and also noting the degree C was formed as one big character. Apologies for the blurry image, not helped with the scratchy plastic over the LCD to protect the glass...

Thanks for your patience and help.

Regards,
Bill

richard
- 19th May 2018, 10:36
I replace the _ chr with @ dw 642 , 9266 ,72 in my fonts to get a deg C chr

achieve double size by math so it probably means making a larger table to accommodate these
correct , I know of no realistic way to smooth the result , it has been tried.
table size is only limited by the memory available.
if you create a large font say 14x10 for digits it would not be an unreasonable size, but would need its own routines to unpack and display
if you plot my font on graph paper its pretty obvious how it works, the pic 18 version is easier to disassemble

richard
- 19th May 2018, 11:16
some 8x8 graphpaper
AND an old spread sheet that did the number crunching

Mike, K8LH
- 19th May 2018, 21:15
I used a spreadsheet to convert my old 5 byte per character tables, too. Works a treat...

Cheerful regards, Mike

8669

richard
- 20th May 2018, 01:42
I came up with the same solution , the freely available font creators [like the mikronta one] don't really
convert the font to the most efficient format for pic's when codespace is an issue.
although they can be a good starting point

Mike, K8LH
- 20th May 2018, 09:58
Nice job on the spreadsheet, Richard. I just finished modifying mine to format the packed font table output for either C or asm. Here's a sample;



0x0000, 0x0000, 0x0000, // 32 ' '
0x0000, 0x2F80, 0x0000, // 33 '!'
0x0007, 0x0007, 0x0000, // 34 '"'
0x0A7F, 0x0A7F, 0x0A00, // 35 '#'
0x122A, 0x3FAA, 0x0900, // 36 '$'
0x1193, 0x0464, 0x3100, // 37 '%'
0x1B49, 0x2AA2, 0x2800, // 38 '&'
0x0005, 0x0180, 0x0000, // 39 '''
0x001C, 0x1141, 0x0000, // 40 '('
0x0041, 0x111C, 0x0000, // 41 ')'
0x0A08, 0x1F08, 0x0A00, // 42 '*'
0x0408, 0x1F08, 0x0400, // 43 '+'

dw 0x0000, 0x0000, 0x0000 ; 32 ' '
dw 0x0000, 0x2F80, 0x0000 ; 33 '!'
dw 0x0007, 0x0007, 0x0000 ; 34 '"'
dw 0x0A7F, 0x0A7F, 0x0A00 ; 35 '#'
dw 0x122A, 0x3FAA, 0x0900 ; 36 '$'
dw 0x1193, 0x0464, 0x3100 ; 37 '%'
dw 0x1B49, 0x2AA2, 0x2800 ; 38 '&'
dw 0x0005, 0x0180, 0x0000 ; 39 '''
dw 0x001C, 0x1141, 0x0000 ; 40 '('
dw 0x0041, 0x111C, 0x0000 ; 41 ')'
dw 0x0A08, 0x1F08, 0x0A00 ; 42 '*'
dw 0x0408, 0x1F08, 0x0400 ; 43 '+'

I also decided to render all 96 characters directly from the input table so that I can see at-a-glance which characters might need tweaking...

8670

Mike, K8LH
- 20th May 2018, 19:48
Just finished the font render part of my spreadsheet. It renders directly from the unpacked 5-byte 'input' table. Change a byte in there and you'll see the changes immediately. Mind if I show it off, guys (see below)?

Cheerful regards, Mike, K8LH
8672

Mike, K8LH
- 24th May 2018, 09:20
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

richard
- 24th May 2018, 23:14
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

Mike, K8LH
- 25th May 2018, 02:20
First, here's how I'm packing font pattern data into 2-1/2 words within groups of 5 words;

8679

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


/************************************************** ******************
* *
* 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) //
{ //
} //
} //

richard
- 25th May 2018, 10:33
thanks mike , the concept works nicely

xc8 version (393)+240 words , uses mssp1


#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

#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

Mike, K8LH
- 25th May 2018, 16:38
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)...

richard
- 25th May 2018, 23:30
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

richard
- 26th May 2018, 02:32
a saner way is, and let the linker locate the font for you

font .c file


#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;

wjsmarine
- 26th May 2018, 06:32
Hi Richard,

Well done to you and Mike for continuing the thread, even though what you are documenting is so far above my head I'm dizzy...

If I can jump in here I'd like to bring your attention to an undocumented feature of your Inc file I've just discovered when converting my previous code to run it. For various reasons, but mainly leading zero suppression, I insert a space but with your Inc file I get error messages e.g.



looper:
LCDCLR
bigtxt = 1 ; double size chrs
LCDSTR 0,0,"Noki+12"
LCDSTR 0,2,"345678@"
bigtxt = 0 ; normal size chrs
' LCDSTR 52,3,"Demo"
LCDSTR 0,4,"With@MSSP xfer"
' LCDSTR 0,5,"Dble Size Chrs"
LCDSTR 0,5," " ; this doesn't compile - causes errors and warnings wherever used.
' LCDSTR 0,5,32 ; same result as above (worth a try).
PAUSE 1000
GOTO looper


resulting in
[ASM ERROR] NOKIA_DEMO PPS.ASM (1701) : Illegal character (0)
[ASM WARNING] NOKIA_DEMO PPS.ASM (1701) : Found label after column 1. (LCDSTR?CCC)

When you have the time may I ask for this to be corrected?

Kind regards,
Bill

richard
- 26th May 2018, 06:53
LCDSTR 0,5," "

its a pbp problem

" " is not a String pbp interprets a single chr as a byte , regardless of the quotes . and its not possible to fix it

you can simply use

LCDC " "
or
LCDC 0,5," "

to print a single character


have a look at this
http://support.melabs.com/forum/picb...strtok-usercmd
it has a rightjustify user command in it,


eg to display a 3 digit field

arraywrite buff,[dec h,0]
RJUSTBUFF buff,3
LCDSTR 36,0,BUFF

Mike, K8LH
- 26th May 2018, 07:12
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


/************************************************** **********************
* *
* 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
/************************************************** **********************/

richard
- 26th May 2018, 10:39
mike

mssp is pretty easy


SSP1CON1=0x21 ;$22,21,20 all work @32mhz 20 is fastest
SSP1STAT=0x40
sdo and sck pins set to dig o/p


to transfer data
PIR1.3=0
SSP1BUF = data
WHILE (!PIR1.3) ;

tried your code on 16f1847 ,its not working

Mike, K8LH
- 26th May 2018, 14:27
It seems XC8 is placing my program code on top of my font table in the 0700h area of memory. More detective work (sigh)...

Thanks for the MSSP/SPI info, Richard. I will get to that after tracking down the current problem...

Mike

<added>

If you get a chance, add the "ovrld" param' to the following line and tell me if that fixes the problem, please?


PSECT myFonts, class=CODE, abs, ovrld, space=0, delta=2
^^^^^

richard
- 26th May 2018, 15:47
ovrld,

does not fix it
even local too

there is more wrong than just that , the putwreg function is getting called six times for the wrchar
and only 5 times for the entire putstr call
its a total bitch to debug with all that inline asm , the debugger just
goes stupid

putcmd looks fine on the logic analyser , it all goes pear shaped from then on

Mike, K8LH
- 26th May 2018, 18:01
Sorry, Richard (and gang). A bug at the very top of the putchar() routine was messing up the font table address. And yes, I know assembler is a PITA... I wish I could get a gratis copy of PBP...

Corrected version attached (375 words total). I still need to dig out my old Nokia 5110 display and test this on real hardware. I also have a tiny 128x32 I2C OLED display and a tiny 128x64 SPI OLED display to play with sometime soon.

Cheerful regards, Mike

8684

richard
- 26th May 2018, 23:09
putstr still not working

I think it should look like this, but it only works for the first call
so I get "Re and then garbage


void putstr(const char *str) // put 'ROM' strings
{ //
while(*str)
wrchar(*str++);
} //

richard
- 27th May 2018, 02:08
more oddly

strcpy(buff,"eady");


putstr(buff);

works with my modified routine


putstr("eady");
crashes the show

richard
- 27th May 2018, 02:25
void wrchar(char d) //
{
volatile char ascii=d;

fixed it, compiler optimised ascii var out

Mike, K8LH
- 27th May 2018, 02:31
Yes, your putstr() routine is better...

While debugging I've found XC8 is using the same memory location for local variables in both the wrchar() and putstr() functions. The wrchar@ascii variable is using 70h and the putstr@str pointer is using 70h and 71h. Is this a result of my heavy use of assembly code? That is, XC8 doesn't realize those local variables need to be unique? How do I get XC8 to use unique memory locations for those local variables?

richard
- 27th May 2018, 02:39
make them static

richard
- 27th May 2018, 03:57
I think I prefer my take on this
since:-
the font is automatically located
the pin/hw defines are in mcc ,therefore its simple to port to any chip that can read its own flash
its easy to debug
bigtext and inverted text are easily implemented
its only 100 or so words bigger



/**

Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2
Device : PIC16F1847
Driver Version : 2.00
* font.c included via ide source files
*/
#include "mcc_generated_files/mcc.h"
void putwreg(char work);
void putcmd(char x);
void WrChar(char );
void WrStr(const char *);
extern const char FNT;
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 d) { // for packed 2.5 word 5x7 font
uint16_t tmp, inx = (uint16_t) & FNT;
char fd[6], j = 0, k = 3, *pt;
inx += ((uint16_t) (d - 32)*5) >> 1;
while (k--) {
tmp = FLASH_ReadWord(inx++);
fd[j + 1] = tmp & 0x7f;
tmp <<= 1;
fd[j] = tmp >> 8;
j += 2;
}
pt = fd;
if ((d & 1))pt++;
k = 5;
// with font now stored in bufer fd its easy to have large and/or inverted text
while (k--) {
putwreg(*pt++);
}
putwreg(0);
}
void putcmd(char x) {
LCD_DC_SetLow();
putwreg(x);
LCD_DC_SetHigh();
}
void WrStr(const char *buff) {
{ //
while (*buff)
WrChar(*buff++); //
}
}


font.c

#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 '&' '''
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

richard
- 27th May 2018, 04:04
tried a pbp version for the 5 byte compressed packed font, the unpacking done without asm
takes more code space than the compressing saves :frown:

inc file

'************************************************* ***************
'* Name : NOKIA_ds5.INC *
'* Author : richard *
'* Notice : *
'* : *
'* Date : 26/05/2018 *
'* Version : 1.0b mssp1 version bigtxt *
'* Notes : inverse text mike 5 byte font version *
'* :FOR pic 16/18 NOKIA LCD *
'************************************************* ***************

goto overglcd
;################################################# #################
; adjust these definitions to suit and place in main prg

'#DEFINE PIC16 1 ;IF PIC18 NOT USED
'#define use_mssp 1 ;if mssp used DON'T FORGET to set sdo and sck pins as o/p's
' lcdheight con 5 ; 6 PAGES
' lcdwidth con 84 ; 84 PIXELS WIDE
;--------------ONLY IF MSSP NOT USED---------------
' LCD_CLK var Portb.4 ' Clock
' LCD_DIN var Portb.2 ' Data
;-----------------------------------------
' LCD_RST var PortA.4
' LCD_DC var PortA.3
' LCD_CE var LATA.6
' LCD_LIGHT var PortA.0
;################################################# #################
USERCOMMAND "LCDC" ;X,Y,CHR 0 < X < 84 , 0 < Y < 7 31 < CHR > 127
USERCOMMAND "LCDCLR" ;clear LCD
USERCOMMAND "LCDSTR" ;STRING @ X,Y or Constant String
USERCOMMAND "LCDCMD" ;cmd BYTE TO LCD
USERCOMMAND "LCDDAT" ;DATA BYTE TO LCD

ASM
;----[const String]---------------------------------------------------------------
LCDSTR?CCS macro Xin ,Yin,Cin
IFNDEF TBLPTRL
local TheString, OverStr ; define local labels so you can call macro multiple times
goto OverStr ; goto over string stored in FLASH, so processor can't execute that
TheString ;label to get address of your string
da Cin, 0 ;add string to flash at TheString address and end string with 0
OverStr
MOVE?CW TheString, _glcd_bigaddress
MOVE?CB Xin , _POSX
MOVE?CB Yin , _POSY
L?CALL _GlcdUnpackStr
ELSE
local TheString, OverStr ; define local labels so you can call macro multiple times
goto OverStr ; goto over string stored in FLASH, so processor can't execute that
TheString ;label to get address of your string
data Cin, 0 ;add string to flash at TheString address and end string with 0
OverStr
movlw UPPER TheString
movwf TBLPTRU
movlw HIGH TheString
movwf TBLPTRH
movlw LOW TheString
movwf TBLPTRL
MOVE?CB Xin , _POSX
MOVE?CB Yin , _POSY
L?CALL GLCD_Cstr_out
ENDIF
endm

;----------------------Strings------------------------------------
LCDSTR?CBB macro Xin ,Yin ,Bin
MOVE?CB Xin , _POSX
MOVE?BB Yin , _POSY
MOVE?CB high Bin, FSR1H ;load highbyte
MOVE?CB low Bin, FSR1L ;load low byte
L?CALL GLCD_str_out
endm
LCDSTR?CCB macro Xin ,Yin ,Bin
MOVE?CB Xin , _POSX
MOVE?CB Yin ,_POSY
MOVE?CB high (Bin), FSR1H ;load highbyte
MOVE?CB low (Bin), FSR1L ;load low byte
L?CALL GLCD_str_out
endm
LCDSTR?BBB macro Xin ,Yin ,Bin
MOVE?B Xin, _POSX
MOVE?B Yin, _POSY
MOVE?CB high Bin, FSR1H ;load highbyte
MOVE?CB low Bin, FSR1L ;load low byte
L?CALL GLCD_str_out
endm
LCDSTR?WBB macro Xin ,Yin ,Bin
MOVE?WB Xin, _POSX
MOVE?BB Yin, _POSY
MOVE?CB high Bin, FSR1H ;load highbyte
MOVE?CB low Bin, FSR1L ;load low byte
L?CALL GLCD_str_out
endm
LCDSTR?WWB macro Xin ,Yin ,Bin
MOVE?WB Xin, _POSX
MOVE?WB Yin, _POSY
MOVE?CB high Bin, FSR1H ;load highbyte
MOVE?CB low Bin, FSR1L ;load low byte
L?CALL GLCD_str_out
endm


LCDCMD?C macro Cin
MOVE?CT 0,_LCD_DC
MOVE?CB Cin , _lcdData
L?CALL _lcd_byte
endm
LCDCMD?B macro Cin
MOVE?CT 0,_LCD_DC
MOVE?BB Cin , _lcdData
L?CALL _lcd_byte
endm
LCDCMD?W macro Cin
MOVE?CT 0,_LCD_DC
MOVE?WB Cin , _lcdData
L?CALL _lcd_byte
endm


LCDDAT?C macro Cin
MOVE?CT 1,_LCD_DC
MOVE?CB Cin , _lcdData
L?CALL _lcd_byte
endm
LCDDAT?B macro Cin
MOVE?CT 1,_LCD_DC
MOVE?BB Cin , _lcdData
L?CALL _lcd_byte
endm
LCDDAT?W macro Cin
MOVE?CT 1,_LCD_DC
MOVE?WB Cin , _lcdData
L?CALL _lcd_byte
endm

LCDCLR? macro
L?CALL _lcd_clr
endm



;----------------------Character @ X,Y ------------------------------------
LCDC?BBB macro Xin ,Yin , Bin
MOVE?BB Xin, _POSX
MOVE?BB Yin, _POSY
MOVE?BB Bin, _glcdCh
L?CALL _gcga
endm
LCDC?WBB macro Xin ,Yin , Bin
MOVE?WB Xin, _POSX
MOVE?BB Yin, _POSY
MOVE?BB Bin, _glcdCh
L?CALL _gcga
endm
LCDC?WWB macro Xin ,Yin , Bin
MOVE?WB Xin, _POSX
MOVE?WB Yin, _POSY
MOVE?BB Bin, _glcdCh
L?CALL _gcga
endm

LCDC?BBC macro Xin ,Yin , Cin
MOVE?BB Xin, _POSX
MOVE?BB Yin, _POSY
MOVE?CB Cin ,_glcdCh
L?CALL _gcga
endm
LCDC?WBC macro Xin ,Yin , Cin
MOVE?WB Xin, _POSX
MOVE?BB Yin, _POSY
MOVE?CB Cin ,_glcdCh
L?CALL _gcga
endm
LCDC?CCC macro Xin ,Yin ,Cin
MOVE?CB Xin , _POSX
MOVE?CB Yin, _POSY
MOVE?CB Cin, _glcdCh
L?CALL _gcga
endm
LCDC?CCB macro Xin ,Yin ,Bin
MOVE?CB Xin , _POSX
MOVE?CB Yin, _POSY
MOVE?BB Bin, _glcdCh
L?CALL _gcga
endm
LCDC?B macro Bin
MOVE?BB Bin, _glcdCh
L?CALL _gcga
endm



GLetAddress macro Label, Wout
CHK?RP Wout
movlw low Label ; get low byte
movwf Wout
movlw High Label ; get high byte
movwf Wout + 1
BANKSEL 0
endm
IFDEF TBLPTRL
GLCD_Cstr_out
tblrd *+
movf TABLAT,w
bz GLCD_exit_Cstr_out ; EXIT ON Null char
CHK?RP _glcdCh
MOVWF _glcdCh
CHK?RP _glcd_bigaddress
movff TBLPTRU,_glcd_bigaddress
movff TBLPTRH,_glcd_bigaddress+1
movff TBLPTRL,_glcd_bigaddress+2
L?CALL _gcga
CHK?RP _glcd_bigaddress
movff _glcd_bigaddress ,TBLPTRU
movff _glcd_bigaddress+1 ,TBLPTRH
movff _glcd_bigaddress+2 ,TBLPTRL
bra GLCD_Cstr_out
GLCD_exit_Cstr_out
BANKSEL 0
return



GLCD_str_out
movf POSTINC1, W ; Get a character
bz GLCD_exit_strout ; EXIT ON Null char
CHK?RP _glcdCh
MOVWF _glcdCh
BANKSEL 0
L?CALL _gcga
bra GLCD_str_out
GLCD_exit_strout
BANKSEL 0
return
ELSE
GLCD_str_out
IFDEF BSR
MOVIW FSR1++ ; Get a character
BTFSC STATUS,Z
BRA GLCD_exit_strout ; EXIT ON Null char
ELSE
movf INDF, W ; Get a character
BTFSC STATUS,Z
GOTO GLCD_exit_strout ; EXIT ON Null char
INCF FSR,F
ENDIF
CHK?RP _glcdCh
MOVWF _glcdCh
MOVE?BB FSR1L,_glcd_bigaddress
MOVE?BB FSR1H,_glcd_bigaddress+1
BANKSEL 0
L?CALL _gcga
MOVE?BB _glcd_bigaddress,FSR1L
MOVE?BB _glcd_bigaddress+1,FSR1H
GOTO GLCD_str_out
GLCD_exit_strout
BANKSEL 0
return
ENDIF
endasm

glcd_bigaddress VAR BYTE[3]
glcdCh var byte 'chr DATA
lcdData VAR byte 'DATA
glcdDC VAR BYTE 'gca var
glcdFont var word 'font address
glcdOffset VAR word 'font offset
dsfbuff var byte[26]
ctemp1 var word
gl var byte
glcdBc var byte
POSY var byte 'gca pg address
gy_ var byte 'gca pg address
POSX var byte 'gca row address
gx_ var byte 'gca row address
ctemp var word
glcdStrAddr var word ext
bigtxt var bit
inverted var bit
@glcdStrAddr = _glcd_bigaddress



GlcdUnpackStr:
readcode glcdStrAddr,CTEMP
glcd_bigaddress[2] = CTEMP&$7f
ctemp=ctemp<<1
glcdCh = CTEMP.HIGHBYTE
glcdStrAddr=glcdStrAddr+1
if glcdCh then
gosub gcga
glcdCh = glcd_bigaddress[2]
else
return
endif
if glcdCh then
gosub gcga
else
return
endif
goto GlcdUnpackStr:
return

lcd_init:
@ GLetAddress _font7x5,_glcdFont
bigtxt = 0
inverted =0
#ifdef use_mssp
SSP1CON1=$21 ;$22,21,20 all work @32mhz 20 is fastest
SSP1STAT=$40
#endif
LCD_CE=1
pause 30
Lcd_RST = 0 ' Reset LCD (HW reset)
pause 1
Lcd_RST = 1 ' Release Reset
' lcd_dc=0
LCDCMD $21 ' LCD EXTENDED COMMANDS
LCDCMD $c8 ' SET LCD Vop (CONTRAST) initial value $C8 = 200.
LCDCMD $06 ' SET TEMP COEFFICIENT
LCDCMD $13 ' LCD BIAS MODE
LCDCMD $20 ' LCD STANDARD COMMANDS
LCDCMD $08 ' LCD blank
LCDCMD $0c ' LCD IN NORMAL MODE
return

lcd_clr: ' clear
FOR gy_ =0 TO 5
FOR GX_=0 TO 83
LCDDAT 0
NEXT
NEXT
return


lcd_byte: 'send command sequence "glcdData "
LCD_CE=0
#ifdef use_mssp
PIR1.3=0
SSP1BUF = LcdData
WHILE !PIR1.3 : wend
#else
PAUSEUS 150
SHiftOUT LCD_DIN,LCD_CLK,1,[LcdData]
#endif
LCD_CE=1
return



LCDxy: ;set LCD XY
POSY = POSY MIN lcdheight
POSX = POSX MIN lcdwidth
LCDCMD POSY|$40
LCDCMD POSX|$80
return



gcga: ;unpack font from flash and display it
#ifdef PIC16
glcdOffset = (glcdch-32)*5/2 + glcdFont ; point to cga data
#ELSE
glcdOffset = (glcdch-32)*6 + glcdFont ; point to cga data
#ENDIF
gosub LCDxy
#ifdef PIC16
' ; COMMENT OUT THIS ASM SECTION IF CHIP HAS NO EEDAT REG
' ASM
' MOVE?CB high _dsfbuff, FSR1H ;load highbyte
' MOVE?CB low _dsfbuff, FSR1L ;load low byte
' MOVE?WW _glcdOffset,EEADRL
' MOVE?CB 3,_glcdDC
'nxtf
' BANKSEL EECON1
' BSF EECON1, EEPGD ;Point to PROGRAM memory
' BSF EECON1, RD ;EE Read
' NOP
' NOP
' RLF EEDAT, W
' RLF EEDATH, W
' MOVE?AB _glcdBc
' BANKSEL EEDAT
' BCF EEDAT,7
' MOVF EEDAT,W
' MOVWI FSR1++
' MOVE?BA _glcdBc
' MOVWI FSR1++
' BANKSEL EEADRL
' incf EEADRL,F
' btfsc STATUS,Z
' incf EEADRH,F
' BANKSEL _glcdDC
' DECFSZ _glcdDC,F ;dec count
' GOTO nxtf
' BANKSEL 0
' ENDASM
; UNCOMMENT IF CHIP HAS NO EEDAT REG
glcdBc=0
gosub getflash
if !glcdch.0 then
dsfbuff[glcdBc] = CTEMP.HIGHBYTE
glcdBc=glcdBc+1
endif
dsfbuff[glcdBc] = glcdDC
glcdBc=glcdBc+1
gosub getflash
dsfbuff[glcdBc] = CTEMP.HIGHBYTE
glcdBc=glcdBc+1
dsfbuff[glcdBc] = glcdDC
glcdBc=glcdBc+1
gosub getflash
dsfbuff[glcdBc] = CTEMP.HIGHBYTE
if glcdch.0 then
glcdBc=glcdBc+1
dsfbuff[glcdBc] = glcdDC
endif
dsfbuff[5] = 0
#else
for glcddc = 0 to 2
dsfbuff[glcddc*2] = CTEMP
dsfbuff[glcddc*2+1] = CTEMP.HIGHBYTE
glcdOffset = glcdOffset + 2
NEXT
#endif
if inverted then
for glcddc = 5 to 0 STEP -1
dsfbuff[glcddc]=~dsfbuff[glcddc]
next
endif
if bigtxt then ;create a big chr from a small one
DSFBUFF[24] = POSX
DSFBUFF[25] = POSy
for glcddc = 5 to 0 STEP -1
ctemp = 0
ctemp1 = 3
gL = dsfbuff[glcddc]
for glcdBc = 0 to 7
IF GL & 1 THEN ctemp = ctemp|ctemp1
ctemp1 = ctemp1<<2
GL = GL>>1
NEXT
gL = glcddc*2
dsfbuff[GL] =ctemp.LOWBYTE
dsfbuff[GL+1] =ctemp.LOWBYTE
dsfbuff[GL+12]=ctemp.HIGHBYTE
dsfbuff[GL+13]=ctemp.HIGHBYTE
NEXT
for glcddc = 0 to 11
LCDDAT dsfbuff[GLCDDC]
NEXT
POSY=POSY+1
POSX=DSFBUFF[24]
gosub LCDxy
for glcddc = 12 to 23
LCDDAT dsfbuff[GLCDDC]
NEXT
POSx = POSX + 12
IF POSX > 72 THEN POSX=0 ;wrap
posy=DSFBUFF[25]
else
for glcddc = 0 to 5
LCDDAT dsfbuff[GLCDDC]
NEXT
POSx = POSX + 6
IF POSX > 78 THEN POSX=0 ;wrap
endif
RETURN

getflash:
readcode glcdOffset,CTEMP
glcdDC= CTEMP&$7f
ctemp = ctemp << 1
glcdOffset = glcdOffset + 1
return
overglcd :






demo file

'************************************************* ***************
'* Name : NOKIA_DEMO.PBP *
'* Author : richard *
'* Notice : *
'* : *
'* Date : 16/5/2018 *
'* Version : mssp1 version with bigtxt ,inverse txt *
'* Notes : used mikes compressed packed 5 byte font *
'* :FOR pic 16F1847@32MHZ NOKIA *
'************************************************* ***************
#CONFIG ; 16FF1847.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG
define OSC 32


; --- *** Oscillator *** ---------------------------------------------------
OSCCON = %11110000 ;32 MHz,
ANSELb = 0
ANSELA = 0
TRISA=%10010000
TRISB=%11101011


;DEFINES FOR DISPLAY use font7x5_16.bas or font7x5_18.bas for pic18
#DEFINE PIC16 1
#define use_mssp 1
lcdheight con 5 ; 6 PAGES
lcdwidth con 83 ; 84 PIXELS WIDE
' LCD_CLK var LATB.4 ' SCK1 pin needs to be set as dig o/p
' LCD_DIN var LATB.2 ' SDO1 pin needs to be set as dig o/p
LCD_RST var LATA.4
LCD_DC var LATA.3
LCD_CE var LATA.6
LCD_LIGHT var LATA.0



BUFF VAR BYTE [16]
char VAR BYTE
Include "nokia_ds5.inc" ' bring it in
include "font7x5_16_5.bas"

'========================== MAIN Routine ==============================
gosub lcd_init
LCDCLR
ARRAYWRITE BUFF,["READY",0]
inverted=1
LCDSTR 5,2,BUFF
PAUSE 1000
LCDCLR
inverted=0
bigtxt = 1
LCDSTR 5,2,BUFF
PAUSE 1000
LCDCLR

bigtxt = 0
posx=0
posy=0
gosub LCDxy
char=32
looper:
lcdc char
while posx
char=char+1
if char>127 then char=32
lcdc char
PAUSE 100
wend
posy=posy+1
if posy>5 then
posy=0
gosub LCDxy
PAUSE 1000
endif

GOTO LOOPER

'

END


font

'************************************************* ***************
'* Name : font7x5_16_5.BAS *
'* Author : mike *
'* Notice : *
'* : *
'* Date : *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
goto overfont
font7x5: ;14BIT PACKED FORMAT [2X7BITS] CHR32-126 [SP TO ~ ]
asm
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
overfont:

Mike, K8LH
- 27th May 2018, 04:37
I think I prefer my take on this ...
A great example. Thank you.


tried a pbp version for the 5 byte compressed packed font, the unpacking done without asm
takes more code space than the compressing saves ...
That's a shame but it was worth a try.

Thank you very much for the pointers and help. It's been a fun experiment and I've learned a lot.

Cheerful regards, Mike

richard
- 27th May 2018, 04:44
Thank you very much for the pointers and help. It's been a fun experiment and I've learned a lot.

ditto
and I finally figured out what I was doing wrong with asm psect labels

richard
- 27th May 2018, 04:49
whats next
a ttf
a double size font for digits (0 to 9 +- : )

wjsmarine
- 27th May 2018, 09:24
Hi Richard,

Thanks for the fix on the single char problem, it works well but I've found another problem...

When I add DT Ints the big characters don't work, I tried with and without using mssp but same result.

Also there's something strange taking place with the led backlight insomuch as I need to sprinkle port pin enable code immediately following any lcd write (with or without DT Ints). I tried changing LCD_LIGHT from A.0 to A.1 (while leaving it connected to A.0) with no difference - does the Inc file employ any commands for the light?

Here's the edited code:



#CONFIG ; 16F1847.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG

@ ERRORLEVEL -306 ; turn off crossing page boundary message

; --- *** Oscillator *** ---------------------------------------------------
define OSC 32
OSCCON = %11110000 ; 32 MHz,
ANSELA = 0 ; all digital
ANSELB = 0 ; all digital
TRISA=%00000000
'TRISB=%00000000
TRISB=%11101011 ; Encoder inputs on B5-7

ch var byte
BUFF VAR BYTE [10]

;DEFINES FOR DISPLAY use font7x5_16.bas or font7x5_18.bas for pic18
#DEFINE PIC16 1
#define use_mssp 1 ; much faster and less words (1027 vs 1106).
lcdheight con 5 ; 6 PAGES
lcdwidth con 83 ; 84 PIXELS WIDE
LCD_RST var LATA.4
LCD_DC var LATA.3
LCD_CE var LATA.6
LCD_LIGHT var LATA.0
LCD_CLK var LATB.4 ' SCK1 pin needs to be set as dig o/p
LCD_DIN var LATB.2 ' SDO1 pin needs to be set as dig o/p
;--------------ONLY IF MSSP NOT USED---------------
' LCD_CLK var Portb.4 ' Clock
' LCD_DIN var Portb.2 ' Data

Include "Modedefs.bas"
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP type interrupts
Include "nokia_ds.INC" ' bring it in
include "font7x5_16.bas"
'include "font7x5_16 edit degC.BAS" ; use @ to access degC symbol.

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Rot_Encoder, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE IOC_INT ; Port Change Interrupt

'========================== MAIN Routine ==============================
gosub lcd_init
LCDCLR
ARRAYWRITE BUFF,["READY",0]
LCDSTR 5,0,BUFF
PortA.0 = 0 ' turn on backlight.
PAUSE 1000
LCDCLR
PAUSE 1000
looper:
LCDCLR
PortA.0 = 0 ' turn on backlight.
bigtxt = 1 ; double size chrs
LCDSTR 0,0,"Noki+12"
LCDSTR 0,2,"345678@"
bigtxt = 0 ; normal size chrs
' LCDSTR 52,3,"Demo"
' LCDSTR 0,4,"With@MSSP xfer"
LCDSTR 0,4,"Hi"
PortA.0 = 0 ' turn on backlight.
' LCDSTR 0,5,"Dble Size Chrs"
' LCDSTR 0,5," " ; this doesn't compile - causes errors and warnings wherever used.
LCDC 0,5,"a" ; use LCDC for single chars.
PortA.0 = 0 ' turn on backlight.
PAUSE 1000
GOTO looper

Rot_Encoder:
' if PortB.7 = 0 then ' Check if Encoder pushbutton was pushed.
' ButtPush = 1 ' Set the flag for a quick exit.
' Old_Bits = New_Bits ' Equalize the disturbance the pushbutton caused.
@ INT_RETURN ; Exit accordingly.
' endif

END


Is the Inc file compatible with DT Ints?

Regards,
Bill

richard
- 27th May 2018, 12:15
works perfectly if done correctly the include's order may matter, ioc int needs to configured
if your programmer is still connected to portb.7 that can load things up a bit [I leave mine connected and avoid using b6,b7 pins]
never use portx.x to set or clear pins , its just asking for rmw problems especially with fast fosc settings
always use latx.x when available or use a shadow register





#CONFIG ; 16F1847.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG
@ ERRORLEVEL -306 ; turn off crossing page boundary message

; --- *** Oscillator *** ---------------------------------------------------
define OSC 32
OSCCON = %11110000 ; 32 MHz,
ANSELA = 0 ; all digital
ANSELB = 0 ; all digital
TRISA=%10010000
'TRISB=%00000000
TRISB=%11101011 ; Encoder inputs on B5-3
IOCBN = %00101000 ;enable ioc falling edge b3,b5
ch var byte
BUFF VAR BYTE [10]
;DEFINES FOR DISPLAY use font7x5_16.bas or font7x5_18.bas for pic18
#DEFINE PIC16 1
#define use_mssp 1 ; much faster and less words (1027 vs 1106).
lcdheight con 5 ; 6 PAGES
lcdwidth con 83 ; 84 PIXELS WIDE
LCD_RST var LATA.4
LCD_DC var LATA.3
LCD_CE var LATA.6
LCD_LIGHT var LATA.0
;LCD_CLK var LATB.4 ' SCK1 pin needs to be set as dig o/p
;LCD_DIN var LATB.2 ' SDO1 pin needs to be set as dig o/p
;--------------ONLY IF MSSP NOT USED---------------
'
Include "nokia_ds.INC" ' bring it in
include "font7x5_16.bas"
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP type interrupts
'
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Rot_Encoder, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE IOC_INT ; Port Change Interrupt
'========================== MAIN Routine ==============================
gosub lcd_init
LCDCLR
ARRAYWRITE BUFF,["READY",0]
LCDSTR 5,0,BUFF
LCD_LIGHT = 0 ' turn on backlight.
PAUSE 1000
LCDCLR
PAUSE 1000
looper:
LCDCLR

bigtxt = 1 ; double size chrs
LCDSTR 0,0,"Noki+12"
LCDSTR 0,2,"345678@"
bigtxt = 0 ; normal size chrs
' LCDSTR 52,3,"Demo"
' LCDSTR 0,4,"With@MSSP xfer"
LCDSTR 0,4,"Hi"

' LCDSTR 0,5,"Dble Size Chrs"
' LCDSTR 0,5," " ; this doesn't compile - causes errors and warnings wherever used.
LCDC 0,5,"a" ; use LCDC for single chars.

PAUSE 1000
GOTO looper
Rot_Encoder:
if IOCBF.3 then LCD_LIGHT = 0 ' Check if button was pushed.
if IOCBF.5 then LCD_LIGHT = 1
IOCBF=0
@ INT_RETURN ; Exit accordingly.
' endif
END

richard
- 27th May 2018, 12:21
include order does not seem to matter [as I hoped]
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP type interrupts
Include "nokia_ds.INC" ' bring it in
include "font7x5_16.bas"
works fine

richard
- 28th May 2018, 04:50
a version with fonts of user defined size

this has a 14x10 font for two char 0,1 ie 2 rows 10 columns


fonts now have a header added to define rows/columns first chr and last chr

eg



#asm
psect FONT_table,class=CODE,local,delta=2
GLOBAL _FNT
_FNT
DW 0X0501, 0X207F //1 ROW 5 COL CHR 32-127
DW 0x0000, 0x0000, 0x0000, 0x005F, 0x0000 // 32 ' ' '!'
DW 0x0007, 0x0007, 0x0014, 0x3F94, 0x3F94 // 34 '"' '#'
DW 0x122A, 0x3FAA, 0x0923, 0x0988, 0x3262 // 36 '$' '%'
...............................




/**

Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2
Device : PIC16F1847
Driver Version : 2.00
* font.c included via ide source files
*/
#include "mcc_generated_files/mcc.h"
void putwreg(char work);
void putcmd(char x);
void WrChar(char );
void WrStr(const char *);
void set_fnt(const char *);
extern const char FNT,NUM;
uint16_t fnt_addr;
char fnt_row,fnt_col,fnt_fc,fnt_lc,POSX,POSY;
void main(void) {
// initialize the device
SYSTEM_Initialize();
set_fnt(&FNT);

/* *
* 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
POSX=32;
POSY=2;
WrChar('R'); // write ascii character
WrStr("eady");

set_fnt(&NUM);
putcmd(0x80 + 0x10); // set DDRAM X address, 0..83
putcmd(0x40 + 0x04); // set DDRAM Y address, 0..5
POSX=16;
POSY=5;
WrChar('0'); // write ascii character
WrChar('1'); // write ascii character

while (1) {
}
}
/**
End of File
*/
void set_fnt(const char *F){
uint16_t tmp;
fnt_addr=(uint16_t)F&0x1fff;
tmp=FLASH_ReadWord(fnt_addr++);
fnt_row = (char)tmp;
fnt_col = tmp>>8;
tmp=FLASH_ReadWord(fnt_addr++);
fnt_lc = (char)tmp;
fnt_fc = tmp>>8;
}

void putwreg(char work) // send byte, msb first (15 words)
{
LCD_CE_LAT = 0; // spi enable on
SPI1_Exchange8bit(work);
LCD_CE_LAT = 1; // spi enable off
} //
void WrChar(char d) { // for packed 2.5 word 5x7 font
uint16_t tmp, inx = fnt_addr;
char fd[32], i = fnt_row, j = 0, k, *pt;
if ((d < fnt_fc) || (d > fnt_lc))return;
inx += ((d - fnt_fc) * fnt_col*fnt_row) >> 1;
while (i--) {
k = fnt_col >> 1;
if (k == 2)k++;
while (k--) {
tmp = FLASH_ReadWord(inx++);
if (!i)
fd[j + 1] = ((char)tmp & 0x7f) ;//<< 1
else
fd[j + 1] = ((tmp & 0x7f)<<1)&0xfe;
tmp <<= 1;
if (!i)
fd[j] = (tmp >> 8)& 0x7f;
else
fd[j] = (tmp >> 7)& 0xfe;;
j += 2;

}
}
pt = fd;
if ((d & 1)&&(fnt_col == 5))pt++;
i = fnt_row;
while (i--) {
k = fnt_col;
putcmd(0x40 +POSY-i);
if(!i){
putcmd(0x80 +POSX);

}
// with font now stored in bufer fd its easy to have large and/or inverted text
while (k--) {
putwreg(*pt++);
}
putwreg(0);
}

POSX+=fnt_col+1;
}
void putcmd(char x) {
LCD_DC_SetLow();
putwreg(x);
LCD_DC_SetHigh();
}
void WrStr(const char *buff) {
{ //
while (*buff)
WrChar(*buff++); //
}
}
#asm
psect nums_table,class=CODE,local,delta=2
_NUM
DW 0X0A02, 0X3031 //2 ROW 10 COL CHR 0,1
DW 15998, 899 ,8691, 15775 ,16252 // chr 0x30 " 0 "
DW 4031, 15486, 14307, 12400, 8095
DW 0, 518, 16383, 0, 0 // chr 0x31 " 1 "
DW 64 ,8288 ,16383 ,12352, 8192

richard
- 28th May 2018, 05:06
some pics of the big fnt

Mike, K8LH
- 28th May 2018, 18:26
Nice work, Richard. This stuff is addicting...

I worked through my problems with XC8 and have put aside the "minimal overhead" 5x7 project for now (stopping at 370 words total). Now I'm lookin' at bigger fonts, too, and a driver that can use an hpos (0..83) and vpos (0..47) starting point for drawing characters.

I looked at someone's 11x16 font (below left) but I don't like it as much as a 10x14 font from Noritake-Itron (below right). I think I'd like to use the Noritake font as a starting point and reduce the character size slightly to allow for descenders on a few select lower case characters.

Take care... Have fun... Regards, Mike

Ioannis
- 28th May 2018, 20:28
some pics of the big fnt

May I ask for that magic excel file please?

Ioannis

richard
- 29th May 2018, 00:02
May I ask for that magic excel file please?

all the magic is done with conditional formatting , a 1 in a field turns it black ,an empty field is blank
make sure no field is greater than 1 or the math is incorrect

complete number font

wjsmarine
- 29th May 2018, 09:33
Great work Richard, I hope Mike has success also we can learn from.

Speaking of... will there be a PBP version arriving anytime soon? Knowing zero languages other than PBP (and I'm still an infant here) I marvel at what you experts can achieve and am quite envious :)

Kind regards,
Bill

PS
no time at present to test your reply to my last problem, hopefully the weekend will allow.

richard
- 29th May 2018, 11:54
will there be a PBP version arriving anytime soon?
don't hold your breath , since pbp has no pointer variable type its a bit tedious to code


and a driver that can use an hpos (0..83) and vpos (0..47) starting point for drawing characters.

maybe ART will grace us with some of his framebuffer code , I think a 504 byte buffer is not out of the question on a 16f1847

richard
- 30th May 2018, 06:02
latest iteration
frame buffer, bitmap graphics, left/right scrolling, text at any x,y offset

Ioannis
- 30th May 2018, 10:51
all the magic is done with conditional formatting , a 1 in a field turns it black ,an empty field is blank
make sure no field is greater than 1 or the math is incorrect

complete number font

Great! Never thought of that!

Thanks Richard.
Ioannis

Mike, K8LH
- 31st May 2018, 02:27
Nice work, Richard. Bravo!

I finally imported that Noritake 10x14 Font into Excel today. It took a bit of work. The Noritake Font file was 1920 separate "retlw 0x00" type lines. Not an ideal format for importing into Excel so I wrote a quick JustBASIC program to generate 96 lines with 10 comma separated words per line. After importing that file into Excel I discovered that Noritake maps the b15 bit to row 0 with the b0 bit all the way down at row 15 so I modified my JustBASIC program to exchange the bit order and finally got the Font into Excel. Whew!

8700


'
' Noritake 10x14 Font Table Converter 30-May-2018, Mike McLaren
'
' Reads the 1920 line one-hex-byte-at-a-time Noritake Font file and
' reformats it as 96 lines (one line per character), 10-words-per-line,
' reversed bit order (row 0 = bit 0), and as CSV text for Excel import.
' Does not alter the source file.
'
' Instructions
'
' 1 - select the Noritake 10x14 text file from the File Dialog
' 2 - output text displayed in console window
' 3 - select text and copy to clipboard using <ctrl-C> or <edit> <copy>
' 4 - paste into your spreadsheet (use text import tool)
'
' JustBASIC v1.01
'

filedialog "Source File?", "*.txt", fileName$ '
output$ = "hex" ' select "dec" or "hex"
if fileName$ <> "" then '
open fileName$ for input as #f '
while eof(#f) > -1 '
for asciichar = 32 to 127 ' 96 characters (32..127)
for n = 1 to 10 ' 10 words per line
'
' read in an MSB and an LSB line (' retlw 0x00') and turn them into
' a single decimal or hexidecimal word ('0x0000' or '00000') with a comma
' delimiter for CSV (comma separated value) import into Excel.
'
line input #f, aLine$: line input #f, bLine$ '
'
' reverse bit order... Noritake uses row 0 = b15 but we want row 0 = b0
'
dec = hexdec(aLine$+right$(bLine$,2)) ' convert hex to decimal
dec = xcgbits(dec) ' exchange bit order
'
if (output$ = "dec") then ' if "dec" output
if (dec < 10000) then print " "; ' print "dec" value
if (dec < 1000) then print " "; ' "
if (dec < 100) then print " "; ' "
if (dec < 10) then print " "; ' "
print dec; ' "
else ' else
print "0x"; ' print "hex" value
print dechex$(dec); ' "
end if '
print ", "; ' print separator
if (n = 10) then ' if last word in line
if (asciichar < 100) then print " "; ' print ascii, 32..127
print asciichar;: print " "; ' "
print "'";:print chr$(asciichar);: print "'" ' print ascii character
end if '

next n
next asciichar ' next character line
print '
wend
close #f
end if

end

'
' Converts hexadecimal number (string) to decimal number.
' Processes the hex number from right to left, so any hex notation is allowed.
' Examples: &hFF = 0xFF = FF
'
function hexdec(HexString$)
Hex$ = "0123456789ABCDEF"
power = 0
hexdec = 0

for i = len(HexString$) to 1 step -1
HexDigit$ = upper$(mid$(HexString$, i, 1))
'
' exit at first non-hexadecimal digit
'
if instr(Hex$, HexDigit$) = 0 then exit for
hexdec = hexdec + ((instr(Hex$, HexDigit$) - 1) * (16^power))
power = power + 1
next
end function

'
' convert decimal number to 4-digit hexidecimal string
'
function dechex$(DecValue)
Hex$ = "0123456789ABCDEF"
dechex$ = ""
for power = 3 to 0 step -1
digitndx = int(DecValue/16^power)
DecValue = DecValue - digitndx*16^power
dechex$ = dechex$ + mid$(Hex$,digitndx+1,1)
next power
end function

'
' exchange bit order b15<>b0, b14<>b1, b13<>b2, ...
'
function xcgbits(decval)
xcgbits = 0
newpwr = 0
for power = 15 to 0 step -1
if (decval >= 2^power) then
decval = decval - 2^power
xcgbits = xcgbits + 2^newpwr
end if
newpwr = newpwr + 1
next power
end function


If you need it, here's the converted "decimal" version of the Noritake 10x14 Font in CSV format for Excel;


0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32 ' '
0, 0, 0, 0, 13311, 13311, 0, 0, 0, 0, 33 '!'
0, 0, 15, 15, 0, 0, 15, 15, 0, 0, 34 '"'
816, 816, 16383, 16383, 816, 816, 16383, 16383, 816, 816, 35 '#'
1584, 3704, 3324, 3276, 16383, 16383, 3276, 4044, 1948, 792, 36 '$'
6, 12303, 15375, 3846, 960, 240, 6204, 15375, 15363, 6144, 37 '%'
3900, 8190, 14531, 12771, 13299, 14139, 7710, 3084, 16128, 13056, 38 '&'
0, 0, 0, 34, 55, 31, 14, 0, 0, 0, 39 '''
0, 0, 1008, 4092, 7710, 6150, 12291, 12291, 0, 0, 40 '('
0, 0, 12291, 12291, 6150, 7710, 4092, 1008, 0, 0, 41 ')'
1584, 1904, 992, 448, 8188, 8188, 448, 992, 1904, 1584, 42 '*'
192, 192, 192, 192, 4092, 4092, 192, 192, 192, 192, 43 '+'
8704, 14080, 7936, 3584, 0, 0, 0, 0, 0, 0, 44 ','
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 45 '-'
6144, 15360, 15360, 6144, 0, 0, 0, 0, 0, 0, 46 '.'
0, 12288, 15360, 3840, 960, 240, 60, 15, 3, 0, 47 '/'
4092, 8190, 16135, 13187, 12739, 12515, 12403, 14399, 8190, 4092, 48 '0'
0, 0, 12300, 12302, 16383, 16383, 12288, 12288, 0, 0, 49 '1'
12300, 14350, 15367, 15875, 14083, 13187, 12739, 12519, 12414, 12348, 50 '2'
3084, 7182, 14343, 12291, 12291, 12483, 12483, 14535, 8190, 3900, 51 '3'
960, 992, 880, 824, 796, 782, 16383, 16383, 768, 768, 52 '4'
3135, 7231, 14387, 12339, 12339, 12339, 12339, 14451, 8163, 4035, 53 '5'
4092, 8190, 14535, 12483, 12483, 12483, 12483, 14791, 8078, 3852, 54 '6'
3, 3, 3, 3, 16323, 16355, 115, 59, 31, 15, 55 '7'
3900, 8190, 14823, 12483, 12483, 12483, 12483, 14823, 8190, 3900, 56 '8'
60, 126, 12519, 12483, 14531, 7363, 3779, 2023, 1022, 508, 57 '9'
0, 0, 0, 1560, 3900, 3900, 1560, 0, 0, 0, 58 ':'
0, 0, 0, 8728, 14140, 7996, 3608, 0, 0, 0, 59 ';'
0, 192, 480, 1008, 1848, 3612, 7182, 14343, 12291, 0, 60 '<'
816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 61 '='
0, 12291, 14343, 7182, 3612, 1848, 1008, 480, 192, 0, 62 '>'
12, 14, 7, 3, 14211, 14275, 195, 103, 126, 60, 63 '?'
3852, 8078, 14791, 12483, 16323, 16323, 12291, 14343, 8190, 4092, 64 '@'
16380, 16382, 775, 771, 771, 771, 771, 775, 16382, 16380, 65 'A'
16383, 16383, 12483, 12483, 12483, 12483, 12483, 14823, 8190, 3900, 66 'B'
4092, 8190, 14343, 12291, 12291, 12291, 12291, 14343, 7182, 3084, 67 'C'
16383, 16383, 12291, 12291, 12291, 12291, 12291, 14343, 8190, 4092, 68 'D'
16383, 16383, 12483, 12483, 12483, 12483, 12483, 12483, 12291, 12291, 69 'E'
16383, 16383, 195, 195, 195, 195, 195, 195, 3, 3, 70 'F'
4092, 8190, 14343, 12291, 12291, 12483, 12483, 14535, 8142, 4044, 71 'G'
16383, 16383, 192, 192, 192, 192, 192, 192, 16383, 16383, 72 'H'
0, 0, 12291, 12291, 16383, 16383, 12291, 12291, 0, 0, 73 'I'
3072, 7168, 14339, 12291, 12291, 14339, 8191, 4095, 3, 3, 74 'J'
16383, 16383, 480, 480, 1008, 1848, 3612, 7182, 14343, 12291, 75 'K'
16383, 16383, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 76 'L'
16383, 16383, 14, 28, 248, 248, 28, 14, 16383, 16383, 77 'M'
16383, 16383, 56, 112, 224, 448, 896, 1792, 16383, 16383, 78 'N'
4092, 8190, 14343, 12291, 12291, 12291, 12291, 14343, 8190, 4092, 79 'O'
16383, 16383, 195, 195, 195, 195, 195, 231, 126, 60, 80 'P'
4092, 8190, 14343, 12291, 13059, 14083, 15875, 7175, 16382, 14332, 81 'Q'
16383, 16383, 195, 451, 451, 963, 963, 3815, 15486, 14396, 82 'R'
6204, 14462, 12519, 12483, 12483, 12483, 12483, 14787, 8071, 3846, 83 'S'
3, 3, 3, 3, 16383, 16383, 3, 3, 3, 3, 84 'T'
4095, 8191, 14336, 12288, 12288, 12288, 12288, 14336, 8191, 4095, 85 'U'
1023, 2047, 3584, 7168, 14336, 14336, 7168, 3584, 2047, 1023, 86 'V'
4095, 8191, 14336, 15360, 7936, 7936, 15360, 14336, 8191, 4095, 87 'W'
15375, 15903, 1848, 1008, 480, 480, 1008, 1848, 15903, 15375, 88 'X'
63, 127, 224, 448, 16256, 16256, 448, 224, 127, 63, 89 'Y'
15363, 15875, 14083, 13187, 12739, 12515, 12403, 12347, 12319, 12303, 90 'Z'
0, 0, 16383, 16383, 12291, 12291, 12291, 0, 0, 0, 91 '['
12, 12, 48, 48, 192, 192, 768, 768, 3072, 3072, 92 '\'
0, 0, 12291, 12291, 12291, 16383, 16383, 0, 0, 0, 93 ']'
48, 56, 28, 14, 7, 7, 14, 28, 56, 48, 94 '^'
12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 95 '_'
0, 0, 3, 7, 14, 28, 24, 0, 0, 0, 96 '`'
3072, 7776, 16240, 13104, 13104, 13104, 13104, 13168, 16352, 8128, 97 'a'
16383, 16383, 12480, 12480, 12480, 12480, 12480, 14784, 8064, 3840, 98 'b'
4032, 8160, 14448, 12336, 12336, 12336, 12336, 14448, 7392, 3264, 99 'c'
3840, 8064, 14784, 12480, 12480, 12480, 12480, 12480, 16383, 16383, 100 'd'
4032, 8160, 15216, 13104, 13104, 13104, 13104, 15216, 7136, 2496, 101 'e'
0, 192, 16380, 16382, 199, 199, 14, 12, 0, 0, 102 'f'
6336, 14816, 13296, 13104, 13104, 13104, 13104, 15152, 8176, 4064, 103 'g'
16383, 16383, 192, 192, 192, 192, 448, 16256, 16128, 0, 104 'h'
0, 0, 0, 0, 16344, 16344, 0, 0, 0, 0, 105 'i'
0, 3072, 7168, 14336, 12288, 12288, 14336, 8179, 4083, 0, 106 'j'
0, 16383, 16383, 1792, 1920, 4032, 7392, 14448, 12336, 0, 107 'k'
0, 0, 12291, 12291, 16383, 16383, 12288, 12288, 0, 0, 108 'l'
16368, 16368, 112, 224, 960, 960, 224, 112, 16368, 16368, 109 'm'
16368, 16368, 192, 224, 112, 48, 48, 112, 16352, 16320, 110 'n'
4032, 8160, 14448, 12336, 12336, 12336, 12336, 14448, 8160, 4032, 111 'o'
16368, 16368, 816, 816, 816, 816, 816, 1008, 480, 192, 112 'p'
192, 480, 1008, 816, 816, 816, 816, 816, 16368, 16368, 113 'q'
16368, 16368, 448, 224, 112, 48, 48, 112, 224, 192, 114 'r'
6336, 14816, 13296, 13104, 13104, 13104, 13104, 16176, 7792, 3168, 115 's'
0, 48, 48, 4095, 8191, 14384, 14384, 7216, 3120, 0, 116 't'
4080, 8176, 14336, 12288, 12288, 12288, 12288, 14336, 8176, 4080, 117 'u'
1008, 2032, 3584, 7168, 14336, 14336, 7168, 3584, 2032, 1008, 118 'v'
4080, 8176, 14336, 14336, 7936, 7936, 14336, 14336, 8176, 4080, 119 'w'
12336, 14448, 7392, 4032, 1920, 1920, 4032, 7392, 14448, 12336, 120 'x'
48, 112, 12512, 14784, 8064, 3968, 448, 224, 112, 48, 121 'y'
12336, 14384, 15408, 15920, 14128, 13232, 12784, 12528, 12400, 12336, 122 'z'
0, 192, 480, 4092, 7998, 14343, 12291, 12291, 12291, 0, 123 '{'
12480, 12480, 16380, 16382, 12487, 12483, 12291, 12295, 12302, 12300, 124 '|'
0, 12291, 12291, 12291, 14343, 7998, 4092, 480, 192, 0, 125 '}'
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 126 '~'
16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 127 ''

Mike, K8LH
- 31st May 2018, 04:39
Richard, here's something fun... Someone over on the MrExcel forum helped me with a VBA macro that allows you to toggle the value in a cell within your 10x16 matrix between "null" and "1" by simply clicking on it. The attached file is your spreadsheet with macros enabled (xlsm rather than xlsx file extension). I'm not sure if you have to enable "developer" mode in Excel or not, but give it a try...

Cheerful regards, Mike


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Modified 5/30/18 9:50 PM EDT
If Not Intersect(Target, Range("B30:K45")) Is Nothing Then
If Target.Cells.CountLarge > 1 Then Exit Sub
If Target.Value = "1" Then
Target.Value = ""
Else
Target.Value = "1"
End If
Range("b28").Select
End If
End Sub

richard
- 31st May 2018, 06:47
thanks mike , its just whats needed and works perfectlty

Mike, K8LH
- 1st June 2018, 14:17
Ok, I'm almost ready to play with real hardware. I located my old 5110 display and an old 5110 test board that I had started to assemble (below). It looks like I need to solder a few wires onto the 8-pin 5110 connector. Maybe I can get this up-n'-runnin' this weekend...

Are you running the PIC and 5110 display at 3.3 volts, Richard?

richard
- 1st June 2018, 14:39
Are you running the PIC and 5110 display at 3.3 volts,

yes the contrast won't accommodate 5v for me.
I still have a bug in the bitmap routine, but my eldest son is getting married tomorrow so I have to play
happy families

Mike, K8LH
- 2nd June 2018, 00:17
Congratulations, Richard. Have fun tomorrow...

richard
- 3rd June 2018, 01:58
bug free {hopefully} version, with a few new functions [circle,rectangle,lines]

wjsmarine
- 10th June 2018, 09:58
Hi Richard,

I finally found some time to try your suggestions as shown in post #41 - it does not work for me.

Copying and pasting your code, I had no display until changing TRISA from %10010000 to all outputs and even then no big characters were seen until DTints and associated parts were commented out. Order of Includes made no difference.

There's still a problem with the backlighting as well because it initially is dim then changes to a short duration pulse of bright background coincident with each LCDCLR command. No difference whether displaying big characters or not wrt these bright flashes. When I add LCD_LIGHT = 1 in the mix I have no text displayed.

Any suggestions where I should go to from here?

Thanks and regards,
Bill

richard
- 10th June 2018, 10:54
I finally found some time to try your suggestions as shown in post #41 - it does not work for me
Any suggestions where I should go to from here?

my code as posted works perfectly for me , so I'm not sure what the problem is.

if you post your latest code attempt and refresh my memory on how its connected I will have a look.

richard
- 11th June 2018, 08:18
I had no display until changing TRISA from %10010000 to all outputs
correct I failed to make the LCD_RST pin an output , all the "LCD" pins need to be digital outputs.
my code did not work after a power cycle , the disp was keeping its config from previous code so resets never happened
it all looked good while the power was still applied.



When I add LCD_LIGHT = 1 in the mix I have no text displayed.


LCD_LIGHT = 1 is backlight off. LCD_LIGHT = 0 is backlight on
if it does anything else then check your wiring , or it may be a power problem

richard
- 11th June 2018, 10:34
found a problem , the init subroutine needs to pause a bit after the rst pulse otherwise display may not initialise properly


lcd_init:
@ GLetAddress _font7x5,_glcdFont
bigtxt = 0
inverted =0
#ifdef use_mssp
SSP1CON1=$21 ;$22,21,20 all work @32mhz 20 is fastest
SSP1STAT=$40
#endif
LCD_CE=1
pause 30
Lcd_RST = 0 ' Reset LCD (HW reset)
pause 1
Lcd_RST = 1 ' Release Reset
pause 1 ;add this pause
' lcd_dc=0
LCDCMD $21 ' LCD EXTENDED COMMANDS
LCDCMD $c8 ' SET LCD Vop (CONTRAST) initial value $C8 = 200.
LCDCMD $06 ' SET TEMP COEFFICIENT
LCDCMD $13 ' LCD BIAS MODE
LCDCMD $20 ' LCD STANDARD COMMANDS
LCDCMD $08 ' LCD blank
LCDCMD $0c ' LCD IN NORMAL MODE
return

richard
- 12th June 2018, 04:12
turns out that testing the bit vars "inverted" and "bigtext" was not always working after the asm section in gcga subroutine .this only shows up when some vars are pushed out of bank 0 .I can not establish the failure mechanism ,seems i'm just guessing what "CHK?RP" AND "RST?RP" macros actually do . I can't find their definitions anywhere . making the vars into bytes and manually setting correct bank fix the issue.
here is a more complex demo and an amended nokia include file to test and overcome this issue

wjsmarine
- 16th June 2018, 08:25
Hi Richard,

I have compile errors with your new code, NB I've renamed them to NOKIA_DEMO#6 to avoid confusion with previous versions:
[ERROR] nokia_demo#6.pbp (184) : Syntax error
[ERROR] nokia_demo#6.pbp (195) : Syntax error
[ERROR] nokia_demo#6.pbp (195) : Redefiniton of LABEL RJUSTBUFF

which is:


RJUSTBUFF buff,4 ;http://support.melabs.com/forum/picbasic-pro-compiler-3-0-and-later/usercommand/983-strtok-usercmd
RJUSTBUFF buff,2 ;http://support.melabs.com/forum/picbasic-pro-compiler-3-0-and-later/usercommand/983-strtok-usercmd


What have I missed?

Regards,
Bill

richard
- 16th June 2018, 08:45
What have I missed?

you can't use my RJUSTBUFF user command unless you include the file that defines it .

it can be found at the link in the comment ,its included with the strtok code


http://support.melabs.com/forum/picbasic-pro-compiler-3-0-and-later/usercommand/983-strtok-usercmd

wjsmarine
- 17th June 2018, 03:19
Hi Richard,

Excellent work, thank you. I found my problem - the "strtok.pbpmod" Inc file I used was the older version, somehow I missed the update further down the page on that link.

All works well, now I need to get my head around how you've performed the magic and modify the code to suit my layout and various pages of information shown on the Nokia display.

Once again many thanks for the help, you are indeed an asset to the forum.

Cheers,
Bill

richard
- 17th June 2018, 04:05
somehow I missed the update further down the page on that link.

because I forgot to post it :o

Mike, K8LH
- 2nd July 2018, 04:37
Richard & gang... Just wanted to mention that my prototype board for the 5110 display works great and my "minimal" XC8 demo program ended up using 370 words of memory, including 240 words for the packed 5x7 font table.

Also just got my little 128x32 SSD1306 I2C OLED display running with a 16F1823. Man, these OLED displays are really nice. A "bare bones" XC8 program + packed 5x7 font table uses 485 words of memory so a bit more 'overhead' for the low-level SSD1306 controller and I2C functions. However, the 2-pin interface more than makes up for the extra code (grin). Not sure how useful a 5x7 font will be on these little displays...

Cheerful regards, Mike

87288729

richard
- 2nd July 2018, 10:23
well done mike
have you tried your code on a pic18 yet ?
I have come unstuck , can't stop xc8 either overwriting my font , or saying it won't fit or just deciding not to include it at all .
wasted days on this . there must be a how to use psect manual somewhere

Mike, K8LH
- 2nd July 2018, 15:27
Is this a problem with PIC18 only, Richard? I haven't tried using a PSECT on PIC18, yet...

richard
- 2nd July 2018, 23:49
I'm working with a 18f25k22 and getting much grief getting a PSECT to work as intended .
I could store the font as const unsigned int font [][3] { {0,0,0},{……}} but it would be nice to have an include that can be used in either
pic16 or pic18 chips

Mike, K8LH
- 3rd July 2018, 23:52
Hi Richard.

I threw a couple PSECT tables into an XC8 program for an 18F14K22 and when I look at the .LST file it seems XC8 is avoiding those tables just as it should.


/************************************************** **********************
* Digits '0' thru '9' of a 10x14 font *
************************************************** **********************/
#asm
PSECT my10x14, class=CODE, abs, ovrld, space=0, delta=2
ORG 0x3E00
Font10x14:
dw 0x0FFC, 0x1FFE, 0x3F07, 0x3383, 0x31C3, 0x30E3, 0x3073, 0x383F, 0x1FFE, 0x0FFC ; 48 '0'
dw 0x0000, 0x0000, 0x300C, 0x300E, 0x3FFF, 0x3FFF, 0x3000, 0x3000, 0x0000, 0x0000 ; 49 '1'
dw 0x300C, 0x380E, 0x3C07, 0x3E03, 0x3703, 0x3383, 0x31C3, 0x30E7, 0x307E, 0x303C ; 50 '2'
dw 0x0C0C, 0x1C0E, 0x3807, 0x3003, 0x3003, 0x30C3, 0x30C3, 0x38C7, 0x1FFE, 0x0F3C ; 51 '3'
dw 0x03C0, 0x03E0, 0x0370, 0x0338, 0x031C, 0x030E, 0x3FFF, 0x3FFF, 0x0300, 0x0300 ; 52 '4'
dw 0x0C3F, 0x1C3F, 0x3833, 0x3033, 0x3033, 0x3033, 0x3033, 0x3873, 0x1FE3, 0x0FC3 ; 53 '5'
dw 0x0FFC, 0x1FFE, 0x38C7, 0x30C3, 0x30C3, 0x30C3, 0x30C3, 0x39C7, 0x1F8E, 0x0F0C ; 54 '6'
dw 0x0003, 0x0003, 0x0003, 0x0003, 0x3FC3, 0x3FE3, 0x0073, 0x003B, 0x001F, 0x000F ; 55 '7'
dw 0x0F3C, 0x1FFE, 0x39E7, 0x30C3, 0x30C3, 0x30C3, 0x30C3, 0x39E7, 0x1FFE, 0x0F3C ; 56 '8'
dw 0x003C, 0x007E, 0x30E7, 0x30C3, 0x38C3, 0x1CC3, 0x0EC3, 0x07E7, 0x03FE, 0x01FC ; 57 '9'
#endasm

/************************************************** **********************
* Packed 96 character 5x7 Font, 2.5-words-per-character, 240 words *
************************************************** **********************/
#asm
PSECT myFonts, class=CODE, abs, ovrld, space=0, delta=2
ORG 0x3F00
Font5x7:

richard
- 4th July 2018, 00:26
extract from .lst , it all looks good yet the font is not there.


114 psect text
115 3E00 org 15872 ;#
116 3E00
117 ;#
118 3E00 0501 207F dw 1281,8319 ;#
119 3E02 0000 0000 0000 005F 0000 dw 0,0,0,95,0 ;#
120 3E07 0007 0007 0014 3F94 3F94 dw 7,7,20,16276,16276 ;#
121 3E0C 122A 3FAA 0923 0988 3262 dw 4650,16298,2339,2440,12898 ;#
122 3E11 1B49 2AA2 2800 0283 0000 dw 6985,10914,10240,643,0 ;#
123 3E16 001C 1141 0000 20A2 0E00 dw 28,4417,0,8354,3584 ;#
124 3E1B 0A08 1F08 0A08 043E 0408 dw 2568,7944,2568,1086,1032 ;#
125 3E20 0050 1800 0008 0408 0408 dw 80,6144,8,1032,1032 ;#
126 3E25 0060 3000 0020 0808 0202 dw 96,12288,32,2056,514 ;#

Mike, K8LH
- 4th July 2018, 06:21
That's wierd. The tables show up in the LST file and in the HEX file but not in the Program Memory window...

Ok, section 6.2.9.3.4 in the XC8 User's Guide describes the PSECT "delta" parameter and as soon as I changed the parameters from "delta=2" to "delta=1" my two font tables showed up in the Program Memory window and my TBLPTR test code started working correctly in the simulator... Whew!

richard
- 4th July 2018, 07:50
test code started working correctly in the simulator... Whew!

I agree , you would think writing word sized data would need delta=2.

my brain hurts but it solves the problem , thanks mike

Mike, K8LH
- 4th July 2018, 15:18
You're very welcome, Sir. And thank you for all the help and hard work you've provided.

BTW, I'm liking this 128x32 I2C SSD1306 OLED display a lot... With built-in RAM for a 128x64 display, you can basically have two display screens. You can write data to one screen while displaying the other then toggle the display screen. Should make easy work for cursor characters, flashing colon characters for a clock, or displaying "odometer" type sliding numbers.

astanapane
- 27th August 2020, 10:34
This thread is being here for couple of years.

Thanks those guys which spent their time for this really nice work.

I'm trying to find a way to combine this low cost nokia lcd display to heart rate monitor project with MAX30102.

Has anyone tried the code with PIC18F?

I tried the first demo code and it looks like is working.

Then i tried the code given in #36 , (Richard shared once again) and i cant make it work. It was late at night and i tired enouph to check if i have set everything as required.

I will give it a go today again.

If there is a new version for pic18f's will be nice if anyone could share it.

Many thanks in advance.

richard
- 27th August 2020, 13:00
looks like i made a later version , did not try it with a pic18 but the code is written to use either 16's or 18's
pic18 probably needs the pic18 version of the font

astanapane
- 27th August 2020, 15:55
Hi Richard,

thanks for the updated files.

I have tried the new inc and got the following errors. (used PIC18f46k22)

Is there a way i could fix those?

8935

astanapane
- 27th August 2020, 17:32
Does it matter that SFR are commented in the pic18f46k22 pbpinc?

8936

astanapane
- 27th August 2020, 17:33
post is duplicated....

richard
- 28th August 2020, 00:39
Does it matter that SFR are commented in the pic18f46k22 pbpinc?
no

I have tried the new inc and got the following errors. (used PIC18f46k22)


Is there a way i could fix those?


if configured correctly you won't get errors

richard
- 28th August 2020, 11:56
IT needed a tweak to work for a 18f26k22

astanapane
- 28th August 2020, 16:10
Richard thanks,

tested and confirmed that is working.

I have tested only the small font 7x5_18 as text.

I'm trying to figure out how to display a variable.

astanapane
- 29th August 2020, 09:07
tested with big fonts as well.

it is really easy to use it like that.

Richard is there a way to print variables other than text?

richard
- 29th August 2020, 09:20
doesn't the demo show that with the contrast and backlight stuff ?
what have you tried ?

astanapane
- 29th August 2020, 09:57
I havent tried the demo. Just download the txt.

As far as i understant it is using the command

ARRAYWRITE BUFF [dec C,0]
LCDSTR x,y, buff


i tried and it worked.

a = 1
b = 2
c = a+b

richard
- 29th August 2020, 10:06
have you read the pbp manual and understood the syntax for
Output Modifiers for Formatting Strings using arraywrite ?

its all there

astanapane
- 29th August 2020, 10:10
Hi Richard,

my fault, yes i have read the arraywrite - arrayread command and corrected the code in my previous edited message.

Many thanks.

astanapane
- 4th September 2020, 10:16
i have a question regarding the library and the code for the nokia 3310.

for the following code:




ARRAYWRITE speed [dec var1,dec2 var2,0]
LCDSTR x,y, buff



VAR1 is a byte and VAR2 is a byte as well. Those two numbers are presenting the Speed in format VAR1,VAR2 (where VAR1 can be any number from 0 to infinity, and VAR2 can be any number from 0 to 99)

In case that the VAR1 gets the variable from 0 to =<255 the it can be used as a byte.

My problem is that i need this floating number for ex. speed = 50,86 to get it as an integer speed = 5086. May i have your help please?

If i set speed (VAR1 VAR2) as word then the following command


LCDSTR x,y, speed

does not accept word.

Could you please help me to get the speed as an integer and read it as it is.

For my program i'm testing:


if speed is > 5086 then limit ; 50,86

thanks once again.

richard
- 4th September 2020, 10:41
i will start here

My problem is that i need this floating number for ex. speed = 50,86 to get it as an integer speed = 5086. May i have your help please?

you do it exactly the same way as for a lcd display



buff var byte[6] ; 4dig+dp+null
speed var word
ARRAYWRITE buff,[dec2 speed/100,".",dec2 speed//100 ,0]
LCDSTR x,y, buff



LCDSTR x,y, speed
does not accept word.

correct lcdstr str buffer var ,const str

from the inc file

;################################################# #################
USERCOMMAND "LCDC" ;X,Y,CHR 0 < X < 84 , 0 < Y < 7 , 31 < CHR > 127
USERCOMMAND "LCDCLR" ;clear LCD
USERCOMMAND "LCDSTR" ;STRING @ X,Y or Constant String
USERCOMMAND "LCDCMD" ;cmd BYTE TO LCD
USERCOMMAND "LCDDAT" ;DATA BYTE TO LCD



i might preempt the next question
leading zero's and right justifying fields

http://support.melabs.com/forum/picbasic-pro-compiler-3-0-and-later/usercommand/983-strtok-usercmd

astanapane
- 4th September 2020, 11:00
im not in front of the circuit and computer in order to test it.

i havent done it as it following /100 and //100 (remainder)



buff var byte[6] ; 4dig+dp+nullspeed
var word
ARRAYWRITE buff,[dec2 speed/100,"."dec2 speed//100 ,0]
LCDSTR x,y, buff


I have used it with "." like the following in the loop and i get it right on the LCD as 50,86 for example. :

I need on the screen the right "floating" value.




ARRAYWRITE speed [dec var1,".",dec2 var2,0]
LCDSTR x,y, speed



then i send the code to sub label

speedlimit:
and i havent used "."

i sent the command like:

ARRAYWRITE speed [dec var1,dec2 var2,0]

having that it was not possible to use speed as word.

richard
- 4th September 2020, 11:10
i sent the command like:
Code:
ARRAYWRITE speed [dec var1,dec2 var2,0]
having that it was not possible to use speed as word.


makes no sense to me

ARRAYWRITE speed

speed must be an existing chr array big enough to contain the text generated plus a null terminator
a word var could hold only 1 chr safely ,since pbp checks nothing anything could get clobbered by misuse like that

astanapane
- 4th September 2020, 11:17
now it makes sense why i was getting some messy chr on the screen like that.

astanapane
- 4th September 2020, 16:27
i've tried the following but didnt work.


rbuf var byte
wbuf var word



checkt:
arraywrite RBUF,[DEC2 speed1/100,DEC2 speed2//100,0] ; for example speed1 = 56 and speed2 is 85
LCDSTR 0,2, RBUF ; ----------> this gives 0085
wbuf = rbuf
if wBUF > 5685 then
gosub limit
return

then i tried:


checkt:
arraywrite RBUF,[DEC speed1,DEC2 speed2//100,0] ; for example speed1 = 56 and speed2 is 85
LCDSTR 0,2, RBUF ; ----------> this gives 5685 which is what i want....BUT!!!! when i try to check if wbuf > than 5685, it doesnt work
wbuf = rbuf
if wBUF > 5685 then ' IF THE TEMPC IS GREATER THAN 37 C THEN LIGHT UP THE BLUE LED
high lata.0
ELSE
low lata.0
endif
return

how is it possible to combine those two speed1 and speed2 vars in one var? and check then the result as an integer number?

Dave
- 4th September 2020, 16:54
You have only declared "rbuf var byte" It is being used as a pointer as far as I can see. It will be NO LARGER than 255.

astanapane
- 4th September 2020, 18:20
Hi dave,

i solved it.

i used the rbuf as var word

Then i didnt add the commands for


arraywrite rbuf,[dec speed1,dec2 speed2,0]

i used the above command only to combine it with the following and present the number to the lcd.

So the solutions for me is:


checkt:
RBUF = (SPEED1*100) + SPEED2
IF RBUF > 5682 THEN ; THIS IS JUST AN EXAMPLE
GOSUB LIMIT
RETURN

Thanks a lot for the help all of you.

astanapane
- 4th September 2020, 18:56
additional missing line from the previous message



arraywrite rbuf,[dec speed1,dec2 speed2,0]
i used the above command only to combine it with the following and present the number to the lcd.


LCDSTR x,y, rbuf

in any case the solution is to use the rbuf as word, multiply by 100 the speed1 and add speed2.

richard
- 5th September 2020, 01:08
i solved it.


i used the rbuf as var word




has not solved it at all , you cannot safely use arraywrite rbuf,[dec speed1,dec2 speed2,0] with a word var as the destination
the destination for the text chrs generated by arraywrite must be an existing chr array big enough to contain the text generated plus a null terminator
not doing so will lead to enormous problems

secondy to expect the result of arraywrite to be usable as a number is absurd , its a textual chr string

astanapane
- 5th September 2020, 20:41
there is a missandestanding. my fault because i consfused you by using the same name for the variable SBUF and RBUF in the previous posts.

vars.....

SBUF var byte
RBUF var word

Program in the main loop includes the command:


arraywrite SBUF, [dec speed1, dec2 speed2,0] ;

then there is a checkSpeed LABEL

checkSpeed:


RBUF = (speed1*100) + speed2
if RBUF > 5687 then; just an example
gosub limit
endif
return

And that is what it works for me. It is under testing for a day now, and havent seen any strange behaviour.

thanks.

richard
- 6th September 2020, 00:41
SBUF var byte


sadly still woefully incorrect.
that reserves 1 byte , you need at least 5 bytes

astanapane
- 6th September 2020, 07:24
sadly still woefully incorrect.
that reserves 1 byte , you need at least 5 bytes

Do you mean something like that?


SBUF var BYTE[6]

it is already configured.

richard
- 6th September 2020, 08:14
well done!
you have proved yet again that code snippets are generally useless time wasters..
this time with the nice added touch of posting snippets that bear no semblance to
the code actually employed. a touch of genius . not


don't know why i bother

astanapane
- 6th September 2020, 11:41
Thanks for any help.

please try to be gentle. Life is small and there are lots of good people out there.

Have a nice day.

astanapane
- 10th September 2020, 07:59
Good day to all.

I have two questions. One is related to this amazing library shared by Richard and the other one is related to a small project i have.

1. May i add a picture to nokia LCD via the usercommand LCDDAT?

For image data could i use the GLCD from Miktoelektronics?


;################################################# #################
USERCOMMAND "LCDC" ;X,Y,CHR 0 < X < 84 , 0 < Y < 7 31 < CHR > 127
USERCOMMAND "LCDCLR" ;clear LCD
USERCOMMAND "LCDSTR" ;STRING @ X,Y or Constant String
USERCOMMAND "LCDCMD" ;cmd BYTE TO LCD
USERCOMMAND "LCDDAT" ;DATA BYTE TO LCD

2. Im working with some speed values. So range can be from 0 to infinity.

How could i catch/retreive the highest value from a Variable? Is there any specific way - path to do that?

thanks.

Ioannis
- 10th September 2020, 08:15
Can you define infinity please?

Your variables can be: bit (0-1), bytes (0-255), word (0-65535) and long (-2147483648 to 2147483647)

Ioannis

astanapane
- 10th September 2020, 08:29
Can you define infinity please?

Your variables can be: bit (0-1), bytes (0-255), word (0-65535) and long (-2147483648 to 2147483647)

Ioannis

Hi Ioanni, thanks for the reply.

Speed is not going to exceed any value more than a logical speed targeting to a bicycle or a car. In that case as i understand we could use "word" variable.

But there is no specific value as a limit. It can be any possible number that a variable may have.

thanks in advance.

Ioannis
- 10th September 2020, 09:12
Maybe the MAX operator can do what you want.

Your check loop can be something like this:

max_value = old_speed MAX speed

old_speed = max_value

But this will lead eventually to a top value on max_value and you may have to reset this value. Don't know what you try to accomplish but a periodic reset may be needed.

Ioannis

astanapane
- 10th September 2020, 09:33
Thanks Ioanni,

i will try the MAX operator.

What i'm trying to export is the maximum speed value of a single run.

As i'm not in my home computer right now i will try your advice later today.

Many thanks.

richard
- 10th September 2020, 13:13
For image data could i use the GLCD from Miktoelektronics?

i did look at the array generated by Mikroelektronics glcd bitmap generator and
it seems i rejected it for that generated by lcdassistant, cannot recall why.
none of my posted examples use mokroe files . they would all need a bit of
work to leverage into pbp anyway



1. May i add a picture to nokia LCD via the usercommand LCDDAT?

the LCDDAT sends 1 byte to the lcd @ the current cursor posn
it would not be the most efficient way to upload an image.
i saw no way to read pixel data back from the display so i decided that the only way to
create a decent bitmapped image function was using a frame buffer. this i have implemented
in the c version as posted.
implementing this function in pbb is not something i'm willing to invest the time into

Ioannis
- 10th September 2020, 13:30
I know 3310 LCD is the cheapest graphic LCD one can buy, but the effort to display something is too much relative to the result (B/W bitmap).

Next best solution is the Nextion 2.4" at about 15 euros, 65536 colors, 4MB memory, 320*240 and touch with RS232 control.

No MCU load to control the display and feedback with touch (no hardware buttons etc).

Richard did an exceptional job on 3310 but is it worth anymore with the cheap smart displays?

Ioannis