Re: IR light dimmer
Here is the code.
#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <stdio.h>
#include "rc5decode.h"
#byte Portb = 0x06
#byte TMR = 0x01
#byte Portb = 0x06
#define IR_IN portb,4//0
int save_w;
#locate save_w=0x7f
int save_status;
#locate save_status=0x20
#byte status = 3
/*--- globals ---*/
int command;
//unsigned char command;
unsigned char address;
unsigned char temp;
unsigned char timer;
unsigned char rc5valid;
int tipka=32;
int com;
int i=0,j=0,a=0,b=0,io=0;
int x=0,t3,t2;
int tomi=0;
unsigned int vred=0;
void pavza()
{
#asm
MOVLW 33
MOVWF T3
MOVF vred,W
MOVWF T2
PAV1:
DECFSZ T3,F
GOTO PAV1
MOVLW 33
MOVWF T3
DECFSZ T2,F
GOTO PAV1
#endasm
}
//#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
//static bit IR_PIN @ PORTBIT(GPIO, 2);
/*--- rc5 decode function ---*/
//static void interrupt //
unsigned char rc5decode(void)
{
#asm
MOVWF save_w
SWAPF status,W
BCF status,5
BCF status,6
MOVWF save_status
;------ calibrate timing
bcf 3,5 ;select bank 0
clrf TMR ;start timer
call Wlow ;get the pulse length
call Whigh
btfsc TMR,7 ;test for timer overflow
goto codeError ;bail out
movf TMR,w ;save pulse length
clrf TMR ;start timer
movwf timer ;take the pulse length,
movwf temp ;save it
bcf 3,0 ;clear carry
rrf temp,f ;divide by 2
bcf 3,0 ;clear carry
rrf temp,f ;divide by 4
movf temp,w ;and subtract to get
subwf timer,f ;3/4 pulse length
movlw 0x0c
movwf temp ;init bit counter
;------ wait for start of data
nextBit: movf timer,w ;wait 3/4 pulse length
subwf TMR,w
btfss 3,2 ;take a look
goto nextBit
;------ start of data stream
btfss IR_IN ;if its high
goto waitlow ;gonna be an 0
;------ wait for high 1
call Whigh ;if its low
bsf 3,0 ;gonna be a 1
goto clock
;------ wait for low 0
waitlow: call Wlow
bcf 3,0 ;gonna be an 0
;------ clock data
clock: clrf TMR ;restart timer
rlf command,f ;save the bit
rlf address,f
decfsz temp,f ;done all bits?
goto nextBit
;------ get system address, toggle bit and command code
movf command,w ;copy low byte
movwf temp ;into temp
rlf temp,f ;need to shift 2 bits
rlf address,f ;into address
rlf temp,f
rlf address,f ;system address is 5 bits
movlw 0x3f ;mask system address + toggle bit
andwf address,f
movlw 0x3f ;mask command code
andwf command,f ;command code is 6 bits
goto rc5ok ;done ok
;------ wait while low
Wlow: btfsc TMR,7 ;test for timer overflow
return ;bail out
btfss IR_IN
goto Wlow
return
;------ wait while high
Whigh: btfsc TMR,7 ;test for timer overflow
return ;bail out
btfsc IR_IN
goto Whigh
return
rc5ok: movlw 0x01
movwf rc5valid
goto rc5end
codeError: clrf rc5valid
rc5end: nop
SWAPF save_status,W
MOVWF status
SWAPF save_w,F
SWAPF save_w,W
#endasm
return rc5valid;
}
#int_ext
isr(){
if(vred==0)goto ss;
output_low(pin_a1);
if(vred==180)goto ns;
pavza();
ss:
output_high(pin_a1);
ns:
x=1;
}
#int_rb
isr_i(void)
{
if(rc5decode())
{
address &= 0x1F;
if(command==32) a=1;
if(command==33) b=1;
rc5valid=0;
}
}
void main(void)
{
set_tris_b(0xff);
ext_int_edge( h_to_l );
setup_timer_0 (RTCC_DIV_128|RTCC_internal);
port_b_pullups(true);
enable_interrupts(global);
enable_interrupts(int_ext);
enable_interrupts(int_rb);
a=0;
i=0;
j=0;
x=0;
io=0;
vred=180;
do
{
if(a==1)
{
a=0;
delay_ms(200);
if((a==0)&&(vred==180)) {vred=0; a=0; goto nap;}
po: if((a==1)) {vred=vred-10; a=0; if(vred==-10)vred=0;}
delay_ms(100);
if(a==1) goto po;
nap: delay_us(1);
}
if(b==1)
{
b=0;
delay_ms(200);
if((b==0)) {vred=180; b=0; goto nap1;}
po1: if((b==1)) {vred=vred+10; b=0; if(vred==190) vred=180; }
delay_ms(100);
if(b==1) goto po1;
nap1: j=1;
}
}while(1);
}
/*--- End of File ---*/