; count.ASM ; version 1.0 written for MPASM ; This program initializes a Hitachi LCD HD44780 module, ; The program includes a subroutine, blip_E, that handles all the required ; handshaking to send data or instructions to the LCD. ; This is the eight bit version but I have tried with four bits. It's not ; difficult to convert blip_E ; There is a demonstration of indirect addressing using the file select ; register and the indirect register. ; ======== ; Counter code ; (c) Matthew Rowe, 20/9/95 ; ======== LIST P=16C84;f=inhx8m ; these are directives for the programmer to set various fuses in the 16C84 _CP_OFF equ H'3FFF' ;code protect off _PWRTE_ON equ H'3FFF' ;Power on timer on _WDT_OFF equ H'3FFB' ;watch dog timer off _XT_OSC equ H'3FFD' ;crystal oscillator __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC ;configure directive w equ 0 ; destination numbers. f equ 1 same equ 1 z equ 2 ; status bits zero equ 2 c equ 0 carry equ 0 ind equ 00 ; indirect register f0 pc equ 02 ; program counter f2 status equ 03 ; status register f3 fsr equ 04 ; file select register. ; contents are used as an address ; when you operate on f0 porta equ 05 ; port a I/O register f5 portb equ 06 ; port b I/O register f6 LCDcontrol = porta ;Control lines to LCD PIC Display pin nos. RW = 2 ;0=write, 1=read 1 5 RS = 1 ;0=instruction reg, 1=data reg 18 4 E = 0 ;0=disable, 1=enable 17 6 LCDdata = portb ;Data to LCD 6-13 7-14 count = 3 ;Number of characters ; LCD commands follow wide = b'111000' ; 8 bit interface narrow = b'101000' ; 4 bit interface clear = 1 ; clear display home = b'10' ; cursor home ns_dec = b'100' ; no shift, decrement s_dec = b'101' ; shift, decrement ns_inc = b'110' ; no shift, increment s_inc = b'111' ; shift, increment dispon = b'1100' ; display on, cursor off, blink off dispoff = b'1000' ; display off cur_line = b'1110' ; line cursor cur_blk = b'1111' ; block cursor curR = b'10100' ; move cursor right curL = b'10000' ; move cursor left movR = b'11100' ; shift display right movL = b'11000' ; shift display left ; Set RAM origin above special registers, declare variables, and set code ; origin. cblock 0C temp ;Temporary counter. temp2 ;Pass data or instructions to blip_E. counter ;Index variable. tmp_bit ;Temp to store RS bit value tmp_w tmp_s tmp_bit1 tmp_bit2 dig1 ; counter display digits. dig2 dig3 dig4 endc org 0 goto start org 5 start movlw 0 ;Initialize ports, power LCD and wait movwf porta ;for it to reset. movlw 0 movwf tmp_bit movlw 0 movwf portb movlw 0 tris porta ;Set control lines to output movlw 0 tris portb bsf LCDcontrol,pwr call wait ;LCD FUNCTIONS initialize movlw wide movwf temp2 ;Initialize LCD: set 8-bit, 2-line ; 2 lines due to a 1 IC LCD display call blip_E ;Send data ;LCD set DISPLAY movlw dispon movwf temp2 ;Display ON, Cursor OFF call blip_E ;Send data ;LCD set ENTRY MODE movlw ns_inc movwf temp2 ;Increment Pointer,no display shift call blip_E ;Send data ;LCD set DD RAM bcf LCDcontrol,RS ;Set control register movlw b'10000000' movwf temp2 ;Write to DD RAM at address 0. call blip_E ;send data init_digs movlw 30 movwf dig1 movlw 30 movwf dig2 movlw 30 movwf dig3 movlw 30 movwf dig4 stopwatch call send_alpha first call wait call update incf dig1 movlw 3A subwf dig1,w btfss status,c goto first movlw 30 movwf dig1 second incf dig2 movlw 3A subwf dig2,w btfss status,c goto first movlw 30 movwf dig2 third incf dig3 movlw 3A subwf dig3,w btfss status,c goto first movlw 30 movwf dig3 fourth incf dig4 movlw 3A subwf dig4,w btfss status,c goto first goto init_digs ;run program again. ;-------------------------------------------------------------------------- ;SUBROUTINES ;-------------------------------------------------------------------------- send_alpha bsf LCDcontrol,RS ;set data register movlw 0 movwf counter ;Send the message string to the LCD. loopalpha movf counter,w call msg movwf temp2 call blip_E incf counter ; counter+=1 movlw count subwf counter,w btfss status,c goto loopalpha return ;-------------------------------------------------------------------------- blip_E ;Store current state of RS btfss LCDcontrol,RS ;bit test skip next if set bcf tmp_bit1,0 ;clear temp bit btfsc LCDcontrol,RS ;bit test skip next if clear bsf tmp_bit1,0 ;set temp bit bcf LCDcontrol,RS ;Clear RS to send instruction. bsf LCDcontrol,RW ;Set RW to read. movlw b'11111111' tris portb ;Portb all inputs. busy bsf LCDcontrol,E ;Enable the LCD. nop movf LCDdata,w movwf temp ;Put LCD data (rb) into temp. bcf LCDcontrol,E ;Disable LCD. btfsc temp,7 ;Is the LCD busy? goto busy ;Yes, try again later. btfss tmp_bit1,0 ; No send the data or instruction bcf LCDcontrol,RS btfsc tmp_bit1,0 bsf LCDcontrol,RS bcf LCDcontrol,RW movlw 0 tris portb ;Portb all outputs. movf temp2,w movwf LCDdata bsf LCDcontrol,E nop bcf LCDcontrol,E return ;-------------------------------------------------------------------------- wait movlw .200 movwf temp2 ;Create a delay for LCD power-on reset. delay decfsz temp goto delay decfsz temp2 goto delay return ;-------------------------------------------------------------------------- msg addwf pc,same ; Table of characters to display. retlw 'm' retlw 'w' retlw 'r' ;-------------------------------------------------------------------------- update bcf LCDcontrol,RS ; set control register movlw b'10000101' ; move to 5th character along movwf temp2 call blip_E bsf LCDcontrol,RS ; set data register movlw 4 movwf counter ;Send the message string to the LCD. movlw dig4 movwf fsr ;put base address of digits in fsr loop movf ind,w ;get indirected digit movwf temp2 call blip_E decf fsr decf counter ; counter-=1 movf counter,w ; get counter back for zero test btfss status,z goto loop return END