Help!! Inaccurate delay_ms(1000); in ATmega8535

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

Why I can't get a precise or real time delay by just using delay_ms() function?

I need it to set a firing angle delay with an interval of 0-10 ms only. If the error is too big, firing angle control will never work.

Well, I just make a simple blinking LED every 1s to test the delay and guess what?

In hardware, the delay is almost 5s. WTH!

here is the code:

#include 
#include       

void main(void)          
 {
  DDRB=0x01;
  
  while (1)
  {                                 
  PORTB=0x01;
  delay_ms(1000); //WHAT'S WRONG WITH THIS DELAY???
  PORTB=0x00;
  delay_ms(1000); 
  }
 }  

Help me please :( [/code]

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

Quote:

delay_ms(1000); //WHAT'S WRONG WITH THIS DELAY???

What compiler are you using? It looks almost like avr-gcc, but the include file names and the function name would be slightly different. A very old version of avr-gcc/avrlibc perhaps?

If so:

You need to read the documentation for _delay_ms().

The parameter to delay_ms() must be a constant value known at compile time. If you use a variable value, the delay times will be wrong - as you've noted. When you need a variable delay, you could code e.g. something like this (sketchy, not tested):

void my_delay_ms(uint16_t ms)
{
   while (ms--)
   {
      delay_ms(1);
   }
}

Also (and again if you are using avr-gcc/avrlibc): You have no definition of F_CPU. It will possibly default to some value, and if that default does not match your actual clock frequency then even calls to delay_ms() with a constant parameter will get wrong timing.

EDIT: Since it's now been revealed that the compiler used is CodeVision, nothing in this post might actually apply. Caveat Emptor.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Wed. Dec 19, 2012 - 08:58 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seems like codevision and the delay.h and delay_ms() also matches that.

Make sure that in the project properties in the C compiler option the clock frequency is correctly set

Alex

"For every effect there is a root cause. Find and address the root cause rather than try to fix the effect, as there is no end to the latter."
Author Unknown

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

I use codevisonAVR. Clock freq 12000000Hz

I've tried using AVR GCC too and the result is the same. F_CPU 12000000UL.

Seriously I have no idea what I should do.

Well, if the delay is still having a big error, will this code work?

void my_delay_ms(uint16_t ms)
{
   while (ms--)
   {
      delay_ms(1);
   }
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your core is not running at the frequency you think it does.
You either haven't set up the fuses correctly or there is a clock divider in effect (if 8535 has one)

Alex

"For every effect there is a root cause. Find and address the root cause rather than try to fix the effect, as there is no end to the latter."
Author Unknown

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

alexan_e wrote:
Your core is not running at the frequency you think it does.
You either haven't set up the fuses correctly or there is a clock divider in effect (if 8535 has one)

Alex

You mean this setting:(attachment)

I know that all ATmega8535 are set to default oscillator 1MHz by the factory. But I want to use external crystal 12MHz.

Is changing a clock freq to 12000000Hz is enaugh, or I need to add something else? Or set the fuse bit?

Attachment(s): 

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

All your C code examples are fine.
Your Project configuration is fine.

You must change the fuses to use 'High speed crystal'.

You can do this via the CodeVision Programmer Menu. However I find this very non-intuitive.

I suggest that you use Studio4 or Studio6 programmer. However they only support genuine Atmel programmers.

If you must use the CodeVision programmer dialog, sort out which boxes to tick by going to http://www.engbedded.com/fusecalc

David.

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

david.prentice wrote:

If you must use the CodeVision programmer dialog, sort out which boxes to tick by going to http://www.engbedded.com/fusecalc

David.

Well actually I use DT-HiQ Programmer to download hex file into mega8535. What should I do with this?

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

I have no idea what a DT-HiQ Programmer is.

Ok, I googled "DT-HiQ Programmer" and got pictures of some silly Chinese box with a ZIF socket on it.

If you want buy this sort of box, you can sort out your own manuals, user guides etc.

Life is far simpler if you use an Atmel programmer or even a $3.60 Chinese usbasp dongle.

If you want to post a link to an English manual, we can possibly help. Otherwise, you will need to decipher it for yourself. i.e. find out how to read and write the fuses.

David.

p.s. here is the English manual

paragraph 3.3.2 Instructions Menu - items 16-22

These "Universal Programmers" are extremely inconvenient for AVRs. In practice, you really want to program 'in-circuit'.

Last Edited: Wed. Dec 19, 2012 - 10:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, you mean I cannot program the fuse bit using this programmer?? :(

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

Quote:

So, you mean I cannot program the fuse bit using this programmer??

I would think that he means that you might be able to use your programmer to program the fuses, but that he has no advice on how you do that.

The programmer you have is rather "exotic" (rare, unknown to most...). I hav certainly never heard about it before. You will probably have to sort out the questions on how to use it on your own by reading the manuals for it.

The final point that David makes, is that if you would use one of the programmers that are wide spread there would be a bigger chance of you getting help. He also points to the "official" programmers from Atmel, and the USBasp as well know programmers.

Anyway, it should not be impossible to figure this out - you will have to do what everyone successing with microcontrollers must do: Read the documentation.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

I am 99% certain that your 'special' programmer can change the fuses on your (almost-obsolete) ATmega8535.

You will just have to read the paragraph that I quoted. Program the fuses to disable the RC, disable the short-startup. e.g. 17, 20. Then check the results with 21, 22.

Let us know how you get on.

I still recommend buying a different programmer. Your 'special' is very good for 'bog-standard' AT89Cxx devices that need High-Voltage-Parallel-Programming. The AT89Sxxx devices are like AVRs. You can program them in-circuit with a very cheap hardware programmer like usbasp.

David.

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

Well this is the screenshot: (attachment)

If I want to use 12MHz external crystal, which part I should change?
I didn't see CKSEL, CKOPT.
I didn't found disable RC as well.

Attachment(s): 

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

It looks as if the "Manual" is a joke !

Uncheck every box on the "Fuse Low Byte" list.
Did you go to the fuse calculator website?
I provided a clickable link.
There is a limit to the help that someone can give from the other side of the world. I am guessing that you don't live in Wormshill.

Experiment with the boxes on the website.
Read what it says for the 'clock source' as you tick/untick boxes.

David.

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

Quote:

If I want to use 12MHz external crystal, which part I should change?

Certainly the fuse bits I marked in red. Perhaps the fuse bits I marked in yellow.

I must ask you this:

1. Have you read the section in the ATmega8535 data sheet on clock source, clock selection and clock fuses?
2. Have you been to the site that David pointed you to?

Someone here once said "there has got to be a time when the spoon-feeding stops and the learning [as in studying, reading, doing] starts". You're not quite there yet but you are quite close.

Attachment(s): 

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Alright, I take your advices, both.
I will try it first and bring the result here.

BTW, thanks a lot.

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

Hi everybody!!

I did it. Now I don't use that "silly Chinese box with a ZIF socket" anymore.

I use PROGISP with the following setting:
Thanks!!

Attachment(s):