PIC16F628 infrared receiver

EL-C1600N100013-B
0805 red light emitting diode

PIC16F628 infrared receiver
;Notes on RC5
;
;14 RC5 bits:
;SSTAAAAACCCCCC
;
;S: 2 start bits, T: 1 toggle bit, A: 5 address bits, C: 6 command bits
;
;Usually both start bits are high. Extended RC5 uses the 2nd start bit for expanding
;the 6 command bits to 7 bits. After receiving a complete 14-bit word, this bit
;is inverted and added as bit 6 to the register 'RC5_CMD'. The toggle bit is
;copied to bit 7 of 'RC5_CMD'. The 5 LSBs of register 'RC5_ADR' contain the
;5 address bits; the 3 MSBs are set to 0.
;Result after a valid code has been received: ;RC5_ADR: 000AAAAA RC5_CMD: TCCCCCCC
;Note that most IR receiver chips (e.g., SFH5110-xx) have an active low output, however, the
;PIC's internal comparator inverts the signal. An inverting driver transistor for the RS232
;interface finally inverts and level shifts the signal again so that the standard LIRC
;configuration (i.e., active low) must be used.
;
;
;PIC16F628 connections
;
;PIN FUNCTION
;
;RB7 ICSP
;RB6 ICSP
;RA5 ICSP
;
; RB5 test output, active high
;RB4 PWRin -- PC switch input active low
;RB3 RESETout -- output transistor redial, active high
;RB2 PWRout -- output transistor for MBATX power on/off, active high
;RB1 LED grn -- output LED green tube, active high
;RB0 LED red -- output LED red tube, active high
;
;RA7 4.000M C crystal
;RA6 4.000M C crystal
;
;RA4 (unused)
;RA3 comparator C1 output -- transistor based drive for RS232 TX
;RA2 (internally connected to Vref = 1.25 volts)
;RA1 ATXin -- comparator C2 inverting input for sensing -5 volts of ATX power supply
;RA0 IRin -- comparator C1 inverting input for IR receiver chip
;
;---Configuration--------------------------------------------- -----------------------------------
;
;PIC16F628, Power-up timer, no watchdog, HS-oscillator, *no* brown-out detect, LVP off, CP off,
;MCLRE off, f=4MHz

List p=16f628

__CONFIG_pwrte_on&_wdt_off&_hs_osc&_boden_off&_lvp_off&_cp_off&_mclre_off

Include

;---Variables[all UPPERCASE]------------------------------------------ -------------------------

cb LOC kh'20'

DATA_1; 16-bit shift register for incoming RC5 bits
DATA_2;
DATA_TMP1; temporary register for RC5 codes
DATA_TMP2; temporary register for RC5 codes
BITCOUNT; counter for the RC5 bits
COUNT; universal temporary count register
TMP; universal temporary registers
TMP1;
TMP2;
RC5_ADR; received RC5 address after cleanup: '000AAAAA'
RC5_CMD; received RC5 command after cleanup: '0CCCCCCC'
RC5_CMD_TMP; temporary register for RC5 command
RC5_CMD_TMP_1; temporary register for RC5 command
KEYCOUNT; counts the incoming RC5 power key packets to set up a delay
KEYCOUNT_1; counts the incoming RC5 0-key packets to set up a delay
RC5_TX_1; 16-bit shift register for outgoing RC5 bits
RC5_TX_2;
EEADR_TMP; holds the EEPROM address when calling the EEPROM write subroutine
EEDATA_TMP; holds the EEPROM data when calling the EEPROM write subroutine

PWR_ON_DELAY; 00...99 (recalled from EEPROM location h'00')
PWR_KEY_ADR; signed RC5 power key address '000AAAAA' (recalled from EEPROM location h'01')
PWR_KEY_CMD; signed RC5 power key command '0CCCCCCC' (recalled from EEPROM location h'02')

D1; temporary registers for delay routines
D2;
D3;

FLAGS; flags, see definitions

Endc

;---EEPROM default data--------------------------------------------- -----------------------------

Org h'2100'
; adr content
De d'45'; h'00' PWR_ON_DELAY
De b'00000101'; h'01' PWR_KEY_ADR
De b'00001100'; h'02' PWR_KEY_CMD

;---Definitions[all Mixed Case]------------------------------------------ -----------------------

#define ATX_C_out cmcon,7; comparator 2 output
#define IRin porta,0; input for IR receiver chip (active low)
#define IRin Tris ISA,0; tris register bit for IRin
#define IR_C_out cmcon,6; comparator 1 output

#define LEDred portb,0; output for bicolor LED red anode
#define LEDgrn portb,1; output for bicolor LED green anode
#define PWRout portb,2; output to drive transistor for MBATX power on/off
#define RESETout portb,3; output to drive transistor for MB reset
#define PWRin portb,4; input for PC power switch
#define TestOut portb,5; debug output for scope

#define TurnOnDelay d'9'; turn on delay when pressing remote power key to
; wake up from standby (9 makes approx. one second)

#define RebootDelay d'15'; additional reboot delay (in seconds)

#define RC5_Flag FLAGS,0; 0: RC_5 code valid, 1: RC_5 code invalid
#define Reboot_Flag FLAGS,1; 0: normal boot delay, 1: additional delay needed


;---Macros[all Mixed Case]------------------------------------------ ----------------------------

Bank_0 macro
Bcf status, 5
Bcf status, 6
Endm

Bank_1 macro
Bsf status, 5
Bcf status, 6
Endm

Test macro
bsf TestOut
bcf TestOut
Endm

LED_red macro
bsf LEDred
bcf LEDgrn
Endm

LED_grn macro
bsf LEDgrn
bcf LEDred
Endm

LED_off macro
bcf LEDred
bcf LEDgrn
Endm

;---Reset--------------------------------------------- -------------------------------------------

Org h'00'
Goto init; reset -> init

;---Interrupt--------------------------------------------- ---------------------------------------

Org h'04'
Goto init; no interrupt

;************************************************* *************************************************
;Initialization
;************************************************* *************************************************

Init

; configuration of porta and portb------------------------------------------------ ----------------

Bank_0
Clrf porta; clear port a register
Clrf portb; clear port b register

Bank_1
MOVlw b'00000111'; RA0...RA2 input, RA3...RA7 output
MOVwf trisa
MOVlw b'00010000'; RB0...RB3 output, RB4 input, RB5...RB7 output
MOVwf trisb
Bcf option_reg,7; enable portb weak pullups
Bank_0

; configuration of analog comparators------------------------------------------------ -------------

MOVlw b'00000110'; two common reference comparators with outputs
MOVwf cmcon
Bank_1
MOVlw b'11100110'; Vref = 1.25 volts, connected to RA2
MOVwf vrcon
Bank_0

; timer0------------------------------------------------ ------------------------------------------

Bank_1
MOVlw b'01000000'; timer0 internal clock, prescaler 1:2, enable portb weak pullups
MOVwf option_reg;
Bank_0

; timer1------------------------------------------------ ------------------------------------------

MOVlw b'00110001'; prescaler = 8, internal clock, enabled
MOVwf t1con

;************************************************* *************************************************
;Main program
;************************************************* *************************************************

Start
clrf FLAGS; clear all flags
Call copy_ee; copy default eeprom values to RAM registers

Main_loop
btfsc ATX_C_out; check if ATX is standby
Goto green; on -> LED green
LED_red; standby -> LED red
Goto pwr_sw
Green
LED_grn

Pwr_sw
btfss PWRin; test PWRin (active low)
Goto pwr_sw_1; if low, go to pwr_sw_1

btfss IR_C_out; wait for high level at IR_C_out
Goto main_loop;
Call rc5_rx; call rc5_rx subroutine
btfsc RC5_Flag; RC5 code OK?
Goto main_loop; no, go to main_loop

LED_off; turn off green LED for 50ms each time a valid code
Call delay_t4; has been received
LED_grn

Pwr_key; check if power key of remote control is pressed
MOVfw RC5_ADR; load RC5_ADR into w
subwf PWR_KEY_ADR, w;
Btfss status, z; do PWR_KEY_ADR match?
Goto no_match; -no, go to no_match
;
MOVfw RC5_CMD; -yes, load RC5_CMD into w
Andlw b'01111111'; and clear toggle bit
subwf PWR_KEY_CMD, w;
Btfss status, z; do PWR_KEY_CMD match?
Goto no_match; -no, go to no_match
;
MOVfw RC5_CMD_TMP; -yes, toggle bit also unchanged?
subwf RC5_CMD, w;
Btfss status, z;
Goto no_match; -no, go to no_match
;
btfsc ATX_C_out; activate PWRout only if ATX is standby to power up PC
Goto vdr_pwr_down; if on, VDR's shutdown script will turn off PC

; ATX is standby, now check if power key of remote control is
; pressed long enough (approx. TurnOnDelay * 114ms)

incf KEYCOUNT, f; -yes, unchanged, increment KEYCOUNT
MOVfw KEYCOUNT;
sublw TurnOnDelay; if reached TurnOnDelay, activate PWRout
Btfss status, z
Goto cont
bsf PWRout; activate PWRout for 250ms
Call delay_t6
bcf PWRout
Goto boot_delay; and go to boot_delay

No_match
clrf KEYCOUNT; clear KEYCOUNT

Cont
MOVfw RC5_CMD; copy RC5_CMD to temporary register
MOVwf RC5_CMD_TMP; for ext toggle bit comparison

Zero_key; check if 0 key on remote control is pressed
; at least 44 * 114ms (RC5 code repetition rate) = approx. 5s
MOVfw RC5_CMD; load RC5_CMD into w
Andlw b'01111111'; and clear toggle bit
Btfss status, z; does O key (command '0000000', any address) match?
Goto no_match_1;

MOVfw RC5_CMD_TMP_1; toggle bit also unchanged?
subwf RC5_CMD, w;
Btfss status, z;
Goto no_match_1; -no, has changed
incf KEYCOUNT_1, f; -yes, unchanged, increment KEYCOUNT_1
MOVfw KEYCOUNT_1;
Sublw d'44';
Btfss status, z; reached 44 (approx. 5s)?
Goto cont_1; -no, loop
Goto pgm_or_reboot; -yes, go to pgm_or_reboot

No_match_1
clrf KEYCOUNT_1; clear KEYCOUNT_1

Cont_1
MOVfw RC5_CMD; copy RC5_CMD to temporary register
MOVwf RC5_CMD_TMP_1; for next toggle bit comparison

Goto main_loop

Pgm_or_reboot
btfss ATX_C_out
Goto pgm_mode; PC is in standby -> enable program mode

LED_red; turn LED red to indicate that reboot has been initialized

MOVlw h'1f'; set address to h'1f'
MOVwf RC5_TX_2;
MOVlw h'3f'; set command to h'3f'
MOVwf RC5_TX_1; This combination is not used by the remote control. Suitable
; entries in lircd.conf and lircrc call reboot script via irexec

Call rc5_tx
bsf Reboot_Flag; set Reboot_flag so that additional delay for green LED flashing
Goto boot_delay; will be added and go to boot_delay

;------------------------------------------------- -----------------------------------------------

Pwr_sw_1; checks if power switch of PC is pressed for less or more than
; 5 seconds: if less -> power on/off, if more -> reset

Call delay_t4; 50ms delay
btfsc PWRin; still low after 50ms?
Goto main_loop; if not, assumes spike and go to main_loop

btfss ATX_C_out; ATX on or standby?
Goto turn_on; standby, a reset would be quite useless, so turn on VDR

Clrf tmr1h; clear timer1 registers
Clrf tmr1l;
MOVlw d'19'; set COUNT to d'19', this makes approx. 19 * 262ms = 5 seconds
MOVwf COUNT;

Chk_low
btfsc PWRin; still low?
Goto vdr_pwr_down; if not, pwr key was pressed <5s -> turn off VDR

Btfsctmr1h,7; check timer1h register bit7 (set after 262ms)
Goto dec_cnt1
Goto chck_low

Dec_cnt1
Clrf tmr1h; clear timer1 registers
Clrf tmr1l
decfsz COUNT, f
Goto chck_low; not yet 5s, loop
Goto setet; power key pressed >5s

Turn_on
bsf PWRout; activate PWRout for 250ms
Call delay_t6;
bcf PWRout;
Goto boot_delay; and go to boot_delay

Reset bsf RESETout; activate RESETout for 250ms
Call delay_t6
Bcf RESETout

Boot_delay; variable delay from 0 to 127s while LED is flashing green
MOVfw PWR_ON_DELAY; and no command is accepted, delay derived from user preset (0..99)
btfsc Reboot_Flag; add additional time (defined in RebootDelay) if Reboot_Flag is set
addlw RebootDelay;
MOVwf COUNT
Bcf status, c
Rlf COUNT; multiply COUNT by two as the g_flash routine takes only 0.5s
Sublw d'0'; if COUNT = 0 stop immediately
Btfss status, z
Goto g_flash
bcf Reboot_Flag; clear Reboot_Flag
Goto main_loop

G_flash
LED_grn
Call delay_t6
LED_off
Call delay_t6

decfsz COUNT, f
Goto g_flash

Goto main_loop

Vdr_pwr_down
LED_red; turn LED red

MOVlw h'1f'; set RC5 address to h'1f' and command to h'3e' and send the code
MOVwf RC5_TX_2; This combination is not used by the remote control and will
MOVlw h'3e'; be sent to LIRC instead of the remote's normal power key code.
MOVwf RC5_TX_1; This way exactly *one* command can be sent instead of multiple
; (auto repeat of RC5 codes) -- VDR would start and immediately
; abort the shutdown if the power key is pressed a bit too long...
; A corresponding entry must be added to lircd.conf and the
; original power key code must be removed.
Call rc5_tx;
; Flash red LED while checking if a key on the remote control is
; pressed (which stops VDR from executing the shutdown script).
; If so, the program returns to the main loop and the LED
; turns green again. Otherwise, flash LED until ATX is in standby
; and finally turn LED red. Note: The remote's power key will be
; ignored (also to avoid problems with RC5/repeat and VDR).

MOVlw d'57'; set COUNT to d'57' for timeout counter
MOVwf COUNT; timeout is approx. 2 * 262ms * 57 = 30 seconds

R_flash
LED_red; turn on red LED
Call tim_sub; call timer subroutine and check if any remote key is pressed
LED_off; turn off LED
Call tim_sub; call timer subroutine and check if any remote key is pressed
decfsz COUNT, f
Goto r_flash; and loop
Goto main_loop; timeout after approx. 30 seconds (if shutdown fails)

Tim_sub;
Clrf tmr1h; clear timer1 registers
Clrf tmr1l;

Ir_chk
btfss IR_C_out; high level at IR?
Goto tim_chk; -no, check timer1
Call rc5_rx; -yes, call rc5_rx subroutine
btfsc RC5_Flag; RC5 code OK?
Goto tim_chk; -no, check timer1

MOVfw RC5_CMD; copy RC5_CMD to w and
Andlw b'01111111'; clear toggle bit
Bcf status, c; clear carry bit
subwf PWR_KEY_CMD, w; check if command is power key; this will be ignored
Btfss status, z;
Goto main_loop; key pressed, abort shutdown and go to main_loop

Tim_chk;
Btfsctmr1h,7; check timer1h register bit7 (set after 262ms)
Goto ir_chk; loop if not yet set

Atx_chk
btfsc ATX_C_out; wait until ATX is standby
Return; still on, continue flashing

Goto main_loop; now standby, go to main_loop

;************************************************* *************************************************
;Program mode
;************************************************* *************************************************

Pgm_mode
MOVlw d'4'
MOVwf COUNT

Rg_flash
LED_red; flash bicolor LED alternately green/red
Call delay_t6; (either for 250ms) 4 times to indicate
LED_grn; that the program mode has been entered
Call delay_t6
decfsz COUNT
Goto rg_flash
LED_off; now ready to learn codes (LED off)

Learn_1
Call ir_chk1; wait for high level at IR_C_out, timeout if idle for >5s
Call rc5_rx; call rc5_rx subroutine
btfsc RC5_Flag; RC5 code OK?
Goto learn_1; no, try again

MOVfw RC5_CMD; copy RC5_CMD to w and
Andlw b'01111111'; clear toggle bit
MOVwf TMP1; copy to TMP1 and TMP2
MOVwf TMP2;
Bsf status, c; check if command is 0...9
Sublw d'9'
Btfss status, c
Goto learn_1; no, try again

LED_grn; turn on green LED for 250ms if a
Call delay_t6; valid code has been received
LED_off

MOVfw RC5_CMD; copy RC5_CMD to temporary register
MOVwf RC5_CMD_TMP; for the next toggle bit comparison

Bcf status, c; multiply TMP1 by 10
rlf TMP1, f; for 10's of PWR_ON_DELAY
rlf TMP1, f
rlf TMP1, f
MOVfw TMP2
addwf TMP1, f
addwf TMP1, f

Learn_2
Call ir_chk1; wait for high level at IR_C_out, timeout if idle for >5s
Call rc5_rx; call rc5_rx subroutine
btfsc RC5_Flag; RC5 code OK?
Goto learn_2; no, try again

MOVfw RC5_CMD; check if toggle bit has changed
subwf RC5_CMD_TMP, w;
Btfsc status, z;
Goto learn_2; no, try again

MOVfw RC5_CMD; copy RC5_CMD to w and
Andlw b'01111111'; clear toggle bit
MOVwf TMP2; copy to TMP2
Bsf status, c; check if command is 0...9
Sublw d'9';
Btfss status, c;
Goto learn_2; no, try again

MOVfw TMP1; add 10's and 1's
addwf TMP2, w;

MOVwf EEDATA_TMP; copy to EEDATA_TMP

MOVlw h'00'; set EEADR_TMP to h'00'
MOVwf EEADR_TMP;
Call write_ee; and write to EEPROM

LED_grn; turn on green LED for 250ms if a
Call delay_t6; valid code has been received
LED_off

MOVfw RC5_CMD; copy RC5_CMD to temporary register
MOVwf RC5_CMD_TMP; for the next toggle bit comparison

Learn_3
Call ir_chk1; wait for high level at IR_C_out, timeout if idle for >5s
Call rc5_rx; call rc5_rx subroutine
btfsc RC5_Flag; RC5 code OK?
Goto learn_3; no, try again

MOVfw RC5_CMD; check if toggle bit has changed
subwf RC5_CMD_TMP, w;
Btfsc status, z;
Goto learn_3; no, try again

MOVfw RC5_CMD; copy RC5_CMD to w and
Andlw b'01111111'; clear toggle bit
Bcf status, c; check if command is 0...9
Sublw d'9'; which cannot be assigned
Btfsc status, c; as power key
Goto learn_3; yes, try again

MOVfw RC5_ADR
MOVwf EEDATA_TMP; copy to EEDATA_TMP
MOVlw h'01'; set EEADR_TMP to h'01'
MOVwf EEADR_TMP;
Call write_ee; and write to EEPROM

MOVfw RC5_CMD; copy RC5_CMD to w and
Andlw b'01111111'; clear toggle bit
MOVwf EEDATA_TMP; copy to EEDATA_TMP
MOVlw h'02'; set EEADR_TMP to h'02'
MOVwf EEADR_TMP;
Call write_ee; and write to EEPROM

Call copy_ee; copy new values to RAM

LED_grn; turn on green LED for 250ms to indicate
Call delay_t6; that a valid code has been received
LED_off

clrf KEYCOUNT_1; clear KEYCOUNT_1 to reset zero key detection delay
Goto main_loop

Ir_chk1; wait for high level at IR_C_out, timeout if idle for >5s
Clrf tmr1h; clear timer1 registers
Clrf tmr1l
MOVlw d'19'; set COUNT to d'19', this makes 19 x 262ms = approx. 5 seconds
MOVwf COUNT

Ir_chk2
btfsc IR_C_out; wait for high level at IR_C_out
Return; and return

Btfsctmr1h,7; check timer1h register bit7 (set after 262ms)
Goto dec_cnt
Goto ir_chk2

Dec_cnt
Clrf tmr1h; clear timer1 registers
Clrf tmr1l
decfsz COUNT, f
Goto ir_chk2; not yet 5s, loop
clrf KEYCOUNT_1; clear KEYCOUNT_1 to reset zero key detection delay
Goto main_loop; timeout after approx. 5s


;************************************************* *************************************************
;RC5 transmit subroutine
;************************************************* *************************************************

Rc5_tx; we have: RC5 address '000AAAAA' and command '0CCCCCCC'
bsf RC5_TX_2,7; set 1st start bit
btfss RC5_TX_1,6; check command bit #6 and
bsf RC5_TX_2,6; set 2nd start bit if necessary
Bcf status, c; clear carry bit
rlf RC5_TX_1; left shift RC5_TX_1 twice to bring command MSB to
Bcf status, c; left-most position
rlf RC5_TX_1; now the 16-bit shift register is ready for
; shifting out: RC5_TX_2 1S0 AAAA ARC5_TX_1 CCCCCC 00

bsf IRin; set port register bit IRin high before setting to output
Bank_1; to avoid a 1祍 spike
bcf IRinTris; set IRin as output
Bank_0;

Call delay_t6; 250ms delay for time coupling (LIRC might still be busy with
; processing IR codes from the receiver and would not react to the
; code generated below)

MOVlw d'14'; set BITCOUNT to 14
MOVwf BITCOUNT;

Bit_test
btfss RC5_TX_2,7; test all bits
Goto out_low_high; remember that we have to invert them

Out_high_low
bsf IRin; output a high-low sequence at IRin
Call delay_t5; either state is 889祍
bcf IRin;
Call delay_t5;
Goto next_bit; go to next_bit

Out_low_high
bcf IRin; output a low-high sequence at IRin
Call delay_t5; either state is 889祍
bsf IRin;
Call delay_t5;

Next_bit
rlf RC5_TX_1; left shift the 16-bit register
rlf RC5_TX_2;
decfsz BITCOUNT; until all 14 bits are out
Goto bit_test;

btfss IRin; if the last bit was a high-low sequence, immediately set IRin
bsf IRin; high to terminate the RC5 code after the correct time

Call delay_t6; 250ms delay for time coupling (IR codes from the receiver chip
; occurring only after the code generated above would destroy
; the integrity of this code)
Bank_1
bsf IRinTris; set IRin back to input
Bank_0

Return


;************************************************* *************************************************
;RC5 receive routine
;************************************************* *************************************************
;
; in: 14-bit data from IRin resp. DTRin
;
; out: RC5_ADR (8-bit, 000AAAAA)
; RC5_CMD (8-bit, TCCCCCCC)
; RC5_Flag (1-bit) 0: RC5 code valid, 1: RC5 code invalid
;
; Self-synchronizing code which tolerates inaccurate RC5 timings.
; Tolerance is achieved by polling +/- approx. 250祍 around each expected level change. To mark the
; received code as valid, the level before and after the edges must be opposite, not timer0 overflow
; (512祍) occurred, and two samples taken at 1200祍 and 1500祍 after each edge must be equal.

Rc5_rx
Clrf DATA_1; clear input shift register
Clrf DATA_2;
MOVlw d'13'; set BITCOUNT to 13
MOVwf BITCOUNT;

Test; 1祍 mark
Call delay_t1a; 1

LED Modules

What is the size of the LED display module?

The LED module is divided into two categories. The indoor led module is generally called table stickers (three -in -one table stickers); outdoor and semi -outdoor are generally called modules. The characteristics of indoor table stickers: high image clarity, color and richness, not enough for high prices; outdoor and semi -outdoor module unit board features: high brightness, waterproof, rich color.



We can choose according to several important parts of the module?
1. Select according to the lamp bead of the module
The quality of LED lamp beads determines the color saturation and clarity of the performance of the entire LED display display. Therefore, the LED module's lamp beads are particularly important at the raw material selection and packaging process. It directly determines the quality and performance of the LED display module product product quality and performance.
2. Select according to the PCB board of the module
PCB boards with stable performance LED display modules are generally composed of substrates and metal coatings. Because there are many links in the quality of PC boards in the external environmental impact module during the application process
3. Select according to the suite of the module
The LED unit board module kit is one of the main causes of the display effect, and is the key element of the entire unit board and the entire stitching screen. The LED unit board kit must be able to prevent moisture, waterproof, and ultraviolet protection, and the quality of the kit will affect the flatness, contrast and service life of the display.


led display module .smd led modules.led screen module

Shenzhen Priva Tech Co., Ltd. , https://www.privaled.com

Posted on