Decoding Infrared Remote Control
Decoding Infrared Remote Control
Decoding Infrared Remote Control
INTRODUCTION
For many years the consumer electronics industry has been employing infrared remote controls for the control of televisions, VCRs, and cable boxes. This same technology has recently started to appear in industrial applications to eliminate keypads. Decoding most of the infrared signals can be easily handled by PIC16C5X microcontrollers. This application note describes how this decoding may be done. The only mandatory hardware for decoding IR signals is an infrared receiver. The use of two types is described here. Both are modular types used often by the consumer electronics industry. The rst type responds to infrared signals modulated at about 40 kHz. The second responds to non-modulated infrared pulses and has a restricted range. The hardware costs of each approach will be less than two dollars. Three PIC16C5X application programs are described, and instructions on how they can be used to create an algorithm that can decode just about any remote control signal. Each PIC16C5X application program represents a step in mapping out a pre-existing infrared format. The nal application is a fully implemented example of decoding and interpreting the infrared signals of a type of Teknika TV remote.
HARDWARE DESCRIPTION
The schematic in Figure 1 shows a tool that can be made to aid development of infrared receiver code. The schematic consists of a PIC16C57 connected to one of two available infrared receivers. One receiver is for non-modulated signals, the other for modulated signals. Modulated receivers are available from Sharp and LiteOn, part numbers GP1U521Y and LT-1060 respectively. The non-modulated type is available from Quality Technologies part number QSE157QT. The choice of the PIC16C57 is not indicative of the processing power required for decoding. Typical IR receiver code can t into less than half the ROM space available in a PIC16C54, and uses four RAM locations. The choice of a PIC16C57 in this case was driven by the need to store a lot of signal lengths for later reading. A ceramic resonator clocks the PIC16C57. It will give adequate frequency accuracy to determine pulse and gap lengths. A RC network does not usually have adequate accuracy. A button is available for resetting the PIC16C57, and four jumpers are provided to control the application start-up. The two digit display is multiplexed and driven through Q1 and Q2. Three octal switches are used as inputs to control the OPTION register and which le is displayed. The whole circuit derives its power from a 9V, 200 mA wall mounted supply. U1 regulates the 9V down to 5V for the PIC16C57 and associated circuitry.
DS00657A-page 1
AN657
DS00657A-page 2
Power Jack
C1 120 F 35V 2 2 2
SW2
+5 +5 +5 RN4 1k A +5 B C 1 4 C 07
SW3
C 07
5 RN5 1k 3 A +5
SW1
C 07
5 RN4 1k 3 d +5 RN5 1k d
+5 1
U1 78M05
2
13 14 15 3 4 5
6 0
7 1
8 2
PORTA PORTA
3 9
PORTB
7 6 16
MCLR
28 +5 +5 0.033 F 40 pulse
RN3 A 10k 1 12 10 7 4 9
RN3 B 10k
3 S
U3
U4
5 18 15 17
A d C e
B G dp A
U5
A
f G e
B C d left
f G e
B C d right
+5
Q1 +5
Q2
AN657
DESCRIPTION OF SOFTWARE TO AID DEVELOPMENT
This application uses four different rmware les. IRMAIN.ASM controls the selection of the three application les. The rst le is MEASURE.ASM which stores the infrared burst and gap lengths into memory and allows playback of that information. IR6121.ASM decodes NEC6121 infrared format and displays the received codes on the LED display. The nal le, TECNICKA.ASM, shows the final firmware for decoding the infrared format for a Teknika Television. IRMAIN.ASM The rmware listed includes three applications that will aid in designing an infrared control system. IRMAIN.ASM reads jumpers 1 and 2 and directs program ow after reset to one of the three applications. Having no jumper in 2 will direct program ow to MEASURE.ASM. A jumper in 2 only will direct program ow to IR6121.ASM. Jumpers in both 1 and 2 will direct program ow to TEKNIKA.ASM. Jumpers 3 and 4 are not used. MEASURE.ASM This is the most basic and most useful of the three applications. This program stores the infrared burst and gap lengths into memory, allowing playback of the measurements through the two digit display. It allows external control of the OPTION register also, through SW1. The setting of SW1 is read directly into the OPTION register prescaler value for TMR0. If SW1 is changed during program operation, the PIC16C57 resets. Upon start-up a hyphen will be displayed in the left digit space until the infrared input settles to the dark logic indicating that the unit is ready to receive an infrared signal. As an infrared signal comes in, the lengths of bursts of infrared, and the lengths of gaps between burst are stored in consecutive le locations until all four pages of the PIC16C57s memory les are lled. If a jumper had been in 1, the program throws away the rst 32 pulse and gap lengths and starts storing pulse and gap lengths with the thirty third pulse length. This allows the decoding of very long formats. When all four pages of le memory are lled with pulse and gap lengths, a number and decimal point are displayed. The decimal point indicates that the unit is done reading. The number is a gap or pulse length. SW2 and SW3 control the time sequence of the pulse or gap length displayed. These are in octal with SW3 being the more signicant digit.
Start
Is No 1 Closed? Yes
Goto MEASURE
Is No 0 Closed? Yes
Goto IR6121
Goto TEKNIKA
DS00657A-page 3
AN657
FIGURE 3: MEASURE.ASM FLOWCHART
MEASURE
No
Yes
SW1
IR
Read Receiver
No
No Read Receiver IR
Receiver changed? No
Yes
Yes
Read TMR0
No
DS00657A-page 4
AN657
IR6121.ASM This is an example of the next stage in development. It uses the IR receiver, PIC16C57 clock frequency, OPTION prescaler value and characteristic time length constants that were found after using MEASURE.ASM with an infrared remote control based on the NEC6121 infrared controller[1]. The resulting algorithm is able to decode the infrared bit stream and display it as four bytes on the two digit display. The bytes are switched using SW1 (changing it will not cause this application to reset). From it, or such a program customized to your particular remote control, a list can be made of how each button on a remote control resolves to a set of bytes in memory. This allows the creation of a button lookup table.
No
Goto NewLoop
No
Goto RESET_IR
Goto NewLoop
DS00657A-page 5
AN657
FIGURE 5: IR6121.ASM FLOWCHART
NewLoop IR6121 Does No gap length equal hold? Yes Set HOLD and HOLD_RCVD
Setup ports, TMR0 and xed Option register Update Display Read IR Receiver IR
IR_STATE = 0
Yes
No
IR_STATE= 0
No
Yes
Is IR_STATE = 0? No
IR_STATE = 1 other
No
IR_STATE = IR_STATE + 1
Yes
Is IR_STATE <= 8? No
Rotate 0 into byte 1 SW1 Rotate 1 into byte 2 1 other Is gap duration 0,1 or other? 0 Yes Is IR_STATE <= 16? No Goto RESET_IR Yes Is IR_STATE <= 24? No
No
Rotate 0 into byte 2 other Rotate 1 into byte 3 1 Is gap duration 0,1 or other? 0 Rotate 0 into byte 3 other Rotate 1 into byte 4 1 Is gap duration 0,1 or other? 0 Rotate 0 into byte 4 Yes
No
DS00657A-page 6
AN657
TEKNIKA.ASM This is an example of a nished product. This program fully decodes the infrared format of a Teknika Television. When a number is pressed on the remote control it is displayed on the display. When channel up or channel down is pressed, the displayed number increases or decreases. It incorporates the nal step in implementing a remote control decoder, that of cross referencing codes to button numbers. The algorithm will only respond if the rst two bytes are 14h and EBh, the characteristic of this type of Teknika television. Byte 3 and byte 4 are checked to see if they are complements. If so, byte 3 is sent through a lookup table to determine which button the received byte corresponds to, then the appropriate action is taken. The lookup table was made by using IR6121 and recording byte 3 with the button pressed. Similar tables can be made using other remote controls.
Service Hold
Read IR receiver
IR
Clear HOLD
Yes
Receiver changed hi to lo? No No TMR0 rollover? Yes BUTTON = BUTTON + 1 Reload TMR0
Yes
Call TekRdRcvr
No
Yes
BUTTON = BUTTON - 1
Is 1/8 second due? Yes Is HOLD set? Yes Goto Service Hold
No
No
DS00657A-page 7
AN657
FIGURE 7: TEKRDRCVR, TEKIRRESET, TEKRDADDR FLOWCHART
TekRdRcvr TekRdAddr
No
Goto TekIRReset
Return
No
Yes
Hold ag? No
No
Goto TekIRReset
Return
No
Return
Set HOLD_RCVD
Goto TekIRReset
No
No
Is gap length > 38h? Yes Is gap length < 48h? Yes IR_STATE = 1 No TekIRReset
Set Carry
No
Return Return Is IR_STATE bit3 set? No rrf IRBYTE13 Yes rrf IRBYTE24
IR_STATE = IR_STATE +1
No
No Return
DS00657A-page 8
AN657
FIGURE 8: TEKCOMMAND FLOWCHART
TekRdCommand
Set ACTIVE_UP
Yes
Is IR_BYTE13 = 13h? No
Yes
Is IR_BYTE13 = IR_BYTE24?
No
Goto TekIRReset
Set ACTIVE_DOWN
Yes
Set IR_BYTE24 = 10
Yes
Is IR_BYTE24 = 0?
Yes
Goto TekLogCommand
DS00657A-page 9
AN657
INSTRUCTIONS ON WRITING AN ALGORITHM TO DECODE IR REMOTES
1. To design a system that uses an infrared remote control, the rst step is to choose a remote control. Self designed or off the shelf, modulated or unmodulated are the primary technical decisions. Once a remote control has been chosen or designed, its modulation frequency, if it has one, must be determined. This controls the kind of hardware used to receive the infrared signal. The next step is to determine the time-base of the data, that is, if the pulses and gaps are short or long in reference to the PIC16C57 clock. The OPTION switch, SW1, is used to get optimum length pulse and gap counts from TMR0. This denes the value of the OPTION prescaler. Fourth, denition is made as to what, in the format, denes a '1', and what, in the format, denes a '0'. This could be gap counts, pulse counts, or a combination of both. Fifth, determination is made of the full length of commands. This enables the determination as to whether a button is being held down or if a new command of the same type as previous is being issued. The sixth step requires the writing of code. The code will resolve the gap and pulse lengths and command lengths into bits and bytes. Each button on the remote will decode to a unique series of bits. The seventh and nal step takes these codes that are received and converts them to button numbers or commands, using a lookup table. ton until the decimal point comes on. Using the jumpers switch through the memorized pulse durations that the PIC16C57 will have stored in its memory. If all of the reading except the rst are below 40h, the infrared format is a modulating one. If half or more of the values show up as 0FFh, then the remote is non-modulating.
2.
3.
4.
5.
6.
7.
DS00657A-page 10
AN657
these lengths to ones and zeros and display them on the two digit display. Also a HOLD ag can be created which will be true as long as the button is being held down. Usually 1/8 second between commands indicates a new command. Use this value to time out HOLD times and times between commands. IR6121.ASM is an example of a program that translates the gap lengths of the NEC6121 format to the four bytes that make up the information in each command.
REFERENCES
[1] Infrared Remote Controls ICs; NEC Electronics. August 1991. Literature available 1-800-632-3531. [2] Sharp Optoelectronics Data Book, 1991/1992, page 961.
DS00657A-page 11
AN657
Please check the Microchip BBS for the latest version of the source code. Microchips Worldwide Web Address: www.microchip.com; Bulletin Board Support: MCHIPBBS using CompuServe (CompuServe membership not required).
APPENDIX A: IRMAIN.ASM
MPASM 01.40 Released IRMAIN.ASM 10-2-1996 10:24:32 PAGE 1
LOC OBJECT CODE VALUE 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00031 00032 00001 00002 00224 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051
00000083
TITLE "IR Receiver Ap-Note Program Selector V0.02" ; ;************************************************************************ ; File Name : IRMAIN.ASM ;************************************************************************ ; Author: William G. Grimm ; Company: Microchip Technology ; Revision: V0.02 ; Date: March 28, 1996 ; Assembler: MPASM version 1.21 ; ;************************************************************************ ; Revision History: ; ; ; V0.01 Original March 28, 1996 ; ; V0.02 Added the Technika routine March 28, 1996 ; ; ;************************************************************************ ; Assembly options LIST P=16C57,r=hex,N=75,C=120,T=ON ; ;************************************************************************ ; Required modules: ; ; picreg.equ ; irundef.asm ; undefines constants for include files ; measure.asm ; decodes all remotes ; ir6121.asm ; decodes all 6121 format remotes include "p16c5x.inc" LIST ; P16C5X.INC Standard Header File, Version 3.30 Microchip Tech, Inc. LIST ; ;************************************************************************ ; ; ; ;************************************************************************ ; Ceramic resonator or Crystal, 4.000Mhz. If a Prescaler of ; 64 (5 in the option register) is used, TMR0 will increment every ; 64.00 microseconds. ; If TMR0 is initially loaded with 131, TMR0 will overflow to 0 ; in 8.000 milliseconds. MSEC8 EQU D'131' ;************************************************************************ ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "File and Flag definitions." ;************************************************************************ ; file memory location definitions
DS00657A-page 12
AN657
00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 ;************************************************************************ ; ; full byte file memory locations ; LEFT_DIGIT EQU 0E ; code to be displayed on left digit RIGHT_DIGIT EQU 0F ; code to be displayed on right digit ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Constant definitions." ; *********************************************************************** ; Definition of program constants SUBTITL "Constant definitions." ; *********************************************************************** ; Definitions of constants used to configure the ports A_CONFIG EQU 0f ; IR input and option dial all inputs ; B_CONFIG EQU 03f ; PORTB has outputs on bits 6 and 7 for ; the display, bits 0 to 5 are inputs for ; the dials ; C_CONFIG1 EQU 01e ; lines 1,2,3, and 4 are input during selection C_CONFIG2 EQU 0 ; all lines are outputs normally ; ;************************************************************************ ; Definition of program constants ; HIPHEN EQU B'10111111' ; - for display ; ; ;DEFINE PORT_A REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| ; | | | | | | |Y| --> OPTION dial bit 0 ; | | | | | |Y| | --> OPTION dial bit 1 ; | | | | |Y| | | --> OPTION dial bit 2 ; | | | |Y| | | | --> IR input ; | | |O| | | | | --> Unavailable ; | |O| | | | | | --> Unavailable ; |O| | | | | | | --> Unavailable ; O| | | | | | | | --> Unavailable ; IR EQU 3 ; IR receiver ; ;DEFINE PORT_B REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| ; | | | | | | |Y| --> Right dial bit 0 ; | | | | | |Y| | --> Right dial bit 1 ; | | | | |Y| | | --> Right dial bit 2 ; | | | |Y| | | | --> Left dial bit 0 ; | | |Y| | | | | --> Left dial bit 1 ; | |Y| | | | | | --> Left dial bit 2 ; |Y| | | | | | | --> controls right digit, LOW is on ; Y| | | | | | | | --> controls left digit, LOW is on ; Y = DEFINED AS SHOWN (0/1) ; RIGHT_OFF EQU 6 LEFT_OFF EQU 7 ; ;DEFINE PORT_C REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| 0 turns element on ; | | | | | | |Y| --> A ; | | | | | |Y| | --> D SW1 ; | | | | |Y| | | --> C SW2
0000000E 0000000F
0000000F 0000003F
0000001E 00000000
000000BF
00000003
00000006 00000007
DS00657A-page 13
AN657
00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 ; | | | |Y| | | | --> E ; | | |Y| | | | | --> F ; | |Y| | | | | | --> B ; |Y| | | | | | | --> G ; Y| | | | | | | | --> dp ; Y = DEFINED AS SHOWN (0/1) ; SW1 EQU 1 SW2 EQU 2 DP EQU 7 ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Display." ; *********************************************************************** ; Display handling routines ; ;-----------------------------------------------------------------------; LookUpDigit ; Inputs a number, outputs the bit pattern to display that number ;-----------------------------------------------------------------------LookUpDigit andlw 0F ; mask off any higher order bits addwf PCL,F ; add to create a jump to a return ; 76543210 ; PORTC line ; GBFECDA ; element assignment retlw B'11000000' ; Zero retlw B'11011011' ; 1 retlw B'10010100' ; 2 retlw B'10011000' ; 3 retlw B'10001011' ; 4 retlw B'10101000' ; 5 retlw B'10100000' ; 6 retlw B'11011010' ; 7 retlw B'10000000' ; 8 retlw B'10001000' ; 9 retlw B'10000010' ; A retlw B'10100001' ; b retlw B'10110101' ; c retlw B'10010001' ; d retlw B'10100100' ; E retlw B'10100110' ; F ; ;-----------------------------------------------------------------------; UpdateDisplay ; Rotates power to each of the three display digits. ;-----------------------------------------------------------------------UpdateDisplay btfss PORTB,RIGHT_OFF ; Check the right digit goto RightOn ; right digit is on now ; call DisplayOff ; turn off all displays, and read PORTC ; inputs if active movf RIGHT_DIGIT,W ; Left digit is on, turn on right digit movwf PORTC ; send right digit out to the port bcf PORTB,RIGHT_OFF ; turn on the right digit retlw 0 RightOn call DisplayOff ; turn off all displays, and read PORTC ; inputs if active movf LEFT_DIGIT,W ; Right digit is on, turn on left digit movwf PORTC ; send left digit out to the port bcf PORTB,LEFT_OFF ; turn on the left digit retlw 0 ; ;-----------------------------------------------------------------------; DisplayOff
0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F 0010 0011
08C0 08DB 0894 0898 088B 08A8 08A0 08DA 0880 0888 0882 08A1 08B5 0891 08A4 08A6
0012 0012 07C6 0013 0A19 0014 091E 0015 0016 0017 0018 0019 0019 001A 001B 001C 001D 020F 0027 04C6 0800 091E 020E 0027 04E6 0800
DS00657A-page 14
AN657
001E 001E 05E6 001F 05C6 0020 0800 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 ; Turns off the display at the three transistors ;-----------------------------------------------------------------------DisplayOff bsf PORTB,LEFT_OFF ; turn off the left digit bsf PORTB,RIGHT_OFF ; turn off the right digit retlw 0 ; ;************************************************************************ ; include files org 200 BeginMeasure include "measure.asm" TITLE "IR Receiver output measurement routine V0.07" ; ;************************************************************************ ; File Name : MEASURE.ASM ;************************************************************************ ; Author: William G. Grimm ; Company: Microchip Technology ; Revision: V0.07 ; Date: March 31, 1996 ; Assembler: MPASM version 1.21 ; ;************************************************************************ ; Revision History: ; ; ; V0.01 Original January 9, 1995 ; ; V0.02 Added overflow indication January 12, 1996 ; ; V0.03 Modified to conform to Microchip specifications ; February 17, 1996 ; ; V0.04 Modified for new hardware March 19, 1996 ; ; V0.05 Changable option register and delay added ; March 20, 1996 ; ; V0.06 Added code that creates 1/8 second time out ; for all options 1 to 7, 0 gets a 1/16 second time out. ; March 26, 1996 ; ; V0.07 Improved roll over detection for long gaps and pulses ; March 27, 1996 ; ; V0.08 Changed to header file March 31, 1996 ; ; V0.09 Fixed bug that kept jumper 1 from being read ; ; ;************************************************************************ ; Assembly options LIST P=16C57,r=hex,N=75,C=120,T=ON ; ;************************************************************************ ; ; ; ;************************************************************************ ;************************************************************************ ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "RAM and Flag definitions." ;************************************************************************ ; file memory location definitions
0200 0200
DS00657A-page 15
AN657
00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 ;************************************************************************ ; ; full byte file memory locations ; START_COUNT EQU 08 ; TMR0 value at previous IR rcvr transition TR_COUNT EQU 09 ; transition being read TIMERM EQU FLAG EQU SCALE_RECORD EQU ; LEFT_DIGIT ; RIGHT_DIGIT 0b 0c 0d EQU EQU ; ; ; ; Bit5 = 1/4 sec, Bit1 = 16 millisecs. program flags prescaler value is stored here defined in main routine
0E 0F
; Files 10h-1fh,30h-3fh,50h-5fh,70h-7fh ; are used to store IR pulse and gap lengths. ; ; ; ; ;DEFINE FLAG REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| ; | | | | | | |Y| --> ; | | | | | |Y| | --> Eighth second flag. ; | | | | |Y| | | --> used for math, TMR0 overdue for reload ; | | | |Y| | | | --> the Value START_COUNT is new ; | | |Y| | | | | --> measurement has overflowed ; | |Y| | | | | | --> Value of last IR bit received. ; |Y| | | | | | | --> if set memory is full, stop reading ; Y| | | | | | | | --> ; _8TH_SEC EQU 1 OVERDUE EQU 2 NEW_START_COUNT EQU 3 OVERFLOW EQU 4 LAST_IR EQU 5 ALL_DONE EQU 6 ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Constant definitions." ; *********************************************************************** ; Definition of program constants ; SKIP_NUM EQU d'32' ; readings to skip before filing them OPTION_MASK EQU B'00000000' ; SET UP PRESCALER, WDT on 18msec. ; lowest three bits must be zero to not ; overwrite the prescaler dialed in ; externally ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Timer routines." ; *********************************************************************** ; Timer servicing routine ; Called every 1.6 to 8 milliseconds this clears the ; watch dog, reloads TMR0 ; and keeps track of relative time. ; ServiceTimerM movlw MSEC8 ;TMR0 = 8 milliseconds. addwf TMR0,W ; Add overflow amount. movwf TMR0 ; / clrwdt btfss FLAG,NEW_START_COUNT ; find if measured length is too long bsf FLAG,OVERFLOW ; length is too long to measure bcf FLAG,NEW_START_COUNT ; set the flag indicating the reload incf TIMERM,F ; increment the timer
00000020 00000000
DS00657A-page 16
AN657
0208 0209 020A 020B 020C 020D 020E 020F 020F 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 090F 018B 0743 0800 006B 052C 0800 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 call xorwf btfss retlw clrf bsf retlw TimerLookup TIMERM,W STATUS,Z 0 TIMERM FLAG,_8TH_SEC 0 ; ; ; ; ; ; ; get the maximum count see if maximum count is here Is maximum count there? not there return reset the timer Set the 1/8 sec flag. reset and ready for 1/8 sec chores
020D 0E07 01E2 0800 0800 0880 0840 0820 0810 0808 0804
021A 021A 05AC 021B 02A9 021C 0509 021D 021E 021F 0220 0C3F 0189 0643 05CC
0225 0225 0208 0226 0081 0227 0028 0228 0229 022A 022B 0C83 0088 0603 0028
; TimerLookup movf SCALE_RECORD,W ; bring in the record of the option andlw 7 ; ensure lookup table is not overjumped addwf PCL,F ; look up the proper timer overflow retlw 0 ; this will only get 1/16 sec time out retlw 0 ; option = 1 retlw b'10000000' ; option = 2 retlw b'01000000' ; option = 3 retlw b'00100000' ; option = 4 retlw b'00010000' ; option = 5 retlw b'00001000' ; option = 6 retlw b'00000100' ; option = 7 ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "IR counter." ; ; ; *********************************************************************** ; IR Receiver routines ; ;-----------------------------------------------------------------------; ReadReceiver ; Second part of the IR receiver. It takes the present count of the ; TMR0 and subtracts the count recorded when the receiver output ; went high (START_COUNT) to find the dark pulse duration. In that duration ; will be encoded the 1, 0, HOLD, or attention. ;-----------------------------------------------------------------------ReadReceiverHi bsf FLAG,LAST_IR ; record the IR receiver state incf TR_COUNT,F bsf TR_COUNT,0 ; Times when IR rcvr is Lo are recorded ; in odd numbered locations movlw 3fh ; bring in highest valid address in xorwf TR_COUNT,W ; TR_count see if highest count is in btfsc STATUS,Z ; skip if not highest address bsf FLAG,ALL_DONE ; set all done flag to stop reading goto TimeIRReceiver ; ReadReceiverLo bcf FLAG,LAST_IR ; record the IR value incf TR_COUNT,F bcf TR_COUNT,0 ; Times when IR rcvr is Hi are recorded ; in even numbered locations ; ; Calc the length of the dark pulse, ; length of time receiver was high. ; (placed in START_COUNT) TimeIRReceiver movf START_COUNT,W ; bring in the start measurement subwf TMR0,W ; subtract the final from the start movwf START_COUNT ; gap or pulse length is now in ; START_COUNT, must be checked movlw MSEC8 ; Base number of TMR0 count. subwf START_COUNT,W ; Subtract the base count of TMR0 btfsc STATUS,C ; skip the store and toss value if neg. movwf START_COUNT ; value was positive, store
DS00657A-page 17
AN657
022C 022C 06E9 022D 0A3A 00187 00188 00189 00190 00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 00213 00214 00215 00216 00217 00218 00219 00220 00221 00222 00223 00224 00225 00226 00227 00228 00229 00230 00231 00232 00233 00234 00235 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 ; MathDone btfsc goto ; movf andlw movwf bsf btfsc bsf btfsc bsf ; movlw btfss movf movwf DoNotStore movf movwf bsf 0ffh FLAG,OVERFLOW START_COUNT,W INDF ; ; ; ; ; bring in the overflow indication skip loading of result if overflowed bring in the measurement store it for display using indirect addressing bring in the count now store it for next time set ind flag that START_COUNT is new. this flag is used to determine if the pulse has gone on too long to measure clear any overflow indication TR_COUNT,7 DoNotStore ; check to see if in delay ; do not store the value if in delay ; ; ; ; ; ; ; ; ; format for FSR Setup place the count will be stored reduce to file location place file address in FSR set to place in upper file group set bank bit 0 / set bank bit 1 /
022E 022F 0230 0231 0232 0233 0234 0235 0236 0237 0238 0239
0209 0E0F 0024 0584 0689 05A4 06A9 05C4 0CFF 078C 0208 0020
bcf ;
0249 04A3 024A 04C3 024B 0380 024C 0900 024D 002E 024E 0200 024F 0900 0250 002F
0251 05A3
retlw 0 ; ; ;************************************************************************ ; The following code segments are called by the executive ; every 1/8 second and every two seconds ; EighthSecondChores ; all that needs doing every 1/8 sec ; can be placed in this subroutine bcf FLAG,_8TH_SEC ; clear the time out flag ; comf PORTB,W ; read the dial settings ; the requested memory location is in W movwf FSR ; Following formats the FSR to point to ; the selected file w/ the IR pulse bcf FSR,6 ; or gap length btfsc FSR,5 ; move bit 5 to 6 bsf FSR,6 ; if 5 was 1, set 6 bcf FSR,5 btfsc FSR,4 ; move bit 4 to 5 bsf FSR,5 ; if 4 was high, set bit 5 of fsr bsf FSR,4 ; Format for FSR, upper bank of bytes ; bcf STATUS,PA0 ; get ready to call from page 1 bcf STATUS,PA1 ; / ; swapf INDF,W ; bring in IR measurement to be dispd call LookUpDigit movwf LEFT_DIGIT ; display more significant digit ; movf INDF,W ; bring in IR measurement to be dispd call LookUpDigit movwf RIGHT_DIGIT ; display less significant digit ; if BeginMeasure==200 ; return the bits to this page bsf STATUS,PA0 ; page 1
DS00657A-page 18
AN657
0252 04C3 00253 00254 00255 00256 00257 00258 00259 00260 00261 00262 00263 00264 00265 00266 00267 00268 00269 00270 00271 00272 00273 00274 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 00286 00287 00288 00289 00290 00291 00292 00293 00294 00295 00296 00297 00298 00299 00300 00301 00302 00303 00304 00305 00306 00307 00308 00309 00310 00311 00312 00313 00314 00315 00316 00317 00318 bcf STATUS,PA1 endif if BeginMeasure==400 bcf STATUS,PA0 bsf STATUS,PA1 endif if BeginMeasure==600 bsf STATUS,PA0 bsf STATUS,PA1 endif ; comf andlw xorwf btfss goto goto PORTA,W ; bring in the reqd prescale value ; from the dial, reverse sense 7 ; AND w/ highest possible prescale value SCALE_RECORD,W ; compare the prescale dial setting ; with the original one STATUS,Z ; skip if the same StartMeasure ; restart the application if different DoneEighthSecondChores ; /
; page 2 ; /
; page 3 ; /
0253 0245 0254 0E07 0255 018D 0256 0743 0257 0A61 0258 0AAD
0259 0259 0024 025A 003F 025B 025B 02A4 025C 025D 025E 025F 0260 0060 021F 0743 0A5B 0800
; ; ClearRam movwf FSR movwf 1fh MemoryInitLoop incf FSR,F clrf movf btfss goto retlw INDF 1fh,w STATUS,Z MemoryInitLoop 0
; clears memory at reset ; place in fsr for indirect addressing. ; when zero, memory init is done. ; ; ; ; ; ; increment to the next memory location to be initialized. clear memory location. Has top memory location zeroed yet? / /
0261 0261 006C 0262 006B 0263 0069 0264 0C0F 0265 0959 0266 0C2F 0267 0959 0268 0C4F 0269 0959 026A 0C6F 026B 0959 026C 0C0F 026D 0005 026E 0C3F 026F 0006
; ; ;************************************************************************ ; Start HERE. ;************************************************************************ StartMeasure clrf FLAG ; Clear out flag bank 1. ; clrf TIMERM ; restart the TIMERM at 0 ; clrf TR_COUNT ; initialize memory counter ; movlw 0f ; start zeroing at memory location 10h call ClearRam ; clear the first bank of memory ; movlw 2f ; start zeroing at memory location 10h. call ClearRam ; clear the second bank of memory ; movlw 4f ; start zeroing at memory location 10h call ClearRam ; clear the third bank of memory ; movlw 6f ; start zeroing at memory location 10h call ClearRam ; clear the fourth bank of memory ; movlw A_CONFIG ; setup for PORTA, in loop so ; micocontroller will never forget tris PORTA ; inputs on bit 0. movlw B_CONFIG tris PORTB ; PORTB has outputs on bits 0,6,7; ; inputs on bits 1, 2, 3, 4, and 5. ; bsf PORTB,LEFT_OFF ; turn off both digits to read jumpers bsf PORTB,RIGHT_OFF ; / movlw C_CONFIG1 ; configuration to read from PORTC
DS00657A-page 19
AN657
0273 0274 0275 0276 0007 0CE0 0727 0029 00319 00320 00321 00322 00323 00324 00325 00326 00327 00328 00329 00330 00331 00332 00333 00334 00335 00336 00337 00338 00339 00340 00341 00342 00343 00344 00345 00346 00347 00348 00349 00350 00351 00352 00353 00354 00355 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 00370 00371 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 tris movlw btfss movwf ; movlw tris ; comf andlw movwf iorlw option ; ; movlw movwf bsf bcf ; movlw movwf MSEC8 TMR0 ;TMR0 = 8 mSEC ; / HIPHEN PORTC PORTB,LEFT_OFF PORTB,RIGHT_OFF ; ; ; ; Disp that unit waiting for dark conds put the Hiphen on right digit turn off left digit turn ON right digit PORTA,W 7 SCALE_RECORD OPTION_MASK ; ; ; ; ; ; bring in the requested prescale value from the dial, reverse sense AND w/ highest possible prescale value record the value of the prescaler Setup prescaler for TMR0, WDT on 18ms. / C_CONFIG2 PORTC ; bring in config to use PORTC for disp ; PORTC is normally all outputs PORTC -(SKIP_NUM) PORTC,SW1 TR_COUNT ; ; ; ; configure PORTC to read the bits let inputs settle, bring in skip numb skip if jumper 1 is not installed move the skip number to file pointer
0277 0C00 0278 0007 0279 0245 027A 027B 027C 027D 0E07 002D 0D00 0002
0282 0C83 0283 0021 0284 0284 0285 0286 0287 0288 0289 028A 028B 028C 028D 028E
0C83 0081 0603 0A84 0900 0765 006B 072C 0A84 006C 05AC
0293 093A
0294
; SettlingLoop movlw MSEC8 ; Check for overflow. subwf TMR0,W ; SEE IF TMR0 < MSEC8, btfsc STATUS,C ; If TMR0 < MSEC8, Overflow. goto SettlingLoop ; No overflow, no carry, loop. call ServiceTimerM ; Keep time and reload time keeper. btfss PORTA,IR ; IR receiver quiet? clrf TIMERM ; not quiet, reset timer btfss FLAG,_8TH_SEC ; Allow out of loop if quiet for 1/8sec goto SettlingLoop ; not quiet long enough yet clrf FLAG ; re-clear all of the flags bsf FLAG,LAST_IR ; set the flag, receiver is now hi ; ; movlw HIPHEN ; Display that unit is ready to receive movwf PORTC ; put the Hiphen on right digit bcf PORTB,LEFT_OFF ; turn on left digit bsf PORTB,RIGHT_OFF ; turn OFF right digit ; call DoNotStore ; setup timer last read for first read ; ;************ Main loop Starts here. ************* Main ; ; InnerLoop btfss FLAG,ALL_DONE ; update display only if memory is full goto CheckIr ; not full, keep reading the IR rcvr bcf STATUS,PA0 ; get ready to call from page 1 bcf STATUS,PA1 ; / call UpdateDisplay ; rotate power to the next display digit ; if BeginMeasure==200 ; return the bits to this page bsf STATUS,PA0 ; page 1 bcf STATUS,PA1 ; / endif if BeginMeasure==400 bcf STATUS,PA0 ; page 2 bsf STATUS,PA1 ; / endif if BeginMeasure==600 bsf STATUS,PA0 ; page 3
DS00657A-page 20
AN657
029B 07C6 029C 04E7 029D 0AA6 029E 029E 029F 02A0 02A1 00385 00386 00387 00388 00389 00390 00391 00392 00393 00394 00395 00396 00397 00398 00399 00400 00401 00402 00403 00404 00405 00406 00407 00408 00409 00410 00411 00412 00413 00414 00415 00416 00417 00418 00419 00420 00196 00197 00198 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 bsf endif btfss bcf goto ; CheckIr btfsc btfsc incf call ; btfss btfss incf call ; ReadDone ; movlw subwf btfsc goto call ; btfsc goto PORTA,IR FLAG,LAST_IR PCL,F ReadReceiverLo ; ; ; ; ?IR receiver receiving an IR burst? was it not receiving burst last time? Not either skip next instruction read the new information STATUS,PA1 PORTB,RIGHT_OFF PORTC,DP ReadDone ; / ; skip if the right digit is off ; lite the decimal to show read taken ; memory is full, done reading receiver
; ; ; ; ;
?IR receiver not recvg an IR burst? was it receiving a burst last time? Not either, skip next instruction Record TMR0 value when the lo to hi transition came from the receiver
02A2 02A3 02A4 02A5 02A6 02A6 02A7 02A8 02A9 02AA
; ; ; ; ;
Check for overflow. SEE IF TMR0 < MSEC8, If TMR0 < MSEC8, Overflow. No overflow, no carry, loop. Keep time and reload time keeper.
; check for 1/8 second time out ; anything that needs doing every 1/8sec ; can go in this subroutine
DoneEighthSecondChores ; goto Main ; ; org 400 BeginIr6121 include "ir6121.asm" TITLE "IR-NEC6121 format Remote Control Detector V0.02" SUBTITL "Comments documentation and history" ; ;************************************************************************ ; File Name : IR6121.ASM ;************************************************************************ ; Author: William G. Grimm ; Company: Microchip Technology ; Revision: V0.02 ; Date: February 27, 1996 ; Assembler: MPASM version 1.21 ; ;************************************************************************ ; Revision History: ; ; ; V0.01 Original February 27, 1996 ; ; V0.02 Converted to Ap-note format and made into a header ; file March 28, 1996 ;************************************************************************ OPTION_CODE EQU B'00000101' ;SET UP PRESCALER, WDT on 18msec. ;************************************************************************ ; ;************************************************************************ ; file memory location definitions ;************************************************************************
0400 0400
00000005
DS00657A-page 21
AN657
00028 00029 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 ; ; full byte file memory locations ; TIMER EQU 0b ; Bit 5 = 1/4 second, Bit 1 = 16 millisecs. TEMP EQU 0c ; temporary file storage ; ; LEFT_DIGIT EQU 0e ; defined in irmain ; RIGHT_DIGIT EQU 0f ; defined in irmain READ_LH EQU 11 ; Low to high reading is stored here. IR_STATE EQU 12 ; Which bit is coming in. IR_BYTE13 EQU 13 ; First byte for collecting inputs. IR_BYTE24 EQU 14 ; Second byte for collecting inputs. ; FLAG2 EQU 18 ; flag bank 2 FLAG3 EQU 19 ; flag bank 3 C_BYTE_1 EQU 1A ; Memory location defs for storing inputs C_BYTE_2 EQU 1B BYTE_1 EQU 1C BYTE_2 EQU 1D BYTE_3 EQU 1E BYTE_4 EQU 1F ; ;DEFINE FLAG2 REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| ; | | | | | | |Y| --> Command Ready. ; | | | | | |Y| | --> Command in process. ; | | | | |Y| | | --> Most Significant bit of time stamp. ; | | | |Y| | | | --> HOLD is active ; | | |Y| | | | | --> Four bytes have been recvd ok ; | |Y| | | | | | --> Value of last IR bit received. ; |Y| | | | | | | --> A Valid hold received < 1/4 sec ago. ; Y| | | | | | | | --> ; Y = DEFINED AS SHOWN (0/1) ; HOLD_RCVD EQU 6 LAST_IR_STATE EQU 5 KEY_READY EQU 4 HOLD EQU 3 STAMP_MSB EQU 2 CMD_PEND EQU 1 ; A channel command is pending. CMD_RDY EQU 0 ; A channel command is ready. ; ;DEFINE FLAG3 REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| ; | | | | | | |Y| --> Quarter second flag. ; | | | | | |Y| | --> Eighth second flag. ; | | | | |Y| | | --> Two second flag. ; | | | |Y| | | | --> ; | | |Y| | | | | --> ; | |Y| | | | | | --> ; |Y| | | | | | | --> ; Y| | | | | | | | --> ; Y = DEFINED AS SHOWN (0/1) ; ; _4TH_SEC EQU 0 EIGTH_SEC EQU 1 TWO_SEC EQU 2 ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Constant definitions." ;************************************************************************ ; Gap length IR decoding time constants. Values were derived from ; successive readings made with MEASURE.ASM
0000000B 0000000C
00000011 00000012 00000013 00000014 00000018 00000019 0000001A 0000001B 0000001C 0000001D 0000001E 0000001F
DS00657A-page 22
AN657
0000001A 00000027 00000038 00000048 0000001F 0000000E 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 ; HOLD_MIN EQU 1a ; Changed from 1e to minimize intermittency. HOLD_MAX EQU 27 ; Changed from 23 to minimize intermittency. HEAD_MIN EQU 38 HEAD_MAX EQU 48 ONE_MAX EQU 1f ZERO_MAX EQU 0e ; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Timer Routines." ;************************************************************************ ; Timer servicing routine ; Called every 8 milliseconds this clears the ; watch dog, reloads the real time clock counter ; and keeps track of relative time. ; SvcTimer movlw MSEC8 ;TMR0 = 8 milliseconds. addwf TMR0,W ; Add overflow amount. movwf TMR0 ; / clrwdt incfsz TIMER,F ; Increment the timer, Skip to two sec ; set up if it rolls over. goto CheckMatch ; Go to other possible set ups. bsf FLAG3,TWO_SEC ; Set the 2 second flag. ; retlw 0 ; sync serviced. CheckMatch ; 1/8 and 1/4 sec flags are staggered ; for more eff use of processor time. movf TIMER,W ; Bring in the timer. andlw b'00001111' ; Check lower bits. xorlw d'2' ; 1/8sec chores called when lo nibble=2. btfsc STATUS,Z ; Was the low nibble not 2? bsf FLAG3,EIGTH_SEC ; No! it was 2, Set the 1/8 sec flag. movf TIMER,W ; Bring in the timer. andlw b'00011111' ; Check five lower bits. xorlw 0x19 ; 1/4 second chores called every 0x19. btfsc STATUS,Z ; Was the low five bits not 0x19? bsf FLAG3,_4TH_SEC ; No! it was 0x19, Set the 1/4sec flag. retlw 0 ; matches checked, return. ; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "6121 type IR remote control reader." ; *********************************************************************** ; The following reads the IR transmitter. ; When the IR transmitter is being read, ; This routine takes control of the clocks ; and suspends all other functions. ; ; *********************************************************************** ; IR Receiver routine ; ; ;-----------------------------------------------------------------------; ReadAddr ; This routine places the first two bytes received in temporary ; locations. Normally this routine would be configured to detect ; weather or not the received command was ment for this equipment ;-----------------------------------------------------------------------ReadAddr movf IR_BYTE13,W ; bring in the first complete byte read movwf C_BYTE_1 ; store it in the contingent first byte
0405 0A08 0406 0559 0407 0800 0408 0408 0409 040A 040B 040C 040D 040E 040F 0410 0411 0412 020B 0E0F 0F02 0643 0539 020B 0E1F 0F19 0643 0519 0800
DS00657A-page 23
AN657
0415 0214 0416 003B 0417 0800 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 00213 00214 00215 00216 00217 00218 00219 00220 00221 00222 00223 00224 00225 movf movwf retlw IR_BYTE24,W C_BYTE_2 0 ; bring in the second complete byte read ; store it in the contingent second byte ; command.
0418 0418 0419 041A 041B 041C 041D 041E 041F 0420 0421
021A 003C 021B 003D 0213 003E 0214 003F 0598 0A48
0423 0211 0424 0081 0425 0031 0426 0427 0428 0429 042A 042A 0678 042B 0A40 042C 094B 042D 01E2 042E 0800 042F 0430 0431 0432 0C1F 0091 0603 0A5E 0C83 0091 0603 0031
; ;-----------------------------------------------------------------------; ReadCommand ; This routine places the third and fourth bytes in memory locations ; so they can be displayed. The first two bytes are transferred from ; their trmporary locations to locations where they too can be ; displayed. Normally this routine would be configured to decode ; the appropriate action from the received number. the third and fourth ; bytes are always complements of each other in this format. Typically ; a complementary check of these two bytes is done at this point in the IR ; reception ;-----------------------------------------------------------------------ReadCommand movf C_BYTE_1,W ; bring in the first complete byte read movwf BYTE_1 ; store it to be dispd as actual first byte movf C_BYTE_2,W ; bring in the first complete byte read movwf BYTE_2 ; store it to be dispd as actual 2nd byte movf IR_BYTE13,W ; bring in the third complete byte read movwf BYTE_3 ; store it to be displayed as the 3rd byte movf IR_BYTE24,W ; bring in the fourth complete byte read movwf BYTE_4 ; store it to be displayed as the 4th byte bsf FLAG2,KEY_READY ; Good set received goto LogHold ; Activate the hold for the first pass. ; ; ;-----------------------------------------------------------------------; ReadReceiver ; Second part of the IR receier. It takes the present count of the ; RTCC and subtracts the count recorded when the receiver output ; went high (READ_LH) to find the dark pulse duration. In that duration ; will be encoded the 1, 0, HOLD, or attention. ;-----------------------------------------------------------------------ReadReceiver bcf FLAG2,LAST_IR_STATE ; Record that the IR receiver output ; is now high ; Calc the length of the dark pulse, ; length of time receiver was high. ; (placed in READ_LH) movf READ_LH,W ; bring in the start measurement subwf TMR0,W ; subtract the final from the start movwf READ_LH ; gap or pulse length is now in ; READ_LH, must be checked movlw MSEC8 ; Base number of TMR0 count. subwf READ_LH,W ; Subtract the base count of TMR0 btfsc STATUS,C ; skip the store and toss value if neg movwf READ_LH ; value was positive, store ; Ir6121MathDone ; btfsc FLAG2,HOLD ; is it now looking for holds? goto LookForHold ; look for HOLD ; call LookForAttentionGap ; look for an attention dark pulse addwf PCL,F ; skip if a 1 was retd, no atten pulse retlw 0 ; a 0 retd, ATTEN pulse found, return ; movlw ONE_MAX ; Test for the max length of one. subwf READ_LH,W ; If no carry gend, A valid 1 is found btfsc STATUS,C ; No carry means the reading is below max goto ResetIR ; IR no good, Above maximum is invalid. ; movlw ZERO_MAX ; Test for the max length of Zero. subwf READ_LH,W ; If no carry gend, A valid 0 is found.
DS00657A-page 24
AN657
00226 00227 00228 00229 00230 00231 00232 00233 00234 00235 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 00253 00254 00255 00256 00257 00258 00259 00260 00261 00262 00263 00264 00265 00266 00267 00268 00269 00270 00271 00272 00273 00274 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 00286 00287 00288 00289 00290 00291 ; the carry now has the newly received bit ; shift the bit into the proper location ; btfss rrf btfsc rrf ; movlw addwf btfss retlw btfss goto goto 1 IR_STATE,F STATUS,DC 0 IR_STATE,5 ReadAddr ReadCommand ; ; ; ; ; ; ; ; Get ready to add one to the IR STATE inc the state setting half carry bits skip if digit carry generated all done reading for now check to determine if the 1st and 2nd bytes or 3rd and 4th bytes are now ready First and second byte ready. Third and fourth byte ready. IR_STATE,3 IR_BYTE13,F IR_STATE,3 IR_BYTE24,F ; Every 8 states result in dest changes ; this bit is a part of IR byte 1 or 3 ; / ; this bit is a part of ir byte 2 or 4
0440 0440 0441 0442 0443 0444 0445 0446 0447 0448 0448 0449 044A
0C1A 0091 0703 0800 0C27 0091 0603 0800 0578 05D8 0800
044B 044B 044C 044D 044E 044F 0450 0451 0452 0453 0454 0455 0455 0456 0457 0458 0459
0C38 0091 0703 0A55 0C48 0091 0603 0A55 0072 0800 0CE0 0152 0743 0800 0801
; ;-----------------------------------------------------------------------; LookForHold ; Reads the length of the received dark pulse and determines if ; a valid HOLD pulse has been received ;-----------------------------------------------------------------------LookForHold movlw HOLD_MIN ; Find if between hold and one. subwf READ_LH,W ; IF no carry is gend, The read is between btfss STATUS,C ; HOLD and one and as such, invalid. retlw 0 ; Return to main routine from invalid read movlw HOLD_MAX ; Test for the max length of HOLD. subwf READ_LH,W ; If no carry is gend, get a valid hold btfsc STATUS,C ; retlw 0 LogHold bsf FLAG2,HOLD ; valid HOLD received bsf FLAG2,HOLD_RCVD ; clear bit for the next hold condition retlw 0 ; ;-----------------------------------------------------------------------; LookForAttentionGap ; Reads the length of the received dark pulse and determines if ; a valid attention pulse has been received ;-----------------------------------------------------------------------LookForAttentionGap ; look for attention dark pulse movlw HEAD_MIN ; Find if between head and one. subwf READ_LH,W ; IF no carry is gend, reading is between btfss STATUS,C ; HOLD and HEAD and as such, invalid. goto CheckIRState ; continue, no attention gap. movlw HEAD_MAX ; Test for the max length of HEAD. subwf READ_LH,W ; If no carry is gend, get a valid head. btfsc STATUS,C ; A carry = a too long gap and is invalid. goto CheckIRState ; continue, no attention gap clrf IR_STATE ; Valid Attention dark pulse. This command ; starts the state machine looking for bits retlw 0 ; return to main routine, ATTEN found CheckIRState movlw 0e0 ; load A mask to mask all counting states andwf IR_STATE,W ; compare with present state btfss STATUS,Z retlw 0 ; not a count state, return to main routine retlw 01 ; counting state, look for 1's and 0's ; ;-----------------------------------------------------------------------; RecordRTCCatLowToHiTransition ; First part of the IR receier. It records the time when the ; output of the IR receiver went from low to high. this creates the ; starting time for timing an IR pulse. ;------------------------------------------------------------------------
DS00657A-page 25
AN657
045A 045A 045B 045C 045D 05B8 0201 0031 0800 00292 00293 00294 00295 00296 00297 00298 00299 00300 00301 00302 00303 00304 00305 00306 00307 00308 00309 00310 00311 00312 00313 00314 00315 00316 00317 00318 00319 00320 00321 00322 00323 00324 00325 00326 00327 00328 00329 00330 00331 00332 00333 00334 00335 00336 00337 00338 00339 00340 00341 00342 00343 00344 00345 00346 00347 00348 00349 00350 00351 00352 00353 00354 00355 00356 00357 RecordRTCC_atLowToHiTransition bsf FLAG2,LAST_IR_STATE ; record that IR was last in dark pulse movf TMR0,W ; bring in the clock time movwf READ_LH ; record for when it goes back low retlw 0 ;-----------------------------------------------------------------------; ResetIR ; Resets the IR state machine to ready it for receiving IR messages. ;-----------------------------------------------------------------------ResetIR bcf FLAG2,HOLD ; not seen clear the hold bcf FLAG2,HOLD_RCVD ; clear the bit for next hold condition clrf IR_STATE ; preset IR_STATE to -1 comf IR_STATE,F ; / retlw 0 ; ;************************************************************************ ; The following subroutines are called by the executive ; every 1/8 second, every 1/4 second, and every two seconds ; EigthSecChores ; all that needs doing every 1/8 sec ; can be placed in this subroutine bcf FLAG3,EIGTH_SEC ; clear the time out flag ; comf PORTA,W ; bring in the requested prescale value ; from the dial, reverse sense andlw 7 ; AND w/ highest possible prescale value btfsc STATUS,Z ; if zero, display hiphens goto DisplayHiphens ; was zero, display hiphens movwf TEMP ; place in temporary storage decf TEMP,F ; dec, dial settings 1 to 4 are valid btfsc TEMP,2 ; if bit2 is set dial is 5 or higher goto DisplayHiphens ; dial is above 5, display hiphens movlw BYTE_1 addwf TEMP,W ; add in dial setting (between 0 and 3) movwf FSR ; place in pointer register. ; NOTE! FSR bits5,6 = clear, File page1 ; bcf STATUS,PA0 ; get ready to call from page 1 bcf STATUS,PA1 ; / ; swapf INDF,W ; bring in IR measurement to be dispd call LookUpDigit movwf LEFT_DIGIT ; display more significant digit ; movf INDF,W ; bring in IR measurement to be dispd call LookUpDigit movwf RIGHT_DIGIT ; display less significant digit ; if BeginIr6121==200 ; return the bits to this page bsf STATUS,PA0 ; page 1 bcf STATUS,PA1 ; / endif if BeginIr6121==400 bcf STATUS,PA0 ; page 2 bsf STATUS,PA1 ; / endif if BeginIr6121==600 bsf STATUS,PA0 ; page 3 bsf STATUS,PA1 ; / endif ; retlw 0 DisplayHiphens movlw HIPHEN ; dial not in range, display hiphens movwf LEFT_DIGIT ; / Hiphen in left digit
0463 0463 0439 0464 0245 0465 0466 0467 0468 0469 046A 046B 046C 046D 046E 0E07 0643 0A7A 002C 00EC 064C 0A7A 0C1C 01CC 0024
046F 04A3 0470 04C3 0471 0380 0472 0900 0473 002E 0474 0200 0475 0900 0476 002F
DS00657A-page 26
AN657
047C 002F 047D 0800 047E 047E 0678 047F 06D8 0480 02A2 0481 095E 0482 04D8 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 00370 00371 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387 00388 00389 00390 00391 00392 00393 00394 00395 00396 00397 00398 00399 00400 00401 00402 00403 00404 00405 00406 00407 00408 00409 00410 00411 00412 00413 00414 00415 00416 00417 00418 00419 00420 00421 00422 00423 movwf retlw RIGHT_DIGIT 0 ; / Hiphen in right digit ; QuarterSecChores btfsc btfsc incf call bcf ; bcf retlw FLAG3,_4TH_SEC 0 ; clear the 1/4 second time out FLAG2,HOLD FLAG2,HOLD_RCVD PCL,F ResetIR FLAG2,HOLD_RCVD
; ; ; ; ; ; ; ; ;
all that needs doing every 1/4 second can be placed in this subroutine Check for HOLD condition still valid Check to see if a hold pulse has been seen in the last 1/4 second reset ready Clear to be the for the set IR state machine and get next hold received flag, it is by IR controller
0483 0419 0484 0800 0485 0485 0C0F 0486 0487 0488 0489 048A 048B 0005 0C3F 0006 0C00 0007 0498
; TwoSecChores movlw A_CONFIG tris movlw tris movlw tris bcf PORTA B_CONFIG PORTB C_CONFIG2 PORTC FLAG2,KEY_READY
; ; ; ; ; ; ; ; ; ; ;
things done every two seconds setup for PORTA, in loop so microcontroller will never forget inputs are on bits 0,1, and 2. PORTB inputs are not used, PORTB outputs control digit drives PORTC is all outputs Routine that would interpret the key will clear the flag that says it is ready clear the two second time out
bcf retlw
FLAG3,TWO_SEC 0
048E 048E 0985 048F 0C05 0490 0002 0491 0078 0492 0079 0493 0494 0495 0496 0497 0CFF 003C 003D 003E 003F
0498 0C83 0499 0021 049A 095E 049B 05B8 049C 04A4 049D 04C4
049E
; ; ;************************************************************************ ; Start HERE. ;************************************************************************ StartIr6121 call TwoSecChores ; re-setup ports A, B, and C ; movlw OPTION_CODE ;SET UP PRESCALER, WDT on 18msec. option ;Clock TMR0 every 64 instruc cycles. ; clrf FLAG2 ; Clear out flag bank 2. clrf FLAG3 ; Clear out flag bank 3. ; movlw 0ff ; Display FF at start up movwf BYTE_1 ; first byte = FF movwf BYTE_2 ; second = FF movwf BYTE_3 ; third = FF movwf BYTE_4 ; fourth byte = FF ; movlw MSEC8 ;TMR0 = 8 mSEC movwf TMR0 ; / ; call ResetIR ; get the IR ready to receive bsf FLAG2,LAST_IR_STATE ; preset the IR flag for a ; RecordRTCCatLowToHiTransition bcf FSR,5 ; File page 1 bcf FSR,6 ; / ; ;************ Main loop Starts here. ************* IRMain ; ; IRInnerLoop btfsc PORTA,IR ; ?IR rcvr not receiving an IR burst? btfsc FLAG2,LAST_IR_STATE ; was it receiving a burst last time?
DS00657A-page 27
AN657
04A0 02A2 04A1 095A 00424 00425 00426 00427 00428 00429 00430 00431 00432 00433 00434 00435 00436 00437 00438 00439 00440 00441 00442 00443 00444 00445 00446 00447 00448 00449 00450 00451 00452 00453 00454 00455 00456 00457 00458 00459 00460 00461 00462 00463 00464 00465 00466 00467 00468 00469 00470 00471 00472 00473 00474 00475 00476 00199 00200 00201 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 incf call PCL,F ; Not either RecordRTCC_atLowToHiTransition ; Record the TMR0 value when the lo to ; hi transition came from the receiver PORTA,IR FLAG2,LAST_IR_STATE PCL,f ReadReceiver MSEC8 TMR0,W STATUS,C IRInnerLoop SvcTimer STATUS,PA0 STATUS,PA1 UpdateDisplay ; ; ; ; ; ; ; ; ; ?IR receiver receiving an IR burst? was it not rcvg a burst last time? Not either read the new information Check for overflow. SEE IF TMR0 < MSEC8, If TMR0 < MSEC8, Overflow. No overflow, no carry, loop. Keep time and reload time keeper.
; btfss btfss incf call movlw subwf btfsc goto call ; bcf bcf call ; if BeginIr6121==200 bsf STATUS,PA0 bcf STATUS,PA1 endif if BeginIr6121==400 bcf STATUS,PA0 bsf STATUS,PA1 endif if BeginIr6121==600 bsf STATUS,PA0 bsf STATUS,PA1 endif ; btfss btfss goto bcf NotHold ; btfsc call ; btfsc call ; btfsc call FLAG3,TWO_SEC TwoSecChores ; check for two second time out ; all that needs doing every two secs ; can go in this subroutine FLAG3,_4TH_SEC QuarterSecChores ; check for 1/4 second time out ; all that needs doing every 1/4sec ; can go in this subroutine PORTB,RIGHT_OFF FLAG2,HOLD NotHold PORTC,DP ; ; ; ; Is display ready to display HOLD? IS the hold active? do not turn on lite for HOLD indicate TURN on LED flag, show HOLD is active ; return the bits to this page ; page 1 ; / ; get ready to call from page 1 ; / ; rotate power to next display digit
; page 2 ; /
; page 3 ; /
FLAG3,EIGTH_SEC EigthSecChores
; check for 1/8 second time out ; all that needs doing every 1/8 second ; can go in this subroutine
goto ;
IRMain
org 600 BeginTeknika include "teknika.asm" TITLE "IR-Technica TV format Remote Control Detector V0.01" SUBTITL "Comments documentation and history" ; ;************************************************************************ ; File Name : TEKNIKA.ASM ;************************************************************************ ; Author: William G. Grimm ; Company: Microchip Technology ; Revision: V0.01 ; Date: March 31, 1996
DS00657A-page 28
AN657
00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 ; Assembler: MPASM version 1.21 ; ;************************************************************************ ; Revision History: ; ; ; V0.01 Original March 28, 1996 ; ; V0.02 repaired bug that kept HOLD from operating ; March 31, 1996 ; ; V0.03 modified gpa and pulse length subtraction ; March 31, 1996 ; ;************************************************************************ ; OPTION_CODE EQU B'00000101' ;SET UP PRESCALER, WDT on 18msec. ; Same as IR6121 ;************************************************************************ ; ;************************************************************************ ; file memory location definitions ;************************************************************************ ; ; full byte file memory locations ; (those commented out are defined in IR6121 or IRMAIN) ; ; TIMER EQU 0b ; Bit5 = 1/4 second, Bit1 = 16 millisecs. BUTTON EQU 0c ; holds last value of last button pressed ; ; RIGHT_DIGIT EQU 0f ; READ_LH EQU 11 ; IR_STATE EQU 12 ; IR_BYTE13 EQU 13 ; IR_BYTE24 EQU 14 ; ; FLAG2 EQU 18 ; FLAG3 EQU 19 ; ;DEFINE FLAG2 REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| ; | | | | | | |Y| ; | | | | | |Y| | ; | | | | |Y| | | ; | | | |Y| | | | ; | | |Y| | | | | ; | |Y| | | | | | ; |Y| | | | | | | ; Y| | | | | | | | ; Y = DEFINED AS SHOWN (0/1) ; (commented definitions are ;HOLD_RCVD EQU 6 ;LAST_IR_STATE EQU 5 ;KEY_READY EQU 4 ;HOLD EQU 3 ;STAMP_MSB EQU 2 ;CMD_PEND EQU 1 ;CMD_RDY EQU 0 ; ;DEFINE FLAG3 REG FUNCTION: ; BIT # 7|6|5|4|3|2|1|0| ;--------------|-|-|-|-|-|-|-| ; | | | | | | |Y| ; | | | | | |Y| | ; | | | | |Y| | | ; ; ; ; ; defined in irmain Low to high reading is stored here. Which bit is coming in. First byte for collecting inputs. Second byte for collecting inputs.
0000000C
Command Ready. Command in process. Most Significant bit of time stamp. HOLD is active 4 bytes have been rcvd successfully Value of last IR bit received. A Valid hold received < 1/4 sec ago.
defined elsewhere)
--> Quarter second flag. --> Eighth second flag. --> Two second flag.
DS00657A-page 29
AN657
00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 ; | | | |Y| | | | --> A channel up has been received ; | | |Y| | | | | --> A Channel Down has been received ; | |Y| | | | | | --> ; |Y| | | | | | | --> ; Y| | | | | | | | --> ; Y = DEFINED AS SHOWN (0/1) ; (commented definitions are defined elsewhere) ; ;_4TH_SEC EQU 0 ;EIGTH_SEC EQU 1 ;TWO_SEC EQU 2 ACTIVE_UP EQU 3 ACTIVE_DOWN EQU 4 ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Constant definitions." ;************************************************************************ ; Gap length IR decoding time constants. Values were derived from ; successive readings made with MEASURE.ASM ; (commented defines are characterisitic of all 6121 remotes ; and are defined in IR6121) ;HOLD_MIN EQU 1a ; Changed from 1e to minimize intermittency. ;HOLD_MAX EQU 27 ; Changed from 23 to minimize intermittency. ;HEAD_MIN EQU 38 ;HEAD_MAX EQU 48 ;ONE_MAX EQU 1f ;ZERO_MAX EQU 0e ; ; ; Definitions characteristic of Teknika TV remote controls ID_BYTE_1 EQU 14 ; Teknika signature byte 1 ID_BYTE_2 EQU 0eb ; Teknika signature byte 2 ; TEK_ZERO EQU 000 ; #0 TEK_ONE EQU 001 ; #1 TEK_TWO EQU 002 ; #2 TEK_THREE EQU 003 ; #3 TEK_FOUR EQU 008 ; #4 TEK_FIVE EQU 009 ; #5 TEK_SIX EQU 00a ; #6 TEK_SEVEN EQU 00b ; #7 TEK_EIGHT EQU 010 ; #8 TEK_NINE EQU 011 ; #9 TEK_ON_OFF EQU 01b ; ON/OFF TEK_MUTE EQU 01a ; Mute button TEK_CHUP EQU 013 ; CHUP Clockwise TEK_CHDN EQU 012 ; CHDN Counter Clockwise ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Timer Routines." ;************************************************************************ ; Timer servicing routine ; Called every 8 milliseconds, this clears the ; watch dog, reloads TMR0 ; and keeps track of relative time. ; TekServiceTimer movlw MSEC8 ;TMR0 = 8 milliseconds. addwf TMR0,W ; Add overflow amount. movwf TMR0 ; / clrwdt incfsz TIMER,F ; Increment the timer, Skip to two second ; set up if it rolls over. goto TekCheckMatch ; Go to other possible setups. bsf FLAG3,TWO_SEC ; Set the two second flag. ;
00000003 00000004
00000014 000000EB 00000000 00000001 00000002 00000003 00000008 00000009 0000000A 0000000B 00000010 00000011 0000001B 0000001A 00000013 00000012
DS00657A-page 30
AN657
0607 0800 0608 0608 0609 060A 060B 060C 060D 060E 060F 0610 0611 0612 020B 0E0F 0F02 0643 0539 020B 0E1F 0F19 0643 0519 0800 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 00207 00208 retlw 0 TekCheckMatch movf andlw xorlw btfsc bsf movf andlw xorlw btfsc bsf retlw TIMER,W b'00001111' d'2' STATUS,Z FLAG3,EIGTH_SEC TIMER,W b'00011111' 0x19 STATUS,Z FLAG3,_4TH_SEC 0 ; ; ; ; ; ; ; ; ; ; ; ; ; ; sync serviced. 1/8 and 1/4 second flags are staggered make more efficient use of processor time Bring in the timer. Check lower bits. 1/8sec chores called when low nibble=2. Was the low nibble not 2? No! it was 2, Set the 1/8 sec flag. Bring in the timer. Check five lower bits. 1/4 second chores called every 0x19. Was the low five bits not 0x19? No! it was 0x19, Set the 1/4 sec flag. matches checked, return.
0613 0613 0614 0615 0616 0617 0618 0619 061A 061B
061C 061C 061D 061E 061F 0620 0621 0622 0623 0624 0625
0253 0194 0743 0A82 0C13 0193 0643 0579 0643 0A39
; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "6121 type IR remote control reader." ; ******************************************* ; The following reads the IR transmitter. ; When the IR transmitter is being read, ; this routine takes control of the clocks ; and suspends all other functions. ; ; ******************************************** ; IR Receiver routine ; ; ;-----------------------------------------------------------------------; TekRdAddr ; This routine determines whether a Teknika remote control is ; sending the command. ;-----------------------------------------------------------------------TekRdAddr movlw ID_BYTE_1 ; bring in what would be the first byte xorwf IR_BYTE13,W ; compare with the byte that came in first btfss STATUS,Z ; if the same, the zero bit is set goto TekIRReset ; wrong ID, reset the IR state movlw ID_BYTE_2 ; bring in what would be the second byte xorwf IR_BYTE24,W ; compare with the byte that came in 2nd btfss STATUS,Z ; if the same, the zero bit is set goto TekIRReset ; wrong ID, reset the IR state retlw 0 ; Success! A Teknika remote sent the command ; ;-----------------------------------------------------------------------; RD_COMMAND ; This routine determines what kind of command was sent, and places ; the result in BUTTON or one of the channel up or down flags. ;-----------------------------------------------------------------------TekRdCommand comf IR_BYTE13,W ; Byte3 must be the complement of Byte4 xorwf IR_BYTE24,W ; For a valid command. btfss STATUS,Z ; If the same, skip to continue. goto TekIRReset ; not complements, not valid. ; movlw TEK_CHUP ; check for a channel up command xorwf IR_BYTE13,W ; compare with byte 3 btfsc STATUS,Z ; skip if no match bsf FLAG3,ACTIVE_UP ; active channel up btfsc STATUS,Z ; skip again if no active channel up goto TekLogCommand ; movlw TEK_CHDN ; check for a channel down command xorwf IR_BYTE13,W ; compare with byte 3 btfsc STATUS,Z ; skip if no match
DS00657A-page 31
AN657
0629 0599 062A 0643 062B 0A39 062C 0C0A 062D 0034 062E 062E 062F 0630 0631 0632 00209 00210 00211 00212 00213 00214 00215 00216 00217 00218 00219 00220 00221 00222 00223 00224 00225 00226 00227 00228 00229 00230 00231 00232 00233 00234 00235 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 00253 00254 00255 00256 00257 00258 00259 00260 00261 00262 00263 00264 00265 00266 00267 00268 00269 00270 00271 00272 00273 00274 bsf btfsc goto ; movlw movwf GuessLoop decf comf btfsc goto movf call CheckGuess xorwf d'10' IR_BYTE24 ; Look for ten possible buttons. ; IR_BYTE24 is converted for use as ; a counter. ; ; ; ; ; ; ; ; ; ; ; ; decrement to next button to look for See if it rolled over to FF If rollover, this not a valid command. not a listed button return. Bring in the counter, which is a guess as to what the button is. NO! Get the code for guessed value for dog biscuit look for a match with the guess and actual value which is in IR_BYTE13. If it matchs skip and stop looping. No match. Guess again. FLAG3,ACTIVE_DOWN STATUS,Z TekLogCommand ; active channel down ; skip again if no active channel down
0633 093B 0634 0634 0193 0635 0636 0637 0637 0638 0639 0639 063A 063B 063B 063C 063D 063E 063F 0640 0641 0642 0643 0644 0645 0743 0A2E 0214 002C 0598 0A6C
01E2 0800 0801 0802 0803 0808 0809 080A 080B 0810 0811
0647 0211 0648 0081 0649 0031 064A 064B 064C 064D 064E 064E 0678 0C83 0091 0603 0031
btfss STATUS,Z goto GuessLoop TekLogButton movf IR_BYTE24,W ; bring in the count movwf BUTTON ; it has the new button number TekLogCommand bsf FLAG2,KEY_READY ; Good set received goto TekLogHold ; Activate the hold for the first pass. ; TekTable addwf PCL,F ; Computed jump for look-up table. retlw TEK_ZERO ; #0 retlw TEK_ONE ; #1 retlw TEK_TWO ; #2 retlw TEK_THREE ; #3 retlw TEK_FOUR ; #4 retlw TEK_FIVE ; #5 retlw TEK_SIX ; #6 retlw TEK_SEVEN ; #7 retlw TEK_EIGHT ; #8 retlw TEK_NINE ; #9 ; ; ;-----------------------------------------------------------------------; TekRdRcvr ; Second part of the IR receiver. It takes the present count of ; TMR0 and subtracts the count recorded when the receiver output ; went high (READ_LH) to find the dark pulse duration. In that duration ; will be encoded the 1, 0, HOLD, or attention. ;-----------------------------------------------------------------------TekRdRcvr bcf FLAG2,LAST_IR_STATE ; Record that the IR rcvr output ; is now high ; Calculate length of the dark pulse, ; length of time receiver was high. ; (placed in READ_LH) movf READ_LH,W ; bring in the start measurement subwf TMR0,W ; subtract the final from the start movwf READ_LH ; gap or pulse length is now in ; READ_LH, must be checked movlw MSEC8 ; Base number of TMR0 count. subwf READ_LH,W ; Subtract the base count of TMR0 btfsc STATUS,C ; skip the store and toss value if neg movwf READ_LH ; value was positive, store ; TekMathDone ; btfsc FLAG2,HOLD ; is it now looking for holds?
DS00657A-page 32
AN657
064F 0A64 0650 096F 0651 01E2 0652 0800 0653 0654 0655 0656 0C1F 0091 0603 0A82 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 00286 00287 00288 00289 00290 00291 00292 00293 00294 00295 00296 00297 00298 00299 00300 00301 00302 00303 00304 00305 00306 00307 00308 00309 00310 00311 00312 00313 00314 00315 00316 00317 00318 00319 00320 00321 00322 00323 00324 00325 00326 00327 00328 00329 00330 00331 00332 00333 00334 00335 00336 00337 00338 00339 00340 goto ; call addwf retlw ; movlw subwf btfsc goto ; movlw subwf ZERO_MAX READ_LH,W ; ; ; ; Test for the max length of Zero. If no carry is gend, get a valid 0. the carry now has the newly rcvd bit shift the bit into the proper location ONE_MAX READ_LH,W STATUS,C TekIRReset ; ; ; ; Test for the max length of one. If no carry is gend, get a valid one No carry means the read is below max IR no good, Above maximum is invalid. TekLookAtten PCL,F 0 ; look for an attention dark pulse ; skip if 1 was retd, no atten pulse ; a 0 retd, ATTEN pulse found, return TekLookHold ; look for HOLD
; btfss rrf btfsc rrf ; movlw addwf btfss retlw btfss goto goto 1 IR_STATE,F STATUS,DC 0 IR_STATE,5 TekRdAddr TekRdCommand ; ; ; ; ; ; ; ; Get ready to add one to the IR STATE inc the state setting half carry bits skip if digit carry generated all done reading for now check to determine if the 1st and 2nd bytes or 3rd and 4th bytes now ready First and second byte ready. Third and fourth byte ready. IR_STATE,3 IR_BYTE13,F IR_STATE,3 IR_BYTE24,F ; Every 8 states gives dest changes ; this bit is a part of IR byte 1 or 3 ; / ; this bit is a part of ir byte 2 or 4
0664 0664 0665 0666 0667 0668 0669 066A 066B 066C 066C 066D 066E
0C1A 0091 0703 0800 0C27 0091 0603 0800 0578 05D8 0800
066F 066F 0670 0671 0672 0673 0674 0675 0676 0677
0678 0800
; ;-----------------------------------------------------------------------; LOOK_HOLD ; Reads the length of the received dark pulse and determines if ; a valid HOLD pulse has been received ;-----------------------------------------------------------------------TekLookHold movlw HOLD_MIN ; Find if between hold and one. subwf READ_LH,W ; IF no carry is gend, The read is between btfss STATUS,C ; HOLD and one and as such, invalid. retlw 0 ; Ret to main routine from invalid read. movlw HOLD_MAX ; Test for the max length of HOLD. subwf READ_LH,W ; If no carry is gend, get a valid hold. btfsc STATUS,C ; retlw 0 TekLogHold bsf FLAG2,HOLD ; valid HOLD received bsf FLAG2,HOLD_RCVD ; clear bit for the next hold condition retlw 0 ; ;-----------------------------------------------------------------------; LOOK_ATTEN ; Reads the length of the received dark pulse and determines if ; a valid attention pulse has been received ;-----------------------------------------------------------------------TekLookAtten ; look for attention dark pulse movlw HEAD_MIN ; Find if between head and one. subwf READ_LH,W ; IF no carry is gend, Reading between btfss STATUS,C ; HOLD and HEAD and as such, invalid. goto TekCheckState ; continue, no attention gap. movlw HEAD_MAX ; Test for the max length of HEAD. subwf READ_LH,W ; If no carry is gend, get a valid head btfsc STATUS,C ; A carry = a too long gap = invalid. goto TekCheckState ; continue, no attention gap clrf IR_STATE ; Valid Atten dark pulse. Command starts ; the state machine looking for bits. retlw 0 ; return to main routine, ATTEN found
DS00657A-page 33
AN657
0679 0679 067A 067B 067C 067D 0CE0 0152 0743 0800 0801 00341 00342 00343 00344 00345 00346 00347 00348 00349 00350 00351 00352 00353 00354 00355 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 00370 00371 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387 00388 00389 00390 00391 00392 00393 00394 00395 00396 00397 00398 00399 00400 00401 00402 00403 00404 00405 00406 TekCheckState movlw 0e0 ; load A mask to mask all count states andwf IR_STATE,W ; compare with present state btfss STATUS,Z retlw 0 ; not a count state, ret to main routine retlw 01 ; counting state, look for 1's and 0's ; ;-----------------------------------------------------------------------; RECORD_LH ; First part of the IR receiver. It records the time when the ; output of the IR receiver went from low to high. this creates the ; starting time for timing an IR pulse. ;-----------------------------------------------------------------------TekRecordLH bsf FLAG2,LAST_IR_STATE ; record that IR was last in dark pulse movf TMR0,W ; bring in the clock time movwf READ_LH ; record for when it goes back low retlw 0 ;-----------------------------------------------------------------------; TekIRReset ; Resets the IR state machine to ready it for receiving IR messages. ;-----------------------------------------------------------------------TekIRReset bcf FLAG2,HOLD ; not seen clear the hold bcf FLAG2,HOLD_RCVD ; clear bit for the next hold condition bcf FLAG3,ACTIVE_UP ; clear channel up if present bcf FLAG3,ACTIVE_DOWN ; clear channel down if present clrf IR_STATE ; preset IR_STATE to -1 comf IR_STATE,F ; / retlw 0 ; ;-----------------------------------------------------------------------; TekSvcHold ; Uses the HOLD to increment or decrement the BUTTON number. ;-----------------------------------------------------------------------TekSvcHold btfsc FLAG3,ACTIVE_UP ; is Channel up now present? goto IncButton ; Yes, increment button btfsc FLAG3,ACTIVE_DOWN ; is Channel Down now present? goto DecButton ; Yes, Decrement button retlw 0 ; neither now active IncButton incf BUTTON,F ; increment button movlw d'10' ; subwf BUTTON,W ; Compare with 10 btfsc STATUS,C ; is BUTTON < 10? clrf BUTTON ; No recycle retlw 0 DecButton decf BUTTON,F ; Decrement button comf BUTTON,W ; Roll to FF? btfss STATUS,Z ; ship if roll over retlw 0 movlw d'9' ; recycle on zero movwf BUTTON ; / retlw 0 ; ;************************************************************************ ; The following subroutines are called by the executive ; every 1/8 second, every 1/4 second, and every two seconds ; TekEigthSec ; all that needs doing every 1/8 sec ; can be placed in this subroutine bcf FLAG3,EIGTH_SEC ; clear the time out flag ; retlw 0
0689 0689 068A 068B 068C 068D 068E 068E 068F 0690 0691 0692 0693 0694 0694 0695 0696 0697 0698 0699 069A
0679 0A8E 0699 0A94 0800 02AC 0C0A 008C 0603 006C 0800 00EC 024C 0743 0800 0C09 002C 0800
DS00657A-page 34
AN657
069D 069D 0678 069E 06D8 069F 02A2 06A0 0982 06A1 04D8 06A2 0678 06A3 0989 06A4 0419 06A5 0800 06A6 06A6 0C0F 06A7 06A8 06A9 06AA 06AB 06AC 0005 0C3F 0006 0C00 0007 0498 00407 00408 00409 00410 00411 00412 00413 00414 00415 00416 00417 00418 00419 00420 00421 00422 00423 00424 00425 00426 00427 00428 00429 00430 00431 00432 00433 00434 00435 00436 00437 00438 00439 00440 00441 00442 00443 00444 00445 00446 00447 00448 00449 00450 00451 00452 00453 00454 00455 00456 00457 00458 00459 00460 00461 00462 00463 00464 00465 00466 00467 00468 00469 00470 00471 00472 ; TekQuarterSec btfsc btfsc incf call bcf btfsc call ; bcf retlw ; TekTwoSec movlw tris movlw tris movlw tris bcf FLAG3,_4TH_SEC 0 ; clear the 1/4 second time-out FLAG2,HOLD FLAG2,HOLD_RCVD PCL,F TekIRReset FLAG2,HOLD_RCVD FLAG2,HOLD TekSvcHold ; ; ; ; ; ; ; ; ; ; ; all that needs doing every 1/4 second can be placed in this subroutine Check for HOLD condition still valid Check to see if a hold pulse has been seen in the last 1/4 second reset the IR state machine and get ready for next Clear the hold received flag, it is to be set by IR controller check for active hold service the hold function
; ; ; ; ; ; ; ; ; ; ;
things done every two seconds setup for PORTA in loop, so microcontroller will never forget inputs are on bits 0,1, and 2. PORTB inputs are not used, PORTB outputs control digit drives PORTC is all outputs Routine that would interpret the key will clear the flag that says it is ready clear the two second time-out
bcf retlw
FLAG3,TWO_SEC 0
06AF 06AF 09A6 06B0 0C05 06B1 0002 06B2 0078 06B3 0079 06B4 006C
06B5 0C83 06B6 0021 06B7 0982 06B8 05B8 06B9 04A4 06BA 04C4
06BB
; ; ;************************************************************************ ; Start HERE. ;************************************************************************ StartTek call TekTwoSec ; re-setup ports A and B ; movlw OPTION_CODE ;SET UP PRESCALER, WDT on 18msec. option ;Clock TMR0 every 64 inst cycles. ; clrf FLAG2 ; Clear out flag bank 2. clrf FLAG3 ; Clear out flag bank 3. clrf BUTTON ; Displays Zero on reset ; ; movlw MSEC8 ;TMR0 = 8 mSEC movwf TMR0 ; / ; call TekIRReset ; get the IR ready to receive bsf FLAG2,LAST_IR_STATE ; preset the IR flag for a RECORD_LH ; bcf FSR,5 ; File page 1 bcf FSR,6 ; / ; ;************ Main loop Starts here. ************* TekMain ; ; TekInnerLoop btfsc PORTA,IR ; ?IR receiver not rcvg an IR burst? btfsc FLAG2,LAST_IR_STATE ; was it receiving a burst last time? incf PCL,F ; Not either call TekRecordLH ; Record the TMR0 value when the lo to ; hi transition came from the receiver ;
DS00657A-page 35
AN657
06BF 06C0 06C1 06C2 06C3 06C4 06C5 06C6 06C7 0765 07B8 02A2 0946 0C83 0081 0603 0ABB 0900 00473 00474 00475 00476 00477 00478 00479 00480 00481 00482 00483 00484 00485 00486 00487 00488 00489 00490 00491 00492 00493 00494 00495 00496 00497 00498 00499 00500 00501 00502 00503 00504 00505 00506 00507 00508 00509 00510 00511 00512 00513 00514 00515 00516 00517 00518 00519 00520 00521 00522 00523 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 00213 00214 00215 00216 btfss btfss incf call movlw subwf btfsc goto call ; bcf bcf ; movf call movwf ; if BeginTeknika==200 bsf STATUS,PA0 bcf STATUS,PA1 endif if BeginTeknika==400 bcf STATUS,PA0 bsf STATUS,PA1 endif if BeginTeknika==600 bsf STATUS,PA0 bsf STATUS,PA1 endif ; btfsc bcf ; bsf bcf ; btfsc call ; btfsc call ; btfsc call FLAG3,TWO_SEC TekTwoSec ; check for two second time-out ; all that needs doing every two sec ; can go in this subroutine FLAG3,_4TH_SEC TekQuarterSec ; check for 1/4 second time-out ; all that needs doing every 1/4 sec ; can go in this subroutine FLAG3,EIGTH_SEC TekEigthSec ; check for 1/8 second time-out ; all that needs doing every 1/8 sec ; can go in this subroutine PORTB,LEFT_OFF PORTB,RIGHT_OFF ; turn off the left digit ; turn on the right digit FLAG2,HOLD PORTC,DP ; IS the hold active? ; TURN on LED flag to show HOLD active ; return the bits to this page ; page 1 ; / BUTTON,W LookUpDigit PORTC ; get the IR measurement to be dispd ; display on Right digit STATUS,PA0 STATUS,PA1 ; get ready to call from page 1 ; / PORTA,IR FLAG2,LAST_IR_STATE PCL,F TekRdRcvr MSEC8 TMR0,W STATUS,C TekInnerLoop TekServiceTimer ; ; ; ; ; ; ; ; ; ?IR receiver receiving an IR burst? was it not rcvg a burst last time? Not either read the new information Check for overflow. SEE IF TMR0 < MSEC8, If TMR0 < MSEC8, Overflow. No overflow, no carry, loop. Keep time and reload time keeper.
06C8 04A3 06C9 04C3 06CA 020C 06CB 0900 06CC 0027
; page 2 ; /
; page 3 ; /
06CF 0678 06D0 04E7 06D1 05E6 06D2 04C6 06D3 0639 06D4 099B
goto ;
TekMain
org 100 ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUBTITL "Start" ; ;************************************************************************ ; Start HERE. ;************************************************************************ StartAll movlw C_CONFIG1 ; configuration to read from PORTC tris PORTC ; configure PORTC to read the bits nop ; allow time for the inputs to settle btfss PORTC,SW2 ; check to see if jumper is in #2 goto TekOr6121 ; Indicates IR6121 or TEK is requested if BeginMeasure==200
DS00657A-page 36
AN657
0105 05A3 0106 04C3 00217 00218 00219 00220 00221 00222 00223 00224 00225 00226 00227 00228 00229 00230 00231 00232 00233 00234 00235 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 00253 00254 00255 00256 00257 00258 00259 00260 00261 00262 00263 00264 bsf STATUS,PA0 bcf STATUS,PA1 endif if BeginMeasure==400 bcf STATUS,PA0 bsf STATUS,PA1 endif if BeginMeasure==600 bsf STATUS,PA0 bsf STATUS,PA1 endif goto StartMeasure TekOr6121 btfss PORTC,SW1 goto Teknika if BeginIr6121==200 bsf STATUS,PA0 bcf STATUS,PA1 endif if BeginIr6121==400 bcf STATUS,PA0 bsf STATUS,PA1 endif if BeginIr6121==600 bsf STATUS,PA0 bsf STATUS,PA1 endif goto StartIr6121 Teknika if BeginTeknika==200 bsf STATUS,PA0 bcf STATUS,PA1 endif if BeginTeknika==400 bcf STATUS,PA0 bsf STATUS,PA1 endif if BeginTeknika==600 bsf STATUS,PA0 bsf STATUS,PA1 endif goto StartTek ; ; START Vector org 0x07ff goto StartAll ; END ; page 1 ; /
; page 2 ; /
; page 3 ; / ; Start the IR measurement routine ; check SW1 to determine if Tek or 6121 ; jumper in, Teknika ; page 1 ; /
; page 2 ; /
; page 1 ; /
; page 2 ; /
; start vector
DS00657A-page 37
AN657
MEMORY USAGE MAP ('X' = Used, '-' = Unused) ------------------------------XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX ---------------XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXX----XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX ------------------------------X 0000 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX X--------------0100 : XXXXXXXXXXXXXXXX ---------------- ---------------0200 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0240 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0280 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXX-0400 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0440 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0480 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0600 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0640 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0680 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 06C0 : XXXXXXXXXXXXXXXX XXXXXXXXXX------ ---------------07C0 : ---------------- ---------------- ---------------All other memory blocks unused. Program Memory Words Used: 629 Program Memory Words Free: 1419 Errors : 0 Warnings : 0 reported, 0 suppressed Messages : 0 reported, 0 suppressed
DS00657A-page 38
Note the following details of the code protection feature on PICmicro MCUs. The PICmicro family meets the specifications contained in the Microchip Data Sheet. Microchip believes that its family of PICmicro microcontrollers is one of the most secure products of its kind on the market today, when used in the intended manner and under normal conditions. There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our knowledge, require using the PICmicro microcontroller in a manner outside the operating specifications contained in the data sheet. The person doing so may be engaged in theft of intellectual property. Microchip is willing to work with the customer who is concerned about the integrity of their code. Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not mean that we are guaranteeing the product as unbreakable. Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our product.
If you have any further questions about this matter, please contact the local sales office nearest to you.
Information contained in this publication regarding device applications and the like is intended through suggestion only and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. No representation or warranty is given and no liability is assumed by Microchip Technology Incorporated with respect to the accuracy or use of such information, or infringement of patents or other intellectual property rights arising from such use or otherwise. Use of Microchips products as critical components in life support systems is not authorized except with express written approval by Microchip. No licenses are conveyed, implicitly or otherwise, under any intellectual property rights.
Trademarks The Microchip name and logo, the Microchip logo, FilterLab, KEELOQ, microID, MPLAB, PIC, PICmicro, PICMASTER, PICSTART, PRO MATE, SEEVAL and The Embedded Control Solutions Company are registered trademarks of Microchip Technology Incorporated in the U.S.A. and other countries. dsPIC, ECONOMONITOR, FanSense, FlexROM, fuzzyLAB, In-Circuit Serial Programming, ICSP, ICEPIC, microPort, Migratable Memory, MPASM, MPLIB, MPLINK, MPSIM, MXDEV, PICC, PICDEM, PICDEM.net, rfPIC, Select Mode and Total Endurance are trademarks of Microchip Technology Incorporated in the U.S.A. Serialized Quick Turn Programming (SQTP) is a service mark of Microchip Technology Incorporated in the U.S.A. All other trademarks mentioned herein are property of their respective companies. 2002, Microchip Technology Incorporated, Printed in the U.S.A., All Rights Reserved.
Printed on recycled paper.
Microchip received QS-9000 quality system certification for its worldwide headquarters, design and wafer fabrication facilities in Chandler and Tempe, Arizona in July 1999. The Companys quality system processes and procedures are QS-9000 compliant for its PICmicro 8-bit MCUs, KEELOQ code hopping devices, Serial EEPROMs and microperipheral products. In addition, Microchips quality system for the design and manufacture of development systems is ISO 9001 certified.
M
WORLDWIDE SALES AND SERVICE
AMERICAS
Corporate Office
2355 West Chandler Blvd. Chandler, AZ 85224-6199 Tel: 480-792-7200 Fax: 480-792-7277 Technical Support: 480-792-7627 Web Address: http://www.microchip.com
ASIA/PACIFIC
Australia
Microchip Technology Australia Pty Ltd Suite 22, 41 Rawson Street Epping 2121, NSW Australia Tel: 61-2-9868-6733 Fax: 61-2-9868-6755
Japan
Microchip Technology Japan K.K. Benex S-1 6F 3-18-20, Shinyokohama Kohoku-Ku, Yokohama-shi Kanagawa, 222-0033, Japan Tel: 81-45-471- 6166 Fax: 81-45-471-6122
Rocky Mountain
2355 West Chandler Blvd. Chandler, AZ 85224-6199 Tel: 480-792-7966 Fax: 480-792-7456
China - Beijing
Microchip Technology Consulting (Shanghai) Co., Ltd., Beijing Liaison Office Unit 915 Bei Hai Wan Tai Bldg. No. 6 Chaoyangmen Beidajie Beijing, 100027, No. China Tel: 86-10-85282100 Fax: 86-10-85282104
Korea
Microchip Technology Korea 168-1, Youngbo Bldg. 3 Floor Samsung-Dong, Kangnam-Ku Seoul, Korea 135-882 Tel: 82-2-554-7200 Fax: 82-2-558-5934
Atlanta
500 Sugar Mill Road, Suite 200B Atlanta, GA 30350 Tel: 770-640-0034 Fax: 770-640-0307
Singapore
Microchip Technology Singapore Pte Ltd. 200 Middle Road #07-02 Prime Centre Singapore, 188980 Tel: 65-334-8870 Fax: 65-334-8850
Boston
2 Lan Drive, Suite 120 Westford, MA 01886 Tel: 978-692-3848 Fax: 978-692-3821
China - Chengdu
Microchip Technology Consulting (Shanghai) Co., Ltd., Chengdu Liaison Office Rm. 2401, 24th Floor, Ming Xing Financial Tower No. 88 TIDU Street Chengdu 610016, China Tel: 86-28-6766200 Fax: 86-28-6766599
Taiwan
Microchip Technology Taiwan 11F-3, No. 207 Tung Hua North Road Taipei, 105, Taiwan Tel: 886-2-2717-7175 Fax: 886-2-2545-0139
Chicago
333 Pierce Road, Suite 180 Itasca, IL 60143 Tel: 630-285-0071 Fax: 630-285-0075
Dallas
4570 Westgrove Drive, Suite 160 Addison, TX 75001 Tel: 972-818-7423 Fax: 972-818-2924
China - Fuzhou
Microchip Technology Consulting (Shanghai) Co., Ltd., Fuzhou Liaison Office Unit 28F, World Trade Plaza No. 71 Wusi Road Fuzhou 350001, China Tel: 86-591-7503506 Fax: 86-591-7503521
EUROPE
Denmark
Microchip Technology Nordic ApS Regus Business Centre Lautrup hoj 1-3 Ballerup DK-2750 Denmark Tel: 45 4420 9895 Fax: 45 4420 9910
Detroit
Tri-Atria Office Building 32255 Northwestern Highway, Suite 190 Farmington Hills, MI 48334 Tel: 248-538-2250 Fax: 248-538-2260
China - Shanghai
Microchip Technology Consulting (Shanghai) Co., Ltd. Room 701, Bldg. B Far East International Plaza No. 317 Xian Xia Road Shanghai, 200051 Tel: 86-21-6275-5700 Fax: 86-21-6275-5060
Kokomo
2767 S. Albright Road Kokomo, Indiana 46902 Tel: 765-864-8360 Fax: 765-864-8387
France
Microchip Technology SARL Parc dActivite du Moulin de Massy 43 Rue du Saule Trapu Batiment A - ler Etage 91300 Massy, France Tel: 33-1-69-53-63-20 Fax: 33-1-69-30-90-79
Los Angeles
18201 Von Karman, Suite 1090 Irvine, CA 92612 Tel: 949-263-1888 Fax: 949-263-1338
China - Shenzhen
Microchip Technology Consulting (Shanghai) Co., Ltd., Shenzhen Liaison Office Rm. 1315, 13/F, Shenzhen Kerry Centre, Renminnan Lu Shenzhen 518001, China Tel: 86-755-2350361 Fax: 86-755-2366086
New York
150 Motor Parkway, Suite 202 Hauppauge, NY 11788 Tel: 631-273-5305 Fax: 631-273-5335
Germany
Microchip Technology GmbH Gustav-Heinemann Ring 125 D-81739 Munich, Germany Tel: 49-89-627-144 0 Fax: 49-89-627-144-44
San Jose
Microchip Technology Inc. 2107 North First Street, Suite 590 San Jose, CA 95131 Tel: 408-436-7950 Fax: 408-436-7955
Hong Kong
Microchip Technology Hongkong Ltd. Unit 901-6, Tower 2, Metroplaza 223 Hing Fong Road Kwai Fong, N.T., Hong Kong Tel: 852-2401-1200 Fax: 852-2401-3431
Italy
Microchip Technology SRL Centro Direzionale Colleoni Palazzo Taurus 1 V. Le Colleoni 1 20041 Agrate Brianza Milan, Italy Tel: 39-039-65791-1 Fax: 39-039-6899883
Toronto
6285 Northam Drive, Suite 108 Mississauga, Ontario L4V 1X5, Canada Tel: 905-673-0699 Fax: 905-673-6509
India
Microchip Technology Inc. India Liaison Office Divyasree Chambers 1 Floor, Wing A (A3/A4) No. 11, OShaugnessey Road Bangalore, 560 025, India Tel: 91-80-2290061 Fax: 91-80-2290062
United Kingdom
Arizona Microchip Technology Ltd. 505 Eskdale Road Winnersh Triangle Wokingham Berkshire, England RG41 5TU Tel: 44 118 921 5869 Fax: 44-118 921-5820
01/18/02