;******************************************************************************* ;** ;** Base code for building data logging device. ;** Memory device designed for 24C64, 8K byte EEPROM ;** ;** Written by Rick Huang, Copyright (C) 2004 ;** Revision YYYY/MM/DD ;** Rev 1. 2004/04/30 - Initial release, code base adapted from USB base code ;** Rev 2. 2004/10/09 - Added ability to capture temperature data off TC-77 sensor ;** Rev 3. 2004/10/10 - Add reliable transfer routine that make bulk transfer reliable ;** ;** ;** Command Functions ;** '1' External EEprom read one byte (Input 16bit address) ;** '2' External EEprom write one byte (Input 16bit address + 8bit data) ;** '3' External EEprom dump data (1024 bytes) ;** '4' Hex test - echo any hex input ;** '5' Thermo Sensor Reading (Output 13 bit data) ;** '6' Clear Timer, Also disable data acq routine ;** '7' Read Timer, Also enable data acq (Output 24bit data in seconds) ;** '8' ;** '9' Clear EEprom, Write 0xff into all the memory ;** ;** ;** This program is free software; you can redistribute it and/or modify ;** it under the terms of the GNU General Public License as published by ;** the Free Software Foundation; either version 2 of the License, or ;** (at your option) any later version. ;** ;** This program is distributed in the hope that it will be useful, ;** but WITHOUT ANY WARRANTY; without even the implied warranty of ;** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;** GNU General Public License for more details. ;** ;** You should have received a copy of the GNU General Public License ;** along with this program; if not, write to the Free Software ;** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;******************************************************************************* ;**************************************************************************** ;** NOTE: Disable the WDT when debugging the code, however, make sure ;** the WDT is enabled when putting the system into lift time test ;** The timeout for WDT is about 2 seconds with 128:1 prescaler ;**************************************************************************** include __config _LP_OSC & _WDT_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_OFF ;***************************************************************** ;** Variables TempW EQU 20h ; ISR use, not utilized CounterA EQU 21h CounterB EQU 22h SerData EQU 23h Temp EQU 24h Output EQU 25h Counter EQU 26h Zero EQU 27h xEEAddrH EQU 28h ; External EEprom stuff xEEAddrL EQU 29h xEEData EQU 2ah ErrorOut EQU 2bh TempH EQU 2ch TempL EQU 2dh TempCnt EQU 2eh TimeL EQU 30h TimeM EQU 31h TimeH EQU 32h WriteAddrL EQU 33h WriteAddrH EQU 34h RunState EQU 35h RunEnable EQU 36h Rchar EQU 37h Rcount EQU 38h Minute EQU 39h DataBuff EQU 0a0h ; Continuous data buffer for 80 bytes #define _SCL PORTB, 7 ; I2C Clock #define _SDA PORTB, 6 ; I2C Data #define _SDAi INDF, 6 ; I2C Data on INDR #define _SCK PORTB, 5 ; SPI Clock #define _SIO PORTB, 4 ; SPI Data #define _SIOi INDF, 4 ; SPI Data direction on INDR #define _TCS PORTB, 3 ; Temperature Sensor select #define _TX PORTB, 2 ; TX for serial Out #define _FASTLO PORTB, 0 ; Fast load ;***************************************************************** ;** Program code here goto Start ORG 4 ;waiting for <0004> ;interrupt vector goto Interrupt ORG 5 ;***************************** DATA StringStart: PWelcomeMsg: addwf PCL, F DT "Welcome!" DT H'0d', H'0a', H'00' PCommandMsg: DT "Command Error?" DT H'0d', H'0a', H'00' PParameterMsg: DT "Parameter Error?" DT H'0d', H'0a', H'00' PNoAckMsg: DT "Missing Ack" DT H'0d', H'0a', H'00' StringEnd: WelcomeMsg EQU 0 CommandMsg EQU PCommandMsg - 1 - 5 ; 5 is the offset where the ParameterMsg EQU PParameterMsg - 1 - 5 ; Strings start NoAckMsg EQU PNoAckMsg - 1 - 5 HexTable: addwf PCL, F DT "0123456789ABCDEF" ;***************************************************************** ;******************** Program Starts here Start: ;********************* Setup WDT clrwdt bsf STATUS, RP0 movlw b'00001111' ;Prescaler to WDT, 1:128 movwf OPTION_REG clrwdt ;********************* Setting up environment movlw b'10000011' ;Serial port in too movwf TRISB ;Set port B I/O clrf TRISA ;Set port A to all output bcf STATUS, RP0 clrf PORTA ;********************** Disable 16f628 specific features movlw b'00000111' ;Disable the analog section movwf CMCON ;********************** Setup UART first bsf STATUS, RP0 movlw d'6' ;300 for 32768Hz Clock, High speed movwf SPBRG ;The only rate with low mismatch movlw b'10100111' ;Async 8-bit @ High speed movwf TXSTA bcf STATUS, RP0 movlw b'10110000' ;Enable serial port movwf RCSTA clrf Zero ;*********************** Dumping data fast ;btfss _FASTLO ;goto FastXfer ;*********************** Initialize Timer interrupt, 32768Hz clock, 1 sec interrupt using Timer1 movlw 0fch movwf TMR1H movlw 0ffh movwf TMR1L ;Set to overflow in 32768 / 4 = 8192 cycles movlw b'00000001' ;Enable Timer1, prescaler = 1 movwf T1CON bsf STATUS, RP0 ;2nd bank bsf PIE1, TMR1IE ;Enable Timer 1 interrupt bcf STATUS, RP0 bcf PIR1, TMR1IF ;Clear TMR1 int flag bsf INTCON, PEIE ;Enable peripheral interrupt bsf INTCON, GIE ;Enable all interrupt ;*********************** Initialize Variable movlw d'60' movwf Minute ;Not used movlw d'60' movwf RunState ;1min per sample clrf TimeL clrf TimeM clrf TimeH clrf WriteAddrL clrf WriteAddrH movlw 01h movwf RunEnable ;----------------------- movlw WelcomeMsg ;Display welcome string on startup call SendString ;----------------------- Wait for command WaitMore: clrwdt btfsc RCSTA, OERR goto ClearError btfss PIR1, RCIF goto WaitMore movfw RCREG movwf SerData movwf TXREG ;Send it back out call SSpace movlw '1' ;Decode command xorwf SerData, W btfsc STATUS, Z goto ReadxEEone ;External EEprom read one byte movlw '2' xorwf SerData, W btfsc STATUS, Z goto WritexEEone ;External EEprom write one byte movlw '3' xorwf SerData, W btfsc STATUS, Z goto ReadxEEburst ;Dump EEprom data movlw '4' xorwf SerData, W btfsc STATUS, Z goto HexTest ;Testing HEX routine movlw '5' xorwf SerData, W btfsc STATUS, Z goto ReadThermo ;Take a temperature reading movlw '6' xorwf SerData, W btfsc STATUS, Z goto ClearTimer ;Clear Timer movlw '7' xorwf SerData, W btfsc STATUS, Z goto ReadTimer ;Read Timer Value movlw '8' xorwf SerData, W btfsc STATUS, Z goto CmdSendString ;Not in use - TESTING movlw '9' xorwf SerData, W btfsc STATUS, Z goto ClearEE ;Clear EEprom DummyNow: ;For all command not in use movlw CommandMsg call SendString ;Send error command message goto WaitMore ;********************* Clear receving overrun error ClearError: movfw RCREG movfw RCREG bcf RCSTA, CREN bsf RCSTA, CREN goto WaitMore ;---------------------- Commands execution HexTest: call RcvHex ;Command 4: Hex test movfw Output call SendHex call NewLine goto WaitMore ;************************************** External Memory routines ReadxEEone: call RcvHex ;Command 1: xEEprom read movfw Output movwf xEEAddrH call RcvHex movfw Output movwf xEEAddrL ;Read in 2 byte of address call SSpace clrf ErrorOut ;Clear error code call xEEreadsingle movfw xEEData call SendHex call SSpace btfss ErrorOut, 0 goto ReeNoError movlw NoAckMsg ;If Error, send message call SendString ReeNoError: call NewLine goto WaitMore ;***************************** WritexEEone: call RcvHex ;Command 2: xEEprom write movfw Output movwf xEEAddrH call RcvHex movfw Output movwf xEEAddrL ;Read in 2 byte of address call SSpace clrf ErrorOut ;Clear error code call RcvHex movfw Output movwf xEEData call xEEwritesingle call SSpace btfss ErrorOut, 0 goto WeeNoError movlw NoAckMsg ;If Error, send message call SendString WeeNoError: call NewLine goto WaitMore ;***************************** ReadxEEburst: call RcvHex ;Command 3: xEEprom Burst movfw Output movwf xEEAddrH call RcvHex movfw Output movwf xEEAddrL ;Read in 2 byte of address call SSpace clrf ErrorOut ;Clear error code call ReliableInit call xEEreadsingle call ReliableLine movfw xEEData call ReliableHex call xEEreadNext ;Dump 2 byte at a time movfw xEEData call ReliableHex btfsc ErrorOut, 0 goto BurstReeError ;Check for error btfsc ErrorOut, 0 goto BurstReeError call ReliableLine ;Loop for 2048-2 times here movlw 04h movwf CounterA movlw 0feh movwf CounterB BurstOuterLoop: BurstInnerLoop: call xEEreadNext ;Dump 2 byte at a time movfw xEEData call ReliableHex btfsc ErrorOut, 0 goto BurstReeError ;Check for error call xEEreadNext movfw xEEData call ReliableHex btfsc ErrorOut, 0 goto BurstReeError ;Check for error call ReliableLine decfsz CounterB, F goto BurstInnerLoop decfsz CounterA, F goto BurstOuterLoop call ReliableClose goto WaitMore ;Exit when done BurstReeError: call ReliableClose movlw NoAckMsg ;If Error, send message call SendString call NewLine goto WaitMore ;***************************** ClearEE: ;Command 9: Clear EEprom movlw 02h movwf CounterA movlw 0feh movwf CounterB clrf xEEAddrH clrf xEEAddrL movlw 0ffh movwf xEEData EraseEEloop: call xEEwritesingle incf xEEAddrL, F btfsc STATUS, Z incf xEEAddrH, F decfsz CounterB, F goto EraseEEloop decfsz CounterA, F goto EraseEEloop movlw 'C' call SendChar movlw 'l' call SendChar movlw 'e' call SendChar movlw 'a' call SendChar movlw 'r' call SendChar call NewLine goto WaitMore ;***************************** CmdSendString: ;Command 8: Send ASCII string Again: btfss PIR1, RCIF goto Again movfw RCREG movwf TXREG ; Send it back out movlw 1bh xorwf RCREG, W btfsc STATUS, Z goto ExitSendString ; If ESC is pressed, exit the routine goto Again ExitSendString: call NewLine ; ESC character mess up the first newline call NewLine goto WaitMore LocSendCommand goto WaitMore ;************************************** Command 5, Take a thermo reading ReadThermo: call TakeTempReading call SSpace call SSpace movfw TempH call SendHex movfw TempL call SendHex call NewLine goto WaitMore ;************************************** Command 6, Clear Timer ClearTimer: clrf RunEnable call SSpace call SSpace clrf TimeL clrf TimeM clrf TimeH movlw 'C' call SendChar movlw 'l' call SendChar movlw 'e' call SendChar movlw 'a' call SendChar movlw 'r' call SendChar call NewLine goto WaitMore ;************************************** ReadTimer: bsf RunEnable, 0 call SSpace call SSpace movfw TimeH ;Command 7: Read Timer Value call SendHex call SSpace movfw TimeM call SendHex call SSpace movfw TimeL call SendHex call NewLine goto WaitMore ;***************************** INTERRUPT Interrupt: movlw 20h subwf TMR1H, F ;decfsz Minute, F ;goto IntNoRun ;movlw d'60' ;movwf Minute ;--------------------------- Runs once per minute btfss RunEnable, 0 ; Check to see if data acq is on goto IntNoRun decfsz RunState, F goto IntNoRun movlw d'60' ; 1min per sample movwf RunState movlw 'I' call SendChar call TakeTempReading movfw WriteAddrH movwf xEEAddrH movfw WriteAddrL movwf xEEAddrL movfw TempH movwf xEEData call xEEwritesingle movfw TempL movwf xEEData incf xEEAddrL, F ; Always odd number, will not carry call xEEwritesingle incf WriteAddrL, F ; Always odd number, will not carry incf WriteAddrL, F ; Even number, might carry btfsc STATUS, Z incf WriteAddrH, F movlw 20h xorwf WriteAddrH, W btfss STATUS, Z goto IntEENotFull ; If EEprom is FULL, disable run clrf RunEnable IntEENotFull: IntNoRun: ;-------------------------- incfsz TimeL, F ; Runs once per second goto ExitInt incfsz TimeM, F goto ExitInt incf TimeH, F ExitInt: bcf PIR1, TMR1IF retfie ;***************************** SUBROUTINE ;----------------------------------------------------------------- ; xEEreadsingle: Read a single byte from external EEprom ; Input in xEEAddrH/L (16bit), Output in W xEEreadsingle: call xI2CInit call xI2CStart movlw b'10100000' ; Write, I2C Address 1010-000 call xI2COutByte ; Write is used to set read addr btfsc ErrorOut, 0 ; If error, exit right away goto xEEReadErrorExit movfw xEEAddrH call xI2COutByte btfsc ErrorOut, 0 ; If error, exit right away goto xEEReadErrorExit movfw xEEAddrL call xI2COutByte btfsc ErrorOut, 0 ; If error, exit right away goto xEEReadErrorExit call xI2CStop nop nop call xI2CStart movlw b'10100001' ; Read, I2C Address 1010-000 call xI2COutByte ; btfsc ErrorOut, 0 ; If error, exit right away goto xEEReadErrorExit call xI2CInByte movwf xEEData xEEReadErrorExit: call xI2CStop return ;----------------------------------------------------------------- ; xEEreadNext: Read a single byte from external EEprom ; Output in W, Addr is auto increment xEEreadNext: call xI2CStart movlw b'10100001' ; Read, I2C Address 1010-000 call xI2COutByte ; btfsc ErrorOut, 0 ; If error, exit right away goto xEENextReadError call xI2CInByte movwf xEEData xEENextReadError: call xI2CStop return ;----------------------------------------------------------------- ; xEEwritesingle: Write a single byte to external EEprom ; Input in xEEAddrH/L (16bit), Data in xEEData xEEwritesingle: call xI2CInit call xI2CStart movlw b'10100000' ; Write, I2C Address 1010-000 call xI2COutByte btfsc ErrorOut, 0 ; If error, exit right away goto xEEWriteErrorExit movfw xEEAddrH call xI2COutByte btfsc ErrorOut, 0 ; If error, exit right away goto xEEWriteErrorExit movfw xEEAddrL call xI2COutByte btfsc ErrorOut, 0 ; If error, exit right away goto xEEWriteErrorExit movfw xEEData call xI2COutByte xEEWriteErrorExit: call xI2CStop return ;----------------------------------------------------------------- ; xI2C routines ; xI2CInit - Initialize external I2C bus xI2CInit: movlw TRISB ; Use INDR, make it easier to access movwf FSR bcf INDF, 7 ; Set SCL to output bcf _SDA ; Always preset SDA to zero bsf _SCL ; Prior to start condition, reset everything nop nop bsf _SDAi ; Stop condition nop nop return ; xI2CStart - Issue a start condition xI2CStart: bcf _SDA ; Always preset SDA to zero bcf _SDAi ; Start condition nop nop nop ; min 600ns for start bcf _SCL return ; xI2CStop - Issue a stop condition xI2CStop: bcf _SDA bcf _SDAi ; SDA must be low to bsf _SCL ; init a stop condition nop nop nop bsf _SDAi ; Stop condition return ;-------------------------------------------------------- ; xI2COutByte - Master send a byte, data in W. ; Register used: Temp, Counter xI2COutByte: movwf Temp movlw d'8' movwf Counter xI2COutLoop: rlf Temp, F bcf _SDA bsf _SDAi btfss STATUS, C bcf _SDAi nop nop bsf _SCL nop nop bcf _SCL decfsz Counter, F goto xI2COutLoop bsf _SDAi ; Read Ack bit nop bsf _SCL nop bcf ErrorOut, 0 btfsc _SDA bsf ErrorOut, 0 ; Ack bit in (ErrorOut, 0) bcf _SCL nop nop nop nop return ; 1200nS for each SCL low ;--------------------------------------------------------- ; xI2COutByte - Master receive a byte, data in W. ; Register used: Temp, Counter xI2CInByte: bsf _SDAi movlw d'8' movwf Counter xI2CInLoop: bsf _SCL nop nop bsf STATUS, C btfss _SDA bcf STATUS, C bcf _SCL rlf Temp, F decfsz Counter, F goto xI2CInLoop ; Read Ack bit nop bsf _SCL nop nop ; No Ack for single byte read bcf _SCL movfw Temp nop nop nop nop return ;----------------------------------------------------------------- ; TakeTempReading, Read a single sample from TC77 thermo sensor ; Output: TempH, TempL 13bit of data total TakeTempReading: bsf _TCS movlw TRISB ; Use INDR, make it easier to access movwf FSR bsf _SIOi ; Make SIO an input movlw d'13' movwf TempCnt ; Read 13 bits clrf TempL ; Clear out old data bcf _SCK bcf _TCS LoopTempRead: bcf STATUS, C ; Take a reading btfsc _SIO bsf STATUS, C bsf _SCK rlf TempL, F rlf TempH, F ; Load data into Temp Reg bcf _SCK ; Falling clock to load new data decfsz TempCnt, F goto LoopTempRead bsf _TCS return ;----------------------------------------------------------------- ; SendHex, Send a single byte out of serial port, hex format ; Input: data stored in W SendHex: movwf Temp swapf Temp, W andlw 00fh call HexTable HexWaitLoop1: btfss PIR1, TXIF ;Wait till buffer is empty goto HexWaitLoop1 movwf TXREG movf Temp, W andlw 00fh call HexTable HexWaitLoop2: btfss PIR1, TXIF ;Wait till buffer is empty goto HexWaitLoop2 movwf TXREG return ;----------------------------------------------------------------- ; RcvHex, Receive a single byte from serial port in hex format ; Output: data stored in Output RcvHex: btfss PIR1, RCIF goto RcvHex movfw RCREG movwf SerData movwf TXREG ; Send it back out movlw 30h subwf SerData, F movlw 10h subwf SerData, W ; F - W btfsc STATUS, C ; Positive means letter input goto Letter1 RtnLetter1: swapf SerData, W movwf Output RcvHexLoop: btfss PIR1, RCIF goto RcvHexLoop movfw RCREG movwf SerData movwf TXREG ; Send it back out movlw 30h subwf SerData, F movlw 10h subwf SerData, W ; F - W btfsc STATUS, C ; Positive means letter input goto Letter2 RtnLetter2: movfw SerData iorwf Output, F call SSpace return Letter1: movlw 07h subwf SerData, F movlw 10h subwf SerData, W btfsc STATUS, C ; Positive means bad input goto Letter1E goto RtnLetter1 Letter1E: movlw d'32' subwf SerData, F goto RtnLetter1 Letter2: movlw 07h subwf SerData, F movlw 10h subwf SerData, W btfsc STATUS, C ; Positive means bad input goto Letter2E goto RtnLetter2 Letter2E: movlw d'32' subwf SerData, F goto RtnLetter2 ;----------------------------------------------------------------- ; LongDelay, 15 cycles, 3ins/cycle 22.5uS for 8Mhz clock long_delay: movlw d'15' movwf Counter long_delay_L: decfsz Counter, F goto long_delay_L return ;----------------------------------------------------------------- ; Delay_1ms, 5000 cycles, actual is 4590 cycle, 0.918mS for 20Mhz clock Delay_1ms: movlw d'6' movwf CounterA Delay_1ms_loop_O: Delay_1ms_loop_I: decfsz CounterB, F goto Delay_1ms_loop_I decfsz CounterA, F goto Delay_1ms_loop_O return ;----------------------------------------------------------------- ; Delay_100us, 500 cycles, actual is 498 cycle, 99.6uS for 20Mhz clock Delay_100us: movlw d'166' movwf CounterA Delay_100us_loop: decfsz CounterA, F goto Delay_100us_loop return ;----------------------------------------------------------------- ; SendString, send the string out to serial port ; Input: String location in W SendString: movwf Counter SendLoop: btfss PIR1, TXIF ;Wait till buffer is empty goto SendLoop call StringStart iorwf Zero, W btfsc STATUS, Z ;Zero is the end of string return movwf TXREG incf Counter, F movfw Counter goto SendLoop ;----------------------------------------------------------------- ; NewLine, send s newline character into serial port ; Input: None NewLine: btfss PIR1, TXIF ;Wait till buffer is empty goto NewLine movlw 0dh movwf TXREG movlw 0ah NewLineLoop: btfss PIR1, TXIF ;Wait till buffer is empty goto NewLineLoop movwf TXREG return ;----------------------------------------------------------------- ; SSpace, send a space character into serial port ; Input: None SSpace: btfss PIR1, TXIF ;Wait till buffer is empty goto SSpace movlw ' ' movwf TXREG return ;----------------------------------------------------------------- ; SendChar, send a single character into serial port SendChar: btfss PIR1, TXIF ;Wait till buffer is empty goto SendChar movwf TXREG return ;---------------------------------------------------------------- ; ReliableInit, A set of routine that provide reliable 300baud data out ReliableInit: clrf RunEnable ;No interrupt allowed bcf INTCON, GIE bsf _TX bcf RCSTA, SPEN ;Disable USART bsf _TX return ;---------------------------------------------------------------- ; ReliableChar, Send a char ; input in W ReliableChar: movwf Rchar bcf _TX ;START bit call Delay20 nop nop nop btfss Rchar, 0 ;1 goto Bit0_0 ;2 nop ;3 bsf _TX ;4 goto Bit0_1 ;5 Bit0_0: bcf _TX ;4 goto Bit0_1 Bit0_1: ;7 call Delay20 nop btfss Rchar, 1 ;1 goto Bit1_0 ;2 nop ;3 bsf _TX ;4 goto Bit1_1 ;5 Bit1_0: bcf _TX ;4 goto Bit1_1 Bit1_1: ;7 call Delay20 nop btfss Rchar, 2 ;1 goto Bit2_0 ;2 nop ;3 bsf _TX ;4 goto Bit2_1 ;5 Bit2_0: bcf _TX ;4 goto Bit2_1 Bit2_1: ;7 call Delay20 nop nop btfss Rchar, 3 ;1 goto Bit3_0 ;2 nop ;3 bsf _TX ;4 goto Bit3_1 ;5 Bit3_0: bcf _TX ;4 goto Bit3_1 Bit3_1: ;7 call Delay20 nop btfss Rchar, 4 ;1 goto Bit4_0 ;2 nop ;3 bsf _TX ;4 goto Bit4_1 ;5 Bit4_0: bcf _TX ;4 goto Bit4_1 Bit4_1: ;7 call Delay20 nop btfss Rchar, 5 ;1 goto Bit5_0 ;2 nop ;3 bsf _TX ;4 goto Bit5_1 ;5 Bit5_0: bcf _TX ;4 goto Bit5_1 Bit5_1: ;7 call Delay20 nop nop btfss Rchar, 6 ;1 goto Bit6_0 ;2 nop ;3 bsf _TX ;4 goto Bit6_1 ;5 Bit6_0: bcf _TX ;4 goto Bit6_1 Bit6_1: ;7 call Delay20 nop btfss Rchar, 7 ;1 goto Bit7_0 ;2 nop ;3 bsf _TX ;4 goto Bit7_1 ;5 Bit7_0: bcf _TX ;4 goto Bit7_1 Bit7_1: ;7 call Delay20 nop nop nop nop nop bsf _TX ;STOP bit return ;----------------------------------------------------------------- ; ReliableLine, send s newline character into serial port ; Input: None ReliableLine: movlw 0dh call ReliableChar call Delay20 nop nop movlw 0ah call ReliableChar return ;----------------------------------------------------------------- ; ReliableHex, Send a single byte out of serial port, hex format ; Input: data stored in W ReliableHex: movwf Temp swapf Temp, W andlw 00fh call HexTable call ReliableChar movf Temp, W andlw 00fh call HexTable call ReliableChar return ;---------------------------------------------------------------- ; ReliableClose: Run when finished ReliableClose: bsf STATUS, RP0 movlw b'10100111' ;Async 8-bit @ High speed movwf TXSTA bcf STATUS, RP0 movlw b'10110000' ;Enable serial port movwf RCSTA bsf INTCON, GIE ;ReEnable Interrupt return ;---------------------------------------------------------------- ; Delay 20 cycles Delay20: movlw d'5' movwf Rcount Delay20loop: decfsz Rcount, F goto Delay20loop return ;******************************************** Fast Transfer FastXfer: LockUp: goto LockUp ;***************************************************************** ; Subede wasure de, kokoni iru end