Professional Documents
Culture Documents
PIC-Decoding IR - AN657 PDF
PIC-Decoding IR - AN657 PDF
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 first 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 final 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 fit 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 file 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
SW2
+5 +5 +5
+5
U1
C
07
SW1
C
07
RN5
1k
RN4
1k
78M05
2
SW3
+5
C
07
+5
RN4
1k
RN5
1k
d
+5
10 11 12
Power Jack
1
2
C3
0.01 F
C2
47 F
10V
13 14 15
PORTB
x1
+5
A
+5
7
17
18 19 20 21 22 23 24 25
MCLR
6
16
40 pulse
28
+5
+5
0.033 F
B
C
10k x4
RN3
B
10k
RN3
A
10k
11
1 12 10
16
5 18 15 17
A d C e
GP1U5 -21Y or
LT-1060
QSE157QT
LN54YA
B G dp
A
f
e
G
C
d left
U3
U5
U3 - Sharp
LiteOn
U4 - Quality Technologies
U5 - Panasonic
+5
RN2
100k x4
PORTB
PORTC
0
+5
PORTA
PIC16C57
26
PORTA
27
1
2
4 MHz
Ceramic
3
Resonator
C
d right
+5
Q1
+5
Q2
1
S
U4
AN657
DS00657A-page 2
C1 120 F
35V
AN657
DESCRIPTION OF SOFTWARE TO
AID DEVELOPMENT
This application uses four different firmware files.
IRMAIN.ASM controls the selection of the three application files. The first file 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 final file, TECNICKA.ASM, shows the final firmware for decoding the
infrared format for a Teknika Television.
IRMAIN.ASM
The firmware listed includes three applications that will
aid in designing an infrared control system.
IRMAIN.ASM reads jumpers 1 and 2 and directs program flow after reset to one of the three applications.
Having no jumper in 2 will direct program flow to
MEASURE.ASM. A jumper in 2 only will direct program
flow to IR6121.ASM. Jumpers in both 1 and 2 will
direct program flow to TEKNIKA.ASM. Jumpers 3 and 4
are not used.
Start
Is
No
1 Closed?
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 file locations until all four pages
of the PIC16C57s memory files are filled. If a jumper
had been in 1, the program throws away the first 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 file memory are filled 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 significant digit.
Goto MEASURE
Yes
Is
No
0 Closed?
Goto IR6121
Yes
Goto TEKNIKA
DS00657A-page 3
AN657
FIGURE 3: MEASURE.ASM FLOWCHART
1/8
second
elapsed?
MEASURE
Is 1
Closed?
No
Yes
No
Read Option
switch
SW1
Yes
Load TR_Count
with delay
Yes
Option
switch
changed?
No
SW1
Read Option SW
Program Option
Register
SW2
Read SW 2 & 3
SW3
Calculate
file to be
displayed
Read Receiver
IR
Convert value
in file to digits
for display
No
Dark 8 ms?
Yes
Is
reading
complete?
No
Read Receiver
IR
Yes
Display digit
not now being
displayed
Receiver
changed?
No
Yes
Calculate time
duration using
subtraction
Store in File
File
registers
full?
Yes
No
Set All Done
Flag
Read TMR0
No
TMR0
Overflow?
Yes
Reload TMR0
Increment Timer
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.
Hold
Set?
No
Goto NewLoop
Yes
HOLD_
RCVD
Set?
No
Goto RESET_IR
Yes
Goto NewLoop
DS00657A-page 5
AN657
FIGURE 5: IR6121.ASM FLOWCHART
IR6121
NewLoop
Does
No
gap length equal
hold?
Yes
Update Display
Read IR Receiver
Set HOLD
and HOLD_RCVD
IR
Receiver
Yes
state changed
lo to hi?
Record TMR0
in Read_LH
No
RESET_IR
Receiver
state changed
lo to hi?
IR_STATE = 0
Calculate gap
duration using
subtraction
Yes
No
No
No
IR_STATE= 0
TMR0
overflow?
Is gap
duration > 38h
& < 48h?
Yes
Yes
Is
IR_STATE
= 0?
No
Yes
IR_STATE = 1
Reload TMR0
other
No
1/8 sec
timeout?
IR_STATE =
IR_STATE + 1
Yes
Yes
Read switch
Rotate 1
into byte 1
Is gap
duration mean
0,1 or other?
No
Rotate 0
into byte 1
SW1
other
Rotate 1
into byte 2
Is gap
duration 0,1
or other?
Yes
0
No
1/4 sec
time-out?
Yes
Is
IR_STATE
<= 8?
Is
IR_STATE
<= 16?
No
Rotate 0
into byte 2
Goto RESET_IR
other
Rotate 1
into byte 3
Is gap
duration 0,1
or other?
Yes
Is
IR_STATE
<= 24?
No
Rotate 0
into byte 3
other
Rotate 1
into byte 4
Is gap
duration 0,1
or other?
Yes
Is
IR_STATE
<= 32?
No
0
Rotate 0
into byte 4
DS00657A-page 6
AN657
TEKNIKA.ASM
This is an example of a finished 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 final step in implementing a remote
control decoder, that of cross referencing codes to button numbers. The algorithm will only respond if the first
Setup ports,
Option register,
and TMR0
Read IR
receiver
Service Hold
Is
Yes
HOLD_RCVD
clear?
No
Clear HOLD
Clear
HOLD_RCVD
Is
HOLD
set?
Receiver
changed lo to
hi?
No
Yes
Record TMR0
in READ_LH
Receiver
changed hi to
lo?
No
Yes
Call
TekRdRcvr
No
TMR0 rollover?
Yes
Is
ACTIVE_UP
set?
IR
Yes
No
Yes
BUTTON =
BUTTON + 1
Reload TMR0
No
Is
Yes
ACTIVE_DOWN
set?
No
BUTTON =
BUTTON - 1
Display value
in button
Is
1/8 second
due?
No
Yes
Is
HOLD
set?
No
Yes
Goto Service
Hold
DS00657A-page 7
AN657
FIGURE 7: TEKRDRCVR, TEKIRRESET, TEKRDADDR FLOWCHART
TekRdRcvr
TekRdAddr
Calculate gap
duration using
subtraction
Is
IR_BYTE13
= 14h?
No
Goto
TekIRReset
No
Goto
TekIRReset
Yes
Is
gap length
> 1Ah?
No
Return
Yes
Yes
Yes
No
Return
Is
gap length
< 27h?
No
Return
Is
IR_BYTE24
= 0EBh?
Hold
flag?
Yes
Set
HOLD_RCVD
Return
Goto
TekIRReset
Set Carry
Is
gap length
> 1Fh?
No
No
Is
gap length
> 38h?
No
Yes
Yes
Is
gap length
< 0Eh?
Is
gap length
< 48h?
Yes
Yes
Clear Carry
TekIRReset
No
IR_STATE = 0
Clear:
Hold, New_Key
HOLD_RCVD
ACTIVE_UP
ACTIVE_DOWN
IR_STATE = 1
Return
Return
Is
IR_STATE
bit3 set?
Yes
rrf IRBYTE24
No
rrf IRBYTE13
IR_STATE =
IR_STATE +1
Is
IR_STATE
= 16?
Yes
Goto
TekRdAddr
DS00657A-page 8
No
Is
IR_STATE
= 32?
No
Return
Yes
Goto
TekRdCommand
AN657
FIGURE 8: TEKCOMMAND FLOWCHART
TekRdCommand
Set
ACTIVE_UP
Yes
Is
IR_BYTE13
= 13h?
Yes
Is
IR_BYTE13
= IR_BYTE24?
No
Goto
TekIRReset
No
Set
ACTIVE_DOWN
Yes
Is
IR_BYTE13
= 12h?
No
TekLogCommand
Goto
TekLogCommand
Set:
KEY_READY
HOLD
HOLD_RCVD
Set
IR_BYTE24
= 10
Return
IR_BYTE24 =
IR_BYTE24 - 1
Use IR_BYTE24
as an index
to read table
Is
table value =
IR_BYTE13?
Yes
Move
IR_BYTE24
into button
to be displayed
No
Is
IR_BYTE24
= 0?
Yes
Goto
TekLogCommand
DS00657A-page 9
AN657
INSTRUCTIONS ON WRITING AN
ALGORITHM TO DECODE IR
REMOTES
1.
2.
3.
4.
5.
6.
7.
DS00657A-page 10
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 first 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.
AN657
these lengths to ones and zeros and display them on
the two digit display. Also a HOLD flag 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
00000083
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
DS00657A-page 12
IRMAIN.ASM
10-2-1996
10:24:32
PAGE
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
AN657
0000000E
0000000F
0000000F
0000003F
0000001E
00000000
000000BF
00000003
00000006
00000007
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
DS00657A-page 13
AN657
00000001
00000002
00000007
0000
0000 0E0F
0001 01E2
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
020F
0027
04C6
0800
001A
001B
001C
001D
020E
0027
04E6
0800
091E
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
DS00657A-page 14
;
| | | |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
AN657
001E
001E 05E6
001F 05C6
0020 0800
0200
0200
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
DS00657A-page 15
AN657
00000008
00000009
0000000B
0000000C
0000000D
00000001
00000002
00000003
00000004
00000005
00000006
00000020
00000000
0200
0200
0201
0202
0203
0204
0205
0206
0207
0C83
01C1
0021
0004
076C
058C
046C
02AB
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
DS00657A-page 16
;************************************************************************
;
; 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
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
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
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
0221 0A25
0222
0222 04AC
0223 02A9
0224 0409
0225
0225 0208
0226 0081
0227 0028
0228
0229
022A
022B
0C83
0088
0603
0028
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
;
;
;
;
;
;
;
;
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
022E
022F
0230
0231
0232
0233
0234
0235
0209
0E0F
0024
0584
0689
05A4
06A9
05C4
0236
0237
0238
0239
0CFF
078C
0208
0020
023A
023A 0201
023B 0028
023C 056C
023D 048C
023E 0800
023F
023F 042C
0240 0246
0241 0024
0242
0243
0244
0245
0246
0247
0248
04C4
06A4
05C4
04A4
0684
05A4
0584
0249 04A3
024A 04C3
024B 0380
024C 0900
024D 002E
024E 0200
024F 0900
0250 002F
0251 05A3
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
DS00657A-page 18
;
MathDone
btfsc
goto
;
TR_COUNT,7
DoNotStore
movf
andlw
movwf
bsf
btfsc
bsf
btfsc
bsf
TR_COUNT,W
0f
FSR
FSR,4
TR_COUNT,4
FSR,5
TR_COUNT,5
FSR,6
;
;
;
;
;
;
;
;
;
movlw
btfss
movf
movwf
0ffh
FLAG,OVERFLOW
START_COUNT,W
INDF
;
;
;
;
;
DoNotStore
movf
movwf
bsf
bcf
TMR0,W
;
START_COUNT
;
FLAG,NEW_START_COUNT
;
;
;
FLAG,OVERFLOW
;
;
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
AN657
0252 04C3
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
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
0270 05E6
0271 05C6
0272 0C1E
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
; /
; page 2
; /
; page 3
; /
;
comf
andlw
xorwf
btfss
goto
goto
PORTA,W
;
;
ClearRam
movwf
FSR
movwf
1fh
MemoryInitLoop
incf
FSR,F
clrf
movf
btfss
goto
retlw
INDF
1fh,w
STATUS,Z
MemoryInitLoop
0
;
;
;************************************************************************
;
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
0277 0C00
0278 0007
0279 0245
027A
027B
027C
027D
027E
027F
0280
0281
0E07
002D
0D00
0002
0CBF
0027
05E6
04C6
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
028F
0290
0291
0292
0CBF
0027
04E6
05C6
0293 093A
0294
0294
0294
0295
0296
0297
0298
07CC
0A9E
04A3
04C3
0912
0299 05A3
029A 04C3
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
DS00657A-page 20
tris
movlw
btfss
movwf
PORTC
-(SKIP_NUM)
PORTC,SW1
TR_COUNT
;
;
;
;
movlw
tris
C_CONFIG2
PORTC
comf
PORTA,W
andlw
movwf
iorlw
option
7
SCALE_RECORD
OPTION_MASK
;
;
;
;
;
;
movlw
movwf
bsf
bcf
HIPHEN
PORTC
PORTB,LEFT_OFF
PORTB,RIGHT_OFF
;
;
;
;
movlw
movwf
MSEC8
TMR0
;TMR0 = 8 mSEC
;
/
;
;
;
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
AN657
029B 07C6
029C 04E7
029D 0AA6
029E
029E
029F
02A0
02A1
0665
06AC
02A2
091A
02A2
02A3
02A4
02A5
0765
07AC
02A2
0922
02A6
02A6
02A7
02A8
02A9
02AA
0C83
0081
0603
0A94
0900
02AB 062C
02AC 0A3F
02AD
02AD 0A94
0400
0400
00000005
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
STATUS,PA1
; /
PORTB,RIGHT_OFF
PORTC,DP
ReadDone
PORTA,IR
FLAG,LAST_IR
PCL,F
ReadReceiverHi
;
;
;
;
;
PORTA,IR
FLAG,LAST_IR
PCL,F
ReadReceiverLo
;
;
;
;
MSEC8
TMR0,W
STATUS,C
InnerLoop
ServiceTimerM
;
;
;
;
;
FLAG,_8TH_SEC
EighthSecondChores
;
btfss
btfss
incf
call
;
ReadDone
;
movlw
subwf
btfsc
goto
call
;
btfsc
goto
DS00657A-page 21
AN657
0000000B
0000000C
00000011
00000012
00000013
00000014
00000018
00000019
0000001A
0000001B
0000001C
0000001D
0000001E
0000001F
00000006
00000005
00000004
00000003
00000002
00000001
00000000
00000000
00000001
00000002
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
DS00657A-page 22
;
; 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
AN657
0000001A
00000027
00000038
00000048
0000001F
0000000E
0400
0400
0401
0402
0403
0404
0C83
01C1
0021
0004
03EB
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
0413
0413 0213
0414 003A
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
DS00657A-page 23
AN657
0415 0214
0416 003B
0417 0800
0418
0418
0419
041A
041B
041C
041D
041E
041F
0420
0421
021A
003C
021B
003D
0213
003E
0214
003F
0598
0A48
0422
0422 04B8
0423 0211
0424 0081
0425 0031
0426
0427
0428
0429
0C83
0091
0603
0031
042A
042A 0678
042B 0A40
042C 094B
042D 01E2
042E 0800
042F
0430
0431
0432
0C1F
0091
0603
0A5E
0433 0C0E
0434 0091
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
DS00657A-page 24
movf
movwf
retlw
IR_BYTE24,W
C_BYTE_2
0
;
;-----------------------------------------------------------------------; 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.
AN657
0435
0436
0437
0438
0772
0333
0672
0334
0439
043A
043B
043C
043D
0C01
01F2
0723
0800
07B2
043E 0A13
043F 0A18
0440
0440
0441
0442
0443
0444
0445
0446
0447
0448
0448
0449
044A
044B
044B
044C
044D
044E
044F
0450
0451
0452
0453
0454
0455
0455
0456
0457
0458
0459
0C1A
0091
0703
0800
0C27
0091
0603
0800
0578
05D8
0800
0C38
0091
0703
0A55
0C48
0091
0603
0A55
0072
0800
0CE0
0152
0743
0800
0801
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
IR_STATE,3
IR_BYTE13,F
IR_STATE,3
IR_BYTE24,F
movlw
addwf
btfss
retlw
btfss
1
IR_STATE,F
STATUS,DC
0
IR_STATE,5
goto
goto
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.
;
;-----------------------------------------------------------------------; 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
045E
045E
045F
0460
0461
0462
0478
04D8
0072
0272
0800
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
0477 04A3
0478 05C3
0479 0800
047A
047A 0CBF
047B 002E
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
DS00657A-page 26
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
AN657
047C 002F
047D 0800
047E
047E 0678
047F 06D8
0480 02A2
0481 095E
0482 04D8
0483 0419
0484 0800
0485
0485 0C0F
0486
0487
0488
0489
048A
048B
0005
0C3F
0006
0C00
0007
0498
048C 0459
048D 0800
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
049E
049E 0665
049F 06B8
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
;
QuarterSecChores
btfsc
btfsc
FLAG2,HOLD
FLAG2,HOLD_RCVD
incf
call
PCL,F
ResetIR
bcf
FLAG2,HOLD_RCVD
bcf
retlw
FLAG3,_4TH_SEC
0
;
;
;
;
;
;
;
;
;
reset
ready
Clear
to be
the
for
the
set
;
TwoSecChores
movlw
A_CONFIG
tris
movlw
tris
movlw
tris
bcf
PORTA
B_CONFIG
PORTB
C_CONFIG2
PORTC
FLAG2,KEY_READY
bcf
retlw
FLAG3,TWO_SEC
0
;
;
;
;
;
;
;
;
;
;
;
;
;
;************************************************************************
;
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
04A2
04A3
04A4
04A5
0765
07B8
02A2
0922
04A6
04A7
04A8
04A9
04AA
0C83
0081
0603
0A9E
0900
04AB 04A3
04AC 04C3
04AD 0912
04AE 04A3
04AF 05C3
04B0
04B1
04B2
04B3
04B4
07C6
0778
0AB4
04E7
04B4 0639
04B5 0963
04B6 0619
04B7 097E
04B8 0659
04B9 0985
04BA 0A9E
0600
0600
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
DS00657A-page 28
incf
call
PCL,F
; Not either
RecordRTCC_atLowToHiTransition
; Record the TMR0 value when the lo to
; hi transition came from the receiver
btfss
btfss
incf
call
PORTA,IR
FLAG2,LAST_IR_STATE
PCL,f
ReadReceiver
;
;
;
;
movlw
subwf
btfsc
goto
call
MSEC8
TMR0,W
STATUS,C
IRInnerLoop
SvcTimer
;
;
;
;
;
bcf
bcf
call
STATUS,PA0
STATUS,PA1
UpdateDisplay
;
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
; page 2
; /
; page 3
; /
;
btfss
btfss
goto
bcf
NotHold
;
btfsc
call
PORTB,RIGHT_OFF
FLAG2,HOLD
NotHold
PORTC,DP
;
;
;
;
FLAG3,EIGTH_SEC
EigthSecChores
btfsc
call
FLAG3,_4TH_SEC
QuarterSecChores
btfsc
call
FLAG3,TWO_SEC
TwoSecChores
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
AN657
0000000C
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.
; flag bank 2
; flag bank 3
-->
-->
-->
-->
-->
-->
-->
-->
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)
DS00657A-page 29
AN657
00000003
00000004
00000014
000000EB
00000000
00000001
00000002
00000003
00000008
00000009
0000000A
0000000B
00000010
00000011
0000001B
0000001A
00000013
00000012
0600
0600
0601
0602
0603
0604
0C83
01C1
0021
0004
03EB
0605 0A08
0606 0559
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
DS00657A-page 30
;
| | | |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.
;
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
0613
0613
0614
0615
0616
0617
0618
0619
061A
061B
0C14
0193
0743
0A82
0CEB
0194
0743
0A82
0800
061C
061C
061D
061E
061F
0253
0194
0743
0A82
0620
0621
0622
0623
0624
0625
0C13
0193
0643
0579
0643
0A39
0626 0C12
0627 0193
0628 0643
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.
;
;
;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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
00F4
0254
0643
0A39
0214
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
0646
0646 04B8
0647 0211
0648 0081
0649 0031
064A
064B
064C
064D
0C83
0091
0603
0031
064E
064E 0678
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
DS00657A-page 32
bsf
btfsc
goto
FLAG3,ACTIVE_DOWN
STATUS,Z
TekLogCommand
movlw
movwf
d'10'
IR_BYTE24
IR_BYTE24,F
IR_BYTE24,W
STATUS,Z
TekLogCommand
IR_BYTE24,W
;
;
;
;
;
;
;
;
;
;
;
;
GuessLoop
decf
comf
btfsc
goto
movf
call
CheckGuess
xorwf
TekTable
IR_BYTE13,W
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?
AN657
064F 0A64
0650 096F
0651 01E2
0652 0800
0653
0654
0655
0656
0C1F
0091
0603
0A82
0657 0C0E
0658 0091
0659
065A
065B
065C
0772
0333
0672
0334
065D
065E
065F
0660
0661
0C01
01F2
0723
0800
07B2
0662 0A13
0663 0A1C
0664
0664
0665
0666
0667
0668
0669
066A
066B
066C
066C
066D
066E
066F
066F
0670
0671
0672
0673
0674
0675
0676
0677
0C1A
0091
0703
0800
0C27
0091
0603
0800
0578
05D8
0800
0C38
0091
0703
0A79
0C48
0091
0603
0A79
0072
0678 0800
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
TekLookHold
call
addwf
retlw
TekLookAtten
PCL,F
0
movlw
subwf
btfsc
goto
ONE_MAX
READ_LH,W
STATUS,C
TekIRReset
;
;
;
;
movlw
subwf
ZERO_MAX
READ_LH,W
;
;
;
;
btfss
rrf
btfsc
rrf
IR_STATE,3
IR_BYTE13,F
IR_STATE,3
IR_BYTE24,F
movlw
addwf
btfss
retlw
btfss
1
IR_STATE,F
STATUS,DC
0
IR_STATE,5
goto
goto
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.
;
;-----------------------------------------------------------------------; 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
067E
067E
067F
0680
0681
05B8
0201
0031
0800
0682
0682
0683
0684
0685
0686
0687
0688
0478
04D8
0479
0499
0072
0272
0800
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
069B
069B 0439
069C 0800
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
DS00657A-page 34
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
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
06AD 0459
06AE 0800
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
06BB
06BB
06BC
06BD
06BE
0665
06B8
02A2
097E
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
FLAG2,HOLD
FLAG2,HOLD_RCVD
incf
call
PCL,F
TekIRReset
bcf
FLAG2,HOLD_RCVD
btfsc
call
FLAG2,HOLD
TekSvcHold
bcf
retlw
FLAG3,_4TH_SEC
0
;
;
;
;
;
;
;
;
;
;
;
;
TekTwoSec
movlw
A_CONFIG
tris
movlw
tris
movlw
tris
bcf
PORTA
B_CONFIG
PORTB
C_CONFIG2
PORTC
FLAG2,KEY_READY
bcf
retlw
FLAG3,TWO_SEC
0
;
;
;
;
;
;
;
;
;
;
;
;
;
;************************************************************************
;
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
0765
07B8
02A2
0946
06C3
06C4
06C5
06C6
06C7
0C83
0081
0603
0ABB
0900
06C8 04A3
06C9 04C3
06CA 020C
06CB 0900
06CC 0027
06CD 05A3
06CE 05C3
06CF 0678
06D0 04E7
06D1 05E6
06D2 04C6
06D3 0639
06D4 099B
06D5 0619
06D6 099D
06D7 0659
06D8 09A6
06D9 0ABB
0100
0100
0100
0101
0102
0103
0104
0C1E
0007
0000
0747
0B08
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
DS00657A-page 36
btfss
btfss
incf
call
PORTA,IR
FLAG2,LAST_IR_STATE
PCL,F
TekRdRcvr
;
;
;
;
movlw
subwf
btfsc
goto
call
MSEC8
TMR0,W
STATUS,C
TekInnerLoop
TekServiceTimer
;
;
;
;
;
bcf
bcf
STATUS,PA0
STATUS,PA1
movf
call
movwf
BUTTON,W
LookUpDigit
PORTC
;
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
; page 2
; /
; page 3
; /
;
btfsc
bcf
FLAG2,HOLD
PORTC,DP
bsf
bcf
PORTB,LEFT_OFF
PORTB,RIGHT_OFF
btfsc
call
FLAG3,EIGTH_SEC
TekEigthSec
btfsc
call
FLAG3,_4TH_SEC
TekQuarterSec
btfsc
call
FLAG3,TWO_SEC
TekTwoSec
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
AN657
0105 05A3
0106 04C3
0107 0A61
0108
0108 0727
0109 0B0D
010A 04A3
010B 05C3
010C 0A8E
010D
010D 05A3
010E 05C3
010F 0AAF
07FF
07FF 0B00
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 3
; /
; Start the 6121 IR format decoder
; page 1
; /
; page 2
; /
; page 3
; /
; Start the Technika Remote decoder
; start vector
DS00657A-page 37
AN657
MEMORY USAGE MAP ('X' = Used,
'-' = Unused)
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
------------------------------XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
---------------XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXX----XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
------------------------------X
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.
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.
M
WORLDWIDE SALES AND SERVICE
AMERICAS
ASIA/PACIFIC
Japan
Corporate Office
Australia
Rocky Mountain
China - Beijing
Atlanta
500 Sugar Mill Road, Suite 200B
Atlanta, GA 30350
Tel: 770-640-0034 Fax: 770-640-0307
Boston
2 Lan Drive, Suite 120
Westford, MA 01886
Tel: 978-692-3848 Fax: 978-692-3821
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
Detroit
Tri-Atria Office Building
32255 Northwestern Highway, Suite 190
Farmington Hills, MI 48334
Tel: 248-538-2250 Fax: 248-538-2260
Kokomo
2767 S. Albright Road
Kokomo, Indiana 46902
Tel: 765-864-8360 Fax: 765-864-8387
Los Angeles
18201 Von Karman, Suite 1090
Irvine, CA 92612
Tel: 949-263-1888 Fax: 949-263-1338
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
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
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
China - Shenzhen
San Jose
Hong Kong
New York
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
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
Singapore
Microchip Technology Singapore Pte Ltd.
200 Middle Road
#07-02 Prime Centre
Singapore, 188980
Tel: 65-334-8870 Fax: 65-334-8850
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
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
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
Germany
Microchip Technology GmbH
Gustav-Heinemann Ring 125
D-81739 Munich, Germany
Tel: 49-89-627-144 0 Fax: 49-89-627-144-44
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
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