Professional Documents
Culture Documents
If your display is Segmented or Alphanumeric, then the amount of data needed to control
the display is relatively small, due to the fact that the controllers on these displays have a built in
ROM that stores predefined numbers and characters. So all you have to do is place your cursor
to the appropriate place on your display and define which character should be placed there.
But if you upgraded to a Small Graphics Display (say 240x320) and you want to display a
screen full of graphical images, then you would have a total of 76,800 pixels that must be either
turned on or off by your program. Now most companies will create small subroutines that
construct 8x8 or 8x16 character sizes, and refer to these subroutines when constructing their
screen. But if that is the extent they are going to use their Small Graphics Display then they are
no better off than if they went to a larger Alphanumeric Display. To take advantage of all 76,800
pixels would require a compilation of an extreme amount of data. And without the aid of any
higher level language to help out, this data would have to come from manually created designs
and drawings on special graph paper. Each picture would then have to be converted into 9,600
bytes of data. This time becomes exponential when we consider the amount of images most
companies would like to create, along with the usual rework that will accompany this process.
By the time the final software becomes complete, the end product might not be on the cutting
edge anymore and they would have been better off staying with their old Alphanumeric Display.
For these attached bitmaps to be of use you must have a subroutine in your program that
can pull the data out of the lower memory and send it to the display. This requires knowledge of
how the bitmap information is stored.
For a bitmap program, the first 62 bytes of data call out the protocol for the rest of the
bitmap code (like the type, size, and layout of the bitmap). Since this information will already be
known (monochrome and layout dimensions), the first 62 bytes can be skipped. The 63rd byte
will define the first eight pixels in the lower left hand corner of the display. The following bytes
will then be sent sequentially to the screen until you hit the right hand edge of your display. The
next byte will either be the first byte on the next row up (on the left hand side), or it will be a
padded zero that the bitmap program has placed in there to maintain certain integers for row
length.
Padded zeros are used when the number of bytes in a row are not divisible by 4. So if you
had 16 bytes of data per row (16x8 = 128 pixel across), then you would have no padded zeros
because 16 is divisible by 4. But if your number of bytes of data per row was 30 (30x8 = 240
pixels across), then 4 would not go evenly into 30. At this point we would round up the number
to the nearest integer that 4 will go into. This number would be 32. And since we have 30 bytes
of data, 32-30 = 2; so there are 2 bytes of padded zeros in your bitmap before the next line of
data begins. Your internal program will have to reflect this and disregard these zeros before
going on with the 33rd byte of data. (see Table 1 for quick reference to your display)
So for example, if you had a 128x240 display, you would set up your assembly code so it
would strip off the first 62 bytes of data from the bitmap file and discard that information. The
63rd byte would be the first byte in the lower left hand side of the LCD display. Then the next
29 bytes of data (2408 = 30) would get placed directly to the display. Now the next 2 bytes (the
padded zeros - see Table 1) must be discarded. The next byte of data will then be placed in the
next row up and over on the left hand side. The user will continue this process until he has
walked up the display all 128 lines.
Totals Divisible By 4
12
30
16
16
32
60
16
32
32
80
40
If you access the upper bitmap memory by using the data pointer address in your
microprocessor, then once you paint the first page and increment the data pointer, you will be
looking at the first byte of the next picture in your list. There is one thing to remember about a
bitmap that is different from a LCD display. In bitmap programs, a 1 in binary is an off pixel
and a 0 in binary is an on pixel. This is the opposite on the LCD. So the user will need to
perform an Exclusive-Or with the number FF Hex and the data to be placed on the display.
This operation will turn the bytes around so they may be viewed properly. If you dont do this
operation, your picture will be the inverse image of your original picture.
For an example of the subroutine that extracted the bitmap data to produce the picture
above, please see the 8051 assembly code listed below. The display above is a 240x320 Small
Graphics Display with a SED1330 controller chip. If you are using a display that is not using the
SED1330 controller chip, this same code can be used with modifications to the WRCMD and
WRDATA subroutines and possibly some alterations on the direction the data is clocked in. The
direction used in the SED1330 is the same as the T6963 controller chip. If you are using the
HD61830 you will need to switch the direction of the data being clocked in (i.e. D7 becomes D0,
D6 becomes D1, etc.)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; This is a base program for clocking in bitmaps to the SED1330 on a 240x320 LCD display
; using 8051 assembly code.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
START:
MOV 30H,#3EH
;SETS UP THE INNER LOOP TO 62
MOV 31H,#01H
;SETS UP FOR NULL DATA
LCALL CK_DATA
;GO GET DATA
MOV B,#0F0H
;SETS UP INNER LOOP FOR 240 LINES OF DATA
MOV 32H,#008H
;SETS LOWER CURSOR ADDRESS (address where program ends/bitmap begins)
MOV 33H,#02AH
;SETS UPPER CURSOR ADDRESS
DO_OVER:
PUSH B
;STORE VALUE
MOV 30H,#28H
;SETS UP THE INNER LOOP TO 40 CHARACTERS PER LINE
MOV 31H,#00H
;SETS UP FOR VALID DATA
LCALL SET_CUR
;SETS THE INITIAL ADDRESS ON DISPLAY
LCALL CK_DATA
;GO GET DATA
POP
B
;RECALLS INNER LOOP
DJNZ B,CONTINUE
;IF NOT ZERO, THEN REDO (moving up one line on display if doing over)
RET
;
CONTINUE:
MOV A,0D0H
;RECALL CARRY FLAG
ANL A,#7FH
;CLEAR THE CARRY FLAG
MOV 0D0H,A
;STORE FLAG
MOV A,32H
;RECALL LOWER CURSOR ADDRESS
SUBB A,#28H
;SUBTRACT 40 FROM THIS ADDRESS TO MOVE UP ONE LINE
MOV 32H,A
;RESTORE THE NEW LOWER ADDRESS
MOV A,0D0H
;RECALL CARRY FLAG
ANL A,#80H
;STRIP OFF CARRY FLAG
CJNE A,#80H,NO_CARRY ;SEE IF FLAG IS SET (if set then must bump down higher address by 1)
MOV A,33H
;RECALL UPPER CURSOR ADDRESS
SUBB A,#01H
;SUBTRACT 1 FORM UPPER
MOV 33H,A
;RESTORE THE VALUE
NO_CARRY:
LJMP DO_OVER
;DO INNER ROUTINE OVER AGAIN
CK_DATA:
MOV A,31H
;RECALL BYTE FOR NULL OR VALID DATA
CJNE A,#00H,GET_DATA ;SEE IF NULL DATA OR NOT (selects appropriate subroutine)
DATA_IN:
LCALL DATA_ARM
;GET THE VALID DATA
LCALL WRCHAR
;SEND IT TO THE DISPLAY
DJNZ 30H,DATA_IN
;COMPARE LOOP AND DECREMENT UNTIL ZERO
RET
;
GET_DATA:
LCALL DATA_ARM
;GET THE NULL DATA
SET_CUR:
DATA_ARM:
WRCHAR:
WRDATA:
WRCMD:
DJNZ 30H,GET_DATA
RET
MOV B,#46H
LCALL WRCMD
MOV B,32H
LCALL WRDATA
MOV B,33H
LCALL WRDATA
RET
MOV 82H,34H
MOV 83H,35H
MOV A,#00H
MOVC A,@A+DPTR
MOV B,A
INC
DPTR
MOV 34H,82H
MOV 35H,83H
RET
PUSH B
MOV B,#042H
LCALL WRCMD
POP
B
XRL
B,#0FFH
LCALL WRDATA
RET
MOV 0C0H,#03H
MOV 0C0H,#01H
MOV 090H,B
MOV 0C0H,#03H
RET
MOV 0C0H,#07H
MOV 0C0H,#05H
MOV 090H,B
MOV 0C0H,#07H
RET
.END
There are a lot more tricks associated with the individual controller that you choose to
use. Some of them write the data left to right, some go right to left, and some go up to down.
You will have to slightly vary your address pointer on the LCD display to accommodate this.
There are also other tricks with using the pictures to act as your display background while you
move discrete bytes of data around inside the image (like in a video game). Densitron
Corporation has more information on these processes and how they can be implemented in your
particular display. If you would like more information on anything in this application note,
please contact Todd Fitzsimmons at Densitron Corporation America at 562-941-5000x247.