??? 03/17/09 00:38 Modified: 03/17/09 01:40 Read: times |
#163513 - Try this, Aamir... Responding to: ???'s previous message |
I have thought about your application a bit and wrote a piece of code.
But first some basic questions: How to fabricate the pixel matrix? A text containing 50 characters yields a 50 x 6 = 300 bit =38 bytes wide pixel pattern per pixel row, if each character is displayed by the help of 5 x 7 matrix and a 6. pixel column is used to separate consecutive characters from another. The 8. pixel row can be used to underline certain characters. You have additionally to think about how to separate the end of text from the begin when scrolling. So, additional bytes should be added to the above pixel pattern. To allow the display to become entirely empty after the text has been fully scrolled, at least 80 bit = 10 bytes should be added to the pattern. These bytes need not to contain "blanks", but can also show dashes, dots or something similar. By this your pixel matrix contains two consecutive blocks of pixels patterns, the "blank" pixel pattern and the "text" pixel pattern. In the following assume, that the pixel matrix starts with the blank pixel pattern. How to store the pixel matrix in code memory? So, you end up with a pixel matrix of 8 pixel rows each containing 48 bytes. This pixel matrix, Aamir, you want to store in the code memory. This is a good idea, as the 8 x 48 byte = 384 byte wide pixel matrix cannot reside in a standard 8052's RAM anyway. The disadvantage is that only a finite set of messages can be displayed with a programmed micro. As you intend to use shift registers for displaying entire rows, the pixel pattern must be stored in a manner that each byte represents a sequence of consecutive pixels of a pixel row. Then the shiftings can be done very easily. Storing bytes containing pixel columns, on the other hand, would only be wise, if you intend to drive pixel columns instead of pixel rows. It's a good idea to store the pixel pattern in the code memory in the following manner. At the first memory location you store the left-most byte of uppermost pixel row of pixel pattern. Second memory location contains the consecutive byte of uppermost pixel row. The 48. memory location contains the right-most byte of uppermost pixel row. The 49. memory location will have the left-most byte of second pixel row. And so on. Don't forget, that the left-most 10 bytes of each row represent the blank pixel pattern. How to do the shiftings? The idea is, not to shift the whole pixel matrix of 48 bytes = 384 bits into the pixel row shift register, but to take only those bytes that actually appear on the 10 byte = 80 bit wide display. Then, only 80...87 shiftings have to be accomplished instead of up to 384, which would take way too much time! To find out which bytes have to be taken out of the pixel matrix for the shiftings and to find out how many shiftings have actually to be carried you must first define the shifting "Index". This index can be in the range 0...383, corresponding to the 384 bits of each pixel row. Index = 0 means that the whole blank pixel pattern has been shifted into the display and that the text pattern is just not yet displayed. (One shifting more and the first text pixel column could be seen.) For the shifting the first 11 bytes of row have to be taken and 80 shiftings have to be done. (Actually, for Index = 0 you only need to take the first 10 bytes. But for most other Index you need to take 11 bytes, so you take 11 bytes for all Index.) If Index = 1, then the first 11 bytes have to be taken and 81 shiftings have to be done. If Index = 2, again the first 11 bytes have to be taken but 82 shiftings have to be done. If Index = 3, again the first 11 bytes have to be taken but 83 shiftings have to be done. The same procedure until Index = 7. But if Index = 8, then the 2. to the 12. bytes of pixel row have to be taken and 80 shiftings have to be done. So, you see, if Index equals multiples of 8, then the 11 bytes wide pixel block for the shiftings wanders to the right by a step of one byte. You also see, that the shiftings count up from 80 to 87 all the time: If Index equals multiples of 8, then always 80 shiftings have to be done. If the pixel block for the shiftings has reached the right end of pixel matrix, which happens for the first time when Index = 384 - 80 = 304, pixels from the begin of pixel row have to be taken again. The code's task is now to get the right 11 pixel bytes into the RAM of micro and to feed the pixel row shift register (BU4094s). Everything with repect to this index. How to do the scrolling? By a simple timer controlled incrementing of Index. Well, in the following code not everything is derived from Index actually, but some counters are running in parallel to the Index counter. You will find them very quickly when having a look at the code (I hope). The code corresponds to your scheme with the BDX54C anode drivers, which I assume are driven by the Port0 lines. The 4094 shift register is fed by the micro via P1.0 (Data), P1.1 (Clock) and P1.2 (Strobe) lines. The code feeds the AT89S52's internal watchdog and allows a display refresh rate of 130Hz. Take care, the code isn't tested at all. Experiment with it and have fun! ;Scrolling software idea for a 8 x 80bit LED matrix. Through this LED ;matrix a much bigger pixel matrix is scrolled. ;The pixel matrix contains 8 rows, each 48 bytes wide. The first 10 bytes ;represent the blank information, the remaining 38 bytes represent the ;text to be scrolled. ;From the pixel matrix, stored at address 7168, an 11 byte wide block is ;selected. The first 10 bytes of this block are fully shifted into the ;4096. From the 11th byte only a certain number (represented by "SHIFT" ;(=0..7)) is shifted into the 4094. ;The start address of this block depends on STRT_BYTE (=0..47),ROW_OFS_L, ;ROW_OFS_H (=0,48,96,144...336, by other words =ROW * 48) and the start ;address of pixel matrix (MATRX_STRT_L, MATRX_STRT_H). ;ROW (=0..7) defines the row to be shifted and displayed. ;The actual scroll position is represented by INDEX_L,INDEX_H (=0..383). ;This INDEX is "0", when the blank block is fully shifted into the 4094 ;and the text is just not yet visible. ;REFRESH is incremented when a full set of 8 rows has been displayed. ;When REFRESH equals SCRL-RATE, then the display is scrolled by one ;pixel column. This is every 16 * 8 * 950µsec = 0.12sec here, assuming ;11.0592MHz clock speed. Adjust SCRL_RATE to change the scroll speed. $NOMOD51 $INCLUDE (89s52.mcu) DATA_OUT BIT P1.0 CLOCK BIT P1.1 STROBE BIT P1.2 ANODE_DRIV DATA 30H INDEX_L DATA 31H INDEX_H DATA 32H REFRESH DATA 33H ROW DATA 34H ROW_OFS_L DATA 35H ROW_OFS_H DATA 36H SHIFT DATA 37H STRT_BYTE DATA 38H SCRL_RATE EQU 16 MATRX_STRT_L EQU 00H MATRX_STRT_H EQU 1CH ORG 0 SJMP Start ORG 002BH Start: MOV AUXR,#00011001B ;AT89S52 specific status byte MOV TMOD,#00000001B ;Configure Timer 0 (Mode 1) MOV TH0,#252 ;Set 950µsec MOV TL0,#148 SETB TR0 ;Start Timer 0 CLR CLOCK ;Prepare the first shifting Initialize: CLR A ;Set registers to "0" MOV STRT_BYTE,A MOV ROW,A MOV ROW_OFS_L,A MOV ROW_OFS_H,A MOV INDEX_L,A MOV INDEX_H,A MOV REFRESH,A MOV SHIFT,A MOV ANODE_DRIV,#11111110B ;Prepare ANODE_DRIV for first ;row. Main_loop: MOV WDTRST,#01EH ;Feed the watchdog MOV WDTRST,#0E1H MOV R6,#10 ;10 pixel bytes to be selected and ;shifted. MOV R7,STRT_BYTE ;Copy STRT_BYTE into R7 MOV A,MATRX_STRT_L ;Fabricate the start address of 11 ADD A,ROW_OFS_L ;bytes wide block. MOV DP0L,A ;Feed the DPTR with the base address MOV A,MATRX_STRT_H ;and use R7 as a "looping" address ADDC A,ROW_OFS_H ;offset. MOV DP0H,A Get_bytes: MOV A,R7 ;R7 contains the address offset MOV AUXR1,#0 ;89S52 needs DPTR to be defined MOVC A,@A+DPTR ;Fetch the pixel byte MOV R5,#8 ;All 8 bits of pixel byte Shift_loop1: RLC A ;Shift the pixel byte fully into MOV DATA_OUT,C ;the 4094. SETB CLOCK CLR CLOCK DJNZ R5,Shift_loop1 ;All 8 bits shifted? INC R7 ;Address the next pixel byte CJNE R7,#48,Repeat ;If end of pixel matrix is reached, MOV R7,#0 ;fetch it from the begin again. Repeat: DJNZ R6,Get_bytes ;First 10 pixel bytes shifted? MOV R5,SHIFT ;Copy SHIFT into R5 CJNE R5,#0,Last_byte ;11th pixel byte to be shifted? SJMP Wait ;11th pixel byte need not to be ;shifted into the 4094. Last_byte: MOV A,R7 ;R7 addresses the 11th pixel byte MOV AUXR1,#0 ;89S52 needs DPTR to be defined MOVC A,@A+DPTR ;Fetch the 11th pixel byte Shift_loop2: RLC A ;11.pixel byte is partially shifted MOV DATA_OUT,C ;into the 4094. SHIFT represents SETB CLOCK ;the number of bits to be shifted. CLR CLOCK DJNZ R5,Shift_loop2 Wait: JNB TF0,Wait ;Timer 0 overrun? MOV P0,#255 ;Turn-off the anode drivers CLR TR0 ;Stop Timer 0 CLR TF0 ;Reset timer flag bit (TF0) MOV TMOD,#00000001B ;Configure Timer 0 (Mode 1) MOV TH0,#252 ;Set 950µsec MOV TL0,#148 SETB TR0 ;Start Timer 0 SETB STROBE ;Latch the new column data in CLR STROBE ;the 4094s. MOV A,ANODE_DRIV ;Copy ANODE_DRIV into A MOV P0,A ;Turn-on selected anode driver RL A ;Prepare ANODE_DRIV for next row MOV ANODE_DRIV,A INC ROW ;Prepare next row MOV A,ROW_OFS_L ;Fabricate next ROW_OFS_L/H address ADD A,#48 MOV ROW_OFS_L,A MOV A,ROW_OFS_H ADDC A,#0 MOV ROW_OFS_H,A MOV A,ROW CJNE A,#8,Go_back ;All 8 rows shifted? CLR A ;8 rows shifted, so reset ROW MOV ROW,A ;and ROW_OFS_L/H MOV ROW_OFS_L,A MOV ROW_OFS_H,A INC REFRESH ;and increment REFRESH. MOV A,REFRESH CJNE A,SCRL_RATE,Go_back ;Time to scroll? SJMP Prepare_scroll Go_back: LJMP Main_loop ;Jump back and shift the next row Prepare_scroll: MOV REFRESH,#0 ;Reset REFRESH MOV A,INDEX_L ;Increment INDEX_L/H ADD A,#1 MOV INDEX_L,A MOV A,INDEX_H ADDC A,#0 MOV INDEX_H,A INC SHIFT ;Increment SHIFT MOV A,SHIFT CJNE A,#8,Go_back ;SHIFT to be reseted? MOV SHIFT,#0 ;Reset SHIFT and INC STRT_BYTE ;increment STRT_BYTE. MOV A,INDEX_L ;INDEX_L/H = 384? CJNE A,#128,Go_back ;No,so go back and shift next row MOV A,INDEX_H CJNE A,#1,Go_back LJMP Initialize ;INDEX_L/H = 384,so initialize and ;start all over again. org 7168 DB 0,0,0,0,0,0,0,0,0,0 ;Uppermost row of pixel matrix DB 255,255,255,255,255 ;"0" represents the blank pixels, DB 255,255,255,255,255 ;"255" the character pixels. DB 255,255,255,255,255 DB 255,255,255,255,255 ;Each row contains 48 bytes DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 DB 0,0,0,0,0,0,0,0,0,0 ;2.row of pixel matrix DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 DB 0,0,0,0,0,0,0,0,0,0 ;3.row of pixel matrix DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 DB 0,0,0,0,0,0,0,0,0,0 ;4.row of pixel matrix DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 DB 0,0,0,0,0,0,0,0,0,0 ;5.row of pixel matrix DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 DB 0,0,0,0,0,0,0,0,0,0 ;6.row of pixel matrix DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 DB 0,0,0,0,0,0,0,0,0,0 ;7.row of pixel matrix DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 DB 0,0,0,0,0,0,0,0,0,0 ;8.row of pixel matrix DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255,255,255 DB 255,255,255 end Kai |