Menu

Problems with TMR0

Help
2011-07-31
2013-05-30
  • alejandro1957

    alejandro1957 - 2011-07-31

    #CHIP 16F877A,4
    #CONFIG OSC=XT,WDT_OFF,PWRTE_ON,CP_OFF,DEBUG_OFF,WRT_OFF,CPD_OFF,LVP_OFF,BODEN_ON    

    On Interrupt Timer0Overflow Call TMR0_Interrupt

    DIM Contador AS INTEGER

    SUB TMR0_Interrupt()#NR
    IF INTCON.TMR0IF=1 THEN                                '
       IF Contador>=100 THEN                               '
          PulseOut PORTB.7,2 s                             '
          Contador=0                                       '
       END IF                                              '
       Contador+=1                                         '
       TMR0=b'01100110'                                    '
       INTCON.TMR0IF=0                                     '
    END IF                                                 '
    END SUB

    Main:

       TRISA=b'000000'                                                 '
       TRISB=b'00000000'                                               '
       TRISC=b'00011000'                                               '
       TRISD=b'00000000'                                               '
       TRISE=b'000'                                                    '
       PORTA=b'000000'                                                 '
       PORTB=b'00000000'                                               '
       PORTC=b'00000000'                                               '
       PORTD=b'00000000'                                               '
       PORTE=b'000'                                                    '
       INTCON=b'10100000'                                              '
       CCP1CON=b'00000000'                                             '
       CCP2CON=b'00000000'                                             '
       ADCON0=b'00000000'                                              '
       ADCON1=b'00000110'                                              '  
       InitTimer0 Osc,PS0_128                                          '
       TMR0=b'01100110'                                                '
       Contador=0                                                      '
       DO                                                              '
         ''                                             '
       LOOP                                                            '

    works very well
    but to apply it to handle 4 servomotor does not work.

    '
    '
    '
    SUB TMR0_Interrupt()#NR
    IF INTCON.TMR0IF=1 THEN                                'TMR0 overflow subroutine
       IF Contador>=100 THEN                               'Si el contador llega a 100 pasaron 2 segundos
          PulseOut PORTB.7,Valor 10us                             '
          PulseOut PORTB.6,Valor 10us                             '
          PulseOut PORTB.5,Valor 10us                              '
          PulseOut PORTB.4,Valor 10us                            '
          Contador=0                                       '
       END IF                                              '
       Contador+=1                                         '
       TMR0=b'01100110'                                    'Preload=102(con correcciòn).Es igual a 01100110 en binario
       INTCON.TMR0IF=0                                     'Limpia el flag del interrupt
    END IF                                                 '
    END SUB
    '
    '
    '
    Main:
             FOR Ciclo=100 TO 200
                      Valor=Ciclo
             Next Ciclo

     
  • alejandro1957

    alejandro1957 - 2011-07-31

    '
    '
    '
    '
    SUB TMR0_Interrupt()#NR
    IF INTCON.TMR0IF=1 THEN                              
       PulseOut PORTB.7,Valor 10us 
       PulseOut PORTB.6,Valor 10us
       PulseOut PORTB.5,Valor 10us
       PulseOut PORTB.4,Valor 10us                                                                    
       TMR0=b'01100110'                                
       INTCON.TMR0IF=0                                
    END IF                                                
    END SUB
    '
    '
    '
    '

    sorry, I made a mistake and copy / paste.this is the sub of the TMR0 interrupt

     
  • kent_twt4

    kent_twt4 - 2011-07-31

    Have you tried disabling interrupts when entering the TMR0_Interrupt sub, If Contador = 100 statement Then: (i.e. TMROIE = 0), then re-enabling them on exit (i.e. TMROIE = 1) ???

    If you wanted to further refine the code, a single refresh period (interrupt) for the servos could be accomplished by setting up a "On Interrupt CCP1 Call  XXXXXX".   Takes more work with the data sheet and the registers, mostly setting CCP1CON in the compare mode, loading CCPR1H and CCPR1L, then turning on TMR1.  Using the CCPx compare in the special event mode, TMR1 resets to zero on CCP1 interrupt, so this becomes a set once and forget operation.

     
  • Nobody/Anonymous

    works very well

    SUB TMR0_Interrupt()#NR
    IF INTCON.TMR0IF=1 THEN
       PulseOut PORTB.7,Valor 10us
       PulseOut PORTB.6,Valor 10us
       PulseOut PORTB.5,Valor 10us
       PulseOut PORTB.4,Valor 10us
       TMR0=b'01100110'
       INTCON.TMR0IF=0
    END IF
    END SUB

    not work

    SUB TMR0_Interrupt()#NR
    IF INTCON.TMR0IF=1 THEN
       PulseOut PORTB.7,Valor 10us
       PulseOut PORTB.6,Valor 10us
       PulseOut PORTB.5,Valor 10us
       PulseOut PORTB.4,Valor 10us
       TMR0=b'01100110'
       INTCON.TMR0IF=0
    END IF
    END SUB

    I'm definitely hurt the interrupt handling.
    you have a code to handle with the servo through the TMR0??

    sorry for my bad English

     
  • Nobody/Anonymous

    sorry for the disaster that I'm doing, but this is the sub that works well with a LED

    SUB TMR0_Interrupt()#NR
    IF INTCON.TMR0IF=1 THEN
        IF Contador>=100 THEN
            PulseOut PORTB.7,2 s
            Contador=0
        END IF
        Contador+=1
        TMR0=b'01100110'
         INTCON.TMR0IF=0
    END IF
    END SUB

     
  • kent_twt4

    kent_twt4 - 2011-07-31

    Are you using TMR1 or CCPx for something else?  I like the set and forget aspect of the CCPx compare module.  My servos are buried in other projects right now so haven't tested the code with a servo:

    'Test for updating four servos at 50Hz in a consecutive manner. 
    #chip 16f877A,20
    #config     _CP_OFF & CPD_OFF  &_WDT_OFF & _BODEN_OFF & _PWRTE_ON  & _HS_OSC  & _LVP_OFF  
    #define servo1 PortB.0
    #define servo2 PortB.1
    #define servo3 PortB.2
    #define servo4 PortB.3
    #define led1 PortB.4        'Verify update frequency
    #define led2 PortB.5
    #define forward 200
    #define neutral 150
    #define reverse 100
    Dir PortB out
    CCP1CON = b'00001011'   'Compare in special event mode
    T1CON = b'00111001'     'Need 1:8 prescale for 20Mhz clock, enable oscillator, start timer
    CCP1RH = 0xC3       '50Hz update, 20Mhz clock, TMR1 1:8 prescale
    CCP1RL = 0x50
    On Interrupt CCP1 Call Servo_Update
    count = 0
    Main:
    PulseOut led2, 1 s
    wait 1 s
    goto Main
    sub Servo_Update
    count += 1
    Set led1 On     'Check for correct update frequency
    If count < 127 Then
        PulseOut servo1, forward 10us  
        PulseOut servo2, neutral 10us
        PulseOut servo3, reverse 10us
        PulseOut servo4, forward 10us
    Else
        PulseOut servo1, reverse 10us
        PulseOut servo2, forward 10us
        PulseOut servo3, forward 10us
        PulseOut servo4, reverse 10us
    End If
    Set led1 Off
    end sub
    
     
  • kent_twt4

    kent_twt4 - 2011-08-01

    Well I made a mess of it with the previous program.  I must be dyslexic ;) wrote CCP1R and CCP1RL, should have been CCPR1H and CCPR1L.  Also forgot the clock is FOSC/4, so the  TMR1prescale shoulld have been 1:2 

    Found a servo and it works:

    'Test for updating four servos at 50Hz in a consecutive manner.
    'Adjust servo boundaries as required.
    #chip 16f877A,20
    #config     _WDT_OFF & _BODEN_OFF & _PWRTE_ON  & _HS_OSC  & _LVP_OFF  
    #define servo1 PortB.0
    #define servo2 PortB.1
    #define servo3 PortB.2
    #define servo4 PortB.3
    #define led1 PortB.4    'Verify update frequency
    #define led2 PortA.0    'Blinky heartbeat
    #define forward 200
    #define neutral 150
    #define reverse 100
    Dir PortB out
    Dir led2 out
    T1CON = b'00011001' 'Need 1:2 prescale for 20Mhz clock, enable osc, start timer
    CCP1CON = b'00111011'   'Compare in special event mode
    'Servo_Period = 50000   Prescale/(FOSC/4) x Servo_Period = 0.02 sec (50Hz)
    CCPR1H = 0xC3
    CCPR1L = 0x50
    On Interrupt CCP1 Call Servo_Update
    count = 0
    Main:
    PulseOut led2, 1 s
    wait 1 s
    goto Main
    sub Servo_Update
    count += 1
    Set led1 On     'Check for correct update frequency
    Set led1 Off
    If count < 127 Then
        PulseOut servo1, forward 10us  
        PulseOut servo2, neutral 10us
        PulseOut servo3, reverse 10us
        PulseOut servo4, forward 10us
    Else
        PulseOut servo1, reverse 10us
        PulseOut servo2, forward 10us
        PulseOut servo3, forward 10us
        PulseOut servo4, reverse 10us
    End If
    end sub
    
     
  • alejandro1957

    alejandro1957 - 2011-08-01

    apply it immediately.
    But the pic has a quartz 4Mhz.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.