ON 20060810@6:40:50 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm#38939.7783449074 Richard H McCorkle[RHM-SSS-SC4] See also: in a new file at: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm Simple Commands – A demonstration program for the 16F873A containing a simple command decoder and example routines to enter and print single and multi-byte data values in HEX, change command bits, and control program execution from a serial port. Using the Simple Commands demonstration program as a starting point for program development and selecting and customizing the routines you need for your application, adding serial port commands and data entry to your PIC program is easy! ON 20060810@6:44:05 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=1 ON 20060810@6:45:44 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=2 ON 20060810@6:50:04 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm#38939.7847685185 Richard H McCorkle[RHM-SSS-SC4] Code:
;********************************************************************* ; Function Description: ;********************************************************************* ; Demonstration of the Simple Commands decoder and HEX routines to ; add commands, HEX data entry, and HEX data print via the serial port ; to a PIC program. The code was developed for the 16F873A, but can be ; adapted to most PIC's with a UART. Runs in the background and no ; interrupts are used to free the interrupt routine for user tasks. ; Command decoder and print routines are loaded in page 1 memory to ; free page 0 memory for the user's program. ; Commands are similar to Motorola style @@Xnxx commands where @@ is ; command start, X capital letter is command, n small letter (optional) ; is sub command, and xx (optional) are HEX data charaters. For Simple ; Commands each data entry expects a known number of characters, no end ; of line or parity is used, and no error testing is performed on the ; data to siplify the code. ; Basic entry and print of single and multi-byte HEX data and control ; functions are demonstrated. Data is sent directly to memory but an ; example of a buffered load is shown. Nested menus are demonstrated ; for easy expansion of the command set as the project grows. By ; selecting and customizing the routines you need for your application, ; adding a custom command menu to your program is easy! ; ; These routines are free for public use but please acknowledge the ; author when using them in your program by commenting your code with ; "Simple Commands by Richard H McCorkle" (Is that so much to ask?) ; Thanks! ; ;********************************************************************* ; Serial Command Functions: ;********************************************************************* ; NOTE: Make sure that RTS is connected to CTS at the PIC serial port ; (DB-9 pin 7 tied to pin 8) and a standard serial cable (all pins ; connected) is used or commands may not function correctly. ; The demo command set is defined as: ; Command Function ; @@- Decrement v1 down 1 count ; @@+ Increment v1 up 1 count ; @@Bxxxxxxxxxx Buffered load of 40-bit value v4 ; @@E Toggle keyboard echo ; @@L Load register commands ; @@L0x Load 4-bit value v0 ; @@L1xx Load 8-bit value v1 ; @@L2xxxx Load 16-bit value v2 ; @@L3xxxxxx Load 24-bit value v3 ; @@L4xxxxxxxxxx Load 40-bit value v4 directly ; @@P Print value to serial TX port ; @@Pc Print Command Bit state ; @@P0 Print a 4-bit value from v0 ; @@P1 Print an 8-bit value from v1 ; @@P2 Print a 16-bit value from v2 ; @@P3 Print 24-bit value a or b (nested menu) ; @@P3a Print the 24-bit register v3 ; @@P3b Print the high 24-bits of 40-bit register v4 ; @@R Reset Command Bit C,0 ; @@S Set Command Bit C,0 ; @@Z Zero 40-bit v4 register ;********************************************************************* ; Program Listing: ;********************************************************************* TITLE "Simple Commands Demonstration - Richard H McCorkle, June 1, 2006" LIST n=58, p=PIC16F873A errorlevel 1 include P16F873A.INC __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF ;********************************************************************* ; Define Storage Locations ;********************************************************************* ;NOTE: Keep registers in H -> L sequential order for indexed ops! CBLOCK 0x20 ;Bank 0 Registers - 80 max, 25 used flg0 ;flag bit storage cHdr0 ;communication header flags ; cHdr1 ;if adding headers, add cHdr1,2, etc Hbyte,Mbyte,Lbyte ;Binary-to-HEX print storage BytCt,Dadr ;serial data entry regs btmp ;background temporary storage ; User variables v0 ;4 bit variable (0-F) v1 ;8 bit variable Hv2,Lv2 ;16 bit variable Hv3,Mv3,Lv3 ;24 bit variable Hv4,Mv4,Lv4 ;40 bit variable Sv4,SSv4 Hbuf,Mbuf,Lbuf ;40-bit Transfer Buffer Sbuf,SSbuf ENDC ;Registers 70-7F common in all banks so stack and buffers stored here ;If not common in PIC used, don't use bank 1 registers in the ;background without disabling interrupts first as background routine ;could be interrupted in either bank and W may not get saved properly ;in W_TEMP on interrupt. CBLOCK 0x70 ;Common registers - 16 max, 6 used W_TEMP ;temp storage for W on interrupt STAT_TEMP ;ditto for status reg PCL_TEMP ;ditto for PCLATH FSR_TEMP ;ditto for FSR TX_BUF ;the next char to be xmitted RX_BUF ;the last char received ENDC ;********************************************************************* ; Hardware Bit Assignments: ;********************************************************************* #define HPF PCLATH,3 ;Hi Program Memory Flag #define Zflag STATUS,Z ;Zero Flag #define Cflag STATUS,C ;Carry Flag #define CmdB PORTC,0 ;Command Bit ;********************************************************************* ; Flag Bit Assignments: ;********************************************************************* #define BrdyF flg0,0 ;Byte Ready flag #define LoByt flg0,1 ;Low Byte flag #define Nrdy flg0,2 ;Not Ready flag #define KBE flg0,3 ;Keyboard Echo flag #define bufF flg0,4 ;Buffered Load flag #define LBF flg0,5 ;Load From Buffer flag ;#define N/U flg0,6 ;Spare flag ;#define N/U flg0,7 ;Spare flag ;********************************************************************* ; Command Header Flags: ;********************************************************************* ;if adding headers, add Hdr7, Hdr8, etc keeping Nrtn last #define Hdr0 cHdr0,0 ;Header 0 Flag (@ ) #define Hdr1 cHdr0,1 ;Header 1 Flag (@@ ) #define Hdr2 cHdr0,2 ;Header 2 Flag (@@P ) #define Hdr3 cHdr0,3 ;Header 3 Flag (@@P3) #define Hdr4 cHdr0,4 ;Header 4 Flag (@@L ) #define Hdr5 cHdr0,5 ;Header 5 Flag (@@L0) #define Hdr6 cHdr0,6 ;Header 6 Flag (Nrtn) ;#define Hdr7 cHdr0,7 ;Header 7 Flag (N/U ) ;********************************************************************* ; Initialization ;********************************************************************* ;Set start of code and interrupt vector org 0 ;initialize code nop ;required for the ICD clrf STATUS ;ensure we are at bank 0 clrf PCLATH ;ensure page bits are cleared goto Start org 4 ;interrupt routine movwf W_TEMP ;"push" instructions swapf STATUS,W ;swapf affects NO status bits bcf STATUS,RP0 ;select bank 0 movwf STAT_TEMP ;save STATUS movf PCLATH,W movwf PCL_TEMP ;save PCLATH clrf PCLATH ;select page 0 movf FSR,W movwf FSR_TEMP ;save FSR bcf INTCON,INTF ;clear interrupt, else int again immediately! goto Int_srv ;initialize bank 0 ports and control registers Start clrf PORTA ;clear port output latches clrf PORTB clrf PORTC clrwdt ;before switching clear WDT & prescaler clrf INTCON ;disable all interrupts for now ;initialize bank 1 control regs bsf STATUS,RP0 ;select bank 1 ; Insert user initialize code here movlw 0xfe ;0 as output, 1-5 as inputs, movwf TRISC ;2 serial port pins clrf OPTION_REG ;no TMR0, int on falling edge clrf PIE1 ;no int on async xmt bsf TXSTA,TXEN ;enable USART Tx (async mode) bsf TXSTA,BRGH ;set USART BRGH = 1 movlw D'129' ;set async rate at 9600 baud movwf SPBRG ;129 for 20 MHz clock ;back to bank 0 bcf STATUS,RP0 ;bank 0 for RCSTA reg bsf RCSTA,CREN ;enable USART rcv (async mode) bsf RCSTA,SPEN ;enable serial port bsf INTCON,INTE ;enable interrupt on RB0 clrf flg0 ;clear all flags clrf cHdr0 ;clear cmd headers ; clrf cHdr1 ;if adding headers, add cHdr1,2, etc ; Insert user initialize code here ; bsf INTCON,GIE ;enable interrupts if used ;********************************************************************* ; Background Routine ;********************************************************************* ;In background routines, insure variables used (like temp) aren't ;changed during an interrupt as this could cause trouble on return. ;Btmp used for temp storage in command decoder to prevent this. Bkgnd call Rx232 ;check for character received btfss BrdyF ;if no byte ready goto $ + 7 ;jump past process command bcf BrdyF ;clear byte ready flag bsf HPF ;set hi program flag call CmdProc ;Process command bcf HPF ;reset hi program flag btfsc LBF ;if load buffered flag set call Buf2v4 ;load v4 from buffer ; Insert user background code here goto Bkgnd ;********************************************************************* ; Interrupt Service Routine ;********************************************************************* Int_srv ;Insert user interrupt code here pop bcf STATUS,RP0 movf FSR_TEMP,W ;restore FSR movwf FSR movf PCL_TEMP,W ;restore PCLATH movwf PCLATH swapf STAT_TEMP,W ;restore STATUS movwf STATUS swapf W_TEMP ;set status bits swapf W_TEMP,W ;restore W retfie ;return from interrupt ;********************************************************************* ; Subroutines ;********************************************************************* ; Load 40-bit v4 reg from buffer to prevent partial load from ; affecting ongoing process until full 40-bit value is entered. Buf2v4 bcf bufF ;clear buffer flag bcf LBF ;clear load buffered flag movf Hbuf,W ;move buffer to v4 movwf Hv4 movf Mbuf,W movwf Mv4 movf Lbuf,W movwf Lv4 movf Sbuf,W movwf Sv4 movf SSbuf,W movwf SSv4 return ;********************************************************************* ; Get serial Rx data from the USART Rx232 btfss PIR1,RCIF ;received a char? return ;no - return movf RCSTA,W ;check Rx status for error andlw 0x06 ;only error bits btfss Zflag ;if any set, jump to goto RxErr ;error service routine movf RCREG,W ;get char from input buffer movwf RX_BUF ;store in RX_BUF btfss KBE ;if keyboard echo set goto $ + 4 bsf HPF ;set hi program flag call Tx ;echo it back out Tx port bcf HPF ;reset hi program flag bsf BrdyF ;set byte available flag return RxErr bcf RCSTA,CREN ;clear CREN to clear overrun error movf RCREG,W ;read RCREG to clear framing error bsf RCSTA,CREN ;set CREN to rcv bcf BrdyF ;clear byte ready flag clrf cHdr0 ;clear header flags ; clrf cHdr1 ;if adding headers, add cHdr1,2, etc return ;********************************************************************* ; Page 1 Programs ;********************************************************************* ;To save space in the first page of program memory for the user's ;application the command decoder and print routines are loaded into ;page 1 of program memory. The HPF flag (PCLATH,3) is set to access ;page 1 programs from page 0, and needs to be reset when the routine ;returns to page 0. To access page 0 routines from page 1, clear ;HPF before call, set HPF when the routine returns to page 1. org 800 ;load following routines into page 1 ;********************************************************************* ; Simple Commands by Richard H McCorkle ;********************************************************************* ; Check command received via USART Rx mode. When adding additional ; headers keep number return as first routine by adjusting the ; header pointers in number return and SBC acordingly CmdProc btfss Hdr6 ;is header 6 flag set? (Number Return) goto H5 ;no, test next header call GetByt ;get data bytes btfsc Nrdy ;check not ready return ;if set, get next data btfsc bufF ;if buffered load selected bsf LBF ;set load from buffer flag goto Chf ;clear header flags and exit ;********************************************************************* ; @@L0x Load register with single byte H5 btfss Hdr5 ;header 5 flag set (@@L0 received)? goto H4 ;no, test for next header call HexC ;convert input to value movwf v0 ;save in v0 goto Chf ;clear header flags and exit ;********************************************************************* ;@@L Load register commands H4 btfss Hdr4 ;header 4 flag set (@@L received)? goto H3 ;no, test for next header ; @@L0x Load 4-bit value v0 movlw "0" ;is char a "0" ? call RxChk btfss Zflag goto $ + 3 ;no, next header bsf Hdr5 ;set Header 5 flag return ; @@L1xx Load 8-bit value v1 movlw "1" ;is char a "1" ? call RxChk btfss Zflag goto $ + 5 ;no, next header movlw v1 ;move indirect address to W G1R movwf Dadr ;store in Dadr movlw 0x01 ;get 1 register (2 bytes) goto SBC ; @@L2xxxx Load 16-bit value v2 movlw "2" ;is char a "2" ? call RxChk btfss Zflag goto $ + 5 ;no, next header movlw Hv2 ;move indirect address to W G2R movwf Dadr ;store in Dadr movlw 0x02 ;get 2 registers (4 bytes) goto SBC ; @@L3xxxxxx Load 24-bit value v3 movlw "3" ;is char a "3" ? call RxChk btfss Zflag goto $ + 5 ;no, next header movlw Hv3 ;move indirect address to W G3R movwf Dadr ;store in Dadr movlw 0x03 ;get 3 registers (6 bytes) goto SBC ; @@L4xxxxxxxxxx Load 40-bit value v4 movlw "4" ;is char a "4" ? call RxChk btfss Zflag goto Chf ;no valid @@L command, exit movlw Hv4 ;move indirect address to W G5R movwf Dadr ;store in Dadr movlw 0x05 ;get 5 registers (10 bytes) SBC movwf BytCt bsf Nrdy ;set not ready flag bsf Hdr6 ;set Header 6 flag return ;********************************************************************* ;@@P3x An example of a nested menu command H3 btfss Hdr3 ;header 3 flag set (@@P3 received)? goto H2 ;no, test for next header ; @@P3a Print the 24-bit register v3 movlw "a" ;is char an "a" ? call RxChk btfss Zflag goto $ + 3 ;no, next header call prt3 goto Prtn ;clear header flags and exit ; @@P3b Print the high 24-bits of 40-bit register v4 movlw "b" ;is char a "b" ? call RxChk btfss Zflag goto Chf ;no valid @@P3 command, exit call prt4 goto Prtn ;clear header flags and exit ;********************************************************************* ;@@P Print Commands H2 btfss Hdr2 ;header 2 flag set (@@P received)? goto H1 ;no, test for next header ; @@P3 Print 24-bit value a or b (nested menu) movlw "3" ;is char a "3" ? call RxChk btfss Zflag goto $ + 3 ;no, next header bsf Hdr3 ;set Header 3 flag return ; @@P0 Print a 4-bit value movlw "0" ;is char a "0" ? call RxChk btfss Zflag goto $ + 3 ;no, next header call prt0 goto Prtn ;clear header flags and exit ; @@P1 Print an 8-bit value movlw "1" ;is char a "1" ? call RxChk btfss Zflag goto $ + 3 ;no, next header call prt1 goto Prtn ;clear header flags and exit ; @@P2 Print a 16-bit value movlw "2" ;is char a "2" ? call RxChk btfss Zflag goto $ + 3 ;no, next header call prt2 goto Prtn ;clear header flags and exit ; @@Pc Print Command Bit state movlw "c" ;is char a "c" ? call RxChk btfss Zflag goto Chf ;no valid @@P command, exit movlw "0" btfsc CmdB movlw "1" call Tx Prtn call TxCrLf ;send new line goto Chf ;clear header flags and exit ;********************************************************************* ;@@X Main Menu Commands H1 btfss Hdr1 ;header 1 flag set (@@ received)? goto H0 ;no, test for command start ; @@- Decrement v1 down 1 count movlw "-" ;is char a "-" ? call RxChk btfss Zflag goto $ + 3 ;no, next header decf v1 goto Chf ;clear header flags and exit ; @@+ Increment v1 up 1 count movlw "+" ;is char a "+" ? call RxChk btfss Zflag goto $ + 3 ;no, next header incf v1 goto Chf ;clear header flags and exit ; @@Bxxxxxxxxxx Buffered 40-bit load register v4 command movlw "B" ;is char a "B" ? call RxChk btfss Zflag goto $ + 4 ;no, next header bsf bufF ;set Buffer Flag movlw Hbuf ;move indirect address to W goto G5R ; @@E Toggle keyboard echo movlw "E" ;is char an "E" ? call RxChk btfss Zflag goto $ + 5 ;no, next header movf flg0,W xorlw 0x08 ;toggle 3 bit movwf flg0 goto Chf ;clear header flags and exit ; @@L Load register commands movlw "L" ;is char an "L" ? call RxChk btfss Zflag goto $ + 3 ;no, next header bsf Hdr4 ;set Header 4 flag return ; @@P Print value to serial TX port movlw "P" ;is char a "P" ? call RxChk btfss Zflag goto $ + 3 ;no, next header bsf Hdr2 ;yes, set header 2 flag return ; @@R Reset Command Bit movlw "R" ;is char an "R" ? call RxChk btfss Zflag goto $ + 3 ;no, next header bcf CmdB ;clear command bit goto Chf ;clear header flags and exit ; @@S Set Command Bit movlw "S" ;is char an "S" ? call RxChk btfss Zflag goto $ + 3 ;no, next header bsf CmdB ;set command bit goto Chf ;clear header flags and exit ; @@Z Zero 40-bit v4 register movlw "Z" ;is char a "Z" ? call RxChk btfss Zflag goto Chf ;no valid @@ command, exit clrf Hv4 ;clear v4 register clrf Mv4 clrf Lv4 clrf Sv4 clrf SSv4 goto Chf ;clear header flags and exit ;********************************************************************* ;Decode @@ as command start, set Hdr1 flag H0 movlw "@" ;is char a "@" ? call RxChk btfsc Zflag goto $ + 4 btfsc Hdr0 ;If @ rcvd but second char not @ bcf Hdr0 ;clear header 0 flag and return ;exit btfsc Hdr0 ;was header 0 flag set? goto $ + 3 bsf Hdr0 ;no, set header 0 flag (@ rcvd) return ;exit bsf Hdr1 ;yes, set header 1 flag (@@ rcvd) return ;exit ;********************************************************************* ;clear header flags and exit Chf clrf cHdr0 ;clear header flags ; clrf cHdr1 ;if adding headers, add cHdr1,2, etc return ;********************************************************************* ; Check Received byte for match to character in W on call ; Sets Zflag if match RxChk movwf btmp movf RX_BUF,W subwf btmp,W return ;********************************************************************* ; Hex Convert - convert ASCII 0-9 or A-F to number 0-15 in W ; converts small a-f to caps by clearing 32 bit first so either caps ; or smalls for a-f work. Invalid chars produce some hex value HexC movf RX_BUF,W ;get the byte movwf btmp btfss btmp,6 ;number or char? goto $ + 4 bcf btmp,5 ;clear 32 bit (convert small to caps) movlw D'55' ;subtract 55 to convert A-F to values 10-15 goto $ + 2 movlw D'48' ;subtract 48 to convert 0-9 values subwf btmp,W andlw 0x0f ;discard high bits (convert to hex return ;if invalid character entered) ;********************************************************************* ; Get Bytes - fetch number of registers in BytCt and store ; at address starting at Dadr, clear Nrdy when finished GetByt movf Dadr,W ;get storage address movwf FSR call HexC ;convert input to value btfsc LoByt ;if LoByte set, goto $ + 5 movwf INDF ;load in storage swapf INDF ;move to hi nibble bsf LoByt ;set low byte flag return addwf INDF ;add to value in storage bcf LoByt ;clear low byte flag decfsz BytCt ;got all the registers? goto $ + 3 bcf Nrdy ;clear not ready flag return incf FSR ;point to next data movf FSR,W movwf Dadr ;and store in Dadr return ;********************************************************************* ; Hex Print Routines ;********************************************************************* ;Display data in the same Hex format used for data entry. ;print the 4-bit value in v0 prt0 movf v0,W ;print 4-bit value movwf Lbyte goto hp4 ;********************************************************************* ;print the 8-bit value in v1 prt1 movf v1,W ;print 8-bit value movwf Lbyte goto hp8 ;********************************************************************* ;print the 16-bit value in v2 prt2 movf Hv2,W ;print 16-bit value movwf Mbyte movf Lv2,W movwf Lbyte goto hp16 ;********************************************************************* ;print the 24-bit value in v3 prt3 movf Hv3,W ;print 24-bit value movwf Hbyte movf Mv3,W movwf Mbyte movf Lv3,W movwf Lbyte goto hp24 ;********************************************************************* ;print the high 24-bits of the 40-bit register v4 prt4 movf Hv4,W ;print 24-bit value movwf Hbyte movf Mv4,W movwf Mbyte movf Lv4,W movwf Lbyte goto hp24 ;********************************************************************* ;output chars in Hbyte, Mbyte, Lbyte as HEX ASCII to TX DATA hp24 swapf Hbyte,W movwf TX_BUF call TxHex ;print Hbyte hi nibble in hex movf Hbyte,W movwf TX_BUF call TxHex ;print Hbyte low nibble in hex hp16 swapf Mbyte,W movwf TX_BUF call TxHex ;print Mbyte hi nibble in hex movf Mbyte,W movwf TX_BUF call TxHex ;print Mbyte low nibble in hex hp8 swapf Lbyte,W movwf TX_BUF call TxHex ;print Lbyte hi nibble in hex hp4 movf Lbyte,W movwf TX_BUF goto TxHex ;print Lbyte low nibble in hex ;********************************************************************* ;convert lo nibble in TX_BUF to HEX ASCII and send TxHex movf TX_BUF,W ;get transmit data andlw 0x0f ;mask hi bits sublw 0x09 ;9 - W if >9, Cflag = 0 movf TX_BUF,W ;get data andlw 0x0f ;mask hi bits btfss Cflag ;is input >9 addlw 0x07 ;if >9 add 7 for A-F addlw "0" ;make ASCII Tx bsf STATUS,RP0 ;set bank 1 to access TXSTA reg btfss TXSTA,TRMT ;test for Tx buffer empty goto $ - 1 ;wait till buffer empty bcf STATUS,RP0 ;back to bank 0 movwf TXREG ;send it return ;********************************************************************* ;transmit carriage return, line feed TxCrLf movlw "\r" ;send CR to Tx call Tx movlw "\n" ;send LF to Tx goto Tx ;Tx returns to caller ;********************************************************************* de "SmplCmds - Richard H McCorkle, 06/01/2006" de " " ENDON 20060810@8:12:49 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=1 ON 20060810@8:19:13 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=2 ON 20060810@8:36:40 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=3 ON 20060810@8:41:20 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=4 ON 20060810@8:47:10 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=5 ON 20060810@8:51:50 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=6 ON 20060810@8:56:35 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=7 ON 20060810@9:00:52 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=8 ON 20060810@9:05:47 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=9 ON 20060810@9:16:56 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=3 ON 20060810@9:19:32 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=4 ON 20060810@9:26:45 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm#38939.8935763889 Richard H McCorkle[RHM-SSS-SC4] Says in a new file at: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm Simple Time Interval Counter with RS-232 Output – The Simple Time Interval Counter uses the 14-pin 16F688 PIC, a GPS receiver 1PPS as a reference, has variable averaging time set by serial port command, and provides a 10-digit BCD output to an RS-232 port. It is a low-cost four-IC solution for determining the time difference between a locally generated 1PPS and a GPS 1PPS and logging the difference to a computer for analysis. Demonstrates the addition of Simple Commands in page 0 memory to alter or print a single variable in a user program.
;********************************************************************* ; Function Description: ;********************************************************************* ;A simple Time Interval Counter with RS-232 output using a GPS 1PPS as ;the reference. By default the counter outputs a 10-digit BCD reading ;once per minute at 1.04ns per count resolution. Per count resolution ;equals (1 / XO speed) / samples per update period. Max specified TMR1 ;async clock speed is 16.7MHz so 16MHz XO is used, but XO's at other ;freqs are usable by adjusting the sample time for the resolution ;desired. Sample time is set using Simple Commands by entering @@Sxx ;where xx = HEX 00-FF (3C default=60 sec). Entering 00 takes 256 ;samples, 01-FF takes 1-255 samples per update. Entering @@P prints ;the current sample time in HEX to the serial port for verification. ;Time readings near zero or max count are not as linear as those at ;mid-scale. Adding an offset by inverting the DUT 1Hz to the TIC ;will improve operation where the inputs are closely aligned. ; ; +5v ; +5v + 1uf | ; |8 +5v GND ----| |---| ; ___|____ |1 |14 |2 | ; | | _|____|_ 1 _|______ 16 | ; | 16 MHZ |5 2| | ---| |---| ; | XO |-------| | + | | | + | ; | | | | --- | | --- ; |________| | | 1uf--- | | --- 1uf ; | | | | 3| |15 | ; |4 | | ---| |---|--- GND ; GND | | 4| | + | ; | | ---| | --- ; +5v | 16F688 | + | | MAX232 | ---1uf _____ ; |___ | | --- | |6 | 7| | ; |16 |5 | | 1uf--- | |--- ---| | ; _|___|__ 3| | | 5| | | 8| | ; 14| | ---| | ---| | ---| | ;GPS 1PPS --------| | | | |5 12| |13 3| | ; |Phillips|15 | 11| |-----------| |----------|DB-9F| ; | HC4046 |-------| |6 11| |14 2| | ; 3 | | | |-----------| |----------| | ;DUT 1Hz --------| | |________| |________| 5| | ; |________| GND ----| | ; | |_____| ; |8 ; GND ; ; NOTE: Fairchild HC4046 won't work, use Phillips (best) or TI HC4046. ; ;********************************************************************* ; I/O Pin Assignments: ;********************************************************************* ; Register Bit Pin Function ; PORTA 0 13 N/U ; 1 12 N/U ; 2 11 Interrupt (Ph Det falling edge) ; 3 4 N/U ; 4 3 TMR1 Gate In (Ph Det hi = count) ; 5 2 TMR1 Clock In (16M XO) ; PORTC 0 10 N/U ; 1 9 N/U ; 2 8 N/U ; 3 7 N/U ; 4 6 USART Async TX Out ; 5 5 USART Async RX In ;********************************************************************* ; Serial Command Functions: ;********************************************************************* ; NOTE: Make sure that RTS is connected to CTS at the PIC serial port ; (DB-9 pin 7 tied to pin 8) and a standard serial cable (all pins ; connected) is used or commands may not function correctly. ; Command Function ; @@Sxx Set Averaging Time 00-FF per sample ; @@P Print Averaging Time once to serial TX ;********************************************************************* ; Change History: ;********************************************************************* ; 08/10/2006 Time Interval Counter with RS-232 Output (Rev 1.00) ;********************************************************************* ; Software Listing: ;********************************************************************* TITLE "Time Interval Counter with RS-232 Output - Richard H McCorkle, August 10, 2006" LIST n=58, p=PIC16F688 errorlevel 1 include P16F688.INC __CONFIG _INTOSCIO & _PWRTE_ON & _WDT_OFF & _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF ;********************************************************************* ; Define Storage Locations ;********************************************************************* CBLOCK 0x20 ;Bank 0 Registers - 96 max, 24 used W_TEMP ;temp storage for W on interrupt STAT_TEMP ;ditto for status reg TX_BUF ;the next char to be xmitted RX_BUF ;the last char received BD4,BD3,BD2,BD1,BD0 ;Keep in sequence BD4,BD3,BD2,BD1,BD0 Hac,Mac,Lac,Sac ;32 bit data for BCD convert bCnt,bTst ;Binary-to-BCD regs BytCt,Dadr ;serial data entry regs HofCtr,LofCtr ;overflow counters cHdr0 ;command header flags flg0 ;flag bit storage temp ;temporary storage TicCt ;Averaging time storage tick ;interrupt counter ENDC ;********************************************************************* ; Flag Bit Assignments: ;********************************************************************* #define t1e T1CON,TMR1ON ;Timer 1 Enable #define t1f PIR1,TMR1IF ;Timer 1 Overflow Flag #define Zflag STATUS,Z ;Zero Flag #define Cflag STATUS,C ;Carry Flag #define BrdyF flg0,0 ;Byte Ready Flag #define LoByt flg0,1 ;Low Byte Flag #define Nrdy flg0,2 ;Not Ready Flag ;********************************************************************* ; Command Header Flags: ;********************************************************************* #define Hdr0 cHdr0,0 ;Header 0 Flag (@ ) #define Hdr1 cHdr0,1 ;Header 1 Flag (@@ ) #define Hdr2 cHdr0,2 ;Header 2 Flag (Nrtn) ;********************************************************************* ; Initialization ;********************************************************************* ;Set interrupt vector and start of code org 0 ;initialize code goto start org 4 ;interrupt routine goto int_srv ;Initialize bank 0 ports and control registers start clrf PORTA ;clear port output latches clrf PORTC clrf INTCON ;disable all interrupts for now clrf T1CON ;Stop Timer1 movlw 0x07 ;set PORTA pins as digital (not comparator inputs) movwf CMCON0 bsf CMCON1,T1GSS ;set to use external gate on TMR1 ;Initialize bank 1 control regs bsf STATUS,RP0 ;select bank 1 movlw 0x71 ;select 8MHz internal clock for PIC movwf OSCCON ;(Using XO for PIC disables TMR1 ext clk!) ; movlw 0x00 ;put a cal value in OSCTUNE to ; movwf OSCTUNE ;calibrate oscillator if desired clrf OPTION_REG ;no TMR0, int on falling edge clrf ANSEL ;PORTA pins as digital movlw 0x3f ;set PORTA pins as inputs movwf TRISA movlw 0x3f ;set PORTC pins as inputs, 2 serial port pins movwf TRISC clrf PIE1 ;no int. on async xmt (tst TRMT instead) ;Back to bank 0 bcf STATUS,RP0 ;select bank 0 bsf TXSTA,TXEN ;enable USART xmt (async mode) bsf TXSTA,BRGH ;set USART hi speed mode movlw D'51' ;set async rate at 9600 baud (51. for 8 MHz int, BRGH=1) movwf SPBRG bsf RCSTA,CREN ;enable USART rcv (async mode) bsf RCSTA,SPEN ;enable serial port bsf INTCON,INTE ;enable interrupt on RA2 clrf PIR1 ;clear peripheral interrupt flags movlw 0xc6 ;set TMR1 as f_osc/1, async, inv gate, ext clk movwf T1CON clrf TMR1H ;clear the counter clrf TMR1L clrf flg0 ;clear all flags clrf cHdr0 ;clear cmd headers clrf HofCtr ;clear overflow counters clrf LofCtr movlw 0x3c ;initialize at 60 samples/update movwf TicCt movwf tick bsf t1e ;enable TMR1 bsf INTCON,GIE ;enable interrupts ;********************************************************************* ; Background Routine ;********************************************************************* ; Check for command and process, check for TMR1 overflow and ; increment the overflow counters as needed. Allows 4.1ms for ; command process with no adverse effect on the count. Bkgnd call Rx232 ;check for character received btfss BrdyF ;if no byte ready goto $ + 3 ;jump past process command bcf BrdyF ;clear byte ready flag call CmdProc ;Process command btfss t1f ;wait for TMR1 overflow goto Bkgnd bcf t1f ;clear TMR1 o/f flag incf LofCtr ;inc Low overflow counter btfsc Zflag ;carry? incf HofCtr ;inc Hi overflow counter goto Bkgnd ;loop ;********************************************************************* ; Interrupt Service Routine ;********************************************************************* ; Disable and read TMR1 counter to get phase data. Reset and enable ; immediately so TMR1 is free to count while BCD convert and print ; are executed to minimize deadband error at max counts. Read and ; reset overflow counters used to extend TMR1 to 32-bits. Data is ; placed in AC, converted to 10-digit BCD, and printed. Reload ; the loop counter and return from interrupt. int_srv movwf W_TEMP ;"push" instructions swapf STATUS,W ;swapf affects no status bits movwf STAT_TEMP ;save STATUS bcf INTCON,INTF ;clear interrupt decfsz tick ;Display @ Loop count goto pop ;otherwise just exit bcf t1e ;disable TMR1 before read movf TMR1H,W ;read TMR1 hi byte movwf Lac ;and store movf TMR1L,W ;read TMR1 lo byte movwf Sac ;and store clrf TMR1H ;clear TMR1 clrf TMR1L bsf t1e ;enable TMR1 to count while printing btfss t1f ;check for TMR1 overflow goto $ + 5 bcf t1f ;if set, clear TMR1 o/f flag incf LofCtr ;inc Low overflow counter btfsc Zflag ;carry? incf HofCtr ;inc Hi overflow counter movf LofCtr,W ;get Low overflow Counter movwf Mac ;store clrf LofCtr ;and clear movf HofCtr,W ;get Hi overflow Counter movwf Hac ;store clrf HofCtr ;and clear call prt32 ;convert and print as 10-digit BCD movf TicCt,W ;reload tick counter movwf tick pop swapf STAT_TEMP,W ;restore STATUS movwf STATUS swapf W_TEMP ;set status bits swapf W_TEMP,W ;restore W retfie ;return from interrupt ;********************************************************************* ; Subroutines ;********************************************************************* ; Print 10-digit BCD ASCII to TX DATA prt32 call BCD32 ;convert to BCD movf BD0,W ;send BD0 (10-digit BCD) call TXBD movf BD1,W ;send BD1 call TXBD movf BD2,W ;send BD2 call TXBD movf BD3,W ;send BD3 call TXBD movf BD4,W ;send BD4 call TXBD TxLfCr movlw "\r" ;send CR direct to Tx call Tx movlw "\n" ;send LF direct to Tx goto Tx ;Tx returns to caller ;********************************************************************* ; 32 bit binary to BCD conversion (adapted from AN544) ; Input in Hac, Mac, Lac, Sac and output in BD0, BD1, BD2, BD3, BD4 BCD32 bcf Cflag ;convert 32 bit data to 10-digit BCD movlw D'32' movwf bCnt ;set bCnt = 32 bits clrf BD0 clrf BD1 clrf BD2 clrf BD3 clrf BD4 RL32 rlf Sac ;rotate 1 bit rlf Lac rlf Mac rlf Hac rlf BD4 rlf BD3 rlf BD2 rlf BD1 rlf BD0 decfsz bCnt ;32 bits done? goto $ + 2 ;no, process more BCD return movlw BD4 ;load addr of BD4 as indir addr movwf FSR movlw 0x05 ;process 5 registers movwf temp Adj movf INDF,W ;get reg via indirect addr addlw 0x03 movwf bTst ;sum to bTst for test btfsc bTst,3 ;test if >0x07 movwf INDF ;yes - store sum movf INDF,W ;get original or sum addlw 0x30 ;test hi byte movwf bTst ;sum to bTst for test btfsc bTst,7 ;test result >0x70 movwf INDF ;save as BCD incf FSR ;next reg decfsz temp ;Done? goto Adj ;no, do next adj goto RL32 ;********************************************************************* ; Send ASCII to TX DATA TXBD movwf TX_BUF swapf TX_BUF ;hi nibble call TxChar swapf TX_BUF ;low nibble TxChar movf TX_BUF,W ;get the buffer andlw 0x0f ;mask high nibble addlw "0" ;make into ASCII Tx btfss TXSTA,TRMT ;test for Tx buffer empty goto $ - 1 ;wait till buffer empty movwf TXREG ;send it return ;********************************************************************* ; Simple Commands by Richard H McCorkle ;********************************************************************* ; Get data via USART rcv mode Rx232 btfss PIR1,RCIF ;have we received a char? return ;no - nothing to do movf RCSTA,W ;check for rcv status for error andlw 0x06 ;select only error bits btfss Zflag ;if any set, jump to goto RxErr ;error service routine movf RCREG,W ;get char from input buffer movwf RX_BUF ;store in RX_BUF bsf BrdyF ;set byte available flag return RxErr bcf RCSTA,CREN ;clear CREN to clear overrun error movf RCREG,W ;read RCREG to clear framing error bsf RCSTA,CREN ;set CREN to rcv bcf BrdyF ;clear byte ready flag clrf cHdr0 ;clear header flags return ;********************************************************************* ; Check command received via USART rcv mode CmdProc btfss Hdr2 ;header 2 flag set (Number Return)? goto H1 ;no, test for next header call GetByt ;get data bytes btfsc Nrdy ;check not ready return ;if set, get next data goto Chf ;clear header flags and exit H1 btfss Hdr1 ;header 1 flag set (@@ received)? goto H0 ;no, test for header start ; @@P Print Averaging Time to serial TX port movlw "P" ;is char a "P" ? movwf temp movf RX_BUF,W subwf temp,W btfss Zflag goto $ + 3 ;no, next header call prtS ;print Averaging Time goto Chf ;clear header flags and exit ; @@Sxx Set Averaging Time 00-FF per sample movlw "S" ;is char an "S" ? movwf temp movf RX_BUF,W subwf temp,W btfss Zflag goto Chf ;no valid @@ command, exit movlw TicCt ;move indirect address to W movwf Dadr ;store in Dadr movlw 0x01 ;get 1 register (2 bytes) movwf BytCt bsf Nrdy ;set not ready flag bsf Hdr2 ;set Header 2 flag return H0 movlw "@" ;is char a "@" ? movwf temp movf RX_BUF,W subwf temp,W btfsc Zflag goto $ + 4 btfsc Hdr0 ;If @ rcvd but second char not @ bcf Hdr0 ;clear header 0 flag and return ;exit btfsc Hdr0 ;was header 0 flag set? goto $ + 3 bsf Hdr0 ;no, set header 0 flag (@ rcvd) return ;exit bsf Hdr1 ;yes, set header 1 flag (@@ rcvd) return ;exit Chf clrf cHdr0 ;clear header flags return ;********************************************************************* ; Hex Convert - convert ASCII 0-9 or A-F to number 0-15 in W ; converts small a-f to caps by clearing 32 bit first ; so either caps or smalls for a-f work. HexC movf RX_BUF,W ;get the byte movwf temp btfss temp,6 ;number or char? goto $ + 4 bcf temp,5 ;clear 32 bit (convert small to caps) movlw D'7' ;subtract 55 to convert A-F to values 10-15 subwf temp movlw D'48' ;subtract 48 to value subwf temp movf temp,W andlw 0x0f ;discard high bits (if wrong char) return ;********************************************************************* ; Get Bytes - fetch number of registers in BytCt and store ; at address starting at Dadr, clear Nrdy when finished GetByt movf Dadr,W ;get storage address movwf FSR call HexC ;convert input to value btfsc LoByt ;if LoByte set, goto $ + 5 movwf INDF ;load in storage swapf INDF ;move to hi nibble bsf LoByt ;set low byte flag return addwf INDF ;add to value in storage bcf LoByt ;clear low byte flag decfsz BytCt ;got all the registers? goto $ + 3 bcf Nrdy ;clear not ready flag return incf FSR ;point to next data movf FSR,W movwf Dadr ;and store in Dadr return ;********************************************************************* ; Provides display of average time in Hex format used for data entry. prtS swapf TicCt,W ;print average time movwf TX_BUF call TxHex ;print hi nibble in hex movf TicCt,W movwf TX_BUF call TxHex ;print low nibble in hex goto TxLfCr ;TxLfCr returns to caller ;********************************************************************* ; Convert lo nibble in TX_BUF to HEX ASCII and send TxHex movf TX_BUF,W ;get transmit data andlw 0x0f ;mask hi bits sublw 0x09 ;9 - W if >9, Cflag = 0 movf TX_BUF,W ;get data andlw 0x0f ;mask hi bits btfss Cflag ;is input >9 addlw 0x07 ;if >9 add 7 for A-F addlw "0" goto Tx ;********************************************************************* de "TIC-232 Rev 1.00, Richard H McCorkle 2006" de " " ENDON 20060810@9:37:13 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=1 ON 20060810@9:45:23 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=2 ON 20060810@9:50:00 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=3 ON 20060810@9:57:52 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=4 ON 20060810@10:07:50 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=5 ON 20060810@10:14:56 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=6 ON 20060810@10:16:35 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=7 ON 20060810@10:17:59 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=8 ON 20060810@10:24:26 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=9 ON 20060810@10:28:27 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/index.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\index.htm&version=10 ON 20060810@10:52:49 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=6 ON 20060810@11:01:55 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=10 ON 20060810@11:22:10 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=11 ON 20060810@11:26:27 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=7 ON 20060810@11:30:07 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=12 ON 20060810@11:32:18 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=13 ON 20060811@1:46:34 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/Scmds.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\Scmds.htm&version=14 ON 20060811@1:55:24 PM at page: http://www.piclist.com/techref/member/RHM-SSS-SC4/TIC232.htm# Richard H McCorkle[RHM-SSS-SC4] edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\member\RHM-SSS-SC4\TIC232.htm&version=8