assembly timer

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

Hi,

By playing around with timers, and reading a little bit. I found a way to use delays with an assembly macro, using the No operation (NOP) command, and then calling this macro in my C code.

asm(".MACRO Delay4\n\t"
      "NOP\n\t"
      "NOP\n\t"
      "NOP\n\t"
      "NOP\n\t"
      ".ENDM\n\t"
      );
       
void delay()
{
asm("Delay4"); //delay of 4 us
}

I still don't get a very "precise" timer with this method. As it is very difficult to get an exact delay with my crystal of 14.7456MHz... I would need 3.6864 NOP's to get an exact delay of 4us...:p
Is there any other method for this? Am I doing something wrong?
I guess this is a more efficient way than using the _delay_us() macro, right?
According to what I've heard, for time constraints it is worth coding in assembly language.

Thanks in advance.

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

Go on. Explain. My eyesight cannot detect nanoseconds. Young people have such swift reaction time.

The whole point of using the macros is to produce something "good enough".

You could achieve 3.9984us with 59 NOPs.
And if you want to do a 1 millisecond delay, you can use 14756 NOPs.

But you will need at least a mega32 to fit this code in.

Start typing now.

David.

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

I got an atmega328, but I need a lot of code besides the NOPs, so I don't want to waste too much space.
Can a vast amount of NOPs be reached using a for or a while loop?

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

There is no way to get a fractional number of clock cycles. Neither a hardware timer or a time-waste loop can do other than an integer number of clocks.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

lcruz007 wrote:
I got an atmega328, but I need a lot of code besides the NOPs, so I don't want to waste too much space.
Can a vast amount of NOPs be reached using a for or a while loop?

Use the regular macros. Be honest with your F_CPU.

Write your code as if everything was perfect to the nearest picosecond.

Then simulate your code in Studio. Likewise you must be honest with your F_CPU, so that the timings will be correct (to the nearest nanosecond).

If you are not happy with the results, change your code to give a slightly shorter delay time and re-simulate. Add the required # of NOPs to bring the delay up to your critical # of nanoseconds.

Bear in mind that any interrupts could ruin all your calculations. But you should be able to spot the interrupt coming with the aid of your lightning fast eyesight.

David.

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

ka7ehk wrote:
There is no way to get a fractional number of clock cycles. Neither a hardware timer or a time-waste loop can do other than an integer number of clocks.

Jim

Yeah, what I meant is that a loop could save a lot of space when using lots of NOPs. For example, if I needed to use a delay of approximately 1us 20 times. I would have to call the macro of 15 NOPs everytime I wanted that delay, in this case, 20 times!! So I was wondering if you could use a for loop instead of calling the macro 20 times, and avoid wasting 20 code lines...

I tried with the for loop but it did NOT work... Am I doing something wrong?

int i;

for( i = 0; i<=20; i++ )
{
delay(); //calls the delay asm macro
}

if( i >= 21 )
i = 0; //resets variable to 0

Quote:

Use the regular macros.

The reasons I changed from the util/delay.h macros was because I was not getting the results I wanted. That's why I was asking if it was better to use the assembly macros instead...

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

Quote:
Use the regular macros. Be honest with your F_CPU.

The OP wants to do video output, so _delay_us won't cut it.

Quote:
I still don't get a very "precise" timer with this method.

Of course you don't. You have assembly code that delays 4 clocks, not 4 microseconds. Then you wrap that code in a C function which greatly changes the amount of delay.
Quote:
I tried with the for loop but it did NOT work... Am I doing something wrong?

Did you take into account the amount of time the for loop adds to the routine?

Please - stick with one thread instead of creating a new one every time.

Regards,
Steve A.

The Board helps those that help themselves.

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

Right, I think I would need about 14-15 NOPs to get a delay of 1us approximately with my xtal.

Quote:
... Then you wrap that code in a C function which greatly changes the amount of delay.

I see, what do you suggest me? Write everything on assembly? NOT using C at all? =o
If I Change the crystal to, let's say 16MHz, would help?

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

Quote:
I see, what do you suggest me?

The same thing that I suggested in the other threads: look at the links you were given and see how they did it.
Quote:
If I Change the crystal to, let's say 16MHz, would help?

No, the problem is not the speed of the chip. The problem is that you don't understand the exacting requirements of what you are trying to do.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:
The OP wants to do video output, so _delay_us won't cut it.

The OP made no mention of video.

You can use _delay_us() macro if you want something greater than about 1us. The macro creates a consistent # of machine cycles, albeit with some granularity. Hence you may want to pad with NOPs.

Video output in software is always tricky. You need to wake up from a short nap to blit a horizontal line. Yes. The horizontal lines are best done in assembler.

Personally I do not think you can afford to waste time in do-nothing delays. Especially when you can get the AVR hardware to govern the timing.

But whatever you want to do can be cycle counted exactly with the Simulator.

David.

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

Quote:

The OP made no mention of video.

Look at his other threads - he starts one - is told that he can't do video output in C so then starts another one and asks the same thing all over again. This has got to stop somewhere and this is where that process starts.

Locked.

(lcruz007, please pick ONE of your existing video timing generation threads and keep ALL the discussion about that subject in the single thread - cross posting here will not be permitted)

Topic locked