Mike said:PORTB performs double duty as both a row driver bus during display "on" time and as a shift register data bus during display "off" time.
As you suspected, loading 64 bits of data into the eight shift registers takes only 32 instruction cycles (6.4 usecs @ 20 MHz) and in this design is accomplished by writing 8 bytes to PORTB with a CLK pulse after each byte during the display "off" time at the beginning of each interrupt cycle.
I try to load the shift registers as quickly as possible in order to keep the display blanking interval as short as possible. This wouldn't be necessary if I wasn't multiplexing PORTB.xorcise said:I think this is a clever idea, one that I will try.Mike said:PORTB performs double duty as both a row driver bus during display "on" time and as a shift register data bus during display "off" time.
As you suspected, loading 64 bits of data into the eight shift registers takes only 32 instruction cycles (6.4 usecs @ 20 MHz) and in this design is accomplished by writing 8 bytes to PORTB with a CLK pulse after each byte during the display "off" time at the beginning of each interrupt cycle.
As a technical aside, with a PIC you are doing a lot more instruction cycles to output 8 bytes simultaneously and serially using software. I can work out the code but it will certainly be a lot of machine cycles. But, that said, it will probably still be fast enough to fit the overall function of what you want to do with the display.
;******************************************************************
;
; K8LH High Performance 10-pin Display Subsystem ISR Driver
;
; This subsystem hardware/software design supports from one
; to eight 8x8 matrix displays.
;
; One matrix 'row' is driven during each 1.0 msec interrupt
; cycle (overall 12.5% duty cycle and 125 Hz refresh rate).
;
; A minimum PWM 'on-time' of 1% provides a 10 usec window
; at the start of each interrupt cycle where the PWM signal
; drives the MIC5821 Output Enable lines high (display off)
; which allows me to use the RB7-RB0 'row' driver lines as
; <DAT> lines to load the MIC5821 shift registers.
;
; Serial data is clocked into eight MIC5821 shift registers
; in parallel by stuffing PORTB with eight "shift register"
; formatted bytes which drive the MIC5821 <DAT> inputs.
;
; The 1% minimum PWM 'on' time limits maximum brightness to
; 99% but the 1% loss of brightness is inperceivable.
;
; 211 cycles, 42.2 usecs, 4.22% "overhead" (20 MHz)
;
ISR_Display_Load
;
; 32 cycles, 6.4 usecs (20 MHz)
;
movff SBuff+7,LATB ; bit 7 byte
bcf LATA,0 ; toggle <CLK> pin
bsf LATA,0 ;
movff SBuff+6,LATB ; bit 6 byte
bcf LATA,0 ;
bsf LATA,0 ;
movff SBuff+5,LATB ; bit 5 byte
bcf LATA,0 ;
bsf LATA,0 ;
movff SBuff+4,LATB ; bit 4 byte
bcf LATA,0 ;
bsf LATA,0 ;
movff SBuff+3,LATB ; bit 3 byte
bcf LATA,0 ;
bsf LATA,0 ;
movff SBuff+2,LATB ; bit 2 byte
bcf LATA,0 ;
bsf LATA,0 ;
movff SBuff+1,LATB ; bit 1 byte
bcf LATA,0 ;
bsf LATA,0 ;
movff SBuff+0,LATB ; bit 0 byte
bcf LATA,0 ;
bsf LATA,0 ;
;
; advance the row ring counter and resume PORTB row driver
; duties before the PWM line goes low (display on)
;
; 3 cycles, 0.6 usecs
;
rlncf RowPos,F ; advance row ring counter
comf RowPos,W ; invert bits (only 1 bit low)
movwf LATB ; setup PORTB row driver lines
;
;
; build the eight '5821 "shift register" bytes in SBuff for the
; next interrupt cycle. first, copy the correct eight display
; buffer bytes into the WBuff work buffer. then combine all of
; the b7 bits, b6 bits, b5 bits, etc., into their own bytes in
; the eight byte SBuff shift register data buffer.
;
; step <1>
; copy 8 byte 'row' into the WBuff work buffer
;
; 23 cycles, 4.6 usecs
;
ISR_Display_Prep
incf Row,F ; Row++
bcf Row,3 ; Row %= 8 (well, sort of)
lfsr 0,DBuff ; FSR0 = address DBuff[0,0]
swapf Row,W ; WREG = Row (0..7) * 16
rrncf WREG,W ; WREG = Row (0..7) * 8
addwf FSR0L,F ; FSR0 = address DBuff[Row,0]
movff POSTINC0,WBuff+0 ; WBuff[0] = DBuff[Row,0]
movff POSTINC0,WBuff+1 ; WBuff[1] = DBuff[Row,1]
movff POSTINC0,WBuff+2 ; WBuff[2] = DBuff[Row,2]
movff POSTINC0,WBuff+3 ; WBuff[3] = DBuff[Row,3]
movff POSTINC0,WBuff+4 ; WBuff[4] = DBuff[Row,4]
movff POSTINC0,WBuff+5 ; WBuff[5] = DBuff[Row,5]
movff POSTINC0,WBuff+6 ; WBuff[6] = DBuff[Row,6]
movff POSTINC0,WBuff+7 ; WBuff[7] = DBuff[Row,7]
;
; step <2>
; build SBuff for next display interrupt cycle. all of the
; b0 bits in one byte, b1 bits in the next byte, and so on.
;
; 153 cycles, 30.6 usecs
;
lfsr 0,SBuff ; for (n=0; n<8; ++n)
V1 rrcf WBuff+0,F ; WBuff[0] >>= 1
rrcf INDF0,F ; SBuff[n] >>= 1 + C*128
rrcf WBuff+1,F ; WBuff[1] >>= 1
rrcf INDF0,F ; SBuff[n] >>= 1 + C*128
rrcf WBuff+2,F ; WBuff[2] >>= 1
rrcf INDF0,F ; SBuff[n] >>= 1 + C*128
rrcf WBuff+3,F ; WBuff[3] >>= 1
rrcf INDF0,F ; SBuff[n] >>= 1 + C*128
rrcf WBuff+4,F ; WBuff[4] >>= 1
rrcf INDF0,F ; SBuff[n] >>= 1 + C*128
rrcf WBuff+5,F ; WBuff[5] >>= 1
rrcf INDF0,F ; SBuff[n] >>= 1 + C*128
rrcf WBuff+6,F ; WBuff[6] >>= 1
rrcf INDF0,F ; SBuff[n] >>= 1 + C*128
rrcf WBuff+7,F ; WBuff[7] >>= 1
rrcf POSTINC0,F ; SBuff[n] >>= 1 + C*128
btfsc FSR0L,3 ;
bra V1 ;
;
sn_burki said:HI ALL
MANY TIMES I HAVE WRITTEN TO THIS TOPIC BUT STILL I HAVE NOT GOT MY ANSWER, I WANT A VERY SIMPLE MOVING MESSAGE DISPLAY BASED ON ATMEL 89C51 WITH ASSEMBLY CODE. MY BIG PROBLEM IS THAT I CAN NOT UNDERSTAND THAT HOW TO SCROLL DIFFERENT TEXT ON MOVING MESSAGE DISPLAY WITH DIFFERETN STYLE???? PLZ PLZ PLZ HELP IF ANY ONE CAN DO SO.
REGARDS
There are a number of 'tricks' to speed up the loading of the shift registers. For example, if you can do with seven 8x8 modules instead of eight then you could use the RB0 line for the SR <CLK> and RB1..RB7 for <DAT> and preset bit 0 in the SR data bytes to '0'. This results in a 9 pin interface instead of 10 pins and loading the shift registers is accomplished like this;xorcise said:As a technical aside, with a PIC you are doing a lot more instruction cycles to output 8 bytes simultaneously and serially using software. I can work out the code but it will certainly be a lot of machine cycles. But, that said, it will probably still be fast enough to fit the overall function of what you want to do with the display.
;
; 24 cycles, 4.8-usecs (20-MHz clock)
;
ISR_load_shift_registers
movff SBuff+7,LATB ; bit 7 byte [ddddddd0]
bsf LATB,0 ; clock data [ddddddd1]
movff SBuff+6,LATB ; bit 6 byte
bsf LATB,0 ;
movff SBuff+5,LATB ; bit 5 byte
bsf LATB,0 ;
movff SBuff+4,LATB ; bit 4 byte
bsf LATB,0 ;
movff SBuff+3,LATB ; bit 3 byte
bsf LATB,0 ;
movff SBuff+2,LATB ; bit 2 byte
bsf LATB,0 ;
movff SBuff+1,LATB ; bit 1 byte
bsf LATB,0 ;
movff SBuff+0,LATB ; bit 0 byte
bsf LATB,0 ;
;
; resume PORTB 'row' driver duties before PWM goes low and
; advance the 'row' ring counter for the next cycle
;
; 3 cycles, 0.6-usecs
;
comf ROWPOS,W ; invert bits (only 1 bit low)
movwf LATB ; setup PORTB column drivers
rlncf ROWPOS,F ; advance column ring counter
leisryan said:Here's an 8by64 single color moving message disply that can be controlled through hyperterminal based on PIC16F877a and written in picbasic pro"very easy to use compiler"!!!
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?