Why is _delay_ms_ behave unpredictably ?

Go To Last Post
81 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ATtiny85 with _delay_ms_ . Weird behavior.

New to AVR programming. I am using this Setup: Visual Studio and Visual Micro with Sparkfun Tiny Programmer.

Using VS Arduino1.6/1.8 Gemma configuration.

I am experimenting with this short bit of code trying to understand why my _delay_ms_ command is not behaving as expected.

When my ATTiny85 boot it will make my LED flash every 12 seconds (6secON 6secOFF), where it should be a 2 seconds period.

After lots of reading and playing around I tried the code line CLKPR = (1 << CLKPCE); Delay got back to normal. I get a 2 seconds period.

Changing F_CPU value from 1MHz to 8MHz makes absolutely no difference.

Why is the delay function not working as expected? I need to understand.

Thanks for any help angel


#define F_CPU 1000000UL  

#define LED_ON PORTB |= (1<<PB1)        //  macro that turn ON  the LED pin6 port PB1
#define LED_OFF PORTB &= ~(1<<PB1)      //  macro that turn OFF the LED pin6 port PB1
#define LED_Toggle PINB |= (1<<PINB1)	//  macro that Toggle the LED

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int main(void) {
     DDRB |= (1 << PB1); // PB1 as Output to drive LED

	while (1) {
		LED_ON;			// Toggle LED On OFF delay 1 second for Clock 1MHz
		_delay_ms(1000);	//  Ask delay 1 second  -  Real delay is 6 seconds
		LED_OFF;
		_delay_ms(1000);	//  Ask delay 1 second

		CLKPR = (1 << CLKPCE);	// After running CLKPCE delay is now back to normal 1 second
		CLKPR = 0;		// Change clock prescaler to 0000  divider by 1
	}
return 0;
}

 

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

F_CPU has ZERO effect on the actual core clock frequency. Nada!

 

What F_CPU does do is tell the software what frequency the clock is operating at. If you lie (that is, use some number for F_CPU that is not the actual frequency), delay will run shorter or longer than it should.

 

F_CPU is also notably used to set the baud rate for the UART and can result in the serial data being sent (or received) at the wrong rate.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

Thank for this confirmation, as I suspected. I still am confused because in this short code, apart from the CLKPR code line, even if I change the F_CPU value from 1MHz to 8MHz the _delay_ms_(1000) is absolutely Not influenced, ei: the initial delay remain 6secON 6secOFF. How can we explain that? If F_CPU only influence the _delay_ms_ function why is there no change in delay ?. I really need to understand that behavior before going further. Thanks for your help.

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

What you report is strange.

 

Do you REALLY have the F_CPU define before 

 

#include <util/delay.h>

 

??

 

Jim

 

 

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

You couldn't get any simpler than that !

 

   #define F_CPU 8000000
// #define F_CPU 1000000     //  Make absolutely No Difference
#include <util/delay.h>
void setup() {      DDRB = 1   ;}

void loop() {

       PORTB = 1;
       delay(500);
      
PORTB = 0;
       delay(500); }

 

I also tried this (thinking maybe the Arduino environment was corrupted somehow ):

     #define F_CPU 8000000
// #define F_CPU 1000000     //  Make absolutely No Difference
#include <util/delay.h>

int main(void) {
    DDRB = 1;

    while (1) {
        PORTB = 1;
        delay(500);
        PORTB = 0;
        delay(500); }
}

 

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

My guess would be that the Arduino system

is including all of these headers itself before

it looks at your code.  When you try to load

util/delay.h it does nothing since it's been

read already, with whatever value of F_CPU

the Arduino has set it to.

 

--Mike

 

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

I will not write "this is why I love assembly", because it will be a non-sense at this point.

But, how is your AVR clock fuses setup?

Most of the small AVRs comes with internal RC clock set to 8MHz with division by 8 active, so it runs on 1MHz.

I don't know if your setup can reprogram the clock fuses, but start to think your setup is running on 1MHz frequency.

You can change that, just need to find our how to change the AVR fuses on your software.

If you were using the USBASP (US$1.50) setup, the cheap USB programmer, I would recommend you to use AVRDUDESS or even Khazama software to read the fuses status.

Wagner Lipnharski
Orlando Florida USA

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

Thanks WagnerLip angel Not too sure, at this point, what fuses means but I did download , installed, WinAVR , AVRdude and AVRdudeSS following your suggestions. Might as well dive deep than contemplate smiley.

Here are my ATtiny85 Fuses setup. Not sure what they mean at this point. I will investigate further. Your input is very welcome. I'm still having this issue where F_CPU as absolutely no effect on my code timing. ??

ATtiny85 Fuse configuration from AVRdudeSS thanks for your help.

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

I've removed the #define F_CPU 1000000 line from my code and added     unsigned long MyCPUf = F_CPU; 

Visual Studio let you peek into the value. IDE show a default value of 8000000 . So now I know that the internal value utilized would be 8MHz.

Still, 8MHz CPU frequency does not explain why my delay(500) turn out to be 4 seconds ?

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

Because F_CPU is set to 8MHz but the chip is really running at 1MHz, eight times slower. When you use delay(500) it generates a loop of several million opcode to execute but it's the number to delay for 500 if the CPU were 8MHz but as it is 1MHz 500ms takes eight times longer, so 4000ms which is 4 seconds.

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

avr-mike wrote:
My guess would be that the Arduino system

is including all of these headers itself before

it looks at your code.

In that case,

OP should be getting a warning about redefining F_CPU.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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

Clawson, thank you for your input. I kind of suspected something like this after further reading. Still, how to explain the fact that if I change F_CPU, regardless of whether the real CPU clock is modified or not (which we know it is not) the delay function keep running with the same delay. I wish someone could come up with a real explanation to this behavior. 

Last Edited: Sun. Apr 7, 2019 - 11:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FredCailloux wrote:

Thanks WagnerLip angel Not too sure, at this point, what fuses means but I did download , installed, WinAVR , AVRdude and AVRdudeSS following your suggestions. Might as well dive deep than contemplate smiley.

Here are my ATtiny85 Fuses setup. Not sure what they mean at this point. I will investigate further. Your input is very welcome. I'm still having this issue where F_CPU as absolutely no effect on my code timing. ??

ATtiny85 Fuse configuration from AVRdudeSS thanks for your help.

 

You can always consult this online fuse calculator, where you can select AtTiny85.

http://www.engbedded.com/fusecalc/

and see exactly the below information.

 

Lets see,  one thing some people forget or really don't know:

Fuses on AVR are programmed reversed, if bit=1 it means it is UNPROGRAMMED.

For the FUSE to be in effect, it must be zero.

 

Low: 0x62     0110-0010:

 

0 : CKDIV8 - Divide Clock by 8  (IT IS PROGRAMMED - This is your problem)

1 : CKOUT  - Clock Output is disable

1 : SUT1 - check start up time along with SUT0

0 : SUT0 - 

 

0 : CKSEL3 - Selection along with the following bits

0 : CKSEL2

1 : CKSEL1

0 : CKSEL0

 

CKSEL3210 = 0010 and SUT1:SUT0 = 10 means "factory default value", Internal RC 8MHz, start up time = 14 clock cycles + 64ms.

If you click the down arrow at the extreme right of the first pull down menu on "Features" of the above online fuse calculator, you will see all possible selections for CKSEL and SUT.

If you will feel courageous enough one day to change clock settings, and plan to use external CRYSTAL, select any of the bottom half of the pull down menu, if by mistake you select "EXT CLOCK" and you have no external clock it will "brick the chip", it will not oscillate with a crystal, it will expect a pulsed line coming from a complete external oscillator.  Most newbies end bricking the chip by misunderstanding the EXT CLOCK with EXTERNAL CRYSTAL.  Again, "Crystal" is part of the internal oscillator of the AVR, the chip will drive and feedback from the crystal.  If set to EXTERNAL CLOCK and you connect a crystal, it WILL NOT oscillate, chip dead, until you connect an external pulsed clock.

 

See, the bit 7 of LOW fuse, CHDIV8 simple divide this 8MHz internal RC oscillator by 8, feeding the chip to run on 1MHz.  If you change that bit to "1", means UNPROGRAMMED, the chip will immediately be 8 times faster... it will fly... ;)

 

Now about the HIGH BYte: 0xDF   1101 1111

 

1 : RSTDISBL - UNPROGRAMMED. If this bit is 0 (programmed) it means the reset function on the pin is not resetting the chip anymore, and you will not be able to further program it via ISP, like USBASP.  Some people need an extra I/O port pin on the chip, so disabling reset you gain PB5 as I/O pin... in some final product it could be neat, but no more programming on it, except if you use some bootloader and program the chip via serial RX/TX pins.

 

1: DWEN - Debug wire UNPROGRAMMED... Good, leave like that.

 

0: SPIEN - Enable Serial Program and Data Downloading, PROGRAMMED - Good, this is what allows you to use the ISP pins to program and read the chip, pins SCK, MISO, MOSI.  If this pin is "1", you lost forever the ability to talk to the chip via ISP.  The only way to reset the fuses to factory default is via "parallel 12V programming", you don't want to go there.

 

1: WDTON = Watchdog Timer UNPROGRAMMED.  If you program this guy, "0", the WDT will reset the chip automaticaly after a certain number of clock cycles. This is used when you don't want the chip to lock or loop in certain routines or waiting some I/O that never happens.  Your software MUST be reseting the WDT before it resets the whole chip, in order to keep the software running okay.  Example, suppose you expect the user to press a key without 8 seconds, else the chip resets.  You don't need to write a special routine for that, just program WDT for 8 seconds, and reset WDT once user presses the key.   Around page 45 of the AtTiny85 datasheet you can find all the WDT configurations, 8s is the maximum, 16ms is the minimum.

 

1: EESAVE = Eeprom memory is preserved through the Chip Erase = UNPROGRAMMED.  It means that when you reprogram the chip, it will do a chip erase, and the eeprom data will also be erased.  Sometimes you don't want to lose the eeprom data when reprogramming, so to have that, just put "0" on this bit (PROGRAM it).

 

1: BODLEVEL2

1: BODLEVEL1

1: BODLEVEL0   This 3 bits specity the Brown-Out Detector Trigger level, it means, if the chip power voltage drops below the specified level here, the chip will reset itself to avoid problems.  As the 3 bits are "1", means UNPROGRAMMED, so it will never reset by voltage drop.

 

The EXTENDED Byte leave 0xFF, it has to be with Self-Programming.

 

One day you need to mess with Fuses bits, just for learning and to feel more confident touching the guts of the beast, but always leave  RSTDSBL=1, SPIEN=0 and never select External Clock, otherwise you may have problems and lose the chip.

 

So, for you to change the chip to run on 8MHz, just change this bit 7 of low byte and that's it.

So, the Fuses will be:

 

LOW: 0xE2

HIGH: 0xDF

EXT: 0xFF

 

You can use any ISP tool to change the fuses, even the one you used to read them.

And then, you will tell the truth for your compiler, saying your chip is running at 8MHz, with #define F_CPU 8000000UL 

 

Cheers.

Wagner Lipnharski
Orlando Florida USA

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

WagnerLip I really appreciate your involvement in this post. I've consulted Engbedded.com , avr-fuse-bits-explained , fuse-bits-arent-that-scary , treehouseprojects.ca/fusebits/

Then I got a headache.indecision Still , none of the content so far have suggested any explanation to the core question: Why is  #define F_CPU as absolutely no effect on my code timing. ??

Some suggested that it may have something to do with the compiler not taking into consideration the #define F_CPU line. Why ? and How to correct it ?

Cheers.

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

FredCailloux wrote:

 Still , none of the content so far have suggested any explanation to the core question: Why is  #define F_CPU as absolutely no effect on my code timing. ??

Perhaps re-phrase the situation NOW.

 

What simple test program are you NOW using?

What speed is your AVR running at NOW?

With that current program, what results are you getting?  What results do you expect?  How are you testing?

Normal stuff like toolchain and version and schematic and clock source and similar.  But, in particular, what optimization level are you building with?

 

It was mentioned earlier the F_CPU has no effect on the speed your AVR is running at.  So yes, you need to re-phrase.  Yes, if you lie to the compiler with an F_CPU value that does not represent the actual speed of your AVR, then delay_ms(1000); will not give you one second.

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Because 8000000 won't fit into an AVR 16-bit  (int) Should the code in #5:

   #define F_CPU 8000000

actually be

   #define F_CPU 8000000UL

 

 

Last Edited: Mon. Apr 8, 2019 - 06:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As Theusch suggested, here is a refresh of the problem description with updated details:
MCU= ATtiny85 /  Setup: Visual Studio and Visual Micro with Sparkfun Tiny Programmer.
Using VS Arduino1.6/1.8 Gemma configuration.

fuse configuration: L=0x62    H=0xdf    E=0xFF
The clock is factory set to 8MHz with CKDIV8 = 0 -> clk divide by 8, hence the CPU run at 1MHz

The code:
 

#define F_CPU 8000000UL  or 1000000UL or 8000000 or 1000000 makes no difference
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
     DDRB |= (1 << PB1); // PB1 as Output to drive LED
	while (1) {
		PORTB |= (1<<PB1);	// LED On
		_delay_ms(1000);	//  Ask delay 1 second
		PORTB &= ~(1<<PB1);	// LED Off
		_delay_ms(1000);	//  Ask delay 1 second
	}
return 0; }

Details: The ATtiny85 is connected with a simple LED and a 430ohms resistor on pin6 PB1. Pin8 to 5Vdc, pin4 to GND, pin1 Vcc, pins 2,3,5,7 not connected.  I'm not sure what is meant by "optimization level". I'm just using the above described setup and upload the simple program and the feedback window shows no error. As it is presently, LED is flashing every 12 seconds, where it should flash at every 2 seconds ( 1000ms + 1000ms = 2000ms = 2 seconds ) . Obviously the internal RC oscillator in the chip could be off by some 10% or 20% worst case, not 600%. This is obviously multiplication factor not correctly applied or interpreted. Right now I am trying to find the solution to 1 only question:

The Question: Why is it that by changing the F_CPU from 8000000 to 1000000 or 8000000UL or 1000000UL it makes no difference in the LED flashing period?

Thanks

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

FredCailloux wrote:

Still , none of the content so far have suggested any explanation to the core question: Why is  #define F_CPU as absolutely no effect on my code timing. ??

 

See #6.

 

Arduino does a lot of stuff for you like

including the avr/io.h header, so it is

going to have set F_CPU to some value

also.  It's this value of F_CPU which is

used by the delay() function, so even

if you later redefine F_CPU to a different

value, the timing of delay() will not be

affected.

 

--Mike

 

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

Can you build the code both for 100000UL and 8000000UL then post the lss file from each here?
.
I have several theories and one involves programming a different hex from the one you are building. The LSS will reveal if the code is changing

Last Edited: Mon. Apr 8, 2019 - 08:40 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

FredCailloux wrote:

Still , none of the content so far have suggested any explanation to the core question: Why is  #define F_CPU as absolutely no effect on my code timing. ??

 

See #6.

 

Arduino does a lot of stuff for you like

including the avr/io.h header, so it is

going to have set F_CPU to some value

also.  It's this value of F_CPU which is

used by the delay() function, so even

if you later redefine F_CPU to a different

value, the timing of delay() will not be

affected.

 

--Mike

 

 

It seems that io.h only checks the chip being used and include the apropriated file.

In case of the AtTiny85 it will include  avr/iotn85.h

Opening this file (all over the net) there is no reference to F_CPU whatsoever, even on this  http://think.ow2.org/kortexdoc/arch/avr/avr.libc.include.avr.iotnx5-h.html  it not states F_CPU.  I know it must be somewhere, because if the user forget to include it, some standard default should take over.

 

So, just for sake of that, I would move the line  "#define F_CPU 8000000UL" to the end of the define lines, right before the "int main(void)", if some strange frequency is defined in obscure previous includes, this will override it. I guess.

Wagner Lipnharski
Orlando Florida USA

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

N.Winterbottom wrote:

Because 8000000 won't fit into an AVR 16-bit  (int) Should the code in #5:

   #define F_CPU 8000000

actually be

   #define F_CPU 8000000UL

No suffix is required.

Given 16-bit ints 8000000 will be signed long.

 

Edit: tipo

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

Last Edited: Mon. Apr 8, 2019 - 11:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think this is just a confirmation of my strong dislike of "arduino".

In an attempt to make C++ simpler than possible it makes you blindly chase rabbits.

Why is there no error message for redefining F_CPU?

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

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

Paulvdh wrote:

I think this is just a confirmation of my strong dislike of "arduino".

In an attempt to make C++ simpler than possible it makes you blindly chase rabbits.

Why is there no error message for redefining F_CPU?

 

The Arduino market intention was not for the semi-pro or even an enthusiast of uC programming.

It was intended for artists and low end blinking led application in general.

For those, if the LEDs were blinking slower than expected, the user just reduce the value in the delay until they were satisfied.

Those people really don't care what is the reason for that.

 

Wagner Lipnharski
Orlando Florida USA

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

Paulvdh wrote:

I think this is just a confirmation of my strong dislike of "arduino".

I think they make great hardware but

the software is ... lacking.  Maybe the

blame should go to the Wiring library?

Quote:

Why is there no error message for redefining F_CPU?

Actually, the Arduino IDE does complain

even at the "Default" level for warnings:

.../Arduino/test_pin_toggle/test_pin_toggle.ino:2:0: warning: "F_CPU" redefined
 #define F_CPU 8000000
 ^

Perhaps the OP has ignored a similar

message?

--Mike

 

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

avr-mike wrote:
Arduino does a lot of stuff for you

...but OP isn't running an Arduino sketch, is he?  No loop() etc.

 

clawson wrote:
post the lss file from each here?
FredCailloux wrote:
 I'm not sure what is meant by "optimization level".

...but that isn't your "only question".  At -O0 the GCC delay functions won't work right.  From the LSS files we can see what is happening with the test program.  Perhaps OP can also post the full build log.

 

Paulvdh wrote:
Why is there no error message for redefining F_CPU?

Why should there be?  If I #define X as something, and redefine it later, is that an error in C?

 

Paulvdh wrote:
In an attempt to make C++ simpler than possible it makes you blindly chase rabbits.

A lively conversation starter, but what does the merits of C++ and Arduino have to do with OP's test C program?

 

Given the source shown, where is any "rogue" redefinition of F_CPU?

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Tue. Apr 9, 2019 - 02:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

...but OP isn't running an Arduino sketch, is he?  No loop() etc.

 

The Arduino stuff is in post #5.

 

--Mike

 

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


made a small test program and tried 1MHz and 8mHz F-CPU value.

I have renamed the lss files so you can identify them.

Winmerge gives distinkt differences were expected:

 

Note I took AS7.0.1931 started a brand new executable project and copied the C program from a comment here.

added a // as to avoid an error on the F-CPU define and just hit " Build"

 

I unfortunately do not have a Tiny85 at hand to actually try the program and see that it indeed does what is expected, but the code suggests there will be a difference.

 

 

Attachment(s): 

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


Well as you can see those are clearly different. The delays are effectively a 24 bit counter. The count for 1MHz is 0x030D3F and the count for 8MHz is 0x1869FF. It's maybe no surprise that 0x30D3F * 8 = 0x1869F8

 

So those two codes have radically different delays and will take a different time to flash when programmed into the hardware.

 

If you are really saying that no matter which one you use the observed flashing is always the same then you are not programming those files into the hardware.

 

There is a "gotcha" in Studio that catches a lot of people - the .hex name in the programming dialog is "sticky" so I rather suspect you once built some variant of code, programmed that, then did something to cause a different .hex to be built (maybe switching between "Debug" and "Release" perhaps?) and now you are building something different to that which you are programming into the AVR.

 

You can verify where the file you are actually building is being created using this ("properties") and looking under "output files" at the details of the .hex file:

 

In my build the file is clearly d:\test\test\Debug\test.hex

 

Then check the name of the file in the Programming dialog. For example I stole this picture from the online manual for AS7:

 

 

In this example the file to be programmed is C:\Atmel\MyProject\MyProjectFlash.hex

 

On your machine make sure that the .hex file listed in "Output Files" is the same file as shown in the programming dialog.

 

BTW if you use some other means to program the code to the AVR (such as avrdude perhaps) then equally check that in the command that invokes it the right pathname is being given for the file that is being built.

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

Cliff,

I posted the code difference as guidance for the OP to clarify were he has to look and spot differences.

 

At the OP: have a look at my example and check that your code does a similar thing.

technically there should be no difference if you use Arduino or just Studio projects. the amount of code will be the same, but the count down counters will have a different value.

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

Oh sorry, I thought that was OP finally posting the LSS I'd asked for. Not concentrating blush

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

Towards the end of this discussion there appear to be an explanation and some suggestions on how to change F_CPU.

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

Arduino was a market phenomenon like several others.  Something that appeared in the market at the right time, with right approach, and mostly, by the right price.  It isn't because it was super-dee-duper-good, lack of competition with the same intentions was mostly the rocket that raised it into orbit.  I remembered several other "testing" and "learning" boards in the market, most of them dedicated for the persons that wanted to learn about microcontrollers and programming, but none specifically dedicated for the ones "not wanting" to learn it all, just use.   In some relative way, humans doesn't want to lose time learning about how a plier is made, forge metals, and how to assemble it, they just want a tool that they can use and to be very simple to deal with.  Tools help us to reach a goal, complete an objective, finish a task.  Right along Arduino and a little bit after that, hundreds of other "competitors" were launched, prices not so bad, RASPI was one of those, it sells pretty good, but obviously it requires "some" expertise to use it, install software.  As far as I can see, RASPI greatest use is for multi-media player, it has all the chipset and connectors for it, without the HDMI port it would be almost useless.  Like it or not, Arduino became a greatest hit, its price pushes people that has no electronics or programming knowledge whatsoever to buy (even in kit with several components and adapters), and lots of them just let it collect dust, but some people goes happy because they were able to build a "Love-O-Meter", or "Mood Cue", so you see, is not the Arduino that sells, the italians created "happiness in a box", other than "pizza".  There are some strong study material opportunity about marketing in the Arduino, some competitors just never understood it.

Wagner Lipnharski
Orlando Florida USA

Last Edited: Tue. Apr 9, 2019 - 02:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

Paulvdh wrote:

Why is there no error message for redefining F_CPU?

 

Why should there be?  If I #define X as something, and redefine it later, is that an error in C?

Yes.

So far as I know, most compilers will just give you a warning,

but they will give you something.

#undef exists to allow deliberate redefinition.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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

For clawson and all others involved in this investigation work, thanks a lot guys.

Here is a test I did involving compilation of exactly the same code except for the #define line 8000000 and 1000000.

Visual Studio fill a folder called /Release. in it are 9 files (see table)

     File	                         size	  Compare	extension
     name	                         byte	  content	name
board.buildinfo	                         18,944  different 	buildinfo
Blink8MHz.cpp.d	                         935 	 different 	d
Blink8MHz.elf	                         6,188 	 different 	elf
Blink8MHz.ino.elf	                 6,188 	 different 	elf
Blink8MHz.ino.with_bootloader.hex	 8,183 	 identical 	hex
Blink8MHz.with_bootloader.hex	         8,183 	 identical 	hex
Blink8MHz.hex	                         283 	 identical 	hex
Blink8MHz.ino.hex	                 283 	 identical 	hex
Blink8MHz.cpp.o	                         3,540 	 different 	o

This table show 9 files from the 8MHz version of the simple code. An identical folder is also created from the 1MHz version.

In both folders we find the exact same file names except from the 8MHz to 1MHz.

All files are the same size from folder A to folder B

Not all files are content identical. Only the *.hex files are content identical from folder A to folder B.

We start to see a hit here. I.E. all hex files of same name are identical. No wonder the code makes no difference between F_CPU 8MHz or F_CPU 1MHz

If this up-loader sends an HEX file identical whether 8 or 1 MHz  this would explain the idiosyncrasy.

Now the question is slowly shifting.

 

QUESTION: Why would Visual Studio not build a difference compile file between two #define lines ?

Where should I look to correct this problem ?

Should I dump using Visual Studio Visual Micro ? (damn!  I started to get acquainted with the UI crying )

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

It's the .Lss files that would be of use. There is a tick box in AS7 project settings to ensure they are created.

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

clawson,  I cant find any tick box within Visual Studio related to *.Lss files. Would there be a descriptive name perhaps ?

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

Project > (yourprojectname) properties > AVR/GNU common > Output files > .lss (generate lss file)

 

Then after building, you find the file in Solution Explorer > Output files > (yourprojectname).lss

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

Jim I am using Visual Studio , not Atmel Studio, Visual Studio

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

skeeve wrote:
Yes.

 

So far as I know, most compilers will just give you a warning,

I didn't say anything about a warning, whatever level.  I was responding to the harrumph about no >>error<<.  Aren't all errors during the syntax passes of the compiler against the rules of C?  Maybe not; never really studied it.

FredCailloux wrote:
Only the *.hex files are content identical from folder A to folder B.

Which makes a guess that the .HEX file isn't what you think it is.

 

You showed a screen shot of your project -- yet haven't dug out the optimization level?

 

Your screen shot showed the build log specification -- but you haven't posted that?  [I'll make a guess that the full name of the hex file will be in that build log...]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

The draft standard for C11 I have (n1570.pdf) says

 

"An identifier currently defined as an object-like macro shall not be redefined by another
#define preprocessing directive unless the second definition is an object-like macro
definition and the two replacement lists are identical."

 

 

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

OK MattRW - If I understand correctly :  #define F_CPU 8000000 is useless since F_CPU is already defined in an #include file such as io.h or delay.h ?

If I use  #if defined F_CPU     #undef F_CPU   #endif  and then I redefine F_CPU  should the new F_CPU be taken into consideration correctly ?

I tried it and still makes no difference. Whether I put in 8000000 or 1000000 it doesn't make any difference, even worst, it doesn't give the proper timing period.

_delay_ms(1000) gives 8 seconds delay, _delay_us(500) gives 4mSec, _delay_loop_1(500) gives 750uSec, _delay_loop_2(500) gives 1.9mSec, with either 1MHz or 8MHz F_CPU, even after #undef.

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

Talking about the normal compiler here.... as I know the arduino has some modifications, buty I do not know which exactly...

 

Normally F_CPU is not defined in either io.h or delay.h.

having said that..... in delay.h there is a 'Safety define' for F_CPU. If you have not defined F_CPU in your program the delay will give a warning ( F_CPU not defined)  and will define it as 1MHz.

 

interestingly.....

you state that _delay_ms(1000) gives a factor of 8 difference this smells like a clkdiv8 fuse that is not set and the compiler thinking it runs on 8MHz but actually it runs only at 1MHz

Same goes for the _delay_us(500) going to 4ms, that also is a factor 8.

The other 2 I do not know what they actually do as they do not seem to have a time reference in the name and thus might well be just burning cycles uncalculated.

 

Perhaps post the INO project such that others can have a look. I would have expected david prentece to be onboard by now, but as this is placed in the general mega/tiny forum it might be that he does not bother to look.

 

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

FredCailloux wrote:
Jim I am using Visual Studio , not Atmel Studio,
How on earth do you use visual studio to invoke avr-gcc? The dialog you show talks about "win32", "Mfc" and creating .exe ??

 

Anyway, assuming that in the guts somewhere it is invoking avr-gcc tools then add a post build step that does an "avr-objdump -S output_file.elf > ouptut_file.lss" (replacing "output_file" with the real ELF name) and this will perform the step that would usually create an LSS.

 

BTW I do wonder thought what possible merit there is in trying to persuade Visual Studio to build AVR code when Atmel Studio 7 *is* Visual Studio 2015 but completely re-engineered to do the best job possible of building avr-gcc code.

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

FredC,  My reading of the standard is that

 

#define FOO 1

#define FOO 1

 

is legal but

 

#define FOO 1

#define FOO 2

 

is not. 

 

How your compiler handled it I don't know.   Here is what I get from avr-gcc:

 

zz.c:2:0: warning: "FOO" redefined
 #define FOO 2

 

 

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

FredCailloux wrote:
using Visual Studio Visual Micro

OP keeps referring to VS/VM and it looks like you all are assuming he/she means AS7! 

Perhaps a clarification of what the OP is actually using and on what platform OS would be helpful?

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
https://www.onegold.com/join/7134f67c2b814c5ca8144a458eccfd61

 

 

 

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

Jim,

the OP states in his first post:

 

New to AVR programming. I am using this Setup: Visual Studio and Visual Micro with Sparkfun Tiny Programmer.

Using VS Arduino1.6/1.8 Gemma configuration.

 

so he is using visual studio and the Arduino compiler.

As I demonstrated with my tiny program there is a clear and distinct difference between 1MHz and 8mHz compile when using GCC.

 

As already said the OP best make a INO ( arduino project file) that has this problem with him and post it here.

There are a number of freaks here that do also have arduino installed so they should be quickly able to see what is wrong ( OP also states to be a newbie).

 

 

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

MattRW wrote:

is legal but

 

#define FOO 1

#define FOO 2

 

is not. 

Yet you say

MattRW wrote:

I get from avr-gcc:

 

zz.c:2:0: warning:

GCC is pretty darnd close (if not exact) to the applicable standard, if you invoke that checking.  [Which standard level did you tell your project to use?]

 

re the standard:  Now I have to dig into the standardese to see what an "identifier" means in this pre-processor context, as well as what an "object-like" macro is.

 

If OP would post the build log for the test program, and the LSS output, then we don't have to debate how many angels are dancing on the head of this pin.  It is a simple C [still not clarified] test program.  The entire source and build results can easily be examined -- if revealed to us.  Is F_CPU value passed to the build?  Does an app get a warning if overridden in the source? 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

An object-like macro is one without a parameter list.

A function-like macro is one with a (possibly empty) parameter list.

 

As a rule, compilers give you warnings about two things:

valid, but dubious code, e.g. "if(x=1) ..."

and invalid code (errors) that it will let you live with, e.g. redefining a macro name.

 

BTW the GNU guys have an ongoing feud with

compiler-testers over the meaning of "diagnostic message".

The GNU guys think warnings count.

Most compiler-testers don't count them,

hence -pedantic-errors.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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


skeeve wrote:

An object-like macro is one without a parameter list.

A function-like macro is one with a (possibly empty) parameter list.

 

Thanks.  Still, I need to find carefully where a redefinition occurred in the posted dozen-line program.

 

For fun,

I took the test program from above.  I played with MYTEST and got the redefinition warning.  No redef warning for F_CPU until I put it in the Symbols section of the project.  -Os and c99

 

I'm still unclear about that Visual Studio versus Atmel Studio thing.   So much could be resolved with a few chosen answers/posts.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

One of my early thoughts was "Symbols" in project properties making a -DF_CPU=nnnnUL that would over-ride any subsequent #define in .h/.c files. But if that were occurring then as Lee showed there would have been warnings about redefinition.

 

Or maybe there are? Now we know this is some mickey mouse visual micro nonsense and not AS7 then perhaps it's just failing to show such a warning or it has some different -D mechanism? Perhaps such a warning was given an OP chose to ignore?? (unwise I now but some people apparently do ignore warnings)

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

Is there a way to show the command to avr-gcc?   I usually include the argument "-DF_CPU=16000000" to avr-gcc and don't define it in any file.  

 

EDIT: Oh, it says defined on the command line.

Last Edited: Wed. Apr 10, 2019 - 04:45 PM

Pages