I'm trying to make a IR-beam barrier using tiny15 and normal ir-receiver.
The code I have uses timer 1 PWM for the 38kHz ir pulse. Also it's switched on and off every 500 us. The ir-receiver is connected to ext int 0 pin and set for falling edge. When interrupted timer 0 is started and interrupt set to rising edge. When interrupted again timer 0 is stopped and it's value read and compared to a constant. If it's lower, PB3 will be cleared and PB4 set and if higher vice versa.
On paper it works and simulates (perhaps a bug in avr studio 4, timer 1 overflow int isn't cleared, makes a bit hard to simulate properly), but IRL something is wrong. PB4 will be cleared even if no signal is given, which shouldn't happen.
As this is my first project i've written in assembly I'm desperately in need of help.
Here's my code:
.include "tn15def.inc" .def TEMP = R16 .def LED = R17 .def ON = R18 .def TIMES = R19 .def EDGE = R20 .equ MIN_TIMES = 48 .equ MIN_DUTY = 0x55 .org 0x0000 rjmp RESET .org 0x0001 rjmp EXT_INT0 .org 0x0004 rjmp TIM1_OVF EXT_INT0: tst EDGE ;Test for rising EDGE brne H_EDGE ;and jump ldi TEMP, 0x02 ;Start Timer 0 out TCCR0, TEMP ldi TEMP, 0x03 ;Set for INT0 for rising EDGE out MCUCR, TEMP ser EDGE ;Set EDGE 1 reti H_EDGE: clr TEMP ;Stop Timer 0 out TCCR0, TEMP clr EDGE ;Clear EDGE ldi TEMP, 0x02 ;Set INT0 for falling EDGE out MCUCR, TEMP in TEMP, TCNT0 ;Read Timer 0 value to TEMP subi TEMP, MIN_DUTY ;Subtract MIN_DUTY from TEMP brlo LOWER ;If TEMP is lower than MIN_DUTY, jump clr TEMP ;Clear TCNT0 out TCNT0, TEMP cbi PORTB, 4 ;PB4 On sbi PORTB, 3 ;PB3 Off reti LOWER: clr TEMP ;Clear TCNT0 out TCNT0, TEMP cbi PORTB, 3 ;PB3 On sbi PORTB, 4 ;PB4 Off reti TIM1_OVF: inc TIMES cpi TIMES, MIN_TIMES breq TOGGLE reti TOGGLE: tst ON ;Test if ON breq OFF ;If not, jump ldi TEMP, 0x45 ;TIMER1 PWM, CK, OC1A discONnected out TCCR1, TEMP clr ON ;Off sbi PORTB, 1 clr TIMES reti OFF: ldi TEMP, 0x75 out TCCR1, TEMP ser ON ;On clr TIMES reti RESET: ;Reset Label ldi TEMP, 0xDB out DDRB, TEMP ldi TEMP, 0xDF out PORTB, TEMP ldi TEMP, 0x75 ;TIMER1 PWM, CK, Inverted PWM out TCCR1, TEMP ldi TEMP, 0x15 ;50% Duty cycle out OCR1A, TEMP ldi TEMP, 0x2A ;38kHz out OCR1B, TEMP ldi TEMP, 0x60 ;INT0 enable out GIMSK, TEMP ldi TEMP, 0x02 ;INT0 interrupt ON falling EDGE out MCUCR, TEMP ldi TEMP, 0x04 ;Timer 1 overflow interrupt out TIMSK, TEMP ser ON sei MAIN: rjmp MAIN