You are on page 1of 40

AN657

Decoding Infrared Remote Controls Using a PIC16C5X Microcontroller


The modulation layer refers to the fact that each burst of infrared signal is often modulated at a frequency between 32.75 kHz and 56.8 kHz. This is done to diminish the effects of ambient light. This layer, however, is optional. Some infrared formats do not modulate their outputs, sending pulses of unmodulated infrared light instead. This is done to extend the remote controls battery life and to reduce the cost of the remote control device. The serial data layer has the information containing a command. This is typically coded in the lengths of infrared bursts or in the lengths of gaps between infrared bursts. A long gap or burst is interpreted as a '1', a short gap or burst is interpreted as a '0'.

Author: William G. Grimm Consultant

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.

THE THREE LAYERS OF AN INFRARED SIGNAL


The typical infrared signal used by remote controls has three layers. The names used for these layers has not been standardized. In this application note they are called the infrared, the modulation, and the serial data. The infrared layer is the means of transmission. Infrared is light whose wavelength is too long to see. Although you cannot see the infrared beam, it behaves the same as light, so if you cannot see the target device, you cannot control it with an infrared signal. To control around corners or through opaque materials, RF, usually UHF signals are used. Although this application note does not further mention RF, much of what is presented here can be used with an RF transmission medium.

1997 Microchip Technology Inc.

DS00657A-page 1

AN657

DS00657A-page 2
Power Jack

FIGURE 1: IR RECEIVER SCHEMATIC

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

10 11 12 1 2 C2 47 F 10V 1 2 4 MHz Ceramic 3 Resonator +5 RN2 100k x4 +5 A 4 3 B +5 +5 2 C 1 d A B C d 10k x4 11 16 2 6 3 8 C3 0.01 F 4 27 x1 26 0 1 0 1 2

13 14 15 3 4 5

6 0

7 1

8 2

PORTB PIC16C57 PORTC


2 3 4 5 6 7 17 18 19 20 21 22 23 24 25

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

U3 - Sharp LiteOn U4 - Quality Technologies U5 - Panasonic

GP1U5 -21Y or LT-1060 QSE157QT LN54YA

f G e

B C d left

f G e

B C d right

1997 Microchip Technology Inc.

+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.

FIGURE 2: IRMAIN FLOWCHART

Start

Is No 1 Closed? Yes

Goto MEASURE

Is No 0 Closed? Yes

Goto IR6121

Goto TEKNIKA

1997 Microchip Technology Inc.

DS00657A-page 3

AN657
FIGURE 3: MEASURE.ASM FLOWCHART

MEASURE

1/8 second elapsed? No SW1 Yes Read Option switch

No

Is 1 Closed? 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 le to be displayed

IR

Read Receiver

Dark 8 ms? Yes

No

Convert value in le to digits for display

Is reading complete? Yes Display digit not now being displayed

No Read Receiver IR

Receiver changed? No

Yes

Calculate time duration using subtraction Store in File

File registers full? No

Yes

Set All Done Flag

Read TMR0

No

TMR0 Overow? Yes Reload TMR0 Increment Timer

DS00657A-page 4

1997 Microchip Technology Inc.

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.

FIGURE 4: 1/4 SECOND CHORES


1/4 Sec Chores

Hold Set? Yes

No

Goto NewLoop

HOLD_ RCVD Set? Yes

No

Goto RESET_IR

Goto NewLoop

1997 Microchip Technology Inc.

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

Receiver Yes state changed lo to hi? RESET_IR No

Record TMR0 in Read_LH

IR_STATE = 0

Receiver state changed lo to hi? No

Yes

Calculate gap duration using subtraction

No

TMR0 overow? Yes Reload TMR0

IR_STATE= 0

No

Is gap duration > 38h & < 48h? Yes

Yes

Is IR_STATE = 0? No

IR_STATE = 1 other

No

1/8 sec timeout? Yes Read switch

IR_STATE = IR_STATE + 1

Rotate 1 into byte 1

Is gap duration mean 0,1 or other? 0

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

Setup display for byte 1, 2, 3, or 4

No

1/4 sec time-out? Yes 1/4 sec Chores

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

Is IR_STATE <= 32?

No

DS00657A-page 6

1997 Microchip Technology Inc.

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.

FIGURE 6: TEKNIKA.ASM FLOWCHART


Teknika

Setup ports, Option register, and TMR0

Service Hold

Read IR receiver

IR

Is Yes HOLD_RCVD clear? No Clear HOLD_RCVD

Clear HOLD

Receiver changed lo to hi? No

Yes

Record TMR0 in READ_LH

Receiver changed hi to lo? No No TMR0 rollover? Yes BUTTON = BUTTON + 1 Reload TMR0

Yes

Call TekRdRcvr

Is HOLD set? Yes Is ACTIVE_UP set? No

No

Yes

Is Yes ACTIVE_DOWN set? No

BUTTON = BUTTON - 1

Display value in button

Is 1/8 second due? Yes Is HOLD set? Yes Goto Service Hold

No

No

1997 Microchip Technology Inc.

DS00657A-page 7

AN657
FIGURE 7: TEKRDRCVR, TEKIRRESET, TEKRDADDR FLOWCHART
TekRdRcvr TekRdAddr

Calculate gap duration using subtraction

Is IR_BYTE13 = 14h? Yes

No

Goto TekIRReset

Return

No

Is gap length > 1Ah? Yes

Yes

Hold ag? No

Is IR_BYTE24 = 0EBh? Yes Return

No

Goto TekIRReset

Return

No

Is gap length < 27h? Yes

Return

Set HOLD_RCVD

Goto TekIRReset

No

Is gap length > 1Fh? Yes

No

Is gap length > 38h? Yes Is gap length < 48h? Yes IR_STATE = 1 No TekIRReset

Set Carry

No

Is gap length < 0Eh? Yes Clear Carry

IR_STATE = 0 Clear: Hold, New_Key HOLD_RCVD ACTIVE_UP ACTIVE_DOWN

Return Return Is IR_STATE bit3 set? No rrf IRBYTE13 Yes rrf IRBYTE24

IR_STATE = IR_STATE +1

Is IR_STATE = 16? Yes Goto TekRdAddr

No

Is IR_STATE = 32? Yes Goto TekRdCommand

No Return

DS00657A-page 8

1997 Microchip Technology Inc.

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

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? No

Yes

Move IR_BYTE24 into button to be displayed

Is IR_BYTE24 = 0?

Yes

Goto TekLogCommand

1997 Microchip Technology Inc.

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.

Step 3: Determine time-base


If the remote control is modulated, switch to a demodulating IR receiver. With the option selector still at 1, press a button on the remote control again until the decimal point comes on. The series of memorized pulse durations will now probably include a lot of FFh values. If so, move the Option selector up until the values are in the 7h to 1Fh range. The Option selector has the optimum value for the option divisor to be used in the TMR0 register. To optimize range and reliability, several demodulating receivers may be tried. These are available from Sharp or LiteOn. The modulating frequencies that are presently used are 32.75 kHz, 35.0 kHz, 36.0 kHz, 36.7 kHz, 38 kHz, 39 kHz, 40 kHz, 41.7 kHz, 48 kHz, and 56.8 kHz[2]. The most common are round 40 kHz. The best match for your remote control will give the longest range and most consistent results.

2.

3.

4.

5.

Step 4: Decoding ones and zeros


The next step is to map out the characteristic pulse and gap lengths that represent ones and zeros. By pressing the same button on the remote, write down the series of numbers read by the PIC16C57 running the MEASURE.ASM program. Each odd numbered entry is the duration of a burst of IR from the remote control. Each even numbered entry is the duration of a gap between bursts of infrared. The lengths of these gaps and bursts dene ones and zeros. Their order will depend on which button is pressed. Once the characteristic lengths have been discovered for a one and a zero, an algorithm can then be created with a counter to translate the lengths into ones and zeros.

6.

7.

Step 1: Choosing a remote control


Depending on your application, you may choose to have an off the shelf remote control or design one yourself. Typically they have small 4-bit microcontrollers in them, preprogrammed for a serial format. Some companies such as General Instrument sell them as complete units, others such as NEC sell the main component which can be customized by external diodes to not interfere with other applications. It is also possible to program a PIC16C57 to generate a signal that can be sent to an infrared LED for transmission. Yet another approach is to use a programmable remote control to generate any number of infrared formats and use them right off the shelf to control the target device.

Step 5: Finding the Command Length


Press the same button again. The command duration can also be found. This is necessary to determine if a button is being held down or a new command of the same type is being issued. Most remote controls repeat the command as long as the button is held down, the repetitions separated by a long dark time, usually 0FFh on an even numbered transition. If no long even numbered counts can be found, consider that some commands can be longer than 64 transitions. The option to delay counting is available for this reason. Insert jumper 1 and MEASURE.ASM will only start storing transition times after the 32nd transition.

Step 2: Determining a modulation frequency


For this and the next step the MEASURE.ASM program will be used. To start out, use the non-modulated receiver and a PIC16C57 running the MEASURE.ASM application. Select 1 on the option selector. Press a but-

Step 6: Translating lengths to bits


Once the characteristic lengths of ones and zeros have been found and the length of the typical command has been found, a program can then be written to decode

DS00657A-page 10

1997 Microchip Technology Inc.

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.

Step 7: Create a button to code cross reference table


TEKNIKA.ASM implements a lookup table to translate the codes received to the actual button pressed. A counter is loaded with the highest number button that can be pressed, and the code is then looked up and compared with the code that was received. If no match, the counter is decremented until a match is found. When found, the counter then has the button number that was pressed. Note too, that more checking may be done at this level on some formats, such as having an address, a complement of the code following the code itself for checking. The result from all of the steps in decoding is that if a button is pressed on a remote control, that button number appears in a PIC16C57 le location. A command such as channel up or channel down will appear as two set ags, one to indicate the command, the other to indicate that it is active, HOLD. From this point the application can access these ags and les to respond appropriately.

1997 Microchip Technology Inc.

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

LINE SOURCE TEXT

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

1997 Microchip Technology Inc.

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

1997 Microchip Technology Inc.

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

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 001A 001B 001C 001D 020F 0027 04C6 0800 091E 020E 0027 04E6 0800

DS00657A-page 14

1997 Microchip Technology Inc.

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

1997 Microchip Technology Inc.

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

00000008 00000009 0000000B 0000000C 0000000D

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

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

DS00657A-page 16

1997 Microchip Technology Inc.

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

0221 0A25 0222 0222 04AC 0223 02A9 0224 0409

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

1997 Microchip Technology Inc.

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

TR_COUNT,W 0f FSR FSR,4 TR_COUNT,4 FSR,5 TR_COUNT,5 FSR,6

023A 023A 0201 023B 0028 023C 056C

023D 048C 023E 0800

bcf ;

TMR0,W ; START_COUNT ; FLAG,NEW_START_COUNT ; ; ; FLAG,OVERFLOW ;

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

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

1997 Microchip Technology Inc.

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

0270 05E6 0271 05C6 0272 0C1E

; ; ;************************************************************************ ; 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

1997 Microchip Technology Inc.

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

027E 027F 0280 0281

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

; 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

1997 Microchip Technology Inc.

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

0665 06AC 02A2 091A

PORTA,IR FLAG,LAST_IR PCL,F ReadReceiverHi

; ; ; ; ;

?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

0765 07AC 02A2 0922

0C83 0081 0603 0A94 0900

MSEC8 TMR0,W STATUS,C InnerLoop ServiceTimerM FLAG,_8TH_SEC EighthSecondChores

; ; ; ; ;

Check for overflow. SEE IF TMR0 < MSEC8, If TMR0 < MSEC8, Overflow. No overflow, no carry, loop. Keep time and reload time keeper.

02AB 062C 02AC 0A3F

; check for 1/8 second time out ; anything that needs doing every 1/8sec ; can go in this subroutine

02AD 02AD 0A94

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

1997 Microchip Technology Inc.

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

00000006 00000005 00000004 00000003 00000002 00000001 00000000

00000000 00000001 00000002

DS00657A-page 22

1997 Microchip Technology Inc.

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

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

1997 Microchip Technology Inc.

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

0422 0422 04B8

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

0433 0C0E 0434 0091

; ;-----------------------------------------------------------------------; 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

1997 Microchip Technology Inc.

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

0435 0436 0437 0438 0439 043A 043B 043C 043D

0772 0333 0672 0334 0C01 01F2 0723 0800 07B2

043E 0A13 043F 0A18

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. ;------------------------------------------------------------------------

1997 Microchip Technology Inc.

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

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

DS00657A-page 26

1997 Microchip Technology Inc.

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

048C 0459 048D 0800

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

049E 049E 0665 049F 06B8

; ; ;************************************************************************ ; 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?

1997 Microchip Technology Inc.

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

04A2 04A3 04A4 04A5 04A6 04A7 04A8 04A9 04AA

0765 07B8 02A2 0922 0C83 0081 0603 0A9E 0900

04AB 04A3 04AC 04C3 04AD 0912

04AE 04A3 04AF 05C3

; page 2 ; /

; page 3 ; /

04B0 04B1 04B2 04B3 04B4

07C6 0778 0AB4 04E7

04B4 0639 04B5 0963

FLAG3,EIGTH_SEC EigthSecChores

; check for 1/8 second time out ; all that needs doing every 1/8 second ; can go in this subroutine

04B6 0619 04B7 097E

04B8 0659 04B9 0985

04BA 0A9E 0600 0600

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

1997 Microchip Technology Inc.

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

; 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)

; A channel command is pending. ; A channel command is ready.

--> Quarter second flag. --> Eighth second flag. --> Two second flag.

1997 Microchip Technology Inc.

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

0600 0600 0601 0602 0603 0604

0C83 01C1 0021 0004 03EB

0605 0A08 0606 0559

DS00657A-page 30

1997 Microchip Technology Inc.

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

0C14 0193 0743 0A82 0CEB 0194 0743 0A82 0800

061C 061C 061D 061E 061F 0620 0621 0622 0623 0624 0625

0253 0194 0743 0A82 0C13 0193 0643 0579 0643 0A39

0626 0C12 0627 0193 0628 0643

; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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

1997 Microchip Technology Inc.

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

00F4 0254 0643 0A39 0214

IR_BYTE24,F IR_BYTE24,W STATUS,Z TekLogCommand IR_BYTE24,W TekTable IR_BYTE13,W

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 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

1997 Microchip Technology Inc.

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

0657 0C0E 0658 0091

; 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

0659 065A 065B 065C 065D 065E 065F 0660 0661

0772 0333 0672 0334 0C01 01F2 0723 0800 07B2

0662 0A13 0663 0A1C

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

0C38 0091 0703 0A79 0C48 0091 0603 0A79 0072

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

1997 Microchip Technology Inc.

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

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

DS00657A-page 34

1997 Microchip Technology Inc.

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

A_CONFIG 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

06AD 0459 06AE 0800

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

06BB 06BB 06BC 06BD 06BE

0665 06B8 02A2 097E

; ; ;************************************************************************ ; 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 ;

1997 Microchip Technology Inc.

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 ; /

06CD 05A3 06CE 05C3

; page 3 ; /

06CF 0678 06D0 04E7 06D1 05E6 06D2 04C6 06D3 0639 06D4 099B

06D5 0619 06D6 099D

06D7 0659 06D8 09A6

06D9 0ABB 0100

goto ;

TekMain

0100 0100 0101 0102 0103 0104

0C1E 0007 0000 0747 0B08

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

1997 Microchip Technology Inc.

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 ; /

0107 0A61 0108 0108 0727 0109 0B0D

010A 04A3 010B 05C3

; page 2 ; /

; page 3 ; / ; Start the 6121 IR format decoder

010C 0A8E 010D

; page 1 ; /

; page 2 ; /

010D 05A3 010E 05C3 010F 0AAF

; page 3 ; / ; Start the Technika Remote decoder

07FF 07FF 0B00

; start vector

1997 Microchip Technology Inc.

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

1997 Microchip Technology Inc.

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.

2002 Microchip Technology Inc.

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

2002 Microchip Technology Inc.

You might also like