Tuesday, May 24, 2011

Controlling a nokia5110 lcd with software SPI on a pic16f84a




My newest project has been implementing a software SPI routine so that my pic (which lacks hardware SPI) can communicate with a cheap nokia 84x48 graphical lcd (later I will show how I wired it up). I've written subroutines in assembly for setting x,y address of the lcd's ram as well as sending data or commands for initialization (8bit, but could be easily modified to work with 9bit color lcd protocols I've seen). I plan on using a look up table to store standard character hex data so that I can make things easier for myself in upcoming projects. I know that my code is pretty inefficient so I plan on fixing it a little later (but not bad for just reading the datasheet and a few hours of coding). I just have the mcu writing "Hello World!" and drawing a video game character sprite at the bottom (I converted the image by hand, but I could easily write a program to do that for me). This is just the beginning, I plan on using this, as well as everything else I've been working on in my projects to come. I plan on adding the ability to animate/scroll text and images and will update the site with the code once I get the chance. I also plan on describing the SPI protocol and lcd commands in detail. For now I will post the code to just write "Hello World" and draw a sprite.

Start    BSF  03h,5         ;switch from bank 0 to 1

    MOVLW  b'00000000' ;Out RB to output
    MOVWF 06h
    MOVLW  b'00000'       ;Out RA to output
    MOVWF 05h

    BCF 03h,5          ;switch from bank 1 to 0     
;RB0=sclk
;RB1=sda
;RB2=D_C
;RB3=Sce
;RB4=reset
;RB5=disp pwr
Begin
    bsf 06h,3 ;disable serial
    bsf 06h,5 ;power on display
    nop
    bcf 06h,4 ;reset
    nop
    bsf 06h,4 ;release from reset

; sel extended instruction set (h=1)
    movlw b'00100001'
    movwf 0Ch
    call spi_command

; set Vop (Contrast)
    movlw b'10111001'
    movwf 0Ch
    call spi_command

; sel normal instruction set (h=0)
    movlw b'00100000'
    movwf 0Ch
    call spi_command

; display normal mode
    movlw b'00001100'
    movwf 0Ch
    call spi_command

;---------------------------

; draw H
    movlw b'01111111'
    movwf 0Ch
    call spi_data
    movlw b'00001000'
    movwf 0Ch
    call spi_data
    movlw b'00001000'
    movwf 0Ch
    call spi_data
    movlw b'00001000'
    movwf 0Ch
    call spi_data
    movlw b'01111111'
    movwf 0Ch
    call spi_data

call _space

; draw e
    movlw b'00001110'
    movwf 0Ch
    call spi_data
    movlw b'00010101'
    movwf 0Ch
    call spi_data
    movlw b'00010101'
    movwf 0Ch
    call spi_data
    movlw b'00010101'
    movwf 0Ch
    call spi_data
    movlw b'00001100'
    movwf 0Ch
    call spi_data

call _space

; draw l
    movlw b'00000000'
    movwf 0Ch
    call spi_data
    movlw b'01000001'
    movwf 0Ch
    call spi_data
    movlw b'01111111'
    movwf 0Ch
    call spi_data
    movlw b'00000001'
    movwf 0Ch
    call spi_data
    movlw b'00000000'
    movwf 0Ch
    call spi_data

call _space

; draw l
    movlw b'00000000'
    movwf 0Ch
    call spi_data
    movlw b'01000001'
    movwf 0Ch
    call spi_data
    movlw b'01111111'
    movwf 0Ch
    call spi_data
    movlw b'00000001'
    movwf 0Ch
    call spi_data
    movlw b'00000000'
    movwf 0Ch
    call spi_data

call _space

; draw o
    movlw b'00001110'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00001110'
    movwf 0Ch
    call spi_data

call _space

; goto y=1,x=0
    movlw b'00000001'
    movwf 0Ch
    movlw b'00000000'
    movwf 0Dh
    call setxy

; draw W
    movlw b'01111110'
    movwf 0Ch
    call spi_data
    movlw b'00000001'
    movwf 0Ch
    call spi_data
    movlw b'00001110'
    movwf 0Ch
    call spi_data
    movlw b'00000001'
    movwf 0Ch
    call spi_data
    movlw b'01111110'
    movwf 0Ch
    call spi_data

call _space

; draw o
    movlw b'00001110'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00001110'
    movwf 0Ch
    call spi_data

call _space

; draw r
    movlw b'00011111'
    movwf 0Ch
    call spi_data
    movlw b'00001000'
    movwf 0Ch
    call spi_data
    movlw b'00010000'
    movwf 0Ch
    call spi_data
    movlw b'00010000'
    movwf 0Ch
    call spi_data
    movlw b'00001000'
    movwf 0Ch
    call spi_data

call _space

; draw l
    movlw b'00000000'
    movwf 0Ch
    call spi_data
    movlw b'01000001'
    movwf 0Ch
    call spi_data
    movlw b'01111111'
    movwf 0Ch
    call spi_data
    movlw b'00000001'
    movwf 0Ch
    call spi_data
    movlw b'00000000'
    movwf 0Ch
    call spi_data

call _space

; draw d
    movlw b'00001110'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00010001'
    movwf 0Ch
    call spi_data
    movlw b'00001001'
    movwf 0Ch
    call spi_data
    movlw b'01111111'
    movwf 0Ch
    call spi_data

call _space

; draw !
    movlw b'01111101'
    movwf 0Ch
    call spi_data

;---------------------------
; goto y=5,x=0
    movlw b'00000101'
    movwf 0Ch
    movlw b'00000000'
    movwf 0Dh
    call setxy
;draw image block 4
    movlw b'10000111';1
    movwf 0Ch
    call spi_data
    movlw b'11111101';2
    movwf 0Ch
    call spi_data
    movlw b'10000001';3
    movwf 0Ch
    call spi_data
    movlw b'01100001';4
    movwf 0Ch
    call spi_data
    movlw b'00010001';5
    movwf 0Ch
    call spi_data
    movlw b'11001001';6
    movwf 0Ch
    call spi_data
    movlw b'00100101';7
    movwf 0Ch
    call spi_data
    movlw b'00100101';8
    movwf 0Ch
    call spi_data
    movlw b'11100001';9
    movwf 0Ch
    call spi_data
    movlw b'00011001';10
    movwf 0Ch
    call spi_data
    movlw b'00000101';11
    movwf 0Ch
    call spi_data
    movlw b'00000011';12
    movwf 0Ch
    call spi_data
    movlw b'00000011';13
    movwf 0Ch
    call spi_data
    movlw b'00000001';14
    movwf 0Ch
    call spi_data
    movlw b'00111001';15
    movwf 0Ch
    call spi_data
    movlw b'11101101';16
    movwf 0Ch
    call spi_data
    movlw b'00000111';17
    movwf 0Ch
    call spi_data

; goto y=4,x=0
    movlw b'00000100'
    movwf 0Ch
    movlw b'00000000'
    movwf 0Dh
    call setxy
;draw image block 3
    movlw b'00000111';1
    movwf 0Ch
    call spi_data
    movlw b'00111100';2
    movwf 0Ch
    call spi_data
    movlw b'01100100';3
    movwf 0Ch
    call spi_data
    movlw b'01010011';4
    movwf 0Ch
    call spi_data
    movlw b'11110000';5
    movwf 0Ch
    call spi_data
    movlw b'00111000';6
    movwf 0Ch
    call spi_data
    movlw b'11111001';7
    movwf 0Ch
    call spi_data
    movlw b'11111011';8
    movwf 0Ch
    call spi_data
    movlw b'10010011';9
    movwf 0Ch
    call spi_data
    movlw b'11110100';10
    movwf 0Ch
    call spi_data
    movlw b'11110100';11
    movwf 0Ch
    call spi_data
    movlw b'01110100';12
    movwf 0Ch
    call spi_data
    movlw b'01110000';13
    movwf 0Ch
    call spi_data
    movlw b'00010000';14
    movwf 0Ch
    call spi_data
    movlw b'00100100';15
    movwf 0Ch
    call spi_data
    movlw b'10011111';16
    movwf 0Ch
    call spi_data
    movlw b'11010000';17
    movwf 0Ch
    call spi_data
    movlw b'01110000';18
    movwf 0Ch
    call spi_data

; goto y=3,x=0
    movlw b'00000011'
    movwf 0Ch
    movlw b'00000000'
    movwf 0Dh
    call setxy
;draw image block 2
    movlw b'00011100';1
    movwf 0Ch
    call spi_data
    movlw b'00010110';2
    movwf 0Ch
    call spi_data
    movlw b'00010010';3
    movwf 0Ch
    call spi_data
    movlw b'00010010';4
    movwf 0Ch
    call spi_data
    movlw b'00010011';5
    movwf 0Ch
    call spi_data
    movlw b'00010001';6
    movwf 0Ch
    call spi_data
    movlw b'00110001';7
    movwf 0Ch
    call spi_data
    movlw b'00100000';8
    movwf 0Ch
    call spi_data
    movlw b'01100000';9
    movwf 0Ch
    call spi_data
    movlw b'01000000';10
    movwf 0Ch
    call spi_data
    movlw b'11000000';11
    movwf 0Ch
    call spi_data
    movlw b'10000000';12
    movwf 0Ch
    call spi_data
    movlw b'00000000';13
    movwf 0Ch
    call spi_data
    movlw b'00000010';14
    movwf 0Ch
    call spi_data
    movlw b'00011111';15
    movwf 0Ch
    call spi_data
    movlw b'01110001';16
    movwf 0Ch
    call spi_data
    movlw b'11000000';17
    movwf 0Ch
    call spi_data

; goto y=2,x=12
    movlw b'00000010'
    movwf 0Ch
    movlw b'00001100'
    movwf 0Dh
    call setxy
;draw image block 1
    movlw b'00000001';12
    movwf 0Ch
    call spi_data
    movlw b'00000001';13
    movwf 0Ch
    call spi_data
    movlw b'00000011';14
    movwf 0Ch
    call spi_data
    movlw b'00000010';15
    movwf 0Ch
    call spi_data
    movlw b'00000010';16
    movwf 0Ch
    call spi_data
    movlw b'00000011';17
    movwf 0Ch
    call spi_data

a goto a

;----------------------------

spi_command
    bcf 06h,3 ;start serial transmission
    bcf 06h,2 ;D_C=0
        btfss 0Ch,7
        goto c1
        call one
        goto c1n
    c1    call zero
    c1n    btfss 0Ch,6
        goto c2
        call one
        goto c2n
    c2    call zero
    c2n    btfss 0Ch,5
        goto c3
        call one
        goto c3n
    c3    call zero
    c3n    btfss 0Ch,4
        goto c4
        call one
        goto c4n
    c4    call zero
    c4n    btfss 0Ch,3
        goto c5
        call one
        goto c5n
    c5    call zero
    c5n    btfss 0Ch,2
        goto c6
        call one
        goto c6n
    c6    call zero
    c6n    btfss 0Ch,1
        goto c7
        call one
        goto c7n
    c7    call zero
    c7n    btfss 0Ch,0
        goto cd
        call one
        goto cdn
    cd    call zero
cdn    bcf 06h,0
    bsf 06h,3 ;end serial transmission
return

spi_data
    bcf 06h,3 ;start serial transmission
    bsf 06h,2 ;D_C=1
        btfss 0Ch,0
        goto b1
        call one
        goto b1n
    b1    call zero
    b1n    btfss 0Ch,1
        goto b2
        call one
        goto b2n
    b2    call zero
    b2n    btfss 0Ch,2
        goto b3
        call one
        goto b3n
    b3    call zero
    b3n    btfss 0Ch,3
        goto b4
        call one
        goto b4n
    b4    call zero
    b4n    btfss 0Ch,4
        goto b5
        call one
        goto b5n
    b5    call zero
    b5n    btfss 0Ch,5
        goto b6
        call one
        goto b6n
    b6    call zero
    b6n    btfss 0Ch,6
        goto b7
        call one
        goto b7n
    b7    call zero
    b7n    btfss 0Ch,7
        goto d
        call one
        goto dn
    d    call zero
dn    bcf 06h,0
    bsf 06h,3 ;end serial transmission
return

zero
    bcf 06h,0
    bcf 06h,1 ;0
    bsf 06h,0 ;sclk pulse
return

one
    bcf 06h,0
    bsf 06h,1 ;1
    bsf 06h,0 ;sclk pulse
return

_space ;send byte='00000000', draw space
    movlw b'00000000'
    movwf 0Ch
    call spi_data
return

setxy
    bsf 0Ch,6
    call spi_command
    bsf 0Dh,7
    movf 0Dh,0
    movwf 0Ch
    call spi_command
return

end

2 comments:

  1. Hi, may I have your email? I want someone to give me more tips on programming the 3310 LCD but seems that I didn't get any response.

    Thanks. My email is abdulhalimpoh at yahoo.com.sg.

    ReplyDelete