TC0 timer in Xmega

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I have a problem with the overflow time in TC0 timer. here's my code:

 

interrupt [PORTH_INT0_vect] void porth_int0_isr(void)
{

    #asm("wdr")     

    if (!(s19==0))
    {
        if(s19==1)
            TCE0.PERBUF=131;
        else if(s19==2)
            TCE0.PERBUF=133;
    }
    else
    {
        TCE0.PERBUF=132;
    }

}

 

This interrupt will be triggered in every falling_edge of an input signal (19 KHz clock). TCE0.PER initial value is 132 and the Xmega clock is 4332 KHz. I have another interrupt which is related to TCE0 overflow:

 

interrupt [TCE0_OVF_vect] void timer_int0_isr(void)
{
   #asm("wdr")
    
    s19+=1;
    if (s19==4)

        s19=0;
 
    s57+=1;        

    if (s57==192) 
    {
        s57=0;

        ...

     }

     ...

}

 

s57 and s19 initial values are 191 and 0, respectively. My question is how many times interrupt [TCE0_OVF_vect] will be triggered in a 19 KHz input clock cycle? and what is the reason of assigning 131, 132 and 133 to TCE0.PERBUF with respect to s19.

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's not enough information given. You say it is your code, so why ask about 131,132,133? Surely if you wrote the code you would know?
What is the code expected to do?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Kartman,

No I didn't write this part, somebody else did and I should understand it to complete the rest of the code. The target of the code is to make a 1187.5 Hz clock signal using the 19 KHz input clock. So, two interrupts has been used to do this. An interrupt on the pin which is 19 KHz input clock signal (interrupt [PORTH_INT0_vect] (this interrupt is falling_edge triggered)), and the other is TCE0 timer overflow interrupt (interrupt [TCE0_OVF_vect]). I know that the 1187.5 Hz clock is produced in if (s57==192) but I don't understand what is going between s19 and TCE0.PERBUF to trigger interrupt [TCE0_OVF_vect] and increment s57 by one to make 1187.5 Hz clock. 

Last Edited: Sat. Jan 7, 2017 - 12:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still not enough information. Dividing 19k by 16 gives you 1187.5. So why the shenanigans? What is the significance of the 19kHz and 1187.5Hz? Are you trying to extract data from RDS or something like that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes exactly, I want to send RDS data to DAC. I need 1187.5 Hz clk because of that. You are right we can divide 19 KHz by 16 but I can't understand this code. Here's the complete functions:

 

TCE0.CTRLE=0x01;       
TCE0.INTCTRLA=0x02;   
TCE0.PER=132; 
TCE0.PERBUF=132;

TCE0.CTRLA=0x01;

//interrupt on PORTH6 which is PILOT 19 KHz
interrupt [PORTH_INT0_vect] void porth_int0_isr (void)
{

    #asm("wdr")     

    if ( !(s19 == 0) )
    {
        if(s19 == 1)
            TCE0.PERBUF = 131;
        else if(s19 == 2)
            TCE0.PERBUF = 133;
    }
    else
    {
        TCE0.PERBUF = 132;
    }

}

 

/////////////////////

interrupt [TCE0_OVF_vect] void timer_int0_isr (void)
{
    uchar uchar1;
       
    #asm("wdr")
    
    s19 += 1;
    if (s19 == 4) 

         s19 = 0;
 
    s57 += 1;        // count 1187.5 counter

    if (s57 == 192)  // if 1187.5
    {
        s57 = 0;
        bit_count += 1;

        if(bit_count == 8)
        {
            bit_count = 0;
            byte_count += 1;
            if(byte_count == 12)
                change_send_group = 1;
            if(byte_count == send_buff_size)
                byte_count = 0;

            rds_send_buff = rds_data[byte_count];
        }
        else 
        {
            rds_send_buff=rds_send_buff << 1;
        } 

      

        uchar1 = rds_send_buff&0x80;
        crnt_rds_bit = uchar1 ^ prvs_rds_bit;

      

        if (crnt_rds_bit == 0)
        {
            if (prvs_rds_bit == 0)
             { bit_mode = 0; }
            else 
             { bit_mode = 2; }
        }   
        else if (prvs_rds_bit == 0)
        {
            bit_mode = 1;
        }
        else
        {
            bit_mode = 3;
        }         
        
        prvs_rds_bit = crnt_rds_bit;

        s_dps += 1;              
    }    
    switch (bit_mode)
    {
        case 0:DACB.CH0DATA = rds_mod0[s57];break;    // rds_mod0
        case 1:DACB.CH0DATA=rds_mod1[s57];break;    // rds_mod1                
        case 2:DACB.CH0DATA=rds_mod2[s57];break;    // rds_mod2         
        case 3:DACB.CH0DATA=rds_mod3[s57];break;    // rds_mod3         
    }
   

    if (change_send_group == 1)
    {
        change_send_group = 0;
        rds_data = Send_group_array[Send_group_counter];
        Send_group_counter = Send_group_counter + 0x01;
        if (Send_group_counter==Send_groups_num)
        {
            Send_group_counter=0x00;
            PORTE.OUT &= 0xfd;
        }
        if (Send_group_counter == 1)
        {
            PORTE.OUT |= 0x02;
        }
        if (Send_group_counter == 0x02) 
            flag_encode_stream_next = 1; 
    }
}

 

rds_mod0(1,2 or 3) is a table with 192 constant integers.

 

Thanks for your help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In situations like this, it's nice if you tell us this crucial information up front rather than have us guess. I guessed at 19kHz as it is the fm pilot frequency and from that I guessed RDS. I might also be nice is you tell us the source of your code so we can read the whole thing rather than your abridged version of the facts.

 

I'd suggest you read up on the Xmega timer operation. Since I've never used an Xmega, I'm finding it hard to figure out how the numbers relate - eg 1187.5 times 192 = 228000. Divide your 4332000 by 19 gives you this. So I don't see how this relates to the timer values - unless the 4.332MHz is multiplied by the xmega pll. Just crunched some numbers at it might seem your 4.332MHz crystal is multiplied. As to why the divisor is changed I can only suggest it is to average out a beat with the 19kHz source.

 

if we multiply 4.332MHz by 7 we get 30.324MHz. Divide this by 133 we get 228000. Divide that by 192 we get 1187.5

 

Since the code cycles between 131,133,132,132 this averages to 132. There's probably a +1 for the timer compare to give us 133. You've tested the powers of my deduction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Kartman, Thank you so much for your help. You were right. The Xmega clock is multiplied by 7 by the pll. So now All of the numbers make sense. Thanks so mush for your attention.

Last Edited: Sun. Jan 8, 2017 - 08:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Kartman, Do you have any idea about that why the timer period changed from 132 to 131, 133 and then 132 again? I think we could set timer period to 132 for all the time. Am I right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would guess he is trying to compensate for a small error by changing the count by one on some cycles.

274,207,281-1 The largest known Mersenne Prime

 

"Head the warning. Avoid strong drink. It will make you shoot at politicians' -and miss."  -- B.Franklin.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've already commented on the reason for the changing divisor. If you want a more specific answer you'll need to provide more information - like a schematic and the code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes I got that but I meant we can set the timer to 132 (It counts from 0 to 132, so 133 times), and then we can have a overflow every 133 times that the counter resets. I can't understand why it got an average between 132,131,133 and 132. The rest of the code isn't related to this part, so I don't think it can help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes maybe you are right. It got an average for being sure about that the average overflow time is every 133 times. Thanks Torby. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 19kHz is probably asynchronous to the xmega, thus you'll get a phase drift due to the slightly different frequencies. Normally you'd use a phase locked loop to eliminate this so I guess ( and i mean guess as i have little evidence to work from) the changing of the divisor is to introduce some 'wiggle' into the system.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Kartman for your help.