; Sample to drive a HD44780 LCD over SPI, using a 74HC595 shift register ; See: https://highfieldtales.wordpress.com/2011/12/04/very-fast-spi-to-parallel-interface-for-netduino/ ; ; PIC 74HC595 HD44780 ; 15 D4 ; 1 D5 ; 2 D6 ; 3 D7 ; 4 RS ; 5 RW ; 6 E ; 7 ; 9 - 12 ; 10 ; CLK 11 ; 12 - 9 ; 13 - GND ; DAT 14 ; ; The SS port resets the shift register, via an inverter list P=16F876A #include p16f876a.inc __CONFIG _CP_ALL & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC #define SS_PORT PORTB #define SS PORTB,1 RES_VECT CODE 0x0000 ; processor reset vector GOTO START ; go to beginning of program ; TODO ADD INTERRUPTS HERE IF USED MAIN_PROG CODE ; let linker place main program START banksel TRISC ; Set up pins for SPI bcf TRISC,5 ; Data pin 16 bcf TRISC,3 ; Clock pin 14 bsf TRISC,4 ; Data in clrf TRISB banksel SSPCON ; Set up SPI bcf SSPCON,5 ; Disable SPI movlw b'00010000' movwf SSPCON movlw b'11000000' ; 1 = Input data sampled at end of data output time ; 1 = Transmit occurs on transition from active to Idle clock state movwf SSPSTAT ; bsf SSPCON,4 ; CKP 1 = Idle state for clock is a high level bcf SSPCON,0 ; 0000 = SPI Master mode, clock = FOSC/4 bcf SSPCON,1 bcf SSPCON,2 bcf SSPCON,3 bsf SSPCON,5 ; SSPEN 1 = Enables serial port and configures SCK, SDO, SDI, and SS as serial port pins call init_lcd loop: GOTO loop ; loop forever init_lcd ; Remember to init ports! ; Initialise HD44780 for 4-bits, 2 lines call Delay_100ms ; 100ms, step 1 banksel FLAGS movlw 0 ; Command movwf FLAGS movlw B'00110000' ; initialise module, step 2 call lcd_byte call Delay5ms ; > 4.1ms movlw B'00110000' ; initialise module, step 3 call lcd_byte call Delay100us ; > 100us movlw B'00110000' ; initialise module, step 4 call lcd_byte call Delay100us ; > 100us movlw B'00100000' ; initialise module, step 5 call lcd_byte call Delay100us ; > 100us ;x3 goto x3 ; Step 6, the real function select movlw B'00101100' ; display function (4-bits, 2 lines, 5x10 dots) call lcd_byte call Delay100us ; > 53us movlw B'00001000' ; Step 7, display on/off call lcd_byte call Delay100us ; > 53us movlw B'00000001' ; Step 8, display clear call lcd_byte call Delay5ms ; > 3ms ; |- 0 = Display off, 1 = display on ; |- 0 = 1 line, 1 = 2 line movlw B'00000110' ; Step 9, entry mode. cursor moves right, display not shifted call lcd_byte call Delay100us ; > 53us ; Actual init ends here ; |- 0 = Display off, 1 = Display on ; |- 0 = Cursor off, 1 = Cursor on ; |- 0 = Blink off, 1 = Blink on movlw B'00001111' ; display on, cursor on, blink on call lcd_byte call Delay100us ; > 53us ; Init done, stuff below is just for testing. banksel FLAGS movlw 1 ; Data movwf FLAGS movlw 'A' call lcd_byte movlw 'B' call lcd_byte movlw 'C' call lcd_byte xy movlw 'D' call lcd_byte call Delay_100ms movlw 'E' call lcd_byte return ; Send byte in W to LCD as command or data, depending on FLAGS ; 0 in flags as command or 1 as data lcd_byte banksel D_STO movwf D_STO swapf D_STO,w ; Swap high and low nibbles, result in W andlw b'00001111' ; Mask out call lcd_push_nibble ; Push high nibble banksel D_STO movf D_STO,w ; get byte andlw b'00001111' ; Mask ou call lcd_push_nibble ; Push low nibble call Delay100us ; > 100us delay return ; Push high nibble in w as data or cmd ; Input: Nibble in W, 0 in flags as command or 1 as data lcd_push_nibble ; Push high nibble in w as data or cmd btfsc FLAGS,0 ; flag set=data, set Q4 in that case iorlw b'00010000' ; Not set leave as is iorlw b'10000000' ; Set high bit call send_w_on_spi ; Send nibble, E is still low iorlw b'11000000' ; Set E bit call send_w_on_spi ; Send nibble, E is high andlw b'10111111' ; E -> low call send_w_on_spi ; Send nibble, E is low return send_w_on_spi ;banksel SS_PORT bcf SS ; Assert SS (low) movwf SSPBUF ; begin transmission WAIT btfss PIR1, SSPIF ; send completed? if Yes skip next goto WAIT bcf PIR1, SSPIF ; yes, clear flag ;banksel SS_PORT bsf SS ; Unassert SS (high) return ;----------------------------------------------- ; Delay = 0.0001 seconds ; Clock frequency = 20 MHz ; Actual delay = 0.0001 seconds = 500 cycles ; Error = 0 % Delay100us ;banksel STORE1 ;499 cycles movlw 0xA6 movwf STORE1 Delay100us_0 decfsz STORE1, f goto Delay100us_0 ;1 cycle nop return ;----------------------------------------------- ; Delay = 0.005 seconds ; Clock frequency = 20 MHz ; Actual delay = 0.005 seconds = 25000 cycles ; Error = 0 % Delay5ms ;banksel STORE1 ;24998 cycles movlw 0x87 movwf STORE1 movlw 0x14 movwf STORE2 Delay5ms_0 decfsz STORE1, f goto $+2 decfsz STORE2, f goto Delay5ms_0 ;2 cycles goto $+1 return Delay_100ms ;----------------------------------------------- ; Delay = 0.1 seconds ; Clock frequency = 20 MHz ; Actual delay = 0.1 seconds = 500000 cycles ; Error = 0 % banksel STORE1 ;499994 cycles movlw 0x03 movwf STORE1 movlw 0x18 movwf STORE2 movlw 0x02 movwf STORE3 Delay_100ms_0 decfsz STORE1, f goto $+2 decfsz STORE2, f goto $+2 decfsz STORE3, f goto Delay_100ms_0 ;6 cycles goto $+1 goto $+1 goto $+1 return udata STORE1 res 1 STORE2 res 1 STORE3 res 1 FLAGS res 1 D_STO res 1 END
file: /Techref/io/lcd/dh44780_spi_hc595.htm, 5KB, , updated: 2016/11/9 08:25, local time: 2024/12/25 17:04,
owner: AWG-PIA-TA5,
3.139.93.168:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.org/Techref/io/lcd/dh44780_spi_hc595.htm"> PIC16 Code to drive a HD44780 display over SPI, using a HC595</A> |
Did you find what you needed? |
Welcome to massmind.org! |
Welcome to massmind.org! |
.