PIC18F4550 driver for 1.8" TFT display part II: moving sinus
In my previous blog
PIC18F4550 driver for 1.8" TFT display (128x160 pixels) I showed how to drive a 1.8" TFT display with the PIC18F4550. Today I'm gonna show an example of drawing a moving sinus.
The concept of the program:
The sinus values are stored in a data block. Actually the data block contains 4 sinus cycles. I added twenty '0x60'==96 values to each cycle. So between each cyle there's a flat line. I use this to be able to measure the time between to cycles. TBLPTR is used to lookup the data y-position. The difference with the previous program is that an offset is used to peek in the data block First we read the data y-value of x and clear this pixel. Then we read the data y-value of x+1 and draw this pixel. After clearing and drawing 180 values, the offset is incremented. This resuls in a moving sinus. Note: when the offset is 180, the offset is reset to 0 otherwise we would run outside our datablock. That's all it takes.
CLRF OFFSETCNT, 0
sin_loop_init:
MOVLW Low(SinusSequence) ;Point Rom pointer to the init sequence
MOVWF TBLPTRL,A
MOVLW High(SinusSequence)
MOVWF TBLPTRH,A
CLRF TBLPTRU,A
CLRF XS, A ; clear x position
MOVF OFFSETCNT, 0, 0
ADDWF TBLPTRL, 1, 0
BTFSS STATUS, Z
GOTO sin_loop
INCF TBLPTRH, 1, 0
;sin_loop_init_end:
TBLRD* ;read current value
sin_loop:
MOVF TABLAT, W ;get data
MOVWF YS ;get byte
CALL clear_pixel ;clear old y value for x position
TBLRD*+ ;read into TABLAT and increment
MOVF TABLAT, W ;get data
MOVWF YS ;get byte
CALL draw_pixel ;draw new y value for x position
INCF XS, 1 ,0 ;inc xs, place result in xs
MOVLW 0xA0
SUBWF XS, 0 ,0 ;substract 160 from xS, place result in WREG
BTFSS STATUS, Z
GOTO sin_loop
INCF OFFSETCNT, 1, 0
MOVF OFFSETCNT, 0, 0
SUBLW 0xB4 ; max 160 + 20 init, for a smooth sinus
BTFSS STATUS, Z
goto sin_loop_init
CLRF OFFSETCNT, 0
goto sin_loop_init
while_1:
goto while_1
If you just want to draw a moving sinus, you must remove the 'db 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60' from each cyle and change the offset = 180 comparison.
sin_loop:
MOVF TABLAT, W ;get data
MOVWF YS ;get byte
CALL clear_pixel ;clear old y value for x position
TBLRD*+ ;read into TABLAT and increment
MOVF TABLAT, W ;get data
MOVWF YS ;get byte
CALL draw_pixel ;draw new y value for x position
INCF XS, 1 ,0 ;inc xs, place result in xs
MOVLW 0xA0
SUBWF XS, 0 ,0 ;substract 160 from xS, place result in WREG
BTFSS STATUS, Z
GOTO sin_loop
INCF OFFSETCNT, 1, 0
MOVF OFFSETCNT, 0, 0
SUBLW 0xA0 ; max 160 instead of 180 (0xB4)
BTFSS STATUS, Z
goto sin_loop_init
CLRF OFFSETCNT, 0
goto sin_loop_init
while_1:
goto while_1
Below you can see the result: a sinus alternated with a flat line at 0x60. I measured the time for one cycle (played it back with a frame by frame video player). The cycle starts at 3.98s and end at 8:69s. This means that we have a refresh rate of 160 frames/4.71seconds = 33.97 frames per second. For the eye this is a smooth movement.