Configuring Timer

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

TCD1_PER = 250;//configure the timer

 

What exactly does the above statement mean? Can somebody please explain?

 

Thank You,

Sha

This topic has a solution.
Last Edited: Wed. May 19, 2021 - 04:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It sets the TCD1_PER register to the value of 250d.

 

Which part are you using?

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

It appears to be setting the PERiod of a Timer/Counter, but it would help to know which AVR your talking about!

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

 

We know from his other threads it is some form of Xmega.

 

From a typical Xmega manual (this is the "A" manual) you find:

 

 

So TCD1 has a 16 bit period (TCD1_PER) which is actually a combination register that involved writing to TCD1_PERL and TCD1_PERH. So when you use TCD1_PER = 250 you are setting PERL to 250 and PERH to 0. Anyway, as the datasheet says, this sets the "TOP" value for the timer so it's counting sequence will be 0, 1, 2, 3, .. 248, 249, 250. I'm guessing you probably want to set it to 249 not 250 if you have determined you want a 250 step counting sequence.

 

But it may be easier if you simply tell us "which AVR (Xmega)?" and "where have you seen this code you don't understand?" then someone here can decode what is going on for you.

 

Last Edited: Tue. May 18, 2021 - 05:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, Thank your for the explanation. Here's the code. The objective of the code is to connect 4 seven segment displays to Atxmega 128 A1 in order to display 4 digits by pressing the increase and decrease button.

 

So I am connecting

the anodes to PORTE (pins 0 to 6)

the cathodes to PORTD(pins 0 to 3)

the increment and decrement to PORTD( pins 5 & 7)

 

The header file for respective connections is as follows :

#define A PIN0_bm
#define B PIN1_bm
#define C PIN2_bm
#define D PIN3_bm
#define E PIN4_bm
#define F PIN5_bm
#define G PIN6_bm

#define cathode_1 PIN0_bm
#define cathode_2 PIN1_bm
#define cathode_3 PIN2_bm
#define cathode_3 PIN3_bm

The following is the main code:

 

#define F_CPU 2000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "7_segment.h" // The h file for pin connections as shown above

void Plus(void);//for increasing the digit through increment button
void Minus(void);//for decresing the digit through decrement button
void Display(uint16_t data);

#define segment_gm A|C|D|E|F|G
#define data_gm cathode_1|cathode_2|cathode_3|cathode_4

#define increment PORTE.PIN5CTRL
#define decrement PORTE.PIN7CTRL

int main(void)
{
    PORTE.DIR |= segment_gm;
    PORTD.DIR |= digit_gm;
    increment=PORT_OPC_PULLUP_gc;
    decrement=PORT_OPC_PULLUP_gc;
    
    TCD1_PER = 250;
    TCD1_CTRLA = TC_CLKSEL_DIV8_gc;
    TCD1_INTCRTLA = TC_OVFINTLVL_LO_gc;
    PMIC_CTRL = 1;
    sei(); //gloabal interrupt are enable
    
    ISR(TCD1_OVF_vect)
    {
        if(number_digit<4) ++number_digit;
        else
        number_digit = 1; 
        Display(count);
    }
}

void Plus(void)//increment button
{
    if((increment)&&(count<9999)) ++count;
    Display(count);
    _delay_ms(500);
}

void Minus(void)//decrement button
{
    if((decrement)&&(count>0)) --count;
    Display(count);
    _delay_ms(500);
}

void Display(void)
{
    PORTD.OUTSET = digit_gm;
    if(number_digit==1)
    {PORTE.OUT = segment[data/1000]; PORTD.OUTCLR = cathode_1;}// PORTD.OUTCLR because it is common cathode
    
    if(number_digit==2)
    {PORTE.OUT = segment[data%1000/100]; PORTD.OUTCLR = cathode_2;}
    
    if(number_digit==3)
    {PORTE.OUT = segment[data%1000%100/10]; PORTD.OUTCLR = cathode_3;}
    
    if(number_digit==4)
    {PORTE.OUT = segment[data%1000%100%10]; PORTD.OUTCLR = cathode_4;}
}

I've understood that one needs to use a timer inn=terrupt in order to control the 4 digits through a switch and for executing each switch one needs to use overflow interrupt handler. But I dont quite understand on how to configure the timer and implement it as in what is the flow of logic?

 

Thank You,

Sha

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

sha1130 wrote:
But I dont quite understand on how to configure the timer and implement it as in what is the flow of logic?
If you are still making that kind of design decision how can you have started to write the code? You need to start by determining what you want to do, then find out how to make that happen, THEN write the code to achieve it.

 

If you start writing code first then you will be left wondering - "OK, so now, how do I added some interrupt code to this?"

 

Also you have ISR(TCD1_OVF_vect) "inside" the body of the main function. It needs to be a global function that can be linked to the jump at the interrupt vector in the vector table.

 

Again this is the kind of thing you should already have determined during the design phase.

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

This code wasn't entirely written by me. I have however, only modified the Plus, Minus and Display Functions. The block involving the timers is where am stuck but I just know on the surface level that one needs to use them but why as exactly is where I ahve no clue.

 

Would be glad if you could help me out.

 

Thank you.

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

sha1130 wrote:
This code wasn't entirely written by me.
There's nothing wrong with pulling in code from others but it's best done in a modular fashion and with clearly define interfaces that you totally understand from their documentation. Just grabbing bits of code you don't wholly understand and pasting it all together is not a great way to structure/learn things.

 

I guess the golden rule is "don't paste a line of someone else's code into your own source files unless you know exactly what it is doing.

 

Of course if you are using someone's "library" and just adding lines to call their functions and access their data then what happens "behind" that is not important to know - but you must fully understand the interface presented to you.

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

Sure. So now it just boils down to figuring out the block dealing with the timer and only then implement the entire code based on how that works.