How to set TMRO & TMR3 as Counter?.


Closed Thread
Results 1 to 22 of 22
  1. #1
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40

    Default How to set TMRO & TMR3 as Counter?.

    Hi all,

    I am a bit confused on how to set TMR0 and TMR3 as a Counter in PIC18F4550?.I plan to use these 2 Counter as a pulse counter from my robots encoder.Thanks for your guidance guys.I am kinda new in this.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    Hi,
    TMR3 seems to share it's clock pin with TMR1 and I haven't really looked into what effects that has but here's what I'd try:
    Code:
    TRISA.4 = 1		'TMR0 CKI Pin as input
    TRISC.0 = 1		'TMR3 (and TMR1) CKI Pin as input
    
    'From Datasheet Section 11
    T0CON.7 = 1		'TMR0 is ON
    T0CON.6 = 0		'TMR0 is 16 bits
    T0CON.5 = 1		'TMR0 clock source is EXTERNAL...
    T0CON.4 = 0		'...and counts on rising edge
    T0CON.3 = 1		'NO prescaler is assigned
    T0CON.2 = 0		'Prescaler 1:1
    T0CON.1 = 0		'Prescaler 1:1
    T0CON.0 = 0		'Prescaler 1:1
    
    
    'From Datasheet Section 14
    T3CON.7 = 0		'Disables 16bit read/write
    T3CON.6 = 0		'TMR1 is clock for both CCP's (together with BIT 3)
    T3CON.5 = 0		'Prescaler 1:1
    T3CON.4 = 0		'Prescaler 1:1
    T3CON.3 = 0		'TMR1 is clock for both CCP's (together with BIT 5)
    T3CON.2 = 1		'Don't sync with internal clock.
    T3CON.1 = 1		'TMR3 clock source is EXTERNAL
    T3CON.0 = 1		'TMR3 is ON
    I've set the bits one by one here so that it's easier to see what each one does. Note that I haven't tested this so it's perfectly normal if it doesn't work...

    /Henrik Olsson.

  3. #3
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default So..

    Thats a great guide HenrikOlsson,

    Well,the truth is .. this is my first time in my life setting up Counter in PIC.Although i know whats it function would work like,i am still confused ( Well,not the pre-scaler part,rising edge or falling edge and so on ..) but how to set it,accumulate it and clear it?.That's what something new to me.I am able to read the datasheet but understand 50/50...

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    Hi,
    Ahh, well the TMR registers are like any other register in the PIC so you can read/write to/from them as you would with any other register. So to set the TMR0 registers to 0 (assuming a 16 bit TMR0 here):
    Code:
    MyCount var WORD		'This is my counter...
    
    TMR0L = 0			'Reset lower byte
    TMR0H = 0			'Reset hogher byte
    
    Start:
      MyCount.HighByte = TMR0H	'Get high byte of counter
      MyCount.LowByte = TMR0L	'Get low byte of counter
      LCDOUT $FE,1,#MyCount		'Display it
      Pause 100
    Goto Start
    To PRESET it you write whatever value you wish to the two registers:
    Code:
    TMR0H = 3        'Preset TMR0 to 878....
    TMR0L = 110     ' ( 3 * 256 + 110 )
    That's really all there is to it. Well, one more thing. When reading the two TMR registers in the way shown above there is a slight chance the lower byte rolls over in the time between reading TMR0H and TMR0L. To come around that problem you can either enable 16bits read/writes (on PICs that supports it) or read the high byte two times, like:
    Code:
    MyCount VAR WORD
    Temp var byte
    
    
    MyCount.HighByte = TMR0H	'Get high byte of counter
    MyCount.LowByte = TMR0L		'Get low byte of counter
    Temp = TMR0H			'Get high byte again
    
    IF Temp <> MyCount.HighByte then  'Do a fresh read
      MyCount.HighByte = TMR0H	'Get high byte of counter
      MyCount.LowByte = TMR0L	'Get low byte of counter
    EndIf
    HTH
    /Henrik Olsson.

  5. #5
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default Great..

    Hi HenrikOlsson,

    Ok.I understand now.I gonna give a try and let you know the result.Thanks a bunch my "Sail on the same ship" friend.

  6. #6
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default Mmm...share

    To HenrikOlsson,

    Hope you remember me.

    Is the TMR0 and TMR3 were shared?.So that means i could only use 1 counter at a time right?.

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    Hi,
    No it seems like TMR1 and TMR3 has it's external clock input connected to the same physical PIC pin (Pin15 on the 4550). That means that you can't use both TMR1 and TMR3 as counters with external clockinput. You would still be able to use, for example, TMR1 as a counter and TMR3 as timer (internaly clocked) though.

    So TMR0 and TMR3 as counters should be fine!

    /Henrik Olsson.

  8. #8
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default What the...

    So that means i can only use 1 counter for a time?.Geez,it seems 16F877 is more easy to use.It supports WDT scale for PORTA.4 interrupt.1:1.I am a bit confused?.

  9. #9
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    Hi,
    I'm sorry but I'm not quite sure what the problem is...?

    You can use TMR0 AND TMR1 as counters at the same time. OR you can use TMR0 AND TMR3 as counters at the same time. BUT you can NOT use TMR1 AND TMR3 as counters at the same time since they both share the same clock-pin (pin 15 on the 40-pin DIP package)

    If this doesn't help please explain what the problem is , if you can.

    /Henrik Olsson.

  10. #10
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default Ahh..

    Hi Henrik,

    Yes,that exactly i wanted to know ( you can NOT use TMR1 AND TMR3 as counters at the same time ).Ok,my doubt is cleared.Seems like i got to use an interrrupt pin and a counter.I hope it would work.And 1 more thing,the selection of QEI in PIC18F4431.If i don't want to use INDEX and wish to reset it using software (POSCNT=MAXCNT),am i have to set value of the maxcount ( Ex : MAXCNT = 1500 ) ??.And could i use single channel encoder output from 2 encoder which is from 2 different motor?.

    I am sorry if i am bothering you alot,but this things is new to me and locally nobody had tried this kind of stuff due to the price of these electronics and availibility.

  11. #11
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default

    Hi,
    Ok,my doubt is cleared.Seems like i got to use an interrrupt pin and a counter.
    Well, if you say so.... If you could explain what it is you're trying to do it may be easier for me or anyone else to suggest a solution. If you don't use TMR0 for anything you CAN use that AND TMR3, both as counters. If you ARE using TMR0 for something ELSE than a counter, perhaps you can shift that work to TMR3 thus making TMR0 and TMR1 available as counters - it all depends....

    And 1 more thing,the selection of QEI in PIC18F4431.
    I'm a bit confused...I thought we were talking about the 18F4550 here, the 18F4431 doesn't even have a TMR3.....

    Regarding the QEI, if you don't want to use the Index channel you can either just let the position register overflow or use the position counter reset on period match. In the later case you set MAXCNT to the value at which you want the postion counter to reset to zero, 1500 for example.... You can NOT use just one channel from the encoder. The QEI module needs two channels, 90 degrees phase shifted with respec to each other. Otherwise it can't tell which way the motor is turning.

    I am sorry if i am bothering you alot,but this things is new to me and locally nobody had tried this kind of stuff due to the price of these electronics and availibility.
    No problem at all. That's what the forum is here for.

    /Henrik Olsson.

  12. #12
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default I am glad.

    Thanks Henrik.You understand my pain.

    Well,what i am trying to do here is actually to have single channel encoder from each encoder (2 encoder) and feed it into PIC.I want to use interrupt but i belive when the interrupt occured,you got to clear it right?.Is this might lead to missing pulse as you have to loop to clear the interrupt?.Although without pause?.I even thought about using RB Port Change Interrupt as i belive i could hook up quadrature encoder to RB7:RB4 but i belive it could make some delay in clearing and again lead to missing pulse.

    My apologise for confusing you with 18F4550 and 18F4431.I do own this chip and it's more awsome than LM629.

  13. #13
    ra68gi's Avatar
    ra68gi Guest


    Did you find this post helpful? Yes | No

    Default

    Hi nature tech,
    Its been a long time since i last posted on this forum. I have written a program for a rotary encoder. But i have written it in C. I have used pic16f72 and have made 1x, 2x, 4x measurements. In 1x it increments counter only once for every pulse. I had used a 1000ppr(pulse per rev) encoder & the count value displayed on a LCD. So the resolution is 360degrees/1000. With 2x you will get double & with 4x you get 360/4000.
    I have used different interrupt sources like portb int0, ccp,timer0, timer1.
    If you are interested i will send you the source code.
    The compiler Iam using is free version & you can write upto 2k code. And all this with instant interrupts.
    If you are interested let me know & i will post it.

    Raghunathan.

  14. #14
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Mikro C
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  15. #15
    ra68gi's Avatar
    ra68gi Guest


    Did you find this post helpful? Yes | No

    Default

    No. It's BoostC.
    If you are new to C & interested to learn it quickly, see this link..http://forum.sourceboost.com/index.php?showtopic=2399. C is more structured & universal language. I migrated to C recently & its power is awsome as regards to microcontroller programming. If you intend to impliment rtos on small ram pics, that too is available called nova rtos. Have a try.
    Regards

    Raghunathan.

  16. #16
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Sounds good... yet another C compiler

    Well, i'm not going to move on it as long as i'll don't have any customer asking for OR if a free and legit full-version appear in my mail-box .

    I have and use too much different compiler now (C, BASIC)... hard to get comfortable with all of them...

    My favourites
    1. PicBasicPro
    2. SwordFish
    3. Hi-Tech C
    Last edited by mister_e; - 15th May 2007 at 05:17.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  17. #17
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default Hi all.

    Hi ra68gi,

    I think i wanna have a look on your code as well.Is your code is an adaptation from "instant interrupt" which you mix with asm or else?Well,1x, 2x,4x resolution sounds great.It might be a choice which i will skip using PLD or CPLD to do the job.If this doesnt work then i will opt for 2 PIC18F4331 which is connected through I2C that will enable me to control 2 motors almost at the same time.

    Talk about C,yes it's a great stuff.You just have to include the related <.h> file and tweak a bit in you code,and there you go.I think you could download sourceboost free?Or limited somehow.

  18. #18
    ra68gi's Avatar
    ra68gi Guest


    Did you find this post helpful? Yes | No

    Default

    Yes, you get 2k version absolutely free with all the frills like a beautiful simulator / debugger with no other limitation other then 2k code limit. Floating point routines is also available. Consider the pic basic compiler(2k page limit pbc) which is sold at $100. And for just $70 you get a full version BoostC compiler( no limit).

    All compilers have instant interrupts its only pic basic compilers that don't have instant interrupts (God knows why)ie. the interrupt latency is much higher than generated by other compilers. more over the pbc commands are non re-enterent, meaning that only after it completes executing the whole command( say pause 1000) will it enter the ISR. Which is very bad & thats why Darrel has created the instant interrupt routines for PBC.

    coming to the project..
    Both clockwise & anti clockwise the LCD is made to display only positive values. If you wish you can rewrite the code to get -ve value displayed.
    Any thing is possible with this compiler.

    The 1x code is commented well but not the 4x( i didn't have time).
    Ask me if you need the 2x code. I suppose the 4x will give you all the information to build the 2x.

    The 1x code is as follows...
    Code:
    --------------------------------------------------------------------------
    // this test builds & works properly.	
    #include "system.h"
    #include "lcd_driver.h"
    #include "stdio.h"
    // Set clock frequency to 4MHz.
    
    #pragma CLOCK_FREQ 4000000
    
    //set configuration fuse.
    #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF
    
    #define LCD_ARGS 	2,	/* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \
    		0, 				/* Use busy signal: 1 = use busy, 0 = use time delays */\
    		PORTC, TRISC, 	/* Data port and data port tris register */ \
    		PORTB, TRISB, 	/* Control port and control port tris register */ \
    		2,				/* Bit number of control port is connected to RS */ \
    		7,				/* Bit number of control port is connected to RW */ \
    		3 				/* Bit number of control port is connected to Enable */
    
    
    
    signed long counter;
    unsigned long counter1;
    unsigned int value1;
    bit update_flag;
    
    /*Interrupt service routine (ISR).On ccp capture interrupt, program 
      will jump to this code location.  */	
    void interrupt( void )
    {
      update_flag = 1 ;
    
       if(portb.0 == 0)   //check the quadrature signal
      {
       counter ++ ;      // increment counter
      }             
       else         //else decrement counter.
      {
       counter -- ;
      }  
       pir1.2 = 0;       //clear ccp1if 
    }
     
    
      
    
    /* function to display counter. */
    void display (unsigned int x)
    {
    unsigned int xn ;
    unsigned int xd ;
    char buf[ 10 ];
        lcd_clear();
        lprintf("count=");
        sprintf( buf, "%d", x );
        lprintf( buf );
    }
    
    
    /* The main code configures the intcon, pie1, t1con & ccpcon1 
       registers.*/
    
    void main()
    {
    	trisb = 1;		 //configure portb.0 as input & rest as 
    	portb = 0;		 //clear port B
    	trisc = 0b00000100; //RC2/ccp1 pin as input.
    
    	
    // enable interrupts: interrupt control register.
    	intcon.6=1;     //enable peripheral interrupts    
    	intcon.7=1;     //enable global interrupt
    	
    //peripheral interrupt enable register 1.
        pie1.2 = 1;    //enable ccp1 interrupt.
        
        
    
        
    /*ccpcon1: capture/compare/pwm control register1. 
        
        bit3-0.....ccpxm3:ccpxm0: ccpx mode select bits.
        we will use...
        0100 = capture mode, every falling edge.
        0101 = capture mode, every rising edge.
        we can choose any one of the above mode.
        but we will use 0101 in our project.
        to get less count use 0110( divide by 4).
        or 0111 for divide by 16.  
    */
    
    /* setup LCD */
        lcd_setup();
     
            
        update_flag = 1;  // start counter from 0
        ccp1con = 0b00000101;  //set capture mode.   
        counter = 0;  //reset counter.
     while(1)
     {      
        while (update_flag == 1)   
       {
         if(counter < 0 )
         { 
          counter1 = (-1)* counter;
           display(counter1) ;
           }
        else
          { 
           display(counter) ;
          }  
        update_flag = 0 ;    
       }	 
      }
    }
    --------------------------------------------------------------------------
    code for the 4x...

    Code:
    // this test builds & works properly.
    	
    #include "system.h"
    #include "lcd_driver.h"
    #include "stdio.h"
    // Set clock frequency to 20MHz.
    
    #pragma CLOCK_FREQ 20000000
    
    //set configuration fuse.
    #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF
    
    #define LCD_ARGS 	2,	/* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \
    		0, 				/* Use busy signal: 1 = use busy, 0 = use time delays */\
    		PORTC, TRISC, 	/* Data port and data port tris register */ \
    		PORTB, TRISB, 	/* Control port and control port tris register */ \
    		2,				/* Bit number of control port is connected to RS */ \
    		7,				/* Bit number of control port is connected to RW */ \
    		3 				/* Bit number of control port is connected to Enable */
    
    
    
    signed long counter;
    unsigned int value1;
    bit update_flag;
    
    /*Interrupt service routine (ISR).On ccp capture interrupt, program 
      will jump to this code location.  */	
    void interrupt( void )
    {
      update_flag = 1 ;
    
       if(intcon.1)   //RB0/int interrupt(rising edge)
     {
       if(portc.1 == 0)
        {
          counter ++ ;      // increment counter
        }             
       else         //else decrement counter.
        {
          counter -- ;
        }  
       intcon.1 = 0;       //clear intf 
     }
            else
       if(intcon.2)   //tmr0if (falling edge)
     {
       if(portc.1 == 1)
        {
           counter ++ ;
        }
       else
        {
           counter -- ;
        }
       tmr0 = 255 ;
       intcon.2 = 0;
      }
           else
        if(pir1.0)    //tmr1if
     {
        if(portc.3 == 1)
         {
            counter ++ ;
         }
        else
         {
            counter -- ;
         }
        t1con.0 = 0 ;
        tmr1l = 255 ;
        tmr1h = 255 ;
        t1con.0 = 1 ;
        pir1.0 = 0 ;
     }
           else
        if(pir1.2)     //ccp1if
     {
        if(portc.3 == 0)
         {
            counter ++ ;
         }                                           
        else
         {
            counter -- ;
         }
        pir1.2 = 0;
     }
    }        
     
    
      
    
    /* function to display counter. */
    void display (unsigned long x)
    {
        char buff [ 10 ] ;
        sprintf32(buff,"%d",x);
        lcd_clear();
        lprintf("count=");   
        lprintf (buff);
        
    }
    
    
    /* The main code configures the intcon, pie1, t1con & ccpcon1 
       registers.*/
    
    void main()
    {
    	trisb = 1;		 //configure portb.0 as input & rest as 
    	portb = 0;		 //clear port B
    	trisc = 0b00000111; //RC2/ccp1, RC0, RC1 as inputs.
    
    //configure option register bits 
    //portb pull-ups(rbpu)(disable)...bit7  
    //interrupt on rising edge(RB0/int)(intedg)...bit6
    //tmr0 clock source(tocs) is transition on RA4...bit5
    //tmr0 source edge select(tose) is high to low transition...bit4
    //bit3-bit0...don't care.
        option_reg.6 = 0b11111111;
        	
    // enable interrupts: interrupt control register.
    //	intcon.6=1;  enable peripheral interrupts    
    //	intcon.7=1;  enable global interrupt
    //  intcon.5=1;  enable tmr0 overflow interrupt.
    //  intcon.4=1;  enable inte (RB0/int)
    //  intcon.1=0;  intf ( RB0/int flag)
     
    //     intcon = 0b11110000 ;	
    //i will enable tmr0 & RB0/int along with ccp and tmr1 interrupt.
    
    
    //timer1 module: configure t1con.
    /*TIMER1 INCREMENTS ONLY IN RISING EDGE*/
    //bit7-6....00
    //bit5-4....00...prescaler 1:1
    //bit3......0....t1oscen cleared.(makes RC0 as clk input)
    //bit2......0....synchronize external clock input.
    //bit1......1....external clock on pin RC0.
    //bit0......1....start timer1. 
    //     t1con = 0b00000011;
    //we will start all interrupts at one go a bit latter. 
       
    //peripheral interrupt enable register 1.
         pie1.2 = 1;        //enable ccp1 interrupt.
         pie1.0 = 1;        //enable tmr1 interrupt.
        
    /*ccpcon1: capture/compare/pwm control register1. 
        
        bit3-0.....ccpxm3:ccpxm0: ccpx mode select bits.
        we will use...
        0100 = capture mode, every falling edge.
        0101 = capture mode, every rising edge.
        we can choose any one of the above mode.
        but we will use 0101 in our project.
        to get less count use 0110( divide by 4).
        or 0111 for divide by 16.  
    */
    
    //  LCD setup 
        lcd_setup();
       
        update_flag = 1;  // start counter from 0
        ccp1con = 0b00000100;  //set capture mode in falling edge.
        tmr0 = 255;  // a pulse will generate an overflow interrupt.
        tmr1l = 255;
        tmr1h = 255;    // a single pulse input will gen an interrupt.
        t1con = 0b00000011;  // start timer1 as pulse counter. 
        intcon = 0b11110000 ;  //enable RB0/int, tmr0 interrupt   
        counter = 0;  //start measurement.
     while(1)
     {      
        while (update_flag == 1)   
       {
         if(counter < 0 )
         { 
           counter = (-1)*counter;
           }
         update_flag = 0 ;
         display(counter) ;
       }	 
     }
    }
    --------------------------------------------------------------------------
    Regards
    Raghunathan.
    Last edited by ra68gi; - 15th May 2007 at 19:54. Reason: unable to see #include <system.h>

  19. #19
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    All compilers have instant interrupts its only pic basic compilers that don't have instant interrupts (God knows why)
    Yeah... but god did it for us...

    Instant interrupts - Revisited
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  20. #20
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default Omg

    Quote Originally Posted by mister_e View Post
    Yeah... but god did it for us...

    Instant interrupts - Revisited
    Don't let it go to your head Darrel, Steve spelled god with a lower case G
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  21. #21
    Join Date
    Jun 2005
    Location
    Penang
    Posts
    40


    Did you find this post helpful? Yes | No

    Default Hahahaha...

    LOL,

    Thanks a lot everyone.I got it now.

    Thanks RA68GI and Henrik.

  22. #22
    tapir's Avatar
    tapir Guest


    Did you find this post helpful? Yes | No

    Default phase angle

    hello friends

    ı try to make a phase failure relay for three phase main power there is a lot of phase failure relay on the bazaar but its not really effective because if one phase loss during motor running in that situation occur an regenerative effect in notor so the loss phase reproducing by motor and phase failure relay does not effect in this position
    and whe ı mesure the phase angle by scop ı see that occur an phase shifting
    so this is my question how can ı measure the phase angle for three phase

Similar Threads

  1. Pin won't stay high during Repeat...Until loop??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 17th August 2009, 00:57
  2. Interruptus Frustratus
    By Byte_Butcher in forum General
    Replies: 16
    Last Post: - 17th April 2009, 21:36
  3. Counter not counting !!!
    By lerameur in forum mel PIC BASIC Pro
    Replies: 24
    Last Post: - 20th February 2009, 23:15
  4. 16F628A - Stops if release power switch.
    By dene12 in forum General
    Replies: 16
    Last Post: - 14th February 2009, 08:57
  5. error on compiling
    By parker in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 16th June 2005, 15:31

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts