Setting fuse bytes of atmega328

I regularly order self made boards with SMT assembly. They come with blank atmega328 chips. The first time when I tried programming one I noticed that the clock speed was around 1/16 of what it should be. Than I realized, o yeah... I have to bootloader first because of fuse settings.

To eliminate the process of burning the bootloader. What fuses and all can I set in the source code of my programs? The atmega should just behave like it is an average arduino nano.

I typically do 'normal' things with coding. So I use analogWrite(), millis(), analogRead() etc.

In boards.txt I found these lines

nano.menu.cpu.atmega328.bootloader.low_fuses=0xFF
nano.menu.cpu.atmega328.bootloader.high_fuses=0xDA
nano.menu.cpu.atmega328.bootloader.extended_fuses=0xFD

I am looking the datasheet and I found the fuse bits.



Wat I don't understand is how I can write values to the registers. I understand how I can address each bit manually, but how do I write all 8 bits at once? Is that possible at all to begin with?

Kind regards,

Bas

You can't set the fuses from your source code
Only during programming using ICSP

to write bootloader and to write only fuses needs nearly the same time amount

You can use avrdude tool from the command line to program fuses, see the avrdude UG. It is programmed by bytes: low fuse byte, high, etc. You can program just one fuse byte, avrdude switch is like this: "-U lfuse:w:0xF7:m".
It is possible to do this in your program (atmega's datasheet, ..avr/boot.h), but why? Especially if "the atmega should just behave like it is an average arduino nano", you will need to do this just once. This is the configuration and you don't suppose to do it in the program.

Ok Thnx for the replies. I get it now.

You can't set the fuses from your source code
Only during programming using ICSP

Ok clear.

It is a board design for other people and I am working on a 2nd easier method (1st method being the Arduino IDE) to program the board. I prefer to have it is as simple as people unzipping a folder of mine, set the COM port in some file and double click on someBatchFile.bat to do the programming. I have used a batch script in the past for flashing boards.
Than people don't need to install the arduino IDE at all.

to write bootloader and to write only fuses needs nearly the same time amount

It is not so much about speed, but about 'labour' (2 whole mouse clicks, right?). How fewer mouse clicks an a-technical person has to do, how fewer things can go wrong.

I think I am best off with a script which uses avrdude to burn both bootloader/set fuses and flash the board.

You can use avrdude tool from the command line to program fuses

Unless if I get this to work. I am happy either way. Whatever works!

Regards :coffee: ,

Bas

has nothing to do with fuses

That's true but what good does that do you. If you don't have a bootloader, then you need an ICSP programmer

a-technical person has

has nothing to do with fuses

I was providing background information I was not trying to provoke an off-topic discussion... Besides the a-technical person has everything to do with the fuse bits. He would be following a tutorial with which his actions will set the fuses. He is just not aware about any of this.

(Jim, that quote was of Budvar not of mine)

.. what good does that do you If you don't have a bootloader, then you need an ICSP programmer

I don't have USB or breakout Uart pins either. I need to program once, fire and forget.

What good it does? Well it simply gets my design to work. That's all. The fuses have te be set one way or another don't they? We are talking about blank chips. Whether the fuses are set during bootloader burning or flashing the final program does not really matter to me. Just as long as it works.

I dug up the script I once used. The upload line is this one. (It could pick different .hex files to use)

avrdude -C avrdude.conf -p atmega328p -c arduino  -P %comNumber% -b 57600 -D -U flash:w:%interface%_%baseType%.hex:i

I am not entirely sure yet how to add the fuse arguments. Can I just add more -U entries like

avrdude -C avrdude.conf -p atmega328p -c arduino  -P %comNumber% -b 57600 -D -U flash:w:%interface%_%baseType%.hex:i -U lfuse:w:0xF7:m  // followed by the other fuses

or put more instructions behind the -U like?

avrdude -C avrdude.conf -p atmega328p -c arduino  -P %comNumber% -b 57600 -D -U flash:w:%interface%_%baseType%.hex:i lfuse:w:0xF7:m  // followed by the other fuses

Tonight I wil look the verbose output for bootloadering an arduino Nano.

Regards :coffee:

Bas

if i hit "Burn bootloader" Arduino IDE say:

avrdude -CC:\Users\user\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -cusbasp -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m 

You can only do this if you're using an ISP programmer (not -c arduino).

But yes, all operations can be done with a single command. Load a hex file to flash, and set all fuse bits.

When using a USBasp programmer for instance, the command would be something like this:

avrdude -C avrdude.conf -c usbasp -p atmega328p -U lfuse:w:%lfuse_val%:m -U lfuse:w:%hfuse_val%:m -U lfuse:w:%efuse_val%:m  -U flash:w:%interface%_%baseType%.hex:i

Yes, you can, like @kolaha and @hansibull wrote. However, you have to have use ISP programming and according -c arduino in your commands it seems that you did not.

I use an arduino nano as ISP programmer. (I once made a fancy pcb for it with ZIF socket for attiny chips and a pogo pin clamp)

Ok I get that I need to add a separate-U before every fuse setting. :ok_hand: That I can do.

Btw, is it a bug or something that the output of avrdude is missing spaces?

-patmega328p  instead of -p atmega328

I have been wondering this for years but never looked for an anwser :thinking:

Regards :coffee:

Bas

The spaces don't have to be there at all, they're optional. I actually prefer without, since it makes it more obvious which parameter the flag belongs to

No difference for avrdude.

For years? Just try it in CMD and you will have an answer instantly.

1 Like

This script here seems to work. Clock frequency checks out allright. Had to do a little bit more reverse engineering with the IDE and verbose mode.

echo off
setlocal EnableDelayedExpansion
(set \n=^
%=Do not remove this line=%
)

set /p comNumber= "select comport number!\n!!\n!"

echo UPLOADING OSSD.hex on COM%comNumber%

tools\avrdude -C tools\avrdude.conf -p atmega328p -V -c stk500v1 -P COM%comNumber% -b 19200 -D -U flash:w:bin\OSSD.hex:i -U efuse:w:0xFD:m -U hfuse:w:0xDE:m -U lfuse:w:0xFF:m

pause

It yields this result.

I think that 'programming' (or flashing actually) doesn't get much simpler than this.
With the upper line you can 'prepare' an Arduino by turning it into a programmer
And the 2nd well. see the screenshots.
afbeelding

Many thanks for all your assistance. :tumbler_glass:

Bas

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.