for pic16 with spi port . 5 digits 6x5 numeric font right justified with leading zero suppression
for pic16 with spi port . 5 digits 6x5 numeric font right justified with leading zero suppression
Warning I'm not a teacher
A bit late but just noticed this valuable post! Thanks once again.
Is this driver for such a display?
looks the same
Warning I'm not a teacher
Since I have on hand only 16F1827, I modified the code for the PortC pins but as expected does not work. Modifications in red.
I really do not know what lata.5 does in your code. Maybe a led to sign start?
IoannisCode:'**************************************************************** '* Name : max7219 16f1825 * '* Author : richard * '* Notice : Copyright (c) 2019 * '* : * '* Date : 25/2/2020 * '* Version : 1.1 * '* Notes : max7219 5 6x5 chrs on 4 8x8 panels * '* : right justified leading zero suppression * '* : * '* : * '* : modified for pic16f1827 * '******************************************************************* #CONFIG __config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF __config _CONFIG2, _PLLEN_ON & _LVP_OFF #ENDCONFIG define OSC 32 goto overasm asm GetAddress macro Label, Wout CHK?RP Wout movlw low Label ; get low byte movwf Wout movlw High Label ; get high byte movwf Wout + 1 endm endasm overasm: SSPCON1 = $20; SSPSTAT = $40; ANSELA = 0 ANSELB = 0 OSCCON = $70 tmp var byte dsp var byte dspbuff var byte[32] BUFF var byte[16] cnt var byte row var byte drow var byte srow var byte col var byte dcol var byte aFont var word fOffset var word cga var byte cgah var byte ch var byte chr var byte inx var byte mask var word counter var word bcnt var byte ncnt var byte number var word clear 'mxld var portc.1 'mxck var portc.0 'mxdi var portc.2 mxld var portb.1 mxck var portb.4 mxdi var porta.6 'trisc = %11111000 'trisa = %11011110 trisb = 0 trisa = 0 init: lata.5 = 1 mxld = 1 dsp = 11 tmp = 5 gosub xfer4 dsp = 9 tmp = 0 gosub xfer4 dsp = 12 tmp = 1 gosub xfer4 dsp = 10 tmp = 8 gosub xfer4 dsp = $b tmp = 7 gosub xfer4 dsp = $f tmp = 0 gosub xfer4 @ GetAddress _font,_aFont loopy: row = 1:col = 1 gosub showrjbuf gosub strchr gosub show counter = counter + 1 pause 100 GOTO loopy end strchr: ;null terminated bcnt = 0 while buff[bcnt] chr = buff[bcnt] gosub gcga bcnt = bcnt + 1 col = col + 6 wend return show: for srow = 0 to 7 GOSUB SHOWROW next return showROW: mxld = 0 for dcol = 0 to 3 SSPBUF = srow + 1 while !pir1.3:wend pir1.3 = 0 SSPBUF = dspbuff[(srow<<2) + dcol] rev 8 while !pir1.3:wend pir1.3 = 0 next mxld = 1 return xfer4: for dcol = 0 to 3 mxld = 0 pir1.3 = 0 SSPBUF = dsp while !pir1.3:wend pir1.3=0 SSPBUF =tmp while !pir1.3:wend pir1.3 = 0 next mxld = 1 return gcga: ;ROW= 0-1 COL=0-28 CHR = SPACE,"0" TO ";" if chr = " " then chr = ";" ;TRANSLATE SPACE TO ";" fOffset = (chr - "0")*3 + aFont ; point to cga data drow = row ;0 or 1 mask = ~(63<<(col//8)) inx = col/8 for tmp = 0 to 2 gosub unpack inx = (drow<<2) + col/8 dspbuff[inx] = dspbuff[inx] & mask.lowbyte dspbuff[inx] = dspbuff[inx] | (cga<<(col//8)) if mask.highbyte then INX = INX + 1 dspbuff[inx] = dspbuff[inx] & mask.highbyte dspbuff[inx] = dspbuff[inx] | (cga>>(8-col//8) ) inx = inx + 3 else inx = inx + 4 endif ' SROW=DROW ' GOSUB SHOWROW ' PAUSE 50 drow = drow + 1 dspbuff[inx] = dspbuff[inx] & mask.lowbyte dspbuff[inx] = dspbuff[inx] | (cgah<<(col//8)) if mask.highbyte then INX = INX+1 dspbuff[inx] = dspbuff[inx] & mask.highbyte dspbuff[inx] = dspbuff[inx] | (cgah>>(8 - col//8) ) endif ' SROW=DROW ' GOSUB SHOWROW ' PAUSE 50 drow = drow + 1 fOffset = fOffset + 1 next return showrjbuf: ;load buff righ justified number = counter for ncnt = 0 to 4 BUFF[ncnt] = $30 next while number >10000 buff[0] = buff[0] + 1 number = number - 10000 wend while number >1000 buff[1] = buff[1] + 1 number = number - 1000 wend while number>100 buff[2] = buff[2] + 1 number = number - 100 wend while number >10 buff[3] = buff[3] + 1 number = number -10 wend buff[4] = buff[4] + number lzr: ;repress leading zeros for ncnt = 0 to 3 if BUFF[ncnt] == $30 then BUFF[ncnt] = $20 else return endif next return unpack: asm CHK?RP _fOffset MOVF _fOffset+1,W CHK?RP EEADRH MOVWF EEADRH ;MS Byte of Program Address to read CHK?RP _fOffset MOVF _fOffset,W CHK?RP EEADR MOVWF EEADR ;LS Byte of Program Address to read CHK?RP EECON1 BSF EECON1, EEPGD ;Point to PROGRAM memory BSF EECON1, RD ;EE Read NOP NOP CHK?RP EEDAT ;UNPACK DATA RLF EEDAT, W RLF EEDATH, W CHK?RP _cgah MOVWF _cgah CHK?RP EEDAT BCF EEDAT,7 MOVF EEDAT,W CHK?RP _cga MOVWF _cga RST?RP return endasm '//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 '//MikroElektrnika 2011 '//http://www.mikroe.com '//GLCD FontName : Untitled5x6 '//GLCD FontSize : 5 x 6 'const unsigned short Untitled5x6[] = { font : ;in packed format for pic16 dw lines ;@ db 0x0E,0x11,0x11,0x11,0x11,0x0E; // Code for char num 48 0 @ dw 0x88e,0x891,0x711 ; ;@ db 0x04,0x06,0x04,0x04,0x04,0x0E; // Code for char num 49 1 @ dw 0x304,0x204,0x704 ;@ db 0x0E,0x11,0x08,0x04,0x02,0x1F; // Code for char num 50 @ dw 0x88e,0x208,0xf82 ;@ db 0x0E,0x10,0x1C,0x10,0x10,0x0E; // Code for char num 51 @ dw 0x80e,0xe10,0x710 ;@ db 0x01,0x01,0x05,0x1F,0x04,0x04; // Code for char num 52 @ dw 0x81,0xf85,0x204 ;@ db 0x0F,0x01,0x01,0x0E,0x10,0x0F; // Code for char num 53 @ dw 0x8f,0x701,0x790 ;@ db 0x0E,0x11,0x01,0x0F,0x11,0x0E; // Code for char num 54 6 @ dw 0x88e,0x781,0x711 ;@ db 0x1F,0x10,0x08,0x04,0x02,0x02; // Code for char num 55 @ dw 0x81f,0x208,0x102 ;@ db 0x0E,0x11,0x11,0x0E,0x11,0x0E; // Code for char num 56 8 @ dw 0x88e,0x88e ,0x711 ;@ db 0x0E,0x11,0x11,0x1E,0x10,0x0E; // Code for char num 57 @ dw 0x88e,0xf11,0x711 ;@ db 0x00,0x04,0x00,0x00,0x04,0x00; // Code for char num 58 ; @ dw 0x200,0,0x200 ;@ db 0x00,0x00,0x00,0x00,0x00,0x00; // space @ dw 0,0, 0
Since I have on hand only 16F1827, I modified the code for the PortC pins but as expected does not work. Modifications in red.
default sdo for that chip is rb2, for mxdi var porta.6 you need to set apfcon0.6
nether do i , most probably a trigger for log analyzerI really do not know what lata.5 does in your code. Maybe a led to sign start?
Warning I'm not a teacher
Well, I was just about to post that logic analyzer keeps data at zero. I was watching that and could not think what was wrong...!
Doh!
Thanks Richard. Works now.
Ioannis
What is the logic in the packing of the characters into words?
Ioannis
uses half the amount of flash memory when using 7bit numbers [pic16 flash is 14 bits wide] so you need to pack it.What is the logic in the packing of the characters into words?
it takes very little time for the pic to unpack so there is no real penalty for a huge saving
Warning I'm not a teacher
Yes, OK. But from 6 bytes you went to 3 words. Cannot understand the calculation you did.
;@ db 0x0E,0x10,0x1C,0x10,0x10,0x0E; // Code for char num 51 "3"
@ dw 0x80e,0xe10,0x710
0E=00001110, 10=00010000 and all these makes 80E?
Ioannis
0xE=0b00001110, 0x10=0b00010000
and all these makes 80E
7 high bits | 7 low bits
0x10<<7 | 0x0e &0x7f = 0x80e
0b000100000000000 | 0b0001110 = 0b00010000001110 <==> 0x80e [14 bits]
Warning I'm not a teacher
After making the paper and pencil homework, I was amazed by your thinking! So simple, so clever, so efficient!
Ioannis
Mikroe outputs the characters in columns but your data is in rows. Did you rotate them by hand or can GLCD do that?
Ioannis
Last edited by richard; - 16th January 2022 at 12:54.
Warning I'm not a teacher
Well, results don't match.
I do this:
1. on GLCD Font Creator 5x6 is selected since that is what says in the program: '//GLCD FontSize : 5 x 6
2. Then the character 48 is designed
3.Then Export for GLCD
The data do not match as can be seen. I am sure that I did something wrong, but what?
Ioannis
thats glcd mode you need tft mode
Warning I'm not a teacher
The 5x6 grid is not very roomy for good fonts. After a bit of experimenting I ended up with the rectangular fonts that follow. I thing they are readable from longer distance.
A small demo video is uloaded here:Code:@ dw 0x89F, 0x891, 0xF91 ; 0 @ dw 0x206, 0x204, 0xF84 ; 1 @ dw 0x81F, 0x9F, 0xF81 ; 2 @ dw 0x81F, 0x81E, 0xF90 ; 3 @ dw 0x489, 0xF89, 0x408 ; 4 @ dw 0x9F, 0x81F, 0xF90 ; 5 @ dw 0x9F, 0x89F, 0xF91 ; 6 @ dw 0x81F, 0x410, 0x408 ; 7 @ dw 0x89F, 0x89F, 0xF91 ; 8 @ dw 0x89F, 0x81F, 0xF90 ; 9 @ dw 0x200, 0x0, 0x200 ; : @ dw 0,0,0 ; space
Ioannis
Last edited by Ioannis; - 22nd January 2022 at 11:29.
I'm slowly working on an 18F version.
Currently running on the 18F57Q43 using the SPI peripheral (planning to get to DMA eventually) but can work with MSSP or even SHIFTOUT.
Supports an arbitrary width display (within limits of available RAM) but only one row (starting to second guess myself on that one). Pixel by pixel scrolling left/right/up/down is almost working. We'll see where this ends up in the comming weeks...
you could always just add a driver to suit this and not have to reinvent the wheel font&graphics wise etc
http://www.picbasic.co.uk/forum/showthread.php?t=24218
i'm sure a max7219 driver would be easy enough to contrive and it would make multi row /column display simpler
Warning I'm not a teacher
now with scrolling
Code:'****************************************************************'* Name : max7219 16f1825 * '* Author : richard * '* Notice : Copyright (c) 2019 * '* : * '* Date : 25/2/2020 * '* Version : 1.1 * '* Notes : max7219 5 6x5 chrs on 4 8x8 panels * '* : right justified leading zero suppression * '* : * '* : * '* : pic16f1825 * '******************************************************************* #CONFIG __config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF __config _CONFIG2, _PLLEN_ON & _LVP_OFF #ENDCONFIG define OSC 32 goto overasm asm GetAddress macro Label, Wout CHK?RP Wout movlw low Label ; get low byte movwf Wout movlw High Label ; get high byte movwf Wout + 1 endm endasm overasm: SSPCON1 = $20; SSPSTAT = $40; ANSELA = 0 ANSELC = 0 OSCCON = $70 tmp var byte dsp var byte dspbuff var byte[32] BUFF var byte[16] cnt var byte row var byte drow var byte srow var byte col var byte dcol var byte aFont var word fOffset var word cga var byte cgah var byte ch var byte chr var byte inx var byte mask var word counter var word bcnt var byte ncnt var byte number var word clear mxld var portc.1 mxck var portc.0 mxdi var portc.2 trisc = %11111000 trisa = %11011110 lata.0=1 init: lata.5 = 1 mxld = 1 dsp = 11 tmp = 5 gosub xfer4 dsp = 9 tmp = 0 gosub xfer4 dsp = 12 tmp = 1 gosub xfer4 dsp = 10 tmp = 8 gosub xfer4 dsp = $b tmp = 7 gosub xfer4 dsp = $f tmp = 0 gosub xfer4 @ GetAddress _font,_aFont 'dspbuff[0]=$73 'dspbuff[4]=$37 counter=1235 col = 1 gosub showrjbuf gosub strchr gosub show pause 100 loopy: gosub rotate ' col = 1 ' gosub showrjbuf ' gosub strchr ' chr=":" + counter.0 ' col = 27 ' gosub gcga gosub show ' counter = counter + 1 pause 100 GOTO loopy end strchr: ;null terminated bcnt = 0 while buff[bcnt] chr = buff[bcnt] gosub gcga bcnt = bcnt + 1 col = col + 5 wend return show: for srow = 0 to 7 GOSUB SHOWROW next return showROW: mxld = 0 for dcol = 0 to 3 SSPBUF = srow + 1 while !pir1.3:wend pir1.3 = 0 SSPBUF = dspbuff[(srow<<2) + dcol] rev 8 while !pir1.3:wend pir1.3 = 0 next mxld = 1 return xfer4: for dcol = 0 to 3 mxld = 0 pir1.3 = 0 SSPBUF = dsp while !pir1.3:wend pir1.3=0 SSPBUF =tmp while !pir1.3:wend pir1.3 = 0 next mxld = 1 return gcga: ;ROW= 0-1 COL=0-28 CHR = SPACE,"0" TO ";" if chr = " " then chr = ";" ;TRANSLATE SPACE TO ";" fOffset = (chr - "0")*4 + aFont ; point to cga data drow = 0 mask = ~(31<<(col//8)) inx = col/8 for tmp = 0 to 3 gosub unpack inx = (drow<<2) + col/8 dspbuff[inx] = dspbuff[inx] & mask.lowbyte dspbuff[inx] = dspbuff[inx] | (cga<<(col//8)) if mask.highbyte then INX = INX + 1 dspbuff[inx] = dspbuff[inx] & mask.highbyte dspbuff[inx] = dspbuff[inx] | (cga>>(8-col//8) ) inx = inx + 3 else inx = inx + 4 endif drow = drow + 1 dspbuff[inx] = dspbuff[inx] & mask.lowbyte dspbuff[inx] = dspbuff[inx] | (cgah<<(col//8)) if mask.highbyte then INX = INX+1 dspbuff[inx] = dspbuff[inx] & mask.highbyte dspbuff[inx] = dspbuff[inx] | (cgah>>(8 - col//8) ) endif drow = drow + 1 fOffset = fOffset + 1 next return showrjbuf: ;load buff righ justified number = counter for ncnt = 0 to 4 BUFF[ncnt] = $30 next while number >10000 buff[0] = buff[0] + 1 number = number - 10000 wend while number >1000 buff[1] = buff[1] + 1 number = number - 1000 wend while number>100 buff[2] = buff[2] + 1 number = number - 100 wend while number >10 buff[3] = buff[3] + 1 number = number - 10 wend buff[4] = buff[4] + number lzr: ;repress leading zeros for ncnt = 0 to 3 if BUFF[ncnt] == $30 then BUFF[ncnt] = $20 else return endif next return unpack: readcode foffset ,cgah cga=(cgah >> 4) cgah=(cgah&15 ) return rotate: asm bcf STATUS,C rrf _dspbuff+3,f rrf _dspbuff+2,f rrf _dspbuff+1,f rrf _dspbuff ,f btfsc STATUS, C bsf _dspbuff+3,7 bcf STATUS,C rrf _dspbuff+7,f rrf _dspbuff+6,f rrf _dspbuff+5,f rrf _dspbuff+4 ,f btfsc STATUS, C bsf _dspbuff+7,7 bcf STATUS,C rrf _dspbuff+11,f rrf _dspbuff+10,f rrf _dspbuff+9,f rrf _dspbuff+8 ,f btfsc STATUS, C bsf _dspbuff+11,7 bcf STATUS,C rrf _dspbuff+15,f rrf _dspbuff+14,f rrf _dspbuff+13,f rrf _dspbuff+12 ,f btfsc STATUS, C bsf _dspbuff+15,7 bcf STATUS,C rrf _dspbuff+19,f rrf _dspbuff+18,f rrf _dspbuff+17,f rrf _dspbuff+16 ,f btfsc STATUS, C bsf _dspbuff+19,7 bcf STATUS,C rrf _dspbuff+23,f rrf _dspbuff+22,f rrf _dspbuff+21,f rrf _dspbuff+20 ,f btfsc STATUS, C bsf _dspbuff+23,7 bcf STATUS,C rrf _dspbuff+27,f rrf _dspbuff+26,f rrf _dspbuff+25,f rrf _dspbuff+24 ,f btfsc STATUS, C bsf _dspbuff+27,7 bcf STATUS,C rrf _dspbuff+31,f rrf _dspbuff+30,f rrf _dspbuff+29,f rrf _dspbuff+28 ,f btfsc STATUS, C bsf _dspbuff+31,7 endasm return font: @ dw 0x69,0x99,0x99,0x96 @ dw 0x46,0x54,0x44,0x4F @ dw 0x69,0x98,0x61,0x1F @ dw 0x69,0x86,0x89,0x96 @ dw 0x99,0x9E,0x88,0x88 @ dw 0xF1,0x17,0x89,0x96 @ dw 0x69,0x17,0x99,0x96 @ dw 0xF8,0x84,0x42,0x22 @ dw 0x69,0x96,0x99,0x96 @ dw 0x69,0x9E,0x89,0x96 @ dw 0x00,0x10,0x01,0x00 @ dw 0x00,0x00,0x00,0x00
Warning I'm not a teacher
Thanks for the new example.
In real life does it look like the video? I mean it seems that the scrolling is not very smooth but stepping a bit. OK, since the resolution is not that great this is expected I guess.
Ioannis
ITS as smooth as silk , can't say the same for the camera
made a better parametric version too
Code:rotate: asm banksel _bcnt ;ROW movlw 8 movwf _bcnt banksel _inx movlw 31 ;BUFFER SIZE movwf _inx NROW banksel _inx movlw high (_dspbuff) movwf FSR0H movlw low (_dspbuff) movwf FSR0L movf _inx,W ADDWF FSR0L,F bcf STATUS, C rrf INDF0 ,f ;PER COLUMN addfsr 0,-1 rrf INDF0 ,f ;PER COLUMN addfsr 0,-1 rrf INDF0 ,f ;PER COLUMN addfsr 0,-1 rrf INDF0 ,f ;PER COLUMN btfss STATUS, C GOTO NBNC addfsr 0,3 bsf INDF0,7 NBNC movlw 4 ;ROW LENGTH SUBWF _inx,F banksel _bcnt DECFSZ _bcnt ,F GOTO NROW endasm return
Warning I'm not a teacher
even nicer
Code:rotate: asm banksel _bcnt ;ROW movlw 8 movwf _bcnt movlw high (_dspbuff) movwf FSR0H movlw low (_dspbuff) movwf FSR0L movlw 31 ;BUFFER SIZE ADDWF FSR0L,F banksel _bcnt NROW bcf STATUS, C rrf INDF0 ,f ;PER COLUMN addfsr 0,-1 rrf INDF0 ,f ;PER COLUMN addfsr 0,-1 rrf INDF0 ,f ;PER COLUMN addfsr 0,-1 rrf INDF0 ,f ;PER COLUMN btfss STATUS, C GOTO NBNC addfsr 0,3 bsf INDF0,7 addfsr 0,-3 NBNC addfsr 0,-1 DECFSZ _bcnt ,F GOTO NROW endasm return
Warning I'm not a teacher
My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.
Not as dumb as yesterday, but stupider than tomorrow!
i pressed the wrong button on my youtube dashboard and deleted a bit of stuff , its not recoverable and the originals are lost too"video not available" for Richard's stuff?
Warning I'm not a teacher
Bookmarks