Hi Glen, Seeing the full code clarifies a few things, that were confusing before. I walked through the code and inserted alternative bits and pieces, there a number of potential gotcha's.. >HERE'S THE FULL CODE > >> ;*********************************************************** >> ; vars >> PORTA equ 0x05 ;CPU equates (program memory map) >> PORTB equ 0x06 ;CPU equates (program memory map) >> souter equ 0x0c ; >> sinner equ 0x0d ; >> inners equ 0x0e ; >> outers equ 0x0f ; >> innerf equ 0x10 ; >> outerf equ 0x11 ; >> chksw equ 0x12 ; >> strttmr equ 0x13 ; no of counts >> STATUS equ 0x03 ; CPU equates (program memory map) >> w equ 0 ; destination designators >> f equ 1 ; destination designators >> ;*********************************************************** >> ; PORTA set-up >> org 0x000 ;address 000 program start I would insert the following here as a matter of course... GOTO start org 0x04 GOTO start org 0x10 >> start movlw 0xff ;ff hex moved to w register >> tris PORTA ;porta set as inputs >> ;*********************************************************** >> ; PORTB set-up >> movlw 0x0f ;00001111 >> tris PORTB ;PORTB >> ;*********************************************************** >> clrf STATUS At this point I would also add initialization of PCLATH CLRF PCLATH This may be part of your problem since when a computed goto is used like "ADDWF PCL" the top few bits of the calculated address come from PCLATH.. could be worth checking further.. >> ;============= prescaler setup ===pullups enabled=========== >> >> movlw b'00000111' ;scale 1:256 , pullups enabled >> OPTION I would have just done... MOVWF OPTION_REG >> ; ============= counter setup ============== > >> ===================for a single timer value================== > >> movlf d'25' :counter value >> movwf strttmr > >> ======================================= > >> ;code below is used for 2 switches >> ; init strttmr from input pins >> >> movf PORTB,w ;get values of RB0 & RB1 >> andlw 0x03 ; extract bits 0,1 PORTB (strttmr sw value) >> movwf chksw ;put rb0 & rb1 values in register chksw You could insert a hardware test here to confirm the actual values being read by on RB0,RB1 copy the bits actually read to the LEDS on RB4 and RB5 BCF PORTB,4 ; default to off BCF PORTB,5 BTFSC chksw,0 ; copy 0 to RB4 BSF PORTB,4 BTFSC chksw,1 ; copy 1 to RB5 BSF PORTB,5 hang goto hang Obviously, once you get this part correctly reading the switches you can delete the test code. >> >> >> caltab CALL table ; use look up table >> movwf strttmr ;move selected value from table to strttmr >> xorwf chksw ;compare strttmr with chksw value >> btfsc STATUS,Z ;if yes,skip next instruction >> GOTO caltab >> Rewriting this, I would prefer something simpler like... CALL table movwf strttmr Repeatedly looping around ain't going to change the lookup table! >> ;********************************************************************** >> ; ============== program start ============= >> >> movlw 0x00 ;move 00 hex to register w >> movwf PORTB ;move reg w to PORTB (clear PORTB) >> >> ;============= prescaler setup ===pullups disabled=========== >> >> movlw b'10000111' ;scale 1:256 , pullups disabled >> OPTION >> ; ============= initialise timer setup ============== >> >> initmr movlw .215 ;40 * .000256 = 10 ms >> movwf TMR0 >> >> loop CALL chcycs ;check for zero crossing >> CALL sttimer >> CALL tog >> >> ; ============= check timer ============== >> >> movf TMR0,w ;move f reg to w >> btfsc STATUS,Z ;if !0 ,GOTO loop >> GOTO loop >> decfsz strttmr,f ;decrement strttmr by 1 >> GOTO initmr ;go around for next delay >> This is a very unreliable way of checking TMR0 overflow, why not something like.. BTFSS INTCON,T0IF GOTO loop DECFSZ strttmr,f GOTO inittmr >> ;drop thru to stop >> >> stop GOTO stop >> ;======================================================================= >> ; delay sub-routine >> >> table Insert the following belts and braces code.... ANDLW 0x03 CLRF PCLATH ; just being paranoid! Be carefull if this code is assembled in some page other than page 0 There a better ways of doing tables that take care of paging problems addwf PCL >> retlw d'25' ; 00 : 250ms (switch position 1) >> retlw d'50' ; 01 : 500ms (switch position 2) >> retlw d'75' ; 10 : 750ms (switch position 3) >> retlw d'100' ; 11 : 1000ms (switch position 4) >> >> ; ================= >> ;============= check start cycle / check finish cycle ============= >> >> chcycs btfsc PORTB,3 ;check AC input at port b pin 2 for 0 >> GOTO chcycs ;check again if still high >> lw btfss PORTB,3 ;check AC input at port b pin 2 for 1 >> GOTO lw ;check again if still low >> RETURN ;found zero crossing - rising edge >> I assume the hardware interface to the AC input works, if it doesn't then the above code will of course hang! A more robust version would perhaps measure the time between successive zero crossings and do something sensible if it waited too long? Kind of depends on the exact application. >> ;********************* delay sub-routines ******************************* >> ; >> ; ============== start timer ============= >> >> sttimer movlw 0x10 ;move 00 hex to register w >> movwf souter ;move register w to "outer" >> sout movlw 0x10 ;move 00 hex to register w >> movwf sinner ;move register w to "inner" >> sinn decfsz sinner,f ;decrement "inner" each scan, scan for 0 >> GOTO sinn ;loop "inner" until it = 0 >> decfsz souter,f ;decrement "outer" each scan, scan for 0 >> GOTO sout ;loop "outer" until it = 0 >> RETURN >> For readability and generality why not make it a 16 bit countdown rather than inner/outer loop presets. >> ; ==============toggle outputs ============= >> >> tog bsf PORTB,4 ;set PORTB bit 4 high } >> bsf PORTB,5 ;set PORTB bit 5 high } >> CALL togs ;CALLs toggle sub-routine } Toggle 4/5 >> bcf PORTB,4 ;set PORTB bit 4 low } >> bcf PORTB,5 ;set PORTB bit 5 low } >> CALL togf ;CALL the delay sub-routine >> btfsc PORTB,3 ;skip next if 0 >> GOTO tog >> RETURN >> >> ; ============== ontime delay ============= >> >> togs movlw 0x2 ;move 00 hex to register w >> movwf outers ;move register w to "outer" >> outs movlw 0x2 ;move 00 hex to register w >> movwf inners ;move register w to "inner" >> inns decfsz inners,f ;decrement "inner" each scan, scan for 0 >> GOTO inns ;loop "inner" until it = 0 >> decfsz outers,f ;decrement "outer" each scan, scan for 0 >> GOTO outs ;loop "outer" until it = 0 >> RETURN >> >> ; ============== offtime delay ============= >> >> togf movlw 0x1 ;move 00 hex to register w >> movwf outerf ;move register w to "outer" >> outf movlw 0x1 ;move 00 hex to register w >> movwf innerf ;move register w to "inner" >> innf decfsz innerf,f ;decrement "inner" each scan, scan for 0 >> GOTO innf ;loop "inner" until it = 0 >> decfsz outerf,f ;decrement "outer" each scan, scan for 0 >> GOTO outf ;loop "outer" until it = 0 >> RETURN >> ;********************************************************************** >> END ; directive 'end of program' >> It would be a bit nicer to make use of a generic TMR0 delay, but no reason why that code shouldn't work.. Ray Gardiner ray@hdc.com.au