Problems with timer

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

Hi,

I have been trying a while ago to use the most precise timer in microseconds you can use with an atmega328P running at 14.7456MHz programmed with C.
But I haven't succeed yet...

I got this code, but it is not working at all, it is not taking the time I need. Does someone knows what is going on?

volatile double timer;
volatile double time;

void realtimeclock_setup() {
  TCCR0A |= (1<<WGM00);
  TCCR0B |= (1<<CS00); //No prescaling
  // set TOP to 9
  // because it counts 0, 1, 2, ... 8..9
  OCR0A = 9;
  // enable interrupt on compare event
  // (14745600 / 10 = 1474560 per second)
  TIMSK0 |= (1<<OCIE0A);
}

ISR(TIMER0_COMPA_vect)  { 
    timer++;
    time = timer / 1474560 * 1000000; //Change 1474560 counts per sec to microsecodns
}

What am I missing here?

Thanks in advance.

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

one thing you are missing is that you are wanting an interrupt every 10 clock cycles. I'm not sure how many clock cycels your ISR is, but its a BAD idea ta have interrupts that often.

Set prescaler to 64, top to 229 and you ahve roughly a 1ms interrupt.
14.7456 / 64/230 = 1001.7Hz

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

I'm about to faint dead away. You're doing floating point math inside a high-rate ISR?!

To start with, what are the minimum and maximum times you want to measure? And what is the minimum resolution you can live with, and what resolution would you like to get?

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

But I want a timer able to measure 10us!! maybe a little less. How can I do this?

kk6gm wrote:
I'm about to faint dead away. You're doing floating point math inside a high-rate ISR?!

To start with, what are the minimum and maximum times you want to measure? And what is the minimum resolution you can live with, and what resolution would you like to get?

Hehe, well I am not an expert using these timers...
I need to measure 10us like I told you before :) Maybe less.... The maximum time would be around 60us

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

Please go into more detail. What do you want to measure, how often, what will you do with the measurement, etc?

You have hardware that can measure to a resolution of 70ns. But you need to specify what exactly it is you are trying to do.

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

I am working on a composite video project. Generating these signals requires very precise times.
Maybe it is not possible to reach an exact value, but I need the most accurate timer as possible for my monochrome composite video project using only C and NOT assembly.

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

OK, but explain in more detail, it's important.

I'm guessing you need to start at time X (call it 0), then generate something (what, a pulse, an interrupt?) at X+T1, then something else at X+T2, and so on and so on.

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

That's correct.
Since filling a line requires a time of 64.5us, I need to measure that time, to be able to tell the TV which line should be "painted" and how much time does this "painting" endures. During this time, a pulse is going to be sent to the TV.

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

So is it enough to generate a single pulse with a total period of 64.5us, with a high portion of N us (~50?) and the rest low? We're getting closer to a workable description of the need.

Lay out all that has to happen in that 64.5us.

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

Hmm, yeah, but that time will change.
For example, I need to send a high pulse that measures half the 64.5us.
I also need the horizontal sync that should be 4us, blanking (8us) and vertical syncs...
I only have a 52us to "paint" a line of the TV.

That's why I need a very precise timer to work with. Sometimes I would need a 2us delay as well...

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

How many different pulses do you need, on how many different output pins?

And what else does your AVR need to do besides executing these delays?

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

I am using FOR NOW 2 output pins, maybe I will need another later. For you to understand better my problem, I will show you part of my code I have using the _delay_us() macro (this is not a very precise way to take time).

I need several pulses. However, most of them are 4us, 52us, and 8us.

void sync ()
{
    PORTB &= ~(1<<PB3);
    PORTB &= ~(1<<PB2);
    _delay_us(4);

}

void Vsync ()
{
    PORTB &= ~(1<<PB3);
    PORTB &= ~(1<<PB2);
    _delay_us(192); //6 long syncs of 30us followed by a 2us sync

}

void paintLine( int color )
{
    ///BLANK (DARK BLACK SCREEN)
    if( color == 0 )
    {
        PORTB |= (1<<PB2);
        _delay_us(60);
    }

    ///WHITE
    if( color == 1 )
    {
    PORTB &= ~(1<<PB2);
    _delay_us(8);
    PORTB |= (1<<PB2);
    _delay_us(52);
    }

    ///GRAY
    if( color == 2 )
    {

    _delay_us(29);
    PORTB |= (1<<PB3);
    _delay_us(2);
    PORTB &= ~(1<<PB3);
    _delay_us(29);
    }
}

That's my code, I need another way to do that by using a more precise timer. =)

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

Are all these delay values fixed? Different, yes, but are they all constants?

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

Yes. The delays should be constant in the code, unfortunately.
The other problem, besides the need of a precise timer, is that I need delays that changes, instead of constants...

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

The syncs should be constant. But I need changes in the delays that should "paint" the lines of the TV...

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

But the "painting" is always done by clocking data out of memory, not by executing code.

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

lcruz007 wrote:
I need several pulses. However, most of them are 4us, 52us, and 8us.
Running at 14.7MHz, 4uS comprises just under 59 cycles. The question is, can you do everything you need to do in 59 cycles less the number of cycles required to determine that it's time to do it. Frankly, I doubt it especially if you insist on using C.

Here's a suggestion: write the code in C that you'll need to execute in one of those 4uS windows and count the cycles that it will take, worst-case. If that is more than 50 cycles or so you're out of luck.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

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

Hmm well, certainly I have been using this method and it works for simple things. But if I need, for example, draw a line after another, I have problems with timing, and they are not in the same part... They are drawn like:

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

@lcruz007, you have been told several times in the other threads you have started all on basically the same topic that you can't do this in straight C. You can set up a timer to do your sync pulses for you, but for any delay that you need to respond to in code you will simply not be able to respond to that delay to do what you need without jitter. You were given links to other projects for video creation on the AVR, did you not look at any of those?

Regards,
Steve A.

The Board helps those that help themselves.

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

Sure, I am aware of it.. However, many other users have told me that there are other precise timers in C that can do this.
The problem is that I don't have any assembly knowledge, that's why I was asking one of those timers in C that some people have told me...

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

If I decided to write the code in assembly, would I have to write EVERYTHING in assembly or just the timers? How do I do this? Got any tuts?

Thank you.

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

Quote:
many other users have told me that there are other precise timers in C that can do this.

No, there are no precise timers in C, only precise timers that can be accessed by C. But in addition, to do what you want to do, any C code in time critical places must be time invariant, something that is very difficult in C since it is the compiler, not the programmer, that will determine how long any particular piece of code will take.
Only the time critical code that is not controlled directly by timers would need to be done in assembly.
Quote:
Got any tuts?

You were given links to several projects in other threads: LOOK AT THEM.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:

The problem is that I don't have any assembly knowledge,

Then the project you are attempting is beyond your current skill set and you are wasting your time. You'd be better off spending your current time learning Asm. One way to do this is to write simple C routines then examine the code the compiler generates. This will give you a taste for the way things are done in Asm.