With no offers from anyone to run my LCD code, I'm posting it here for code review. I'd appreciate any help I can get. My code is mostly a flat-out copy of Myke's demo code, with minor modifications. For instance, the code on Myke's page generates a huge number of MPASM compiler warnings, so I tweaked (basically adding destination operands) until the compiler warnings went away. Also, Myke's code contained inline decimal math. Rather than figuring out how to tell the compiler to use decimal evaluation, I did the evaluation and replaced the constant. My code can be compared almost line for line with Myke's code at http://www.myke.com/code/2wirepic.asm My program is built on top of my first PIC program. This program is supposed to reset the LCD, display "Hi there" on the LCD, and then count infinitely on the portB pins. I can see that *something* is getting to the LCD, as it does change its behavior/display when my project is powered up. This is running on a 4MHz PIC16F84. The LCD routines are marked with highly visible comments if you want to scroll straight to them. My initialization code is also likely to have errors. Many thanks in advance to anyone who looks at my code! -Matt My code looks like this: list p=16f84 __config _CP_OFF & _PWRTE_ON & _WDT_OFF ;add XT include ;file register variables inner equ 0x0c ;temp variable outer equ 0x0d ;temp variable output equ 0x0e ;the byte sent to the output pins of port b Dlay equ 0x0f ;scratch byte for LCD delay routines Temp equ 0x10 ;temp byte for LCD routines NOTemp equ 0x11 ;temp byte for LCD routines ;constants INNER_LOOP_DELAY equ 0x8a #DEFINE LCDData PORTA,0 #DEFINE LCDClock PORTA,1 ;macros ClockStrobe MACRO bsf LCDClock bcf LCDClock ENDM EStrobe MACRO bsf LCDData bcf LCDData ENDM ;start of program org 0x00 ;program memory base at 0x00 reset ;reset vector goto start ;Go to start of main program org 0x04 ;Beginning of user code start ;=========================================================================== = ;Setup stuff here. ;=========================================================================== = clrf output ;clear the output shadow register clrf outer ;initialize the outer loop counter clrf PORTB ;clear the LED output pins clrf PORTA ;clear the LCD output pins movlw INNER_LOOP_DELAY movwf inner ;initialize the inner loop counter bsf STATUS,5 ;select bank 1 clrf TRISB ;set portb to outputs bcf TRISA,0 ;set LCDData to output bcf TRISA,1 ;set LCDClock to output bcf STATUS,5 ;select bank 0 ;=========================================================================== = ;Test things by writing to the LCD ;=========================================================================== = call ResetLCD movlw "H" call SendLCDChar movlw "i" call SendLCDChar movlw " " call SendLCDChar movlw "t" call SendLCDChar movlw "h" call SendLCDChar movlw "e" call SendLCDChar movlw "r" call SendLCDChar movlw "e" call SendLCDChar ;=========================================================================== Main program code was here, stripped out for code review to save space. ;=========================================================================== test goto test ;=========================================================================== = ;LCD routines start here. ;=========================================================================== = ResetLCD call Dlay5 ;Wait 20msec before resetting the LCD call Dlay5 call Dlay5 call Dlay5 bcf STATUS,C ;clear the carry flag (//WHY?) movlw 0x03 ;reset command (//Is this right? Should be 0x30?) call NybbleOut ;send the command call Dlay5 ;wait 5 usec before sending second time EStrobe call Dlay160 ;wait 160 usecs before sending third time EStrobe call Dlay160 ;wait 160 usecs before continuing ;LCD should now be reset. bcf STATUS,C movlw 0x02 ;LCS 4-bit mode command call NybbleOut call Dlay160 movlw 0x28 ;?? for two-line display call SendLCDINST movlw 0x08 ;turn off the display call SendLCDINST movlw 0x01 ;Clear display RAM call SendLCDINST call Dlay5 movlw 0x06 ;enable cursor move direction call SendLCDINST movlw 0x0c ;turn LCD back on call SendLCDINST return SendLCDINST movwf Temp swapf Temp,w bcf STATUS,C call NybbleOut movf Temp,w bcf STATUS,C call NybbleOut return SendLCDChar movwf Temp swapf Temp,w bsf STATUS,C call NybbleOut movf Temp,w bsf STATUS,C call NybbleOut return NybbleOut movwf NOTemp ;save the nybble to shift out swapf NOTemp,F movlw 6 ;clear the shift register movwf Dlay NOLoop1 ClockStrobe decfsz Dlay,F goto NOLoop1 bsf LCDData ;Put out the Gate bit ClockStrobe bcf LCDData ;Put out the RS bit rlf PORTA,F ClockStrobe movlw 4 movwf Dlay NOLoop2 rlf NOTemp,F bcf LCDData rlf PORTA,F ClockStrobe decfsz Dlay,F goto NOLoop2 EStrobe return Dlay160 movlw 0xD8 ;256 - ( 160 / 4 ) addlw 1 btfss STATUS,C goto $-2 return Dlay5 movlw 4 movwf Dlay movlw 0x18 ;256 - 0x0E8 addlw 1 btfsc STATUS,Z decfsz Dlay,F goto $-3 return end -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics