I have a signal fluctuate from 1.89V to 2.10V, i.e. the signal have 200mV fluctuation. I want to use it to control a relay. When the signal change from 2.1V to 1.89V, set the relay. When the signal change from 1.89V to 2.10V, reset the relay. I use PIC16c73b's RA0 as A/D channel to sample the signal, and RA3 as the reference Vref(3V), and RB7 as the output to control the relay. The question is that: When I debug the system step by step it works just as I expected, but when I run it all the way it does not work, i.e. when I change the signal, the relay does not work. The program is revised from the example program of INTAD.ASM. The possible reason is that the change of the signal is lost. I don't know when and why it is lost. (I'd say that I am new to PIC) LIST P=16C73b ; ERRORLEVEL -302 ; include "P16c73b.inc" ; flag equ 20 TEMP equ 21 adover equ 0 oldad equ 22 tmp equ 23 first equ 24 PORTB_TMP equ 25 status_tmp equ 26 #define differ 0x05 ;adif equ 1 ;adgo equ 2 ;adie equ 6 ;gie equ 7 ;rp0 equ 5 ; ORG 0x00 ; ; goto start ; org 0x04 goto service_ad ;interrupt vector ; ; org 0x10 start movlw 0x00 ;init i/o ports clrf PORTB BSF STATUS, RP0 ;Bank1 MOVWF TRISB ;PortB as outputs BCF STATUS, RP0 ;Bank0 clrf oldad clrf tmp movlw 0x01 movwf first movlw 0x00 movwf PORTB_TMP ; call InitializeAD ; update bcf flag,adover ;reset software a/d flag call SetupDelay ;setup delay >= 10uS. movf adres, W movwf oldad bcf PIR1,adif ;reset a/d int flag (ADIF) bsf INTCON, peie ;Enable peripheral interrupts bsf INTCON,gie ;enable global interrupt bsf ADCON0,go ;start new a/d conversion loop btfsc flag,adover ;a/d over? goto update ;yes goto loop ;no then keep checking ; service_ad btfss PIR1,adif ;ad interrupt? retfie ;no then ignore bsf flag,adover ;a/d done set movf ADRES,W ;get a/d value ; subwf oldad, W ;(oldad)-(adres) movwf tmp movf status, W movwf status_tmp btfsc first, 0 ;the first time? goto TheFirst goto FirstOut TheFirst decf first, F bcf PORTB, 7 bcf PORTB_TMP, 0 goto out ;omit the first time FirstOut btfss status_tmp, 0 goto negative ;adres>oldad ; movf tmp, W ;adres<=oldad sublw differ ;differ-((oldad)-(adres)) btfsc STATUS, 0 goto nochange ;no change bsf PORTB, 7 ;change bsf PORTB_TMP, 0 goto out ;start new conv. nochange btfsc PORTB_TMP, 0 goto one bcf PORTB, 7 bcf PORTB_TMP, 0 goto out one bsf PORTB, 7 bsf PORTB_TMP, 0 goto out negative comf tmp, W addlw 0x01 ;|(oldad)-(adres)| sublw differ ;differ-|(oldad)-(adres)| btfsc STATUS, 0 goto nochange ;no change bcf PORTB, 7 ;change bcf PORTB_TMP, 0 out return ;do not enable int ; ; ;InitializeAD, initializes and sets up the A/D hardware. ;select ch0 to ch3, RC OSC., a/d interrupt. ; InitializeAD clrf INTCON ;clear all interrupts bsf STATUS,rp0 ;select Bank1 movlw 0x01 ;select ch0-ch3 as analog inputs... movwf ADCON1 ;and RA3 as Vref bsf PIE1, adie ;Enable A/D interrupts bcf STATUS,rp0 ;select Bank0 movlw 0xc1 ;RC clock, turn on a/d, ... movwf ADCON0 ;Channel 0 is selected return ; ;This routine is a software delay of 10uS for the a/d setup. ;At 4Mhz clock, the loop takes 3uS, so initialize TEMp with ;a value of 3 to give 9uS, plus the move etc should result in ;a total time of > 10uS. SetupDelay movlw 0x03 movwf TEMP SD decfsz TEMP, F goto SD return ; ; END -- _______________________________________________ Talk More, Pay Less with Net2Phone Direct(R), up to 1500 minutes free! http://www.net2phone.com/cgi-bin/link.cgi?143 -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics