This is a program made from chopped up bits of other routines. It compiles OK but I've not got a circuit handy to try it out on. The routines themselves work, and it should be 99% of what you need. Hopefully I've not missed any banking instructions or something dopey like one variable doing two jobs It's for an F628 @ 9.8304MHz. If you've got something different you'd need to change the timing. As the program I cut a lot of this from uses many small timeouts, which I've called to get the 1 minute, you may find the small cumulative error unacceptable. And it ain't too pretty put together this way. In that case I'd suggest you use the Timers (maybe as an IRQ source, as could RCIF be) and prescalers. Timer values will also depend on the speed of the PIC, although a 32kHz can be used on Timer1 with good results I don't use the F84 any more so this is for any PIC with a UART and a 16x2 LCD in 4-bit mode on PortA and the top half of PortB I'm not entirely clear about the interaction between the PIC and PC. I've assumed that the PIC waits until the PC sends a char out of the serial port. One potential problem is the PC and PIC not being in synch at some point. The PIC should probably be able to process all bytes it sees without framing errors etc, but I couldn't really guarantee that. Clearing receive errors in the comms section does seem to minimise this IME and I can't say I've ever had any major difficulties ; 2chars.asm ; ; 15th June 2003 ; ; Pick up 2 chars from PC serial port and display on LCD list P = 16F628 include "P16F628.inc" ; errorlevel -305, -302, -306 ; ;instruction time at 9.8304MHz = 407ns ; __CONFIG _CP_OFF & _HS_OSC & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF & _LVP_OFF ;================================================ ; Macros for bank and page selection ;================================================ bank0 macro bcf status,rp0 bcf status,rp1 bcf status,irp endm bank1 macro bsf status,rp0 bcf status,rp1 bcf status,irp endm clrscrn macro movlw 0x01 call write_c endm #define rs porta,2 ;LCD RS #define en porta,3 ;LCD enable #define rw porta,4 ;LCD R/W #define busy portb,7 ;LCD Busy flag #define carry status,0 #define zero status,2 cblock 0x20 dg1 ;display digit 1 dg2 ;display digit 2 cnt1 ;scratch cnt2 cnt3 temp bshad ;PortB shadow seconds endc org 0x00 ;start address goto init init clrf status ;bank0 clrf porta clrf portb clrf t1con ;Timer1 off, no pre-scaler, use Fosc clrf intcon clrf pir1 clrf tmr1h clrf tmr1l bank1 movlw b'00000000' ; 0 LCD R/W ; 0 LCD Enable ; 0 LCD RS ; 0 spare ; 0 spare movwf trisa movlw b'00000010' ; 0 LCD data 3 ; 0 LCD data 2 ; 0 LCD data 1 ; 0 LCD data 0 ; 0 spare ; 0 Serial Tx ; 1 Serial Rx ; 0 spare movwf trisb movlw 0x80 ;PortB pullups off movwf option_reg bank0 movlw 0x07 ;comparators off movwf cmcon call lcd_init ;initialise LCD call line1 ;set display to line 1, position 0 movlw 0x07 ;display "Ready" for 1 second movwf pclath clrf cnt1 gettch1 movf cnt1,w call ready ;get chars from 0x700 call write_d incf cnt1 movlw .05 ;number of display chars to get xorwf cnt1,w bnz gettch1 movlw .246 ;1 second delay movwf cnt3 call ms100 incfsz cnt3 goto $-2 clrscrn goto comms ;set up UART ;================================================ ; LCD commands ;================================================ line1 movlw 0x00 ;line 1, column 0 call address return line2 movlw 0x40 ;line 2, column 0 call address return address addlw 0x80 ;set high bit of address command call write_c return write_c bcf rs ;write command goto d_out write_d bsf rs ;write data d_out movwf temp ;store 8-bit value movf portb,w ;read port andlw 0x0f ;clear MS Nybble movwf bshad movf temp,w ;add temp MS Nybble to bshad andlw 0xf0 addwf bshad,w movwf portb ;write back to port bcf rw nop bsf en nop bcf en movf portb,w ;read port andlw 0x0f ;clear MS Nybble movwf bshad swapf temp,w ;add LS Nybble to bshad andlw 0xf0 addwf bshad,w movwf portb ;write back to port bcf rw nop bsf en nop bcf en call getbusy return getbusy bsf rw ;set LCD RW for Read nop bcf rs bank1 movlw b'11110010' ;make d7 an input movwf trisb bank0 bsf en rdbusy btfsc busy ;loop until Busy Flag clear goto rdbusy bcf en bcf rw bank1 movlw b'00000010' ;d7 as output again movwf trisb bank0 return ;================================================ ; Initialise LCD screen in 4-bit mode ;================================================ lcd_init call write30 call msdelay ;delay > 4.1ms call msdelay call msdelay call msdelay call msdelay call write30 call msdelay ;delay > 100us call write30 call msdelay ;delay > 100us movlw 0x20 ;2 lines, 5x7 font call write_c movlw 0x08 ;1+DCB = display on, no cursor, no blink call write_c movlw 0x0c ;display clear call write_c movlw 0x06 ;entry mode set, increment address call write_c return ;return from initialisation write30 movlw 0x30 movwf temp ;store 8-bit value movf portb,w ;read port andlw 0x0f ;clear MSN movwf bshad movf temp,w ;add temp MSN to bshad andlw 0xf0 addwf bshad,w movwf portb ;write to port bcf rw nop bsf en nop bcf en movf portb,w ;read port andlw 0x0f ;clear MSN movwf bshad swapf temp,w ;add LSN to bshad andlw 0xf0 addwf bshad,w movwf portb ;write to port bcf rw nop bsf en nop bcf en return ;================================================ ; Initialise RS232 serial comms ;================================================ ; 9600 with BRGH = 1 @ 9.8304MHz ; X = ( (9830400 / 9600) / 16 ) -1 ; X = (1024/16)-1 ; X = 63 comms bank1 movlw .63 ;9600 baud movwf spbrg movlw b'00100100' ;brgh=1, Asynch, 8-bit, Tx enabled movwf txsta bank0 movlw b'10010000' ;Asynch, 8-bit, Rx enabled movwf rcsta movf rcreg,w ;clear receive reg, buffer, and rcif movf rcreg,w movf rcreg,w bcf rcsta,cren ;clear any errors bsf rcsta,cren ;================================================ ; Receive loop ;================================================ receive clrscrn ;clear LCD bank0 movf rcreg,w ;clear receive reg movf rcreg,w movf rcreg,w bcf rcsta,cren bsf rcsta,cren btfss pir1,rcif ;get char1 goto $-1 movf rcreg,w ;optional add #30 to convert hex digit to ASCII ; addlw 0x30 call write_d ;display W btfss pir1,rcif ;get char2 goto $-1 movf rcreg,w ;optional add #30 to convert hex digit to ASCII ; addlw 0x30 call write_d ;display W ;================================================ ; Timeout for 1 minute ;================================================ movlw .03 movwf seconds call s20 ;delay 20 seconds decfsz seconds goto $-2 goto receive ;exit after 60 sec ;================================================ ; Delays ;================================================ s20 movlw (.256-.200) ;20 second delay movwf cnt3 call ms100 ;do 200 * .1s incfsz cnt3 goto $-2 return ;100ms delay ms100 bank0 movlw .156 movwf temp call msdelay incfsz temp goto $-2 return ;1ms delay - call 100us delay 10 times msdelay movlw 0xf6 movwf cnt1 call usdelay incfsz cnt1 goto $-2 return ;100us delay usdelay movlw -4f movwf cnt2 incfsz cnt2 goto $-1 return ;================================================ org 700h ;init display chars ready addwf pcl,f retlw "R" retlw "e" retlw "a" retlw "d" retlw "y" end -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu