micro timer help plz ASAP :( im having it after 2 few days :(

Thread Starter

goldfish300

Joined Mar 12, 2009
12
well first of all im working on a pic 16f84a

we need to connect the circuit to an oscilloscope and to fit these conditions :

if signal on portA,0 < 10 hz ------> motor stop

else
if 10 hz < signal < 100 hz -----> motor left
else
if signal > 100 ------>motor right

plz if anyone knows how to write such a program help

i wrote something about interupt at RB0
in which its as follow:
at startup led PORTA, 0 is on for one second then im having two leds instead of motor which turn on after the delay of the first leds and just keep blinking like left >right and right > left until i press on the button and it just turn the right led for one second and then stop for one sec then cont to the left >right and right > left until i press on the button. im askin how to fix that for the timer0 with the conditions i need above

i don't know how to link this with an oscilloscope and writing the timer function.

well i the code is as follows


Rich (BB code):
#INCLUDE <P16F84.INC>
	 #DEFINE		LED				PORTA, 0
	 #DEFINE		RELAY1			PORTB, 1
	 #DEFINE		RELAY2			PORTB, 2
	 #DEFINE		PB				PORTB, 0

     __CONFIG _WDT_OFF  &  _PWRTE_OFF  &  _CP_OFF  &  _XT_OSC 



      CBLOCK  0X0C
         W_TEMP, STATUS_TEMP, A1, A2, A3, B1, B2, B3


     ENDC




     ORG     0X000
     GOTO    MAIN
     ORG     0X004
     MOVWF   W_TEMP 
     SWAPF   STATUS,W
     MOVWF   STATUS_TEMP


     BTFSC   INTCON,INTE 
     BTFSS   INTCON,INTF
     GOTO    $+4  
     CALL    INTRB0 
     BCF     INTCON,INTF
     GOTO    RESTOREREG

RESTOREREG
     SWAPF   STATUS_TEMP,W 
     MOVWF   STATUS  
     SWAPF   W_TEMP,F  
     SWAPF   W_TEMP,W   
     RETFIE  


INTRB0 
	CALL	MOTOR_RIGHT
	CALL	DELAY_1S_B
	CALL	MOTOR_STOP
	CALL	DELAY_1S_B
    RETURN

MAIN
        CALL    SETUP
	BSF	 	LED
	CALL	DELAY_1S_A
	BCF		LED
	CALL	MOTOR_RIGHT	
	CALL	DELAY_1S_A
	CALL	MOTOR_LEFT
	CALL	DELAY_1S_A
	GOTO	$-4

MOTOR_RIGHT
			BCF		RELAY1
			BSF		RELAY2
			RETURN

MOTOR_LEFT
			BSF		RELAY1
			BCF		RELAY2
			RETURN

MOTOR_STOP
			BSF		RELAY1
			BSF		RELAY2
			RETURN

DELAY_1S_A
    MOVLW    D'46'
    MOVWF    A3
    MOVLW    D'189'
    MOVWF    A2
    MOVLW    D'37'
    MOVWF    A1
    DECFSZ   A1, F
    GOTO     $-1
    DECFSZ   A2, F
    GOTO     $-5
    DECFSZ   A3, F
    GOTO     $-9
    RETURN

DELAY_1S_B
    MOVLW    D'46'
    MOVWF    B3
    MOVLW    D'189'
    MOVWF    B2
    MOVLW    D'37'
    MOVWF    B1
    DECFSZ   B1, F
    GOTO     $-1
    DECFSZ   B2, F
    GOTO     $-5
    DECFSZ   B3, F
    GOTO     $-9
    RETURN


SETUP
     CLRF    PORTA
     CLRF    PORTB
     BSF     STATUS, RP0
     MOVLW   B'00000000'
     MOVWF   TRISA
     MOVLW   B'00000001'
     MOVWF   TRISB
     MOVLW   B'11000000'
     MOVWF   OPTION_REG
     MOVLW   B'10010000'
     MOVWF   INTCON
     BCF     STATUS, RP0
     RETURN


     END
 
Last edited:

thatoneguy

Joined Feb 19, 2009
6,359
Unable to set up a capture interrupt on port RA0, polling will have to do. Most PICs made before about 2004 didn't have Interrupts anyway...

Set up Timer0 to timeout around 9mS (110Hz). Or 200-ish Hz to get two samples for reliability (suggested). You will need to use your clock frequency and set prescaler to the right value, 9mS for single pulse is a guess, and since not all prescaler values fit nicely, different math is involved.

The most important part is to keep the Interrupt Routine as short as possible, only set flags that the main loop processes. Actually, at the speeds you are dealing with, it's not that important, but it's best to not miss a pulse if one can help it...

Rich (BB code):
unsigned integer count
char dir (use defines for stop, left, right)

Interrupt()
{
If Timer Interrupt{
Save anything that will be changed
test for count < 1 (below 10Hz) dir = stop
Test for count > 12 (over 100Hz) dir = right
else dir = left
count = 0
Reset Timer0
Clear interrupt flag
cleanup
}

main(void)
{
porta = 0 ; don't want to accidentally send a signal out;
trisa=0x1 ; Set Porta.0 for input

for(; ;) Loop Forever
if (porta.0 = 1)
   {
      while(porta.0 == 1); // Wait for end of pulse
     count++; // count pulse
    }

//dir is set in ISR above

if (dir == stop) stop_motor();;
if (dir == left) run_left();
if (dir == right) run_right();
} // End main

motor direction functions here...
 

Thread Starter

goldfish300

Joined Mar 12, 2009
12
10x u very much for that but is diff than writing it in a lang diff then c i mean the assembly code . could u plz translate that to an assembly code if possible or other wise give me the hint for every part . 10x
 

thatoneguy

Joined Feb 19, 2009
6,359
The code at the bottom is for mid range devices in general. Please post questions here rather than PM, and any code you have, so others can both help, and learn from it.
 

thatoneguy

Joined Feb 19, 2009
6,359
The two links go to the same site, I guess I don't understand the question?

That site covers interrupts, not counting. The counting in the pseudo-code above would be the same, and the interrupt would be the same, although all in assembly langauge.
 
Top