MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 1 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00001 ;******************************************************************* 00002 ; 00003 ; IR2RS232.ASM 00004 ; IR to RS232 to IR Program 00005 ; Version 1.0 (09/12/05) (Checksum ----) 00006 ; (C) 2005 Reymes 00007 ; Programmer: Jim Furey 00008 ; 00009 ;******************************************************************* 00010 ; 00011 ; Purpose: 00012 ; 00013 ; This program uses a PIC16F627A for RS232 communication, IR receive and IR transmit. 00014 ; Through a switch, it can be set for learn or operate to communicate with Infared signals 00015 ; from various modulated and non-modulated remote controls. Once it detects these signals, 00016 ; it stores it in EEPROM and asks the operator for a control character in ASCII to re-transmit 00017 ; the signal. 00018 ; 00019 ; Description: 00020 ; 00021 ; There are two modes of operation. One is "Learn" and the other is "Operate". This is 00022 ; changed by switch SW1. 00023 ; 00024 ; The description of "Learn" is as follows: 00025 ; 00026 ; Using the PORTB interrupt, the program waits for a "dark space" (low signal) out of the IR 00027 ; detector for more than 2mS. (There are many short pulses brought about by ambient noise 00028 ; before solid remote control IR.) 00029 ; This is the pre-amble (2 to 3 mS low). Each following "mark" high pulse (inverted condition 00030 ; out of IR detector) is followed by either a short (700uS) or long (1300us) low. A short low 00031 ; means "0" and long low means "1". This method of IR transmission/reception is called 00032 ; "space width coded" IR. 00033 ; Timer 1 determines the 0 or 1 space length by its width and saves one bit per byte into 00034 ; the RAM bytes "IRDATA". The count of how many bits is saved in "CLENGTH". The maximum 00035 ; bits that can be saved is 32. Most IR commands are between 12 and 22. 00036 ; When the IR detector outut goes high for more than 2mS, the transmission is over. 00037 ; The message "Ready to save, pick a character: " is then transmitted over the RS232 port. 00038 ; The unit waits for an ASCII character (see list of usable ASCII characters) and then searches the 00039 ; EEPROM for a match. If this character is already used, it outputs "Already used. Overwrite?" 00040 ; A "Y" will overwrite the previous bitstream saved for that character. A "N" will abandon the write. 00041 ; If that character is not already used, or "Y" was selected, the program searches for an unused 00042 ; block in the EEPROM to store the data in. If all blocks are used, it will output "No available 00043 ; space" and then end without storing. 00044 ; If a block is found, it then writes the data along with it's associated ASCII character in EEPROM 00045 ; and outputs the message "Ready". 00046 ; 00047 ;The description if "Operate" is as follows: 00048 ; 00049 ; When the SW1 switch is in the "Operate" mode, the unit will accept RS232 commands (at 9600 baud) 00050 ; and output associated IR bitstreams. When first powered up in the Operate mode, and also after 00051 ; every ASCII character in sent, the unit outputs "Ready" to the RS232 port. 00052 ; When each character is entered, (the return key is not needed) the unit goes to a look up table 00053 ; created by the user in "Learn" mode, and finds the associated match in ASCII. MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 2 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00054 ; If no match is found, then the message "Error" is output to the RS232 port. 00055 ; If a match is found, then using the timer 1, it outputs a preamble 2.5mS low and then a 500uS 00056 ; pulse followed by each bit saved. This "pulse-bit-pulse-bit" is continued until all bits are sent. The n 00057 ; the last pulse stays high. This completes the IR transmission, and a "Ready" is sent again. 00058 ; 00059 ; ASCII table: 00060 ; 00061 ; 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 00062 ; A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 00063 ; 00064 ; 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 00065 ; a b c d e f g h i j k l m n o p q r s t u v w x y z 00066 ; 00067 ; Notes: 00068 ; 1. For use with modulated or non-modulated, space width coded remotes with less than 00069 ; 31 characters per instruction. If there are more than 32 bits, then only the first 32 00070 ; are captured. (Most are 12-22 bits) 00071 ; 2. RS232 operates at 9600 baud, 8 bits, 1 stop bit, no parity, ANSI emulation only 00072 ; 00073 ;******************************************************************* 00074 ; 00075 ; Revisions: 00076 ; 1.0 : Original program 00077 ; 00078 ;******************************************************************* 00079 ; Notes: 00080 ; Things left to do: 00081 ; 1. DONE 00082 ; 2. Do bits to real time IR out 00083 ; 3. Do bitstream output to IR 00084 ; 4. Logic for store, overwrite, delete of commands: 00085 ; a. Check for match, offer overwrite 00086 ; b. If full, show all used characters 00087 ; c. Entering characters while in learn mode deletes command 00088 ; d. 00089 ; 00090 ; 00091 list p=16f627a ; list directive to define processor 00092 #include ; processor specific variable definitions 00001 LIST 00002 ; P16F627A.INC Standard Header File, Version 1.10 Microchip Technology, Inc. 00265 LIST 2007 3F2B 00093 __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF &_EXTCLK_OSC &_LVP_OFF 00094 00095 errorlevel -302 ; suppress message 302 from list file 00096 00097 ;***** VARIABLE DEFINITIONS ***** 00098 ; RAM has 3 banks of usable space: | 0x20 to 0x7F (96 bytes)| 0xA0 to 0xEF (80 bytes)| 0x120 to 0x14F (48 bytes)| 00099 00000020 00100 IRDATA equ 0x20 ; 32 bytes of data (from 0x20 to 0x3F) each representing a bit of IR 00000040 00101 irsave equ 0x40 ; Saved 32 bytes (from 0x40 to 0x5F) of IRDATA for storage to E2 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 3 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00000060 00102 AMTCH equ 0x60 ; ASCII charater to match to from incoming RS232 command 00000061 00103 asave equ 0x61 ; Saved ASCII matched character 00000062 00104 CLENGTH equ 0x62 ; Length of bits to send on outgoing comand 00000063 00105 lsave equ 0x63 ; Saved bit length count 00000064 00106 E2A equ 0x64 ; Byte for EEPROM address 00000065 00107 E2D equ 0x65 ; 6 bytes of data for E2 data to/from EEPROM (65-6A) 0000006B 00108 dcnth equ 0x6B ; Delay counter high 0000006C 00109 dcntl equ 0x6C ; Delay counter low 0000006D 00110 pointer equ 0x6D ; ASCII Message pointer 0000006E 00111 counter equ 0x6E ; ASCII byte counter 0000006F 00112 wtemp equ 0x6F ; Temporary storage of W register during interrupt 00000070 00113 stemp equ 0x70 ; Temporary storage of Status register during interrupt 00000071 00114 stat1 equ 0x71 ; Status byte for flags 00000072 00115 irctrl equ 0x72 ; Counter for input capture and output strobe of IR 00000073 00116 irctrh equ 0x73 ; Counter for input capture and output strobe of IR 00000074 00117 ectr equ 0x74 ; 8 bit counter for E2 bit transfer 00000075 00118 e2bctr equ 0x75 ; Byte contains the number f bytes to transfer in/out of E2 00000075 00119 ircnt equ 0x75 ; IR output counter 00000077 00120 xctr equ 0x77 ; Transfer counter 00000078 00121 tempb equ 0x78 ; Temp byte for black transfer 00000079 00122 RCV_REG equ 0x79 ; Receive register 0000007A 00123 irlength equ 0x7A 0000007B 00124 irpoint equ 0x7B ; Pointer for irplay's output 00125 00126 00127 ; ************** stat1 explanation: *************** 00128 ; 7 1 = Enable IR out condition stat1,7 00129 ; 6 1 = If 1 being sent to IR LED (for 40kHz) stat1,6 00130 ; 5 0 = space, 1 = pulse for IR out stat1,5 00131 ; 4 1 = RS232 RCV character received stat1,4 00132 ; 3 0/1 = history of Modulate/Non-modulate pin (PORTB,7) stat1,3 00133 ; 2 1 = echos what's on the IROUT pin stat1,2 00134 ; 1 1 = flag to output "Ready to save, pick a character:" stat1,1 00135 ; 0 1 = start bit found (in IR input) stat1,0 00136 00137 ;PORTA: 00000004 00138 O_L equ 4 ; Used for Operate/Learn switch in 00000003 00139 MODSW equ 3 ; Used for Modulate/Non-modulate SW2 in 00000002 00140 BITSW equ 2 ; Used for ASCII/Bitstream SW3 in 00000001 00141 REDLED equ 1 ; Used for red LED error indicator out 00000000 00142 GRNLED equ 0 ; Used for green LED IR accept indicator out 00143 00144 ;PORTB: 00000007 00145 NU1 equ 7 ; Port pin not used out 00000006 00146 NU2 equ 6 ; Port pin not used out 00000005 00147 NU3 equ 5 ; Port pin not used out 00000004 00148 IRIN equ 4 ; IR receiver input in 00000003 00149 IRNOT equ 3 ; Inverse of IROUT pin out 00000002 00150 RS232O equ 2 ; RS232 output to PC out(in) 00000001 00151 RS232I equ 1 ; RS232 input from PC in 00000000 00152 IROUT equ 0 ; IR transmitter output out 00153 0000 00154 org 0 ; Reset Vector MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 4 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0000 2805 00155 goto start ; Go to Main Program 00156 0004 00157 org 0004 ; Interrupt Vector 0004 2A4A 00158 goto ints ; Go to Interrupt service routine 00159 00160 0005 00161 org 0005h ; Start of user program ($0005h to $03FFh) (twice as much in PIC16F628A) 00162 ;**************************************************************************** 00163 ;**************************************************************************** 00164 ;******************************** Main Program ********************************* 00165 ;**************************************************************************** 00166 ;**************************************************************************** 00167 ; 00168 ;************************* INITIALIZE PIC ********************** 0005 00169 start 0005 1283 00170 bcf STATUS,RP0 ; Select Bank 0 0006 1303 00171 bcf STATUS,RP1 0007 1383 00172 bcf STATUS,IRP 00173 0008 301F 00174 movlw 0x1F ; Initialize data for PORTA 0009 0085 00175 movwf PORTA 000A 30D1 00176 movlw 0xD1 ; Initialize data for PORTB 000B 0086 00177 movwf PORTB 00178 000C 1683 00179 bsf STATUS,RP0 ; Initialize PORTA directions - Select Bank 1 000D 3010 00180 movlw 0x10 ; Set porta directions (a 0 is out, a 1 is in) 000E 0085 00181 movwf TRISA 000F 1283 00182 bcf STATUS,RP0 ; De-select Bank 1 00183 0010 1683 00184 bsf STATUS,RP0 ; Initialize PORTB directions - Select Bank 1 0011 30D6 00185 movlw 0xD6 ; Set portb directions (a 0 is out, a 1 is in) was 1B 0012 0086 00186 movwf TRISB 0013 1283 00187 bcf STATUS,RP0 ; De-select Bank 1 00188 0014 3007 00189 movlw 0x07 ; Initialize the comparitors as off 0015 009F 00190 movwf CMCON 00191 0016 1383 00192 bcf STATUS,IRP ; Clear all RAM locations from 0x20 to 0x7F 0017 3020 00193 movlw 0x20 0018 0084 00194 movwf FSR 0019 0180 00195 rcloop clrf INDF 001A 0A84 00196 incf FSR,f 001B 1F84 00197 btfss FSR,7 001C 2819 00198 goto rcloop 00199 00200 ; ******* INITIALIZE RS232 PORT ******* 001D 1683 00201 bsf STATUS,RP0 ; Initialize RS232 TSCR - Select Bank 1 001E 30A0 00202 movlw 0xA0 ; WAS A2 Load Transmit Status and Control Register ((24)) 001F 0098 00203 movwf TXSTA ; 7)NA, 6)1=9bit, 5)1-TX EN, 4)0=Asyn/1=Sync, 3)NA, 2)Baud 0=lo/1=hi, 1) TXFLG, 0)Parity bit set 0020 1283 00204 bcf STATUS,RP0 ; De-select Bank 1 00205 0021 1683 00206 bsf STATUS,RP0 ; Initialize RS232 SPBRG - Select Bank 1 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 5 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0022 3020 00207 movlw 0x20 ; Load Baud Rate Register (Set for 9600 baud using a 20MHz Xtal) 0023 0099 00208 movwf SPBRG ; Entire byte for baud divisor. 0024 1283 00209 bcf STATUS,RP0 ; De-select Bank 1 00210 0025 3090 00211 movlw 0x90 ; Was B0 WAS A0 (Could be B0) Load Transmit Status and Control Register (B0 is enable receiver) ((90)) 0026 0098 00212 movwf RCSTA ; 7)RS232 EN, 6)9bitRcvEN, 5)Single Rcv En, 4)Cont. Rcv En, 3)Addr En, 2 -1-0)Rest are flags 00213 00214 00215 ; ******** INITIALIZE OTHER PERIPHERAL INTERRUPTS ********* 0027 1683 00216 bsf STATUS,RP0 ; Select Bank 1 0028 30C0 00217 movlw 0xC0 ; Set Opt_Reg: disable pull-ups(7), rising edge int on PORTB(6), Timer0 clock source(5)prescale 0029 0081 00218 movwf OPTION_REG ; Timer0 source edge select(4), prescaller assignment(3), Timer0 prescal ler(0-2) 002A 1283 00219 bcf STATUS,RP0 ; De-select Bank 1 00220 002B 1683 00221 bsf STATUS,RP0 ; Select Bank 1 002C 30C8 00222 movlw 0xC8 ; Set Interrupt Control Reg. Global(7), Peripheral enable(6) [for RS232, E2, TMR1&2], Timer0 OVF(5), 002D 008B 00223 movwf INTCON ; External Int.(4), RB Port Change(3), Flags(0-2) 002E 1283 00224 bcf STATUS,RP0 ; De-select Bank 1 00225 002F 018E 00226 clrf TMR1L ; Clear Timer1 values 0030 018F 00227 clrf TMR1H 00228 0031 1683 00229 bsf STATUS,RP0 ; Select Bank 1 0032 3001 00230 movlw 0x01 ; 03 Was 01 WAS 21 Set Perpherial Interrupt Control Reg. EE Int.(7), Com paritor(6), RS232RCV(5), RS232TX(4) 0033 008C 00231 movwf PIE1 ; Not used(3), Compare(2), Timer2 match(1), Timer1 OVF(0) 0034 1283 00232 bcf STATUS,RP0 ; De-select Bank 1 00233 0035 3005 00234 movlw 0x05 ; 05 Initialize Timer1 Control Register 0036 0090 00235 movwf T1CON 00236 0037 1683 00237 bsf STATUS,RP0 ; Select Bank 1 0038 303E 00238 movlw 0x3E ; Initialize Timer2 value (This will make a 40kHz signal) 0039 0092 00239 movwf PR2 003A 1283 00240 bcf STATUS,RP0 ; De-select Bank 1 003B 3004 00241 movlw 0x04 ; Initialize Timer2 pre and post scalers 003C 0092 00242 movwf T2CON 00243 ;TMR2 00244 00245 00246 ; *********************************************************************** 00247 ; * Main routine. The main routine detects first the transmission * <<<<<<<<<<<<<<<<<<<<<< 00248 ; * time of the incoming calibration character. After that the * <<<<<<<<<<<<<<<<<<<<<< 00249 ; * routine receives and transmits incoming characters. * <<<<<<<<<<<<<<<<<<<<<< 00250 ; *********************************************************************** 00251 003D 00252 Main ;bsf STATUS,RP0 ; Select bank 1 +++ Clear random MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 6 LOC OBJECT CODE LINE SOURCE TEXT VALUE interrupts happening from O/L transition +++ 00253 ;main1 bcf INTCON,GIE ; Disable interrupts 00254 ; btfsc INTCON,GIE ; Test if no other interrupts happened during disable 00255 ; goto main1 00256 ; bsf INTCON,GIE ; Re-enable interrupts 00257 ; bcf STATUS,RP0 ; Deselect bank 1 00258 003D 3000 00259 movlw 0x00 ; RS232 transmit message "Ready" 00,07 003E 00ED 00260 movwf pointer 003F 3007 00261 movlw 0x07 0040 00EE 00262 movwf counter 0041 2119 00263 call msgout 00264 00265 ;goof goto goof 00266 00267 0042 1A05 00268 loop1 btfsc PORTA,O_L ; Check if switch set for Learn(0) or Operate(1) 0043 2845 00269 goto oper 0044 286B 00270 goto learn 00271 00272 ; <<<<<<<<<< OPERATE >>>>>>>>>>> 0045 1683 00273 oper bsf STATUS,RP0 ; Select Bank 1 0046 118B 00274 bcf INTCON,RBIE ; Disable Interrupts on PORTB change 0047 111C 00275 bcf EECON1,WREN ; Disable E2 writes 0048 1283 00276 bcf STATUS,RP0 ; De-select Bank 1 00277 0049 1E05 00278 oper1 btfss PORTA,O_L ; Check if switch still set for Operate(1) or changed to Learn(0) 004A 283D 00279 goto Main ; If switch changed to LEARN while in OPERATE, then restart main loop 004B 20EC 00280 call modchk ; Check if modulate/non-modulate switch has changed and set accordingly 00281 004C 1905 00282 btfsc PORTA,BITSW ; Test if E2 mode (1) or Bitstream mode (0) on SW3 004D 284F 00283 goto oper2 ; If E2 mode, go to that mode continue 00284 ; Bitstream mode: 00285 ; Wait for "b" or "B" to start 00286 ; Accumulate charaters 00287 ; Wait for "e" or "E" to end, and then: 00288 ; call irplay 004E 2849 00289 goto oper1 ; And return 00290 ; E2 mode: 004F 1E8C 00291 oper2 btfss PIR1,RCIF ; Check if data in RS232 Receiver buffer (looking for input character) +++ WAIT FOR CHARACTER +++ 0050 2849 00292 goto oper1 ; Go on to next test if nothing there 0051 2213 00293 call rcv232 ; Get byte OR clear errors. If return with 1, then error. If return with 0, then good 0052 3A00 00294 xorlw 0x00 ; Check if good 0053 1D03 00295 btfss STATUS,Z ; Check if 0 which is good 0054 2849 00296 goto oper1 ; If it was a 1, then is was just an error, loop back again. Else: 0055 0879 00297 movf RCV_REG,w ; Get what's in Received byte 00298 0056 2188 00299 call e2mtch ; Do match to compare E2 data with RCV_REG ASCII character C=0=no, C=1=y es 0057 1C03 00300 btfss STATUS,C ; Test if match was found. 0058 2863 00301 goto opernm ; Match not found - loop back to main operate loop MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 7 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0059 1005 00302 bcf PORTA,GRNLED ; Turn on the green LED 005A 2175 00303 call ee2r ; Transfer E2D 6 bytes to "IRDATA" bytes 005B 21BB 00304 call irplay 005C 3064 00305 movlw 0x64 ; Then RS232 transmit message "OK" 64,06 005D 00ED 00306 movwf pointer 005E 3006 00307 movlw 0x06 005F 00EE 00308 movwf counter 0060 2119 00309 call msgout 0061 1405 00310 bsf PORTA,GRNLED ; Turn off the green LED 0062 2849 00311 goto oper1 ; Loop the main operate loop 00312 0063 1085 00313 opernm bcf PORTA,REDLED ; No match found so send "Abort" - Turn on red LED +++ NO MATCH FOUND +++ 0064 305D 00314 movlw 0x5D ; RS232 transmit message "Abort" 5D,09 Need to be 1 back (5C rather than 5D) because sub in a sub 0065 00ED 00315 movwf pointer 0066 3009 00316 movlw 0x09 0067 00EE 00317 movwf counter 0068 2119 00318 call msgout 0069 1485 00319 bsf PORTA,REDLED ; Turn off red LED 006A 2849 00320 goto oper1 ; Loop the main operate loop 00321 00322 00323 ; <<<<<<<<<< LEARN >>>>>>>>>>> 006B 1683 00324 learn bsf STATUS,RP0 ; Select Bank 1 006C 158B 00325 bsf INTCON,RBIE ; Enable Interrupts on PORTB change 006D 108C 00326 bcf PIE1,TMR2IE ; Disable Timer2 Interrupts (40kHz timer) 006E 1283 00327 bcf STATUS,RP0 ; De-select Bank 1 00328 006F 1A05 00329 learn1 btfsc PORTA,O_L ; Check if switch set for Learn(0) or Operate(1) 0070 283D 00330 goto Main ; If switch changed to OPERATE while in LEARN, then restart main loop 00331 0071 1905 00332 btfsc PORTA,BITSW ; Test if E2 mode (1) or Bitstream mode (0) on SW3 0072 287C 00333 goto learn2 ; If E2 mode, go to that mode continue 00334 00335 ; Bitstream mode: 0073 1FF1 00336 btfss stat1,7 ; If in Bitstream mode, test if "send string" bit set 0074 286F 00337 goto learn1 ; if not set, loop back 0075 2228 00338 call cmdout ; If set, send out string of characters - THIS IS FOR BITSTREAM MODE ONL Y 0076 1071 00339 bcf stat1,0 ; Clear start bit found 0077 01E2 00340 clrf CLENGTH 0078 01F2 00341 clrf irctrl ; Clear counters 0079 01F3 00342 clrf irctrh 007A 13F1 00343 bcf stat1,7 ; Clear this and any new bit set 007B 286F 00344 goto learn1 00345 00346 ; E2 mode: +++CHECK FOR ~ TO ERASE ALL E2+++ 007C 1E8C 00347 learn2 btfss PIR1,RCIF ; Check if data in RS232 Receiver buffer (looking for tilde) 007D 28AE 00348 goto learng ; Go on to next test if nothing there 007E 2213 00349 call rcv232 ; Get byte OR clear errors. If return with 1, then error. If return with 0, then good MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 8 LOC OBJECT CODE LINE SOURCE TEXT VALUE 007F 3A00 00350 xorlw 0x00 ; Check if good 0080 1D03 00351 btfss STATUS,Z ; Check if 0 which is good 0081 28AE 00352 goto learng ; If it was a 1, then is was just an error, loop on to next test. Else: 0082 0879 00353 movf RCV_REG,w ; Get what's in Received byte 0083 3A7E 00354 xorlw 0x7E ; Compare with tilde (~) 0084 1D03 00355 btfss STATUS,Z ; Check if the same 0085 28AE 00356 goto learng ; If not the same, go on to next test 00357 0086 3048 00358 movlw 0x48 ; If it's a tilde, then RS232 transmit message "Erase all E2? Y/N? " 48, 15 0087 00ED 00359 movwf pointer 0088 3015 00360 movlw 0x15 0089 00EE 00361 movwf counter 008A 2119 00362 call msgout 00363 ; +++LOOKING FOR "Y" ON TILDE +++ 008B 1E8C 00364 learna btfss PIR1,RCIF ; Check if data in RS232 Receiver buffer (looking for tilde) 008C 288B 00365 goto learna ; Go on to next test if nothing there 008D 2213 00366 call rcv232 ; Get byte OR clear errors. If return with 1, then error. If return with 0, then good 008E 3A00 00367 xorlw 0x00 ; Check if good 008F 1D03 00368 btfss STATUS,Z ; Check if 0 which is good 0090 288B 00369 goto learna ; If it was a 1, then is was just an error, loop on to next test. Else: 0091 0879 00370 movf RCV_REG,w ; Get what's in Received byte 0092 3A79 00371 xorlw 0x79 ; Compare with 'y" 0093 1903 00372 btfsc STATUS,Z ; Check if the same 0094 28A6 00373 goto learnec ; If the same, go to clear all E2 0095 1085 00374 abort bcf PORTA,REDLED ; If not a "y", then RS232 transmit message "Abort" 5D,09 - Turn on red LED +++ NOT A "Y" ON TILDE +++ 0096 305D 00375 movlw 0x5D ; RS232 transmit message "Abort" 5D,09 Need to be 1 back (5C rather than 5D) because sub in a sub 0097 00ED 00376 movwf pointer 0098 3009 00377 movlw 0x09 0099 00EE 00378 movwf counter 009A 2119 00379 call msgout 009B 1485 00380 bsf PORTA,REDLED ; Turn off red LED 00381 009C 3000 00382 lsame1 movlw 0x00 ; Then RS232 transmit message "Ready" 00,07 009D 00ED 00383 movwf pointer 009E 3007 00384 movlw 0x07 009F 00EE 00385 movwf counter 00A0 2119 00386 call msgout 00A1 1405 00387 bsf PORTA,GRNLED ; Turn off the green LED 00A2 13F1 00388 bcf stat1,7 ; Clear all bits and restart 00A3 10F1 00389 bcf stat1,1 ; Clear "Send - Ready to save, pick a character:" bit 00A4 1071 00390 bcf stat1,0 ; Clear start bit found 00A5 286F 00391 goto learn1 00392 00A6 1005 00393 learnec bcf PORTA,GRNLED ; Turn on the green LED +++ YES, A "Y" ON TILDE +++ 00A7 21AB 00394 call clre2 ; Clear all internal E2 data (except last 2 bytes) to "00" 00A8 3064 00395 movlw 0x64 ; Then RS232 transmit message "OK" 64,06 00A9 00ED 00396 movwf pointer MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 9 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00AA 3006 00397 movlw 0x06 00AB 00EE 00398 movwf counter 00AC 2119 00399 call msgout 00AD 289C 00400 goto lsame1 00401 00402 00AE 1FF1 00403 learng btfss stat1,7 ; If in E2 mode, check if command found +++ CHKING FOR COMMAND END BIT +++ 00AF 286F 00404 goto learn1 ; If not loop back 00405 00B0 1CF1 00406 btfss stat1,1 ; Test for "output "Ready to save, pick a character:" bit 00B1 286F 00407 goto learn1 ; If status bit not set, loop back 00B2 21FE 00408 call bxfer ; Transfer data from IRDATA and CLENGTH to irsave and lsave +++ XFER FROM IRDATA TO IRSAVE +++ 00B3 3007 00409 movlw 0x07 ; RS232 transmit message "Ready to save, pick a character:" 07,21 +++ XMIT "PICK A CHARACTER" +++ 00B4 00ED 00410 movwf pointer 00B5 3021 00411 movlw 0x21 ; Load message count of bytes (characters) to send 00B6 00EE 00412 movwf counter 00B7 2119 00413 call msgout 00B8 10F1 00414 bcf stat1,1 ; Clear send message bit 00415 00416 00B9 1E8C 00417 learnk btfss PIR1,RCIF ; Check if data in RS232 Receiver buffer +++ CHKING FOR CHARACTER +++ 00BA 28B9 00418 goto learnk ; Go on to next test if nothing there 00BB 2213 00419 call rcv232 ; Get byte OR clear errors. If return with 1, then error. If return with 0, then good 00BC 3A00 00420 xorlw 0x00 ; Check if good 00BD 1D03 00421 btfss STATUS,Z ; Check if 0 which is good 00BE 28B9 00422 goto learnk ; If it was a 1, then is was just an error, loop on to next test. Else: 00423 00BF 0879 00424 movf RCV_REG,w ; Get what's in Received byte +++ CHK WHAT'S IN CHARACTER +++ 00C0 3A1B 00425 xorlw 0x1B ; Compare with escape key +++ CHK IF IT'S AN ESCAPE +++ 00C1 1D03 00426 btfss STATUS,Z ; Check if the same 00C2 28CB 00427 goto learnsc ; If not the same, go to save character 00C3 300D 00428 abort2 movlw 0x0D ; Do a carriage return 00C4 0099 00429 movwf TXREG ; Put the returned byte into the RS232 buffer 00C5 2123 00430 call bitchk ; Check transmit flag, that byte is sent 00C6 13F1 00431 bcf stat1,7 ; Clear all bits and restart +++ IT'S AN ESCAPE, SO ABORT +++ 00C7 10F1 00432 bcf stat1,1 00C8 1071 00433 bcf stat1,0 ; Clear start bit found 00C9 1405 00434 bsf PORTA,GRNLED ; Clear the LED 00CA 2895 00435 goto abort 00436 00437 ; +++ IT'S A CHARACTER, CHK 4 MATCH +++ 00CB 2188 00438 learnsc call e2mtch ; Check if there's a match in internal E2 that matches ascii in RCV_REG. C=0=no, C=1=yes 00CC 1C03 00439 btfss STATUS,C ; Test if match found MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 10 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00CD 28DE 00440 goto learnbl ; If no match, go to "find a blank" 00441 ; +++ MATCH FOUND WITH E2 +++ 00CE 3028 00442 movlw 0x28 ; If already saved/a match, then RS232 message "Already used. Overwrite? Y/N? " 28,20 +++ "OVERWRITE?" +++ 00CF 00ED 00443 movwf pointer 00D0 3020 00444 movlw 0x20 ; Load message count of bytes (characters) to send 00D1 00EE 00445 movwf counter 00D2 2119 00446 call msgout 00447 00D3 1E8C 00448 learni btfss PIR1,RCIF ; Check if data in RS232 Receiver buffer (looking for tilde) +++ LOOKING 4 "Y" on OVERWRITE +++ 00D4 28D3 00449 goto learni ; Go on to next test if nothing there 00D5 2213 00450 call rcv232 ; Get byte OR clear errors. If return with 1, then error. If return with 0, then good 00D6 3A00 00451 xorlw 0x00 ; Check if good 00D7 1D03 00452 btfss STATUS,Z ; Check if 0 which is good 00D8 28D3 00453 goto learni ; If it was a 1, then is was just an error, loop on to next test. Else: 00D9 0879 00454 movf RCV_REG,w ; Get what's in Received byte 00DA 3A79 00455 xorlw 0x79 ; Compare with 'y" 00DB 1903 00456 btfsc STATUS,Z ; Check if the same 00DC 28E2 00457 goto learn5 ; If the same, go to save in same location +++ "Y" FOUND, GOTO +++ 00DD 28C3 00458 goto abort2 ; If not a "y", then RS232 transmit message "Abort" 5D,09 - Turn on red LED and clear and start over +++ ELSE ABORT +++ 00459 00DE 219A 00460 learnbl call findsp ; Locate empty slot for new command +++ FIND EMPTY SLOT +++ 00DF 1803 00461 btfsc STATUS,C ; Test if blank spot was found. C=0=no space found, C=1=space found 00E0 28E2 00462 goto learn5 ; If yes, then save it to empty space 00E1 28C3 00463 goto abort2 ; If no blank spaces, then RS232 transmit message "Abort" 5D,09 00464 ; +++ "Y" ON OVERWRITE OR WRITE +++ 00E2 2164 00465 learn5 call r2ee ; Convert IRDATA 32 bytes into E2D data 4 bytes, ready for writing. +++ SO CONVERT DATA TO 6 BYTES +++ 00E3 2128 00466 call e2wr ; Write 6 bytes to internal E2 +++ AND SAVE IN E2 +++ 00E4 3064 00467 movlw 0x64 ; RS232 transmit message "OK" 64,06 +++ XMIT "OK" +++ 00E5 00ED 00468 movwf pointer 00E6 3006 00469 movlw 0x06 00E7 00EE 00470 movwf counter 00E8 2119 00471 call msgout 00E9 289C 00472 goto lsame1 ; RS232 transmit message "Ready" 00,07, clear bits and return to main lo op +++ XMIT "READY", CLR & LOOP +++ 00473 00474 00EA 13F1 00475 learnez bcf stat1,7 ; Clear this and any new bit set 00EB 286F 00476 goto learn1 00477 00478 00479 ; *********************************************************************** 00480 ; *********************************************************************** MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 11 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00481 ; ************************** End Of Main Loop ****************************** 00482 ; *********************************************************************** 00483 ; *********************************************************************** 00484 00485 ;************************************************************************ 00486 ;************************************************************************ 00487 ;******************************* Subroutines ****************************** 00488 ;************************************************************************ 00489 ;************************************************************************ 00490 00491 ;************************** CHECK MODULATE SWITCH SW2 ***************** 00EC 1D85 00492 modchk btfss PORTA,MODSW 00ED 28F5 00493 goto turnon 00494 00EE 1DF1 00495 turnoff btfss stat1,3 ; Test status MODSW is high (normal) 00EF 0008 00496 return 00F0 11F1 00497 bcf stat1,3 00F1 1683 00498 bsf STATUS,RP0 ; Select Bank 1 00F2 108C 00499 bcf PIE1,TMR2IE ; Disable TIMER2 Interrupts 00F3 1283 00500 bcf STATUS,RP0 ; De-select Bank 1 00F4 0008 00501 return 00502 00F5 19F1 00503 turnon btfsc stat1,3 ; MODSW is low (Modulate) 00F6 0008 00504 return 00F7 15F1 00505 bsf stat1,3 00F8 1683 00506 bsf STATUS,RP0 ; Select Bank 1 00F9 148C 00507 bsf PIE1,TMR2IE ; Enable TIMER2 Interrupts 00FA 1283 00508 bcf STATUS,RP0 ; De-select Bank 1 00FB 0008 00509 return 00510 00511 00FC 1DF1 00512 btfss stat1,3 ; Check status of Modulate switch history 00FD 2905 00513 goto mody 00514 ; History is 1 00FE 1985 00515 modn btfsc PORTA,MODSW ; Check if modulated switch is on (low) 00FF 0008 00516 return ; End mod check 00517 ; Switch changed from 1 to 0 0100 11F1 00518 bcf stat1,3 ; Change occured to create modulate state 0101 1683 00519 modu bsf STATUS,RP0 ; Select Bank 1 0102 148C 00520 bsf PIE1,TMR2IE ; Enable TIMER2 Interrupts 0103 1283 00521 bcf STATUS,RP0 ; De-select Bank 1 00522 ;bsf T2CON,TMR2ON ; Turn on the timer 0104 0008 00523 return ; End mod check 00524 ; History is 0 0105 1D85 00525 mody btfss PORTA,MODSW ; Check if modulated switch is off (high) 0106 0008 00526 return ; End mod check 00527 ; Switch changed from 0 to 1 0107 15F1 00528 bsf stat1,3 ; Change occured to go to non-modulated state 0108 1683 00529 nonmod bsf STATUS,RP0 ; Select Bank 1 0109 108C 00530 bcf PIE1,TMR2IE ; Disable TIMER2 Interrupts 010A 1283 00531 bcf STATUS,RP0 ; De-select Bank 1 00532 ;bcf T2CON,TMR2ON ; Turn off the timer 010B 0008 00533 modend return MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 12 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00534 00535 00536 ;************************** GENERAL DELAY OF 40MS ********************** 010C 301F 00537 cdelay movlw 0x1F ; Load small delay count 010D 290F 00538 goto delcom 010E 307F 00539 idelay movlw 0x7F ; Load large delay count (IDELAY IS 40 MS LONG) 010F 00EB 00540 delcom movwf dcnth 0110 01EC 00541 idly0 clrf dcntl ; Load small delay count 0111 0000 00542 idly1 nop ; Wait a bit 0112 0000 00543 nop 0113 0000 00544 nop 0114 0BEC 00545 decfsz dcntl, F ; Decrement small delay count and check for 0 0115 2911 00546 goto idly1 ; If not 0, loop 0116 0BEB 00547 decfsz dcnth, F ; Decrement large delay count and check for 0 0117 2910 00548 goto idly0 ; If not 0, loop 0118 0008 00549 return 00550 00551 ;************************* RS232 MESSAGE OUT SUBROUTINE ************** 0119 3003 00552 msgout movlw 0x03 011A 008A 00553 movwf PCLATH 011B 086D 00554 movf pointer,0 ; Load with beginning pointer of message 011C 2390 00555 call msg1 ; Get byte to load into RS232 buffer 011D 0099 00556 movwf TXREG ; Put the returned byte into the RS232 buffer 011E 2123 00557 call bitchk ; Check transmit flag, that byte is sent 011F 0AED 00558 incf pointer,1 ; Increment the pointer to the next character address 0120 0BEE 00559 decfsz counter,1 ; Decrement counter and check for last byte 0121 2919 00560 goto msgout ; If not last byte, return for more 0122 0008 00561 return 00562 00563 ;************************* TEST FOR RS232 TRANSMITTER BUFFER EMPTY ***** 0123 1683 00564 bitchk bsf STATUS,RP0 ; Initialize RS232 TSCR - Select Bank 1 0124 1C98 00565 bc1 btfss TXSTA,TRMT ; Test if ready for next character 0125 2924 00566 goto bc1 ; Loop if not 0126 1283 00567 bcf STATUS,RP0 ; De-select Bank 1 0127 0008 00568 return 00569 00570 ; 00571 ; Relationship of 32 "bit" data to Internal E2 data bytes 00572 ; 00573 ; AMTCH (0x40 1 byte) --> E2D (0x43 first byte) 00574 ; CLENGTH (0x21 1 byte) --> E2D+1 (0x44 second byte) 00575 ; IRDATA (0x20 32 bytes) --> E2D+2 to E2D+5 (0x45 to 0x48 4 bytes) 00576 ; 00577 00578 00579 ;********************** Writes 6 bytes into internal E2 ********************** 00580 ; Set up is: start address to write is already in E2A and will be transferred to EEADR. 00581 ; For saving of data, subroutine "r2ee" has already been run and IRDATA, AMTCH 00582 ; and CLENGTH is already in E2D through E2D+5. Note: 8mS write time per byte. 00583 ; 0128 0864 00584 e2wr movf E2A,w ; Get start address to write to 0129 1683 00585 bsf STATUS,RP0 ; Select bank 1 012A 009B 00586 movwf EEADR ; Store it in Internal EE address byte MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 13 LOC OBJECT CODE LINE SOURCE TEXT VALUE 012B 1283 00587 bcf STATUS,RP0 ; Deselect bank 1 00588 012C 0865 00589 movf E2D,w ; Get ascii character to save as first byte 012D 2139 00590 call e2wsub ; Write byte 012E 0866 00591 movf E2D+1,w ; Load command length byte 012F 2139 00592 call e2wsub ; Write byte 0130 0867 00593 movf E2D+2,w ; Load command data byte 1 0131 2139 00594 call e2wsub ; Write byte 0132 0868 00595 movf E2D+3,w ; Load command data byte 2 0133 2139 00596 call e2wsub ; Write byte 0134 0869 00597 movf E2D+4,w ; Load command data byte 3 0135 2139 00598 call e2wsub ; Write byte 0136 086A 00599 movf E2D+5,w ; Load command data byte 4 0137 2139 00600 call e2wsub ; Write byte 0138 0008 00601 return 00602 00603 0139 1683 00604 e2wsub bsf STATUS,RP0 ; Write to E2 - Set to bank 1 013A 009A 00605 movwf EEDATA ; Save byte to Internal EEDATA byte 013B 138B 00606 esub1 bcf INTCON,GIE ; Disable interrupts 013C 1B8B 00607 btfsc INTCON,GIE ; Test if no other interrupts happened during disable 013D 293B 00608 goto esub1 00609 013E 151C 00610 bsf EECON1,WREN ; Enable writes 013F 3055 00611 movlw 0x55 ; Do start sequence (55h first) 0140 009D 00612 movwf EECON2 0141 30AA 00613 movlw 0xAA ; Do start sequence (then AAh writes to E2) 0142 009D 00614 movwf EECON2 0143 149C 00615 bsf EECON1,WR ; Set write bit to start write 00616 0144 1283 00617 bcf STATUS,RP0 ; Return to bank 0 0145 1F8C 00618 esub2 btfss PIR1,EEIF ; Check if write is complete 0146 2945 00619 goto esub2 ; If not, loop and test 0147 1683 00620 bsf STATUS,RP0 ; If write is done - Set to bank 1 0148 0A9B 00621 incf EEADR,f ; Increment the address to write to 0149 178B 00622 bsf INTCON,GIE ; Re-enable interrupts 014A 1283 00623 bcf STATUS,RP0 ; Return to bank 0 014B 0008 00624 return 00625 00626 00627 ;********************** Reads 6 bytes from internal E2 ********************** 00628 ; Set up is: start address to write is already in E2A and will be transferred to EEADR. 00629 ; 014C 0864 00630 e2rd movf E2A,w ; Get start address to write to 014D 1683 00631 bsf STATUS,RP0 ; Select bank 1 014E 009B 00632 movwf EEADR ; Store it in Internal EE address byte 014F 141C 00633 bsf EECON1,RD ; Initiate a read 0150 081A 00634 movf EEDATA,w ; Save data into w 0151 1283 00635 bcf STATUS,RP0 ; Deselect bank 1 0152 00E5 00636 movwf E2D ; Save it to first byte 0153 215E 00637 call e2rsub 0154 00E6 00638 movwf E2D+1 ; Save it to second byte byte 0155 215E 00639 call e2rsub MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 14 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0156 00E7 00640 movwf E2D+2 ; Save it to third byte byte 0157 215E 00641 call e2rsub 0158 00E8 00642 movwf E2D+3 ; Save it to fourth byte byte 0159 215E 00643 call e2rsub 015A 00E9 00644 movwf E2D+4 ; Save it to fifth byte byte 015B 215E 00645 call e2rsub 015C 00EA 00646 movwf E2D+5 ; Save it to sixth byte byte 015D 0008 00647 return 00648 015E 1683 00649 e2rsub bsf STATUS,RP0 ; Select bank 1 015F 0A9B 00650 incf EEADR,f ; Increment to next address 0160 141C 00651 bsf EECON1,RD ; Initiate a read 0161 081A 00652 movf EEDATA,w ; Save data into w 0162 1283 00653 bcf STATUS,RP0 ; Deselect bank 1 0163 0008 00654 return 00655 00656 00657 ;*** Transfers bit data in asave(AMTCH), csave(CLENGTH) and irsave(IRDATA) bytes into 8 bit bytes in E2D bytes for Internal EEPROM storage *** 00658 ; 0164 0879 00659 r2ee movf RCV_REG,w ; Transfer ASCII match byte 0165 00E5 00660 movwf E2D 0166 0863 00661 movf lsave,w ; Transfer bit length byte 0167 00E6 00662 movwf E2D+1 00663 0168 3020 00664 movlw 0x20 ; Load total bit counter with 32 0169 00F5 00665 movwf e2bctr 016A 3040 00666 movlw irsave ; Load pointer with IR data start 016B 0084 00667 movwf FSR 00668 016C 0C00 00669 r2e1 rrf INDF,w ; Rotate b0 of pointed IR data register into Carry 016D 0CE7 00670 rrf E2D+2,1 016E 0CE8 00671 rrf E2D+3,1 016F 0CE9 00672 rrf E2D+4,1 0170 0CEA 00673 rrf E2D+5,1 ; Rotate through 00674 0171 0A84 00675 incf FSR,1 ; Point to next bit 0172 0BF5 00676 decfsz e2bctr,1 ; Check if last (32nd) bit 0173 296C 00677 goto r2e1 ; If not, go do another rotate 0174 0008 00678 return 00679 00680 00681 ; Relationship of 32 "bit" data to Internal E2 data bytes 00682 ; 00683 ; AMTCH (0x20 1 byte) --> E2D (0x50 first byte) 00684 ; CLENGTH (0x21 1 byte) --> E2D+1 (0x51 second byte) 00685 ; IRDATA (0x22 32 bytes) --> E2D+2 to E2D+5 (0x52 to 0x55 4 bytes) 00686 00687 00688 ;************** Transfers 8 bit bytes in E2D bytes into (active output) bit data in IRDATA, CLENGTH and IRDATA bytes *********** 00689 ; This subroutine is called in the operate mode when a match has already been found and the internal EEP ROM data is already in the MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 15 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00690 ; E2D bytes. It then transfers those bits/bytes to the "active" IRDATA and CLENGTH to be transmitted out . AMTCH is not necessary. 00691 ; 0175 0866 00692 ee2r movf E2D+1,w ; Transfer bit length byte 0176 00E2 00693 movwf CLENGTH 00694 0177 3020 00695 movlw 0x20 ; Load total bit counter with 32 0178 00F5 00696 movwf e2bctr ; Will transfer full 32 bits even if not all were used 0179 3020 00697 movlw IRDATA ; Load pointer with IR data start address (IRDATA) 017A 0084 00698 movwf FSR 00699 017B 0CE7 00700 rmore rrf E2D+2,1 ; Rotate through 017C 0CE8 00701 rrf E2D+3,1 017D 0CE9 00702 rrf E2D+4,1 017E 0CEA 00703 rrf E2D+5,1 00704 017F 1C03 00705 btfss STATUS,C ; Test if 0 or 1 0180 2983 00706 goto risa0 0181 1400 00707 risa1 bsf INDF,0 0182 2984 00708 goto bitin 0183 1000 00709 risa0 bcf INDF,0 0184 0A84 00710 bitin incf FSR,f ; Point to next byte for bit 0185 0BF5 00711 decfsz e2bctr,1 ; Decrement the total bit counter 0186 297B 00712 goto rmore ; Not done with stored bits, go get another 0187 0008 00713 return 00714 00715 00716 ;******************* E2 MATCH - Check each location for 00 or ASCII match ***************** 00717 ; Addresses: 00, 06, 0C, 12, 18, 1E, 24, 2A, 30, 36, 3C, 42, 48, 4E, 54, 5A, 60, 66, 6C, 72, 78 0188 3000 00718 e2mtch movlw 0x00 ; Set E2 address to the beginning 0189 00E4 00719 movwf E2A ; Store inE2A for EEADR 018A 214C 00720 e2m1 call e2rd ; Reads 6 bytes from that address and puts in E2D data 018B 0865 00721 movf E2D,w ; Load what's in first read character byte from E2 (CHaracter location) 018C 0679 00722 xorwf RCV_REG,w ; Compare it with what's in RCV_REG 018D 1903 00723 btfsc STATUS,Z ; Test if Zero, which means a match 018E 2998 00724 goto mtched ; If Zero, then it matched 018F 0864 00725 movf E2A,w ; Check address byte for top (78) address already achieved 0190 3A78 00726 xorlw 0x78 ; 0191 1D03 00727 btfss STATUS,Z ; If zero, it's a match with 78 0192 2995 00728 goto e2m2 ; If not zero yet, go get another block to test 0193 1003 00729 bcf STATUS,C ; Clear the carry bit, meaning "no match" 0194 0008 00730 return ; And return 0195 3006 00731 e2m2 movlw 0x06 ; Else get ready to add 6 to address 0196 07E4 00732 addwf E2A,f ; Store back to E2A 0197 298A 00733 goto e2m1 0198 1403 00734 mtched bsf STATUS,C ; Set the carry bit meaning "match found" 0199 0008 00735 return ; And return 00736 00737 00738 ;************************* Look for empty spot in Internal E2 *********************** 019A 3000 00739 findsp movlw 0x00 ; Set E2 address to the beginning 019B 00E4 00740 movwf E2A ; Store in EEADR 019C 214C 00741 findsp1 call e2rd ; Reads 6 bytes from that address MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 16 LOC OBJECT CODE LINE SOURCE TEXT VALUE 019D 08E5 00742 movf E2D,f ; Check if data is "00" 019E 1D03 00743 btfss STATUS,Z ; Check if byte was a 0 019F 29A2 00744 goto notsp ; If not 0, then get another location 01A0 1403 00745 bsf STATUS,C ; Return with carry bit set, meaning "here's a space" 01A1 0008 00746 return ; And return (This will leave the open address intact in E2A) 01A2 0864 00747 notsp movf E2A,w ; Check address byte for top (78) address already achieved 01A3 3A78 00748 xorlw 0x78 ; Compare with top address 01A4 1D03 00749 btfss STATUS,Z ; If zero, it's a match with 78 01A5 29A8 00750 goto nextsp 01A6 1003 00751 bcf STATUS,C ; Clear the carry bit, meaning "no match" 01A7 0008 00752 return ; And return 01A8 3006 00753 nextsp movlw 0x06 ; Else get ready to add 6 to address 01A9 07E4 00754 addwf E2A,f ; Store back to E2A 01AA 299C 00755 goto findsp1 00756 00757 00758 ;************************* Clear all Internal E2 ******************************* 01AB 3000 00759 clre2 movlw 0x00 ; Set E2 address to the beginning 01AC 00E4 00760 movwf E2A ; Store in EEADR 01AD 01E5 00761 clre22 clrf E2D 01AE 01E6 00762 clrf E2D+1 01AF 01E7 00763 clrf E2D+2 01B0 01E8 00764 clrf E2D+3 01B1 01E9 00765 clrf E2D+4 01B2 01EA 00766 clrf E2D+5 01B3 2128 00767 call e2wr ; Write 6 blanks to byte block 01B4 0964 00768 comf E2A,w ; Check address byte for top (78) address already achieved 01B5 3E87 00769 addlw 0x87 ; Add compliment of 78 01B6 1903 00770 btfsc STATUS,Z ; If zero, it's a match with 78 01B7 0008 00771 return 01B8 3006 00772 movlw 0x06 ; If not, add 6 to address 01B9 07E4 00773 addwf E2A,f ; Store back to E2A 01BA 29AD 00774 goto clre22 ; And go clear another block 00775 00776 00777 ;******************* IR output ***************** 01BB 00778 irplay ; 2.5ms on 50 (x50uS) [12.750mS max with 0xFF] 00779 ; 0 = 550uS off / 650uS on 11 / 14 (x50uS) 00780 ; 1 = 550uS off / 1250uS on 11 / 26 (x50uS) 00781 ; 10ms on 200 (x50uS) 00782 01BB 30FF 00783 movlw 0xFF ; Do 12.75mS dark/on time 01BC 00F5 00784 movwf ircnt 01BD 1571 00785 bsf stat1,2 ; Show that ir is "on" 01BE 1006 00786 bcf PORTB,IROUT ; Turn on IR LED 01BF 1586 00787 bsf PORTB,IRNOT ; Do inverse 01C0 16F1 00788 bsf stat1,5 ; Set enable bit 01C1 1AF1 00789 irplay1 btfsc stat1,5 ; Check if 12.75mS has gone by 01C2 29C1 00790 goto irplay1 ; If not, wait 00791 01C3 3032 00792 movlw 0x32 ; Now do start marking by turning off LED for 2.5mS 01C4 00F5 00793 movwf ircnt 01C5 1171 00794 bcf stat1,2 ; Show that ir is "off" MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 17 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01C6 1406 00795 bsf PORTB,IROUT ; Turn off IR LED 01C7 1186 00796 bcf PORTB,IRNOT ; Do inverse 01C8 16F1 00797 bsf stat1,5 ; Set enable bit 01C9 1AF1 00798 irplay2 btfsc stat1,5 ; Check if 2.5mS has gone by 01CA 29C9 00799 goto irplay2 ; If not, wait 00800 01CB 0862 00801 movf CLENGTH,w ; Load with count to do 01CC 00FA 00802 movwf irlength 00803 01CD 3020 00804 movlw IRDATA ; Load pointer with starting bit 01CE 0084 00805 movwf FSR 00806 01CF 21E9 00807 irbits call iroff ; Start with a "space" 01D0 1AF1 00808 irout3 btfsc stat1,5 ; Test if enable bit reset 01D1 29D0 00809 goto irout3 ; If not, keep testing 00810 01D2 0C00 00811 rrf INDF,w ; Rotate bit into carry bit 01D3 1C03 00812 btfss STATUS,C ; Test to see if it's a 0 or 1 01D4 29D7 00813 goto irout0 01D5 21F7 00814 irout1 call ir1 ; Send out a long 1 01D6 29D8 00815 goto irout2 01D7 21F0 00816 irout0 call ir0 ; Send out a short 0 01D8 1AF1 00817 irout2 btfsc stat1,5 ; Test if enable bit reset 01D9 29D8 00818 goto irout2 ; If not, keep testing 01DA 0A84 00819 incf FSR,f ; Increment to the next bit to send 01DB 0BFA 00820 decfsz irlength,f ; Check if this is the last 01DC 29CF 00821 goto irbits ; If not, go get another bit 00822 01DD 30FF 00823 movlw 0xFF ; Do another 12.75mS of dark/on time before returning 01DE 00F5 00824 movwf ircnt 01DF 1571 00825 bsf stat1,2 ; Show that ir is "on" 01E0 1006 00826 bcf PORTB,IROUT ; Turn on IR LED 01E1 1586 00827 bsf PORTB,IRNOT ; Do inverse 01E2 16F1 00828 bsf stat1,5 ; Set enable bit 01E3 1AF1 00829 irplay3 btfsc stat1,5 ; Check if 12.75mS has gone by 01E4 29E3 00830 goto irplay3 ; If not, wait 01E5 1171 00831 bcf stat1,2 ; Show that ir is "off" 01E6 1406 00832 bsf PORTB,IROUT ; Turn off IR LED before leaving 01E7 1186 00833 bcf PORTB,IRNOT ; Do inverse 01E8 0008 00834 return 00835 01E9 1571 00836 iroff bsf stat1,2 ; Show that ir is "on" 01EA 1006 00837 bcf PORTB,IROUT ; Turn off IR LED 01EB 1586 00838 bsf PORTB,IRNOT ; Do inverse 01EC 300B 00839 movlw 0x0B ; Load a count of 11 for 550uS off 01ED 00F5 00840 movwf ircnt 01EE 16F1 00841 bsf stat1,5 ; Set enable bit 01EF 0008 00842 return 00843 01F0 1171 00844 ir0 bcf stat1,2 ; Show that ir is "off" 01F1 1406 00845 bsf PORTB,IROUT ; Turn on IR LED 01F2 1186 00846 bcf PORTB,IRNOT ; Do inverse 01F3 300D 00847 movlw 0x0D ; Load a count of 13 for 650uS on MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 18 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01F4 00F5 00848 movwf ircnt 01F5 16F1 00849 bsf stat1,5 ; Set enable bit 01F6 0008 00850 return 00851 01F7 1171 00852 ir1 bcf stat1,2 ; Show that ir is "off" 01F8 1406 00853 bsf PORTB,IROUT ; Turn on IR LED 01F9 1186 00854 bcf PORTB,IRNOT ; Do inverse 01FA 3019 00855 movlw 0x19 ; Load a count of 25 for 1250uS on 01FB 00F5 00856 movwf ircnt 01FC 16F1 00857 bsf stat1,5 ; Set enable bit 01FD 0008 00858 return 00859 00860 00861 ;*** Transfers 34 bytes from AMTCH/CLENGTH/IRDATA to asave/lsave/irsave for saving *** 00862 01FE 00863 bxfer ;movf AMTCH,w 00864 ; movwf asave 01FE 0862 00865 movf CLENGTH,w 01FF 00E3 00866 movwf lsave 00867 0200 3020 00868 movlw 0x20 ; Load total bit counter with 32 0201 00F5 00869 movwf e2bctr ; Will transfer full 32 bits even if not all were used 00870 0202 3020 00871 movlw IRDATA ; Save source location address 0203 00F4 00872 movwf ectr 0204 3040 00873 movlw irsave ; Save destination location address 0205 00F7 00874 movwf xctr 00875 0206 0874 00876 blkloop movf ectr,w ; Load with source address 0207 0084 00877 movwf FSR 0208 0800 00878 movf INDF,w ; Get byte at source address 0209 00F8 00879 movwf tempb ; Save it temporarily 020A 0877 00880 movf xctr,w ; Load with destination address 020B 0084 00881 movwf FSR 020C 0878 00882 movf tempb,w ; Get temporary byte 020D 0080 00883 movwf INDF ; And save it in destination address 020E 0AF4 00884 incf ectr,f ; Increment addresses 020F 0AF7 00885 incf xctr,f 0210 0BF5 00886 decfsz e2bctr,f ; Decrement byte transfer counter 0211 2A06 00887 goto blkloop ; If not last byte, loop back for another 0212 0008 00888 return ; Else return 00889 00890 00891 ;**************************** RS232 Receive Byte Subroutine **************************** 00892 ; Call this routine after successfully testing PIR1,RCIF flag for byte present. Will put byte in RCV_RE G 0213 1C98 00893 rcv232 btfss RCSTA,OERR ; If overrun error occurred (in bank 0) 0214 2A18 00894 goto rcv1 0215 1218 00895 bcf RCSTA,CREN ; Reset the receiver logic 0216 1618 00896 bsf RCSTA,CREN ; Enable reception again 0217 3401 00897 retlw 1 ; Return with error 0218 1D18 00898 rcv1 btfss RCSTA,FERR ; If framing error occurred 0219 2A1C 00899 goto rcv2 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 19 LOC OBJECT CODE LINE SOURCE TEXT VALUE 021A 081A 00900 movf RCREG,W ; Discard received data that has error 021B 3401 00901 retlw 1 ; Return with error 021C 081A 00902 rcv2 movf RCREG,W ; Get received data (in bank 0) 021D 00F9 00903 movwf RCV_REG ; Save it in Receive Register 00904 021E 3EBF 00905 ffff addlw 0xBF ; Test if less than 41(capital A) 021F 1C03 00906 btfss STATUS,C 0220 3400 00907 retlw 0 ; If less than 41, then bail 0221 0879 00908 movf RCV_REG,w ; Get byte again 0222 3EA5 00909 addlw 0xA5 ; Test if more than 5A (capital Z) 0223 1803 00910 btfsc STATUS,C 0224 3400 00911 retlw 0 ; If more than 5A, then bail 0225 3020 00912 movlw 0x20 ; If it's a capital letter, add 0x20 to it 0226 07F9 00913 addwf RCV_REG,f ; And make it a small case letter and save 0227 3400 00914 retlw 0 ; Return good 00915 00916 00917 ;************************************************************************ 00918 ;************************************************************************ 00919 ;************************** ALTERNATE SUBROUTINES *********************** 00920 ;************************************************************************ 00921 ;************************************************************************ 00922 00923 ;******************* Alternate send command as 1's and 0's subroutine ********* 00924 ; Addresses: 00, 06, 0C, 12, 18, 1E, 24, 2A, 30, 36, 3C, 42, 48, 4E, 54, 5A, 60, 66, 6C, 72, 78 00925 0228 3042 00926 cmdout movlw 0x42 ; Send a "B" 0229 0099 00927 movwf TXREG ; Put the returned byte into the RS232 buffer 022A 2123 00928 call bitchk ; Check transmit flag, that byte is sent 00929 022B 0862 00930 movf CLENGTH,w ; Save length to counter 022C 00F4 00931 movwf ectr 00932 022D 3020 00933 movlw IRDATA ; Set FSR with beginning of IR data to serve as pointer 022E 0084 00934 movwf FSR 00935 022F 0C00 00936 cmdl1 rrf INDF,0 0230 1C03 00937 btfss STATUS,C 0231 2A33 00938 goto itsa0 0232 2A37 00939 goto itsa1 00940 0233 3030 00941 itsa0 movlw 0x30 ; Send a "0" 0234 0099 00942 movwf TXREG ; Put the returned byte into the RS232 buffer 0235 2123 00943 call bitchk ; Check transmit flag, that byte is sent 0236 2A3A 00944 goto cmd2 00945 0237 3031 00946 itsa1 movlw 0x31 ; Send a "1" 0238 0099 00947 movwf TXREG ; Put the returned byte into the RS232 buffer 0239 2123 00948 call bitchk ; Check transmit flag, that byte is sent 00949 023A 0A84 00950 cmd2 incf FSR,1 ; Increment the pointer 023B 0BF4 00951 decfsz ectr,1 ; Decrement the counter and test if that was the last byte to be sent 023C 2A2F 00952 goto cmdl1 ; If not the last byte, send another byte. Else if last byte, then: MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 20 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00953 023D 3045 00954 movlw 0x45 ; Send an "E" 023E 0099 00955 movwf TXREG ; Put the returned byte into the RS232 buffer 023F 2123 00956 call bitchk ; Check transmit flag, that byte is sent 0240 210E 00957 call idelay ; Delay 40mS 00958 0241 3020 00959 movlw 0x20 ; Send an " " 0242 0099 00960 movwf TXREG ; Put the returned byte into the RS232 buffer 0243 2123 00961 call bitchk ; Check transmit flag, that byte is sent 0244 210E 00962 call idelay ; Delay 40mS 00963 0245 3020 00964 movlw 0x20 ; Send an " " 0246 0099 00965 movwf TXREG ; Put the returned byte into the RS232 buffer 0247 2123 00966 call bitchk ; Check transmit flag, that byte is sent 0248 210E 00967 call idelay ; Delay 40mS 00968 0249 0008 00969 return 00970 00971 00972 00973 ;**************************************************************************** 00974 ;**************************************************************************** 00975 ;*********************************** Interrupts ******************************** 00976 ;**************************************************************************** 00977 ;**************************************************************************** 00978 ; ; *** For all interrupts, save registers *** 024A 00EF 00979 ints movwf wtemp ; save off current W register contents 024B 0803 00980 movf STATUS,w ; move status register into W register 024C 00F0 00981 movwf stemp ; save off contents of STATUS register 024D 1283 00982 bcf STATUS,RP0 ; STATUS saved, so now corrupt and select bank 0 no matter what 00983 00984 ; ***** Timer 1 interrupt service routine ***** 024E 1C0C 00985 tmr1 btfss PIR1,TMR1IF ; Test if Timer 1 has Overflowed [50uS] (bit 0) 024F 2A66 00986 goto rsrcv ; If not, go to next interrupt check 0250 3018 00987 movlw 0x18 ; Reload low end register for 50uS 0251 008E 00988 movwf TMR1L 0252 30FF 00989 movlw 0xFF ; Reload high end register for 50uS 0253 008F 00990 movwf TMR1H 00991 0254 1E05 00992 btfss PORTA,O_L ; Check if switch set for Learn(0) or Operate(1) 0255 2A5C 00993 goto tmr1l ; If learn, go to learn section 0256 1EF1 00994 tmr1o btfss stat1,5 ; Check if bit set meaning enable count 0257 2A65 00995 goto tmr1b ; If not set, clear and go on 0258 0BF5 00996 decfsz ircnt,f ; Decrement counter 0259 2A65 00997 goto tmr1b ; If not 0 yet, bail 025A 12F1 00998 bcf stat1,5 ; It's zero so clear request and bail 025B 2A65 00999 goto tmr1b 01000 025C 0AF2 01001 tmr1l incf irctrl,1 ; Increment the IR interval counter lower byte 025D 1D03 01002 btfss STATUS,Z ; Test if low IR counter didn't roll over to zero 025E 2A65 01003 goto tmr1b ; If not, just clear interrupt and return 025F 0AF3 01004 incf irctrh,1 ; If rolled over, increment the IR counter high byte 0260 1D03 01005 btfss STATUS,Z ; Test if high byte is rolling over MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 21 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0261 2A65 01006 goto tmr1b ; If not, just clear interrupt and return 0262 30FF 01007 movlw 0xFF ; But if rolling over, don't want to do that 0263 00F2 01008 movwf irctrl ; So load both bytes with FF to show as high 0264 00F3 01009 movwf irctrh ; Gets stuck high until RB interrupt clears it, so never rolls over to l ow (00) number 01010 0265 100C 01011 tmr1b bcf PIR1,TMR1IF ; Clear Timer1 Interrupt Flag 01012 01013 01014 ; ***** USART Receive Interrupt service routine ***** 0266 1E8C 01015 rsrcv btfss PIR1,RCIF ; Test if USART Receive Interrupt Flag set (bit 5) 0267 2A68 01016 goto pbint ; If not, go to next interrupt check 01017 ;movf RCREG,w ; Get byte from internal RS232 Receiver byte 01018 ;movwf RCV_REG ; And store it in ascii receiver byte 01019 ;bsf stat1,4 ; Set ascii character received bit 01020 ;bcf PORTA,REDLED ; Turn on red LED 01021 ;bcf PIR1,RCIF ; Clear USART Receive Interrupt Flag 01022 ; Not using Interrupt so skip over clearing or worrying about 01023 01024 ; ***** PORT B Interrupt service routine ***** 0268 1C0B 01025 pbint btfss INTCON,RBIF ; Test if PORTB Transition Interrupt Flag set (bit ) 0269 2ABD 01026 goto rstx ; If not, go to next interrupt check 01027 026A 1A05 01028 btfsc PORTA,O_L ; Check if switch set for Learn(0) or Operate(1) 026B 2ABB 01029 goto rbO ; Was rstx ; If switch is in OPERATE, don't do a thing 01030 026C 1E06 01031 btfss PORTB,IRIN ; Test if transition was on falling edge 026D 2ABB 01032 goto rbO ; If falling edge, then ignore, go to save value of PORTB and clear inte rrupt 01033 026E 1BF1 01034 btfsc stat1,7 ; for lock bit - Check if "LOCK" bit is set 026F 2ABB 01035 goto rbO ; If yes, ignore input and just clear and exit 01036 0270 1871 01037 rbA btfsc stat1,0 ; Test if start bit set 0271 2A85 01038 goto rbF ; If yes, go to test for 1/0/end 01039 0272 08F3 01040 rbB movf irctrh,f ; Test of irctrh is 00 - TEST HIGH BYTE 0273 1D03 01041 btfss STATUS,Z ; Test if result is 0 0274 2A79 01042 goto rbC ; Not 0, so continue to check if 01, 02, 03 or more 0275 309B 01043 movlw 0x9B ; Else, high byte zero, so see what's in low byte - Load w with 9B h (in verse of 64h = 5mS) 0276 0772 01044 addwf irctrl,w ; Add w with value in irctrl. If higher, i.e. more than 5mS, the n negative on STATUS,C = 0 0277 1C03 01045 btfss STATUS,C ; If number is too small, C will be 0 0278 2AB9 01046 goto rbN ; Number was less than 5mS, Clear and bail 0279 08F3 01047 rbC movf irctrh,f ; Check if anything in counter high byte 027A 1D03 01048 btfss STATUS,Z ; 027B 2A80 01049 goto rbE ; Something in high byte, so definately more than 8mS 027C 305F 01050 movlw 0x5F ; Now we know that high counter is 0, so let's see if more than 8mS in l ow byte 027D 0772 01051 addwf irctrl,w ; Start with 5F (inverse of A0 = 8mS) and add value 027E 1C03 01052 btfss STATUS,C 027F 2AB9 01053 goto rbN ; If less than 8mS, then bail MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 22 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0280 1471 01054 rbE bsf stat1,0 ; Set start bit found 0281 01E2 01055 clrf CLENGTH ; Clear the counter byte 0282 3020 01056 movlw IRDATA ; 0x20 - Start with beginning of data storage area 0283 0084 01057 movwf FSR ; Load it into the register pointer 0284 2AB9 01058 goto rbN 01059 0285 08F3 01060 rbF movf irctrh,f ; Test if irctrh is 00 0286 1D03 01061 btfss STATUS,Z ; If loaded and not zero, to continue to check 0287 2AAD 01062 goto rbL ; But, if anything in high byte, it's more than 12.5mS so do final check 0288 30EE 01063 movlw 0xEE ; Load w with EE (inverse of 11h) (850us) 0289 0772 01064 addwf irctrl,w ; Add with lower (17x50us = 850us) from current counter value in W 028A 1C03 01065 btfss STATUS,C ; If number is too small, C will be 0 028B 2AB6 01066 goto rbD ; If less than 850uS, too small for anything, clear start bit and restar t 028C 30E3 01067 rbG movlw 0xE3 ; Load w with E3 (inverse of 1Ch (1400us) 028D 0772 01068 addwf irctrl,w ; Subtract 1Ch (28d) (28x50us = 1400us) from current counter val ue in W 028E 1C03 01069 btfss STATUS,C ; If number is too small, C will be 0 028F 2A9C 01070 goto rbH ; If less than 1400uS, then it's a 0, go to store it 0290 30D7 01071 rbI movlw 0xD7 ; Load w with D7 (inverse of 28h (2000us) 0291 0772 01072 addwf irctrl,w ; Subtract 28h (40d) (40x50us = 2000us = 2mS) from current count er value in W 0292 1C03 01073 btfss STATUS,C ; If number is too small, C will be 0 0293 2AA4 01074 goto rbJ ; If less than 2000uS, then it's a 1, go to store it 0294 08F3 01075 rbK movf irctrh,f ; Check if more than 8 mS. Load high counter and if anything the re, it's greater 0295 1D03 01076 btfss STATUS,Z ; If loaded and NOT zero... 0296 2AAD 01077 goto rbL ; ...it's more than 10mS, so go check if it's less than 30mS 0297 305F 01078 movlw 0x5F ; High byte zero, so see what's in low byte - Load w with 5F h (inverse of A0h = 8mS) 0298 0772 01079 addwf irctrl,w ; Add w with value in irctrl. If higher, i.e. more than 8mS then negative on STATUS,C = 0 0299 1C03 01080 btfss STATUS,C ; If number is too small, C will be 0 029A 2AB6 01081 goto rbD ;WAS rbM ; Number was smaller than 8mS so might be an error. Go t o clear all. 029B 2AAD 01082 goto rbL ; Number was at least 8mS so consider it the end of scan. 029C 01083 rbH ; Store a 0 029C 30E0 01084 movlw 0xE0 ; Check if already 32 bytes stored 029D 0762 01085 addwf CLENGTH,w ; Add inverse of 20h 029E 1903 01086 btfsc STATUS,Z ; Check if zero, meaning it's 20 already 029F 2AB9 01087 goto rbN ; Already 20 (32 bytes stored), don't store any more 02A0 0180 01088 clrf INDF ; Store "0" in the current pointed register 02A1 0A84 01089 incf FSR,1 ; Point to next location 02A2 0AE2 01090 incf CLENGTH,1 ; Increment the character pointer 02A3 2AB9 01091 goto rbN 02A4 01092 rbJ ; Store a 1 02A4 30E0 01093 movlw 0xE0 ; Check if already 32 bytes stored 02A5 0762 01094 addwf CLENGTH,w ; Add inverse of 20h 02A6 1903 01095 btfsc STATUS,Z ; Check if zero, meaning it's 20 already 02A7 2AB9 01096 goto rbN ; Already 20 (32 bytes stored), don't store any more 02A8 3001 01097 movlw 0x01 ; Store "1" in the current pointed location 02A9 0080 01098 movwf INDF MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 23 LOC OBJECT CODE LINE SOURCE TEXT VALUE 02AA 0A84 01099 incf FSR,1 ; Point to next location 02AB 0AE2 01100 incf CLENGTH,1 ; Increment the character pointer 02AC 2AB9 01101 goto rbN 01102 02AD 01103 rbL ; Done, store command 02AD 30FA 01104 movlw 0xFA ; Check to see if at least 5 bits were stored 02AE 0762 01105 addwf CLENGTH,w 02AF 1C03 01106 btfss STATUS,C 02B0 2AB6 01107 goto rbD ; If less than 5 bits stored, it's noise, so clear all and bail 02B1 1071 01108 bcf stat1,0 ; ELSE GOOD/DONE! Then: Clear the start bit 02B2 14F1 01109 bsf stat1,1 ; Set send message bit 02B3 1005 01110 bcf PORTA,GRNLED ; Turn on green LED 02B4 17F1 01111 bsf stat1,7 ; Set "output string" bit 01112 02B5 2AB9 01113 goto rbN 02B6 1071 01114 rbD bcf stat1,0 ; Clear start bit found 02B7 1405 01115 bsf PORTA,GRNLED ; Turn off the green LED 02B8 01E2 01116 clrf CLENGTH 02B9 01117 rbM ; Error condition here. Final measure was less than 8mS. Clear all previously stored bits, point er, the start bit, and then: 02B9 01F2 01118 rbN clrf irctrl ; Clear counters 02BA 01F3 01119 clrf irctrh 02BB 0886 01120 rbO movf PORTB,f ; Acts to save changed transitions on PORTB and stop double interrupts 02BC 100B 01121 bcf INTCON,RBIF ; Clear PORTB Transition Interrupt Flag set 01122 01123 ; ***** USART Transmit Interrupt service routine ***** 02BD 1E0C 01124 rstx btfss PIR1,TXIF ; Test if USART Transmit Interrupt Flag set (bit 4) 02BE 2ABF 01125 goto tmr0 ; If not, go to next interrupt check 01126 ;bcf PIR1,TXIF ; Clear the interrupt flag 01127 ; Not using Interrupt so skip over clearing or worrying about 01128 01129 ; ***** Timer 0 interrupt service routine ***** 02BF 1D0B 01130 tmr0 btfss INTCON,T0IF ; Test if Timer0 has Overflowed (bit ) 02C0 2AC2 01131 goto othint ; If not, go to next interrupt check 02C1 110B 01132 bcf INTCON,T0IF ; Clear the interrupt flag 01133 01134 01135 ; ***** All other Interrupts ***** 02C2 1B8C 01136 othint btfsc PIR1,7 ; Test for EEPROM written Interrupt Flag 02C3 138C 01137 bcf PIR1,7 02C4 1B0C 01138 btfsc PIR1,6 ; Test for Comparitor Interrupt Flag 02C5 130C 01139 bcf PIR1,6 02C6 190C 01140 btfsc PIR1,2 ; Test for Capture 1 Interrupt FLag 02C7 110C 01141 bcf PIR1,2 01142 01143 ; ***** Timer 2 interrupt service routine ***** 02C8 1C8C 01144 btfss PIR1,1 ; Test for Timer 2 Match Interrupt FLag 02C9 2AD3 01145 goto othint2 02CA 1E05 01146 btfss PORTA,O_L ; Test if set for operate(1) of learn(0) 02CB 2AD3 01147 goto othint2 ; If learn (0) then skip 02CC 1DF1 01148 btfss stat1,3 ; PORTA,MODSW ; Test if set for modulation(0) 02CD 2AD2 01149 goto tmr2a ; If not set for modulation, just clear and return 02CE 1D71 01150 btfss stat1,2 ; Check if current bit being transferred is a 1 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 24 LOC OBJECT CODE LINE SOURCE TEXT VALUE 02CF 2AD2 01151 goto tmr2a ; If not, skip and just output 0. Otherwise, is 1, then: 02D0 3009 01152 movlw 0x09 ; Toggle IR on state @ 40kHz (39.01kHz) (on PORTB,0 and PORTB,3) 02D1 0686 01153 xorwf PORTB,1 02D2 108C 01154 tmr2a bcf PIR1,TMR2IF ; Clear Timer2 Interrupt flag 01155 01156 02D3 190B 01157 othint2 btfsc INTCON,T0IF ; Test for Timer0 Interrupt Flag 02D4 110B 01158 bcf INTCON,T0IF 02D5 188B 01159 btfsc INTCON,INTF ; Test for External Interrup Flag 02D6 108B 01160 bcf INTCON,INTF 01161 01162 02D7 0870 01163 iend movf stemp,w ; Retrieve copy of STATUS register 02D8 0083 01164 movwf STATUS ; Restore pre-isr STATUS register contents 02D9 0EEF 01165 swapf wtemp,f 02DA 0E6F 01166 swapf wtemp,w ; Restore pre-isr W register contents 01167 02DB 0009 01168 retfie 01169 01170 01171 01172 01173 ;**************************************************************************** 01174 ;**************************************************************************** 01175 ;************************************ Tables ********************************* 01176 ;**************************************************************************** 01177 ;**************************************************************************** 0390 01178 org 0390h 0390 0782 01179 msg1 addwf PCL,F ;,1 0391 3452 01180 retlw 'R' ; "Ready" 00,07 0392 3465 01181 retlw 'e' 0393 3461 01182 retlw 'a' 0394 3464 01183 retlw 'd' 0395 3479 01184 retlw 'y' 0396 340D 01185 msgx retlw 0x0D ; Carriage return 0397 340A 01186 retlw 0x0A ; Line feed 0398 3452 01187 msg2 retlw A'R' ; "Ready to save, pick a character: " 07,22 0399 3465 01188 retlw A'e' 039A 3461 01189 retlw A'a' 039B 3464 01190 retlw A'd' 039C 3479 01191 retlw A'y' 039D 3420 01192 retlw A' ' 039E 3474 01193 retlw A't' 039F 346F 01194 retlw A'o' 03A0 3420 01195 retlw A' ' 03A1 3473 01196 retlw A's' 03A2 3461 01197 retlw A'a' 03A3 3476 01198 retlw A'v' 03A4 3465 01199 retlw A'e' 03A5 342C 01200 retlw A',' 03A6 3420 01201 retlw A' ' 03A7 3470 01202 retlw A'p' 03A8 3469 01203 retlw A'i' MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 25 LOC OBJECT CODE LINE SOURCE TEXT VALUE 03A9 3463 01204 retlw A'c' 03AA 346B 01205 retlw A'k' 03AB 3420 01206 retlw A' ' 03AC 3461 01207 retlw A'a' 03AD 3420 01208 retlw A' ' 03AE 3463 01209 retlw A'c' 03AF 3468 01210 retlw A'h' 03B0 3461 01211 retlw A'a' 03B1 3472 01212 retlw A'r' 03B2 3461 01213 retlw A'a' 03B3 3463 01214 retlw A'c' 03B4 3474 01215 retlw A't' 03B5 3465 01216 retlw A'e' 03B6 3472 01217 retlw A'r' 03B7 343A 01218 retlw A':' 03B8 3420 01219 retlw A' ' 03B9 340D 01220 msg3 retlw 0x0D ; Carriage return ; "Already used. Overwrite? Y/N?" 29,1C 03BA 340A 01221 retlw 0x0A ; Line feed 03BB 3441 01222 retlw A'A' 03BC 346C 01223 retlw A'l' 03BD 3472 01224 retlw A'r' 03BE 3465 01225 retlw A'e' 03BF 3461 01226 retlw A'a' 03C0 3464 01227 retlw A'd' 03C1 3479 01228 retlw A'y' 03C2 3420 01229 retlw A' ' 03C3 3475 01230 retlw A'u' 03C4 3473 01231 retlw A's' 03C5 3465 01232 retlw A'e' 03C6 3464 01233 retlw A'd' 03C7 342E 01234 retlw A'.' 03C8 3420 01235 retlw A' ' 03C9 344F 01236 retlw A'O' 03CA 3476 01237 retlw A'v' 03CB 3465 01238 retlw A'e' 03CC 3472 01239 retlw A'r' 03CD 3477 01240 retlw A'w' 03CE 3472 01241 retlw A'r' 03CF 3469 01242 retlw A'i' 03D0 3474 01243 retlw A't' 03D1 3465 01244 retlw A'e' 03D2 343F 01245 retlw A'?' 03D3 3420 01246 retlw A' ' 03D4 3459 01247 retlw A'Y' 03D5 342F 01248 retlw A'/' 03D6 344E 01249 retlw A'N' 03D7 343F 01250 retlw A'?' 03D8 3420 01251 retlw A' ' 03D9 340D 01252 msg4 retlw 0x0D ; "Erase all E2? Y/N?" 43,12 (Carriage return first) 03DA 340A 01253 retlw 0x0A ; Line feed 03DB 3445 01254 retlw A'E' 03DC 3472 01255 retlw A'r' 03DD 3461 01256 retlw A'a' MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 26 LOC OBJECT CODE LINE SOURCE TEXT VALUE 03DE 3473 01257 retlw A's' 03DF 3465 01258 retlw A'e' 03E0 3420 01259 retlw A' ' 03E1 3461 01260 retlw A'a' 03E2 346C 01261 retlw A'l' 03E3 346C 01262 retlw A'l' 03E4 3420 01263 retlw A' ' 03E5 3445 01264 retlw A'E' 03E6 3432 01265 retlw A'2' 03E7 343F 01266 retlw A'?' 03E8 3420 01267 retlw A' ' 03E9 3459 01268 retlw A'Y' 03EA 342F 01269 retlw A'/' 03EB 344E 01270 retlw A'N' 03EC 343F 01271 retlw A'?' 03ED 3420 01272 retlw A' ' 03EE 340D 01273 msg5 retlw 0x0D ; "Abort" 5B,09 - Carriage return 03EF 340A 01274 retlw 0x0A ; Line feed 03F0 3441 01275 retlw A'A' 03F1 3462 01276 retlw A'b' 03F2 346F 01277 retlw A'o' 03F3 3472 01278 retlw A'r' 03F4 3474 01279 retlw A't' 03F5 340D 01280 msg6 retlw 0x0D ; "OK" 62,06 Carriage return 03F6 340A 01281 retlw 0x0A ; Line feed 03F7 344F 01282 retlw A'O' 03F8 344B 01283 retlw A'K' 03F9 340D 01284 retlw 0x0D ; Carriage return 03FA 340A 01285 retlw 0x0A ; Line feed 01286 01287 01288 ;--------------------------------------------------------------------------------------------------- 01289 END MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 27 SYMBOL TABLE LABEL VALUE ADEN 00000003 AMTCH 00000060 BITSW 00000002 BRGH 00000002 C 00000000 C1INV 00000004 C1OUT 00000006 C2INV 00000005 C2OUT 00000007 CCP1CON 00000017 CCP1IE 00000002 CCP1IF 00000002 CCP1M0 00000000 CCP1M1 00000001 CCP1M2 00000002 CCP1M3 00000003 CCP1X 00000005 CCP1Y 00000004 CCPR1H 00000016 CCPR1L 00000015 CIS 00000003 CLENGTH 00000062 CM0 00000000 CM1 00000001 CM2 00000002 CMCON 0000001F CMIE 00000006 CMIF 00000006 CREN 00000004 CSRC 00000007 DC 00000001 E2A 00000064 E2D 00000065 EEADR 0000009B EECON1 0000009C EECON2 0000009D EEDATA 0000009A EEIE 00000007 EEIF 00000007 F 00000001 FERR 00000002 FSR 00000004 GIE 00000007 GRNLED 00000000 INDF 00000000 INTCON 0000000B INTE 00000004 INTEDG 00000006 INTF 00000001 IRDATA 00000020 IRIN 00000004 IRNOT 00000003 IROUT 00000000 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 28 SYMBOL TABLE LABEL VALUE IRP 00000007 MODSW 00000003 Main 0000003D NOT_BO 00000000 NOT_BOD 00000000 NOT_BOR 00000000 NOT_PD 00000003 NOT_POR 00000001 NOT_RBPU 00000007 NOT_T1SYNC 00000002 NOT_TO 00000004 NU1 00000007 NU2 00000006 NU3 00000005 OERR 00000001 OPTION_REG 00000081 OSCF 00000003 O_L 00000004 PCL 00000002 PCLATH 0000000A PCON 0000008E PEIE 00000006 PIE1 0000008C PIR1 0000000C PORTA 00000005 PORTB 00000006 PR2 00000092 PS0 00000000 PS1 00000001 PS2 00000002 PSA 00000003 RBIE 00000003 RBIF 00000000 RCIE 00000005 RCIF 00000005 RCREG 0000001A RCSTA 00000018 RCV_REG 00000079 RD 00000000 REDLED 00000001 RP0 00000005 RP1 00000006 RS232I 00000001 RS232O 00000002 RX9 00000006 RX9D 00000000 SPBRG 00000099 SPEN 00000007 SREN 00000005 STATUS 00000003 SYNC 00000004 T0CS 00000005 T0IE 00000005 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 29 SYMBOL TABLE LABEL VALUE T0IF 00000002 T0SE 00000004 T1CKPS0 00000004 T1CKPS1 00000005 T1CON 00000010 T1OSCEN 00000003 T2CKPS0 00000000 T2CKPS1 00000001 T2CON 00000012 TMR0 00000001 TMR1CS 00000001 TMR1H 0000000F TMR1IE 00000000 TMR1IF 00000000 TMR1L 0000000E TMR1ON 00000000 TMR2 00000011 TMR2IE 00000001 TMR2IF 00000001 TMR2ON 00000002 TOUTPS0 00000003 TOUTPS1 00000004 TOUTPS2 00000005 TOUTPS3 00000006 TRISA 00000085 TRISB 00000086 TRMT 00000001 TX9 00000006 TX9D 00000000 TXEN 00000005 TXIE 00000004 TXIF 00000004 TXREG 00000019 TXSTA 00000098 VR0 00000000 VR1 00000001 VR2 00000002 VR3 00000003 VRCON 0000009F VREN 00000007 VROE 00000006 VRR 00000005 W 00000000 WR 00000001 WREN 00000002 WRERR 00000003 Z 00000002 _BODEN_OFF 00003FBF _BODEN_ON 00003FFF _BOREN_OFF 00003FBF _BOREN_ON 00003FFF _CP_OFF 00003FFF _CP_ON 00001FFF MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 30 SYMBOL TABLE LABEL VALUE _DATA_CP_OFF 00003FFF _DATA_CP_ON 00003EFF _ER_OSC_CLKOUT 00003FFF _ER_OSC_NOCLKOUT 00003FFE _EXTCLK_OSC 00003FEF _HS_OSC 00003FEE _INTOSC_OSC_CLKOUT 00003FFD _INTOSC_OSC_NOCLKOUT 00003FFC _INTRC_OSC_CLKOUT 00003FFD _INTRC_OSC_NOCLKOUT 00003FFC _LP_OSC 00003FEC _LVP_OFF 00003F7F _LVP_ON 00003FFF _MCLRE_OFF 00003FDF _MCLRE_ON 00003FFF _PWRTE_OFF 00003FFF _PWRTE_ON 00003FF7 _RC_OSC_CLKOUT 00003FFF _RC_OSC_NOCLKOUT 00003FFE _WDT_OFF 00003FFB _WDT_ON 00003FFF _XT_OSC 00003FED __16F627A 00000001 abort 00000095 abort2 000000C3 asave 00000061 bc1 00000124 bitchk 00000123 bitin 00000184 blkloop 00000206 bxfer 000001FE cdelay 0000010C clre2 000001AB clre22 000001AD cmd2 0000023A cmdl1 0000022F cmdout 00000228 counter 0000006E dcnth 0000006B dcntl 0000006C delcom 0000010F e2bctr 00000075 e2m1 0000018A e2m2 00000195 e2mtch 00000188 e2rd 0000014C e2rsub 0000015E e2wr 00000128 e2wsub 00000139 ectr 00000074 ee2r 00000175 esub1 0000013B esub2 00000145 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 31 SYMBOL TABLE LABEL VALUE ffff 0000021E findsp 0000019A findsp1 0000019C idelay 0000010E idly0 00000110 idly1 00000111 iend 000002D7 ints 0000024A ir0 000001F0 ir1 000001F7 irbits 000001CF ircnt 00000075 irctrh 00000073 irctrl 00000072 irlength 0000007A iroff 000001E9 irout0 000001D7 irout1 000001D5 irout2 000001D8 irout3 000001D0 irplay 000001BB irplay1 000001C1 irplay2 000001C9 irplay3 000001E3 irpoint 0000007B irsave 00000040 itsa0 00000233 itsa1 00000237 learn 0000006B learn1 0000006F learn2 0000007C learn5 000000E2 learna 0000008B learnbl 000000DE learnec 000000A6 learnez 000000EA learng 000000AE learni 000000D3 learnk 000000B9 learnsc 000000CB loop1 00000042 lsame1 0000009C lsave 00000063 modchk 000000EC modend 0000010B modn 000000FE modu 00000101 mody 00000105 msg1 00000390 msg2 00000398 msg3 000003B9 msg4 000003D9 msg5 000003EE MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 32 SYMBOL TABLE LABEL VALUE msg6 000003F5 msgout 00000119 msgx 00000396 mtched 00000198 nextsp 000001A8 nonmod 00000108 notsp 000001A2 oper 00000045 oper1 00000049 oper2 0000004F opernm 00000063 othint 000002C2 othint2 000002D3 pbint 00000268 pointer 0000006D r2e1 0000016C r2ee 00000164 rbA 00000270 rbB 00000272 rbC 00000279 rbD 000002B6 rbE 00000280 rbF 00000285 rbG 0000028C rbH 0000029C rbI 00000290 rbJ 000002A4 rbK 00000294 rbL 000002AD rbM 000002B9 rbN 000002B9 rbO 000002BB rcloop 00000019 rcv1 00000218 rcv2 0000021C rcv232 00000213 risa0 00000183 risa1 00000181 rmore 0000017B rsrcv 00000266 rstx 000002BD start 00000005 stat1 00000071 stemp 00000070 tempb 00000078 tmr0 000002BF tmr1 0000024E tmr1b 00000265 tmr1l 0000025C tmr1o 00000256 tmr2a 000002D2 turnoff 000000EE turnon 000000F5 MPASM 4.02 Released RS232.ASM 10-17-2005 0:50:47 PAGE 33 SYMBOL TABLE LABEL VALUE wtemp 0000006F xctr 00000077 MEMORY USAGE MAP ('X' = Used, '-' = Unused) 0000 : X---XXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 00C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0100 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0140 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0180 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 01C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0200 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0240 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0280 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 02C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXX---- ---------------- ---------------- 0380 : ---------------- XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 03C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXX----- 2000 : -------X-------- ---------------- ---------------- ---------------- All other memory blocks unused. Program Memory Words Used: 836 Program Memory Words Free: 188 Errors : 0 Warnings : 0 reported, 0 suppressed Messages : 0 reported, 27 suppressed