4

I'm using this function:

__delay_cycles(var); 

and I get the following error:

Argument to _delay_cycles must be a constant expression

Fair enough! But how can I bypass this? I have to delay my program with a different value every time. I receive my data from RS232 and I sore it in an int variable. I have to use this function and I can't modify its structure. I'm using AtMega16.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • 1
    [This thread on the TI support forum](http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/18638.aspx) appears to answer your question. As noted in the thread, `__delay_cycles` generates code at compile-time, which is why the argument must be constant. – Raymond Chen Nov 08 '11 at 20:54
  • Based on your reply to aix, this sounds like homework. If so, please tag the question as such. – Sam Skuce Nov 08 '11 at 21:44
  • 1
    `__delay_cycles()` requires a constant expression. You have to use `__delay_cycles()`. You can't give it a constant expression. Conclusion: Either one of the above assumptions is incorrect, or there is no solution to your problem. Explaining exactly *why* you have to use this function would be very helpful; the obvious answer is "use something else". – Keith Thompson Nov 08 '11 at 22:55
  • It doesn't make sense that it must have a constant as parameter, unless __delay_cycles() is some sort of icky macro. C implicitly converts non-const function parameters to const ones for you - it is the other way around which is the big no-no. – Lundin Nov 09 '11 at 12:18
  • 1
    @Lundin: It is an "intrinsic", a function-like syntax that is built into the compiler and causes it to generate code directly without importing library code. That is why the compiler error is so specific. – Clifford Nov 09 '11 at 20:44

3 Answers3

3

One suggestion that immediately springs to mind is to call __delay_cycles() with a constant argument, but do it in a loop, and vary the number of loop iterations.

The loop will add some overhead, so if you need precision you'll have to subtract the (constant) cost of one loop iteration from the (constant) argument to __delay_cycles().

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • i'm not allowed to do this. It works this way but i have to try something else. – Black Joker Nov 08 '11 at 20:58
  • 4
    @Black: "not allowed"!? Why not? Not allowed to get work done by the sounds of it. What pointy-haired moron imposed that constraint? Don't use __delay_cycles() at all is probably the correct answer. If you need a significant time delay, use a hardware timer and poll it or wait on its interrupt. – Clifford Nov 08 '11 at 22:02
  • 1
    He is probably not allowed, because it is a very bad idea to build delays using loops? This answer is a beginner/hobbyist one. You'll have to disassemble the loop each time you compile at worst, each time you change compiler and optimizer settings at best. And if you change the CPU clock, all bets are off. Use on-chip hardware timers for this. – Lundin Nov 09 '11 at 12:16
  • @Lundin: I was assuming that he meant that he was obliged to use __delay_cycles(), rather than just not allowed ot use a loop. Neither is a good idea in this case. – Clifford Nov 09 '11 at 20:56
2

Don't use that function. It is apparently some non-standard Texas junk that doesn't behave according to the rules of the C language. Write your own delay function using on-chip timers instead, or find one on the net. Takes less than 1 hour of work, which is no doubt less time than you will spend pondering the meaning of various non-standard junk.

The real reason why the embedded industry have so many crappy compilers, is because embedded programmers accept to be constantly fed with non-standard junk, even when there is no reason what-so-ever to deviate from the C standard.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 2
    Unfortunately, many of people who write embedded software are poor C programmers and don't know well the C standard if at all. Many think C is assembly. They will not use volatiles, they will implement delays as nested loops that do nothing (which means delays depend on how the code's compiled/optimized) and do other nasty things and hope everything will work. And it often does. Predefining special variables may actually be helpful here as it will be easier to write code and the compiler will take care of the volatile aspect. OTOH, it's a kind of way to attract and retain consumers too. – Alexey Frunze Nov 09 '11 at 13:03
  • @Alex: Sad but true. I always say that the embedded programming branch consists of 10% professionals, 40% beginners and 50% quacks. I don't work a lot with Texas chips, but the little I have seen from their data sheets, app notes and source codes, suggests that most of them belong with those latter 50%. – Lundin Nov 09 '11 at 14:30
  • 1
    @Lundin: ATMega16 is not a TI chip, somone else mentioned TI, they just happen to have an identically named intrinsic. It is sad that you and Alex appear to have such a dim view of embedded systems programmers. There are poor programmers in all domains I suggest; in embedded systems it is perhaps harder to get away with it, without being exposed. – Clifford Nov 09 '11 at 20:50
  • @Clifford: Oh ok, someone linked to TI and there the function was. I suppose TI and Atmel both use it - still, my answers stands, don't accept to be handed non-standard crap when there is no reason for it. – Lundin Nov 10 '11 at 07:45
  • 1
    My view of programmers in general and embedded programmers in particular is very cynical but comes from real life experience. I think the main problem is that many of them are electronic engineers without any proper, in-depth study of program design, OO concepts etc. They write C like they write VHDL. Or alternatively they are PC programmers who know how to structure their programs, but are clueless of what CPU instructions their programs turn into, and even more clueless about anything hardware-related. – Lundin Nov 10 '11 at 07:48
0
if(var==1)
  __delay_cycles(1);
else if(var==2)
  __delay_cycles(2);
else if(var==3)
  __delay_cycles(3);

...and so on.

Frederico
  • 101
  • 1
  • 1
  • 4