In this
article:
Source Code
License
Navigation:
HomeHardware
Software
Techniques
Controllers
Reviews
Description
These are utility routines I wrote for dealing with the LAB-X3 peripherals. They include a simple LCD driver (initialization, character writing), some declarations for the LEDs, and the implemntation of a delay loop that can be called (versus generated inline as with the macros in util.inc). Note that you will need to modify your LAB-X3 if you want these to work. If you have not done the mod the LCD driver won't work.
The Source Code
; vim: set syntax=pic : ; UTIL.ASM - Utility Routines ; Written by Chuck Manis (http://www.mcmanis.com/chuck) ; This Version 28-Dec-01 ; Copyright (c) 2001 Charles Manis, All Rights Reserved ; ; Change Log: ; 28-DEC-01 Initially created file as the useful ; functions out of my LCD test programs. ; ; NOTICE: THIS CODE COMES WITHOUT WARRANTY OF ANY KIND EITHER ; EXPRESSED OR IMPLIED. USE THIS CODE AT YOUR OWN RISK! ; I WILL NOT BE HELD RESPONSIBLE FOR ANY DAMAGES, DIRECT ; OR CONSEQUENTIAL THAT YOU MAY EXPERIENCE BY USING IT. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; ; Declare variables that we will use internally. ; CBLOCK DLY_CNT CMD_DELAY LCD_TMP NUM:2 ; Number to convert low byte ... NUM_STR:5 ; ... high byte ENDC #include "util.inc" LED1 EQU 4 LED2 EQU 5 LCD_E EQU 6 CVT_NUM: BIN2ASCII NUM, NUM_STR RETURN ; ; The LCD on the LAB-X3 (modified) is connected thusly: ; RA0 - DB4 RA4 - RS ; RA1 - DB5 ; RA2 - DB6 RB6 - E (this was my modification) ; RA3 - DB7 ; ; The LCD needs to be initialized into 4 bit mode and then ; we should be able to write letters to it. Note that on the ; LAB-X3 the LCD is ALWAYS in write mode, no reading allowed so ; you just have to hope it isn't busy. ; ; According to the Hitachi data sheet, you first have to ; wait 15 mS to insure the display is "stable" after Vcc is ; applied. Then the following sequence puts it into "4 bit" ; mode (reset by instruction) ; 0x03 ' wait > 4.1 mS ; 0x03 ' wait > .1 mS ; 0x03 ' wait > .1 mS ; 0x02 ' wait > .1 mS ; Display is now in 4-bit mode so initialize it with: ; 0x02 0x08 ' Set 4-bit mode, 2 line display ; 0x00 0x08 ' Display "ON" ; 0x00 0x01 ' Clear Display ; 0x00 0x06 ' Entry mode, auto increment cursor ; LCD_INIT: MOVLW D'200' ; Wait for LCD to settle CALL DELAY MOVLW H'03' ; Set LCD for 4 bits MOVWF PORTA ; Data Lines BSF PORTB,LCD_E ; Toggle E BCF PORTB,LCD_E ; MOVLW H'50' ; Wait 5 mS CALL DELAY BSF PORTB, LCD_E ; Send command again BCF PORTB, LCD_E MOVLW H'2' CALL DELAY BSF PORTB, LCD_E ; Third time's the charm BCF PORTB, LCD_E MOVLW H'2' CALL DELAY MOVLW H'02' ; Set for 4 bits MOVWF PORTA ; like so BSF PORTB, LCD_E ; BCF PORTB, LCD_E MOVLW H'2' ; Wait .2 mS CALL DELAY ; ; Now at this point its in 4-bit mode so send setup ; commands through the 4-bit interface. ; MOVLW H'28' ; Set 2 line display, 4 bit I/O CALL LCD_CMD ; MOVLW H'08' ; Turn off the Display CALL LCD_CMD MOVLW H'01' ; Clear the contents of the display CALL LCD_CMD MOVLW H'06' ; Set the Entry mode CALL LCD_CMD MOVLW H'0C' ; Turn it on again CALL LCD_CMD RETURN ; Ready to rock and roll ; ; LCD_CMD ; ; Generic routine to send a command to the LCD. Since some ; commands take longer to run this routine waits 1mS after it ; sending the command to insure the LCD is done with it. ; LCD_CMD: MOVWF LCD_TMP ; Store command MOVLW H'1' ; This is the generic delay MOVWF CMD_DELAY ; Used by default MOVLW H'FC' ; This is how we check for clear/home ANDWF LCD_TMP,W ; If any bit other than 0 or 1 is set BTFSS STATUS,Z ; GOTO OK_DELAY ; If non-zero leave delay alone MOVLW D'20' ; Else store 2mS delay value. MOVWF CMD_DELAY OK_DELAY: SWAPF LCD_TMP,W ; Read it, put upper nibble down ANDLW H'0f' ; Turn OFF the R/S bit MOVWF PORTA ; Out it goes BSF PORTB,LCD_E ; Clock it out BCF PORTB,LCD_E ; Like so MOVF LCD_TMP,W ; Get lower nybble ANDLW H'0F' ; Turn off R/S MOVWF PORTA ; Put it on PortA BSF PORTB,LCD_E ; Clock it out BCF PORTB,LCD_E ; MOVF CMD_DELAY,W ; Wait for it to complete CALL DELAY RETURN ; ; ; LCD_CHAR ; ; Generic routine to send a command to the LCD. In this ; version it just sends it, a "smarter" version would watch ; for <CR> or <LF> and do something appropriate to the display. ; LCD_CHAR: MOVWF LCD_TMP ; Store it in LCD_TMP SWAPF LCD_TMP,W ; Upper Nybble ANDLW H'0F' ; Clear upper bits IORLW H'10' ; Turn On R/S bit MOVWF PORTA ; Put it out to PortA BSF PORTB,LCD_E ; Clock it out BCF PORTB,LCD_E ; MOVF LCD_TMP,W ; Get the lower nybble ANDLW H'0F' ; Clear upper bits IORLW H'10' ; Turn on R/S Bit MOVWF PORTA ; Out to PORTA BSF PORTB, LCD_E ; Clock it out BCF PORTB, LCD_E ; MOVLW H'2' ; Wait a bit CALL DELAY RETURN ; ; Delay Loop ; ; This function is designed to delay for 100uS times the number ; of times through the loop ; Once through : ; 1+91+2+1+2+1+2 = 100 ; ; Twice through ; 1+91+2+1+1+2+96+1+2+1+2 = 200 ; ****** ; Thrice through ; 1+91+2+1+1+2+96+1+1+2+96+1+2+1+2 = 300 ; ******** ****** ; "N" times through (n * 100) cycles. ; ; NOTE: This will have to be changed when you change the ; frequency from 4Mhz, but for the LAB-X3 it works great! ; DELAY: MOVWF DLY_CNT ; Store delay count (1) WAIT 91 ; Delay 95 GOTO D2_LOOP ; Check to see if it was 1 (2) D1_LOOP: WAIT 96 ; (20) D2_LOOP: DECF DLY_CNT,F ; Subtract 1 (1) INCFSZ DLY_CNT,W ; Check for underflow (2) GOTO D1_LOOP ; Not zero so loop (2) NOP RETURN
License
This work is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License. You are free to play around with it and modify it but you are not licensed to use it for commercial purposes. Click the link above for more details on your rights under this license.