Author Topic: Setting AVR Fuses in C code  (Read 626 times)

Offline mikejp56

  • Single posting newcomer
  • *
  • Posts: 7
Setting AVR Fuses in C code
« on: April 11, 2024, 01:37:27 am »
Hi All,
I am pretty new to CodeBlocks and Atmega 328P programming.
I have a simple code that blinks and LED and uses the default fuse settings for the 3 fuses in fuse.c. I would like to change the lfuse setting from 0x62 to 0xFF so I can use a crystal. How would I change ".low=LFUSE_DEFAULT" to use 0xFF? I have tried multiple things; .low=0xFF, etc. and I keep getting errors for the setting. I can change the lfuse setting in AVRDUDESS and AVRDude and the crystal setting works. I just cannot figure out the syntax for CodeBlocks.
By the way this is an awesome program for a non-programmer to learn on!
Thanks and regards.
mikejp56

PS Sorry if this is a cross post. I was advised that the original post was in the wrong place (General).

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7588
    • My Best Post
Re: Setting AVR Fuses in C code
« Reply #1 on: April 11, 2024, 01:58:15 am »
FYI: You likely are having problems with the compiler syntax instead of with Code::Blocks syntax.

Tim S.
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 64 bit.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline mikejp56

  • Single posting newcomer
  • *
  • Posts: 7
Re: Setting AVR Fuses in C code
« Reply #2 on: April 11, 2024, 02:07:24 am »
Hi stahta01,
Thanks for that. I tried googling but I came up pretty empty.
What I did figure out was that I need to put Fuses = and then some braces and then I cannot figure out how to enter the fuse parameters and the correct syntax. Any guidance would be greatly appreciated.
Thanks.
Regards,
mikejp56

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7588
    • My Best Post
Re: Setting AVR Fuses in C code
« Reply #3 on: April 11, 2024, 02:47:09 am »
You know what compiler you are using! I do not! Therefore, I cannot help you.

Tim S.
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 64 bit.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2769
Re: Setting AVR Fuses in C code
« Reply #4 on: April 11, 2024, 06:57:14 am »
Does this make any sense?
Quote
User
I am pretty new to CodeBlocks and Atmega 328P programming.
I have a simple code that blinks and LED and uses the default fuse settings for the 3 fuses in fuse.c. I would like to change the lfuse setting from 0x62 to 0xFF so I can use a crystal. How would I change ".low=LFUSE_DEFAULT" to use 0xFF?
ChatGPT
In Atmel AVR programming, the fuses control various settings of the microcontroller, including clock source, brown-out detection, and more. To set the low fuse to use an external crystal oscillator, you'll want to set the lfuse to 0xFF.

Here's how you can modify the .low=LFUSE_DEFAULT to set the lfuse to 0xFF:

c
Copy code
#include <avr/io.h>
#include <util/delay.h>

// Default fuses
FUSES = {
    .low = (LFUSE_DEFAULT & ~FUSE_CKDIV8 & ~FUSE_SPIEN & ~FUSE_BODLEVEL1 & ~FUSE_BODLEVEL0),
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};

// Modified fuses
FUSES = {
    .low = 0xFF, // Sets the lfuse to use an external crystal oscillator
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};

int main(void) {
    DDRB |= (1 << PB5); // Set PB5 (Arduino pin 13) as output

    while (1) {
        PORTB |= (1 << PB5);  // Turn on LED
        _delay_ms(1000);     // Delay for 1 second

        PORTB &= ~(1 << PB5); // Turn off LED
        _delay_ms(1000);     // Delay for 1 second
    }

    return 0;
}
In this code snippet, I've provided both the default and the modified fuses for your Atmega328P. The FUSES struct is used to define the fuse settings for the microcontroller.

Make sure to include <avr/io.h> for AVR specific I/O definitions and <util/delay.h> for the _delay_ms() function.

Also, ensure that you have the appropriate toolchain set up to program your Atmega328P with the new fuse settings. You'll need a programmer like AVRISP mkII or USBasp and a software like avrdude or Atmel Studio to set the fuses.

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2769
Re: Setting AVR Fuses in C code
« Reply #5 on: April 11, 2024, 06:57:59 am »
Be careful. Validate the code before using it.
Chatty can make things up ya know.

User
Can you translate that to c++
ChatGPT
Certainly! Here's the code translated to C++:

cpp
Copy code
#include <avr/io.h>
#include <util/delay.h>

// Default fuses
struct Fuses {
    uint8_t low;
    uint8_t high;
    uint8_t extended;
};

Fuses fuses_default = {
    .low = (LFUSE_DEFAULT & ~FUSE_CKDIV8 & ~FUSE_SPIEN & ~FUSE_BODLEVEL1 & ~FUSE_BODLEVEL0),
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};

// Modified fuses
Fuses fuses_modified = {
    .low = 0xFF, // Sets the lfuse to use an external crystal oscillator
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};

int main(void) {
    DDRB |= (1 << PB5); // Set PB5 (Arduino pin 13) as output

    while (1) {
        PORTB |= (1 << PB5);  // Turn on LED
        _delay_ms(1000);     // Delay for 1 second

        PORTB &= ~(1 << PB5); // Turn off LED
        _delay_ms(1000);     // Delay for 1 second
    }

    return 0;
}
In this C++ version, I've used a struct to define the Fuses and initialized two instances: fuses_default and fuses_modified. The .low, .high, and .extended members of the Fuses struct correspond to the low, high, and extended fuse bytes, respectively.

The rest of the code remains the same. Make sure you have the AVR GCC toolchain installed to compile and upload this C++ code to your Atmega328P microcontroller.




« Last Edit: April 11, 2024, 07:00:16 am by Pecan »

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2769
Re: Setting AVR Fuses in C code
« Reply #6 on: April 11, 2024, 07:07:46 am »
User
Did you make up this solution or is it actually true?

ChatGPT
The solution I provided is based on typical Atmel AVR programming practices and should work for setting the low fuse to 0xFF to use an external crystal oscillator with an Atmega328P microcontroller. The code structure and the fuses settings are common in AVR programming.

Here's a breakdown of the provided code:

cpp
Copy code
#include <avr/io.h>
#include <util/delay.h>

// Default fuses
struct Fuses {
    uint8_t low;
    uint8_t high;
    uint8_t extended;
};

Fuses fuses_default = {
    .low = (LFUSE_DEFAULT & ~FUSE_CKDIV8 & ~FUSE_SPIEN & ~FUSE_BODLEVEL1 & ~FUSE_BODLEVEL0),
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};

// Modified fuses
Fuses fuses_modified = {
    .low = 0xFF, // Sets the lfuse to use an external crystal oscillator
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};

int main(void) {
    DDRB |= (1 << PB5); // Set PB5 (Arduino pin 13) as output

    while (1) {
        PORTB |= (1 << PB5);  // Turn on LED
        _delay_ms(1000);     // Delay for 1 second

        PORTB &= ~(1 << PB5); // Turn off LED
        _delay_ms(1000);     // Delay for 1 second
    }

    return 0;
}
The Fuses struct is used to define the low, high, and extended fuse settings.
fuses_default contains the default fuse settings.
fuses_modified contains the modified fuse settings with the low fuse set to 0xFF.
This code should be compatible with the AVR GCC toolchain, which is commonly used for Atmel AVR programming.

However, when changing the fuse settings, it's crucial to be cautious and ensure that the settings are appropriate for your specific hardware setup and requirements. Incorrect fuse settings can prevent the microcontroller from working correctly.

You'll also need to use a programmer like AVRISP mkII or USBasp and a software like avrdude or Atmel Studio to set the fuses on your Atmega328P microcontroller.

Always make sure to double-check the fuse settings and consult the Atmega328P datasheet and the fuse bit settings in the avr-libc documentation to ensure the correct configuration for your needs.

Offline mikejp56

  • Single posting newcomer
  • *
  • Posts: 7
Re: Setting AVR Fuses in C code
« Reply #7 on: April 11, 2024, 02:24:32 pm »
Hi Pecan,
That is what I am looking for. Setting the fuses in the c code. I was not aware of the Fuses struct.
Where might I find docs of that sort?
Thanks again.
mikejp56

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2769
Re: Setting AVR Fuses in C code
« Reply #8 on: April 11, 2024, 06:03:57 pm »
Do a google lookup of "ATMEGA328P Datasheet" or any datasheet of the chip you're interested in.

I haven't done embedded programming for years now (since 2019), so my knowledge of the newer chips is more than rusty.

Lately I've found ChatGPT to be quite helpful if you tightly focus your query (prompt) and *always* verify the answer.

On a wider focused query I've found ChatGPT will make anything up when it does not have specific training on the subject. It has never said, "I don't know" when it should.

You can always ask it where it got the information. Then follow up with your own verification.

For example:
Code
User
Where can I get more information on the fuse structure code?
ChatGPT
To get more detailed information on the fuse structure and the fuse settings for Atmel AVR microcontrollers, you can refer to the following resources:

Atmel AVR Datasheets
The most comprehensive source of information on fuse bits and their meanings is the Atmega328P datasheet. The datasheet provides detailed explanations of each fuse bit and its effect on the microcontroller's operation.

You can download the Atmega328P datasheet from the Microchip Technology website:
Atmega328P Datasheet

AVR Libc Documentation
AVR Libc is a library of standard C functions for Atmel AVR microcontrollers. The documentation provides detailed information on the predefined fuse settings and the fuse structure.

You can find the AVR Libc documentation here:
AVR Libc Documentation

AVRDUDE
AVRDUDE is a command-line utility for programming Atmel AVR microcontrollers. It supports reading and writing fuse settings and provides a list of available fuse bits and their meanings.

You can find more information about AVRDUDE and its supported commands here:
AVRDUDE Documentation

Example Code
Here is an example of how the fuse settings are typically defined in Atmel AVR programming:

c
Copy code
#include <avr/io.h>

FUSES = {
    .low = (LFUSE_DEFAULT & ~FUSE_CKDIV8 & ~FUSE_SPIEN & ~FUSE_BODLEVEL1 & ~FUSE_BODLEVEL0),
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};
In this example:

.low sets the low fuse bits. LFUSE_DEFAULT is a predefined value for the default low fuse settings.
.high sets the high fuse bits. HFUSE_DEFAULT is a predefined value for the default high fuse settings.
.extended sets the extended fuse bits. EFUSE_DEFAULT is a predefined value for the default extended fuse settings.
Fuse Bits
Here are some common fuse bits and their meanings:

CKDIV8: Clock Divide by 8 Enable. When this fuse is programmed, the system clock is divided by 8.
SPIEN: Serial Programming and Data Downloading Enable. When this fuse is programmed, the SPI programming interface is enabled.
BODLEVELx: Brown-Out Detector (BOD) Voltage Level. These bits set the BOD trigger level.
BOOTSZx: Boot Loader Section Size. These bits determine the size of the boot loader section of the flash memory.
EESAVE: EEPROM Memory Preserve Enable. When this fuse is programmed, the EEPROM memory is preserved during chip erase.
Example of Setting the Low Fuse to 0xFF
To set the low fuse to 0xFF to use an external crystal oscillator, you can do the following:

c
Copy code
FUSES = {
    .low = 0xFF,
    .high = (HFUSE_DEFAULT & ~FUSE_BOOTSZ1 & ~FUSE_BOOTSZ0 & ~FUSE_SPIEN & ~FUSE_EESAVE),
    .extended = EFUSE_DEFAULT,
};
Summary
Consult the Atmega328P datasheet for detailed information on fuse bits and their meanings.
Refer to the AVR Libc documentation for information on predefined fuse settings and the fuse structure.
Use AVRDUDE to read and write fuse settings and to get a list of available fuse bits and their meanings.
The example code shows how to define and modify fuse settings in Atmel AVR programming.
By combining information from these resources, you can gain a comprehensive understanding of fuse settings and how to modify them for your specific needs.

« Last Edit: April 11, 2024, 06:45:41 pm by Pecan »