Author Topic: max bit variable in AVR  (Read 1529 times)

0 Members and 1 Guest are viewing this topic.

Offline tariqTopic starter

  • Contributor
  • Posts: 24
  • Country: ir
max bit variable in AVR
« on: July 22, 2021, 06:32:46 pm »
hi I'm using AVR codevision after defining 16 bit variable I get this error :
too many global/static 'bit' variables
Does bit variables are limited in AVR?or they are just limited in codevision?or it's something else?
« Last Edit: July 22, 2021, 06:36:45 pm by tariq »
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: gb
Re: max bit variable in AVR
« Reply #1 on: July 22, 2021, 06:57:02 pm »
Show us the part of the code causing problems.
 

Offline tariqTopic starter

  • Contributor
  • Posts: 24
  • Country: ir
Re: max bit variable in AVR
« Reply #2 on: July 22, 2021, 07:05:34 pm »
its on the last bit variable.
 

Offline jenniferkim

  • Contributor
  • Posts: 12
  • Country: ae
Re: max bit variable in AVR
« Reply #3 on: July 22, 2021, 08:53:29 pm »
There is no support for bit type in AVR. You can use a struct like this:

Code: [Select]
typedef struct {
    uint8_t bit0:1;
    uint8_t bit1:1;
    uint8_t bit2:1;
    uint8_t bit3:1;
    uint8_t bit4:1;
    uint8_t bit5:1;
    uint8_t bit6:1;
    uint8_t bit7:1;
} BitField;

typedef union {
    BitField asBits;
    uint8_t asByte;
} BitByte;

BitByte mBitField;

And to access one bit at once you only have to

Code: [Select]
mBitField.asBits.bit3 = 1
That's why I prefer Arduino Micro or Raspberry Pi modules.
« Last Edit: August 08, 2021, 09:12:39 pm by jenniferkim »
 
The following users thanked this post: tariq

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: max bit variable in AVR
« Reply #4 on: July 22, 2021, 09:55:48 pm »
Quote
too many global/static 'bit' variables
Does bit variables are limited in AVR?
There is apparently a configuration parameter that allows you to set the max number of "bit" variables.:
Quote
A number of maximum 104 bit variables can be declared. The size of the bit variables allocated to the program can be specified in the Project|Configure|C
Compiler|Code Generation|Bit Variables Size list box. This size should be as low as possible, in order to free registers for allocation to other global variables.
(https://www.thierry-lequeu.fr/data/CodeVisonAVR-doc.pdf (page 68)

Quote
or they are just limited in codevision?
Bit variables are not standard C, and most compilers don't implement them at all.
The portable method is to use structure-based bitfields as described by jenniferkim...
« Last Edit: July 22, 2021, 09:59:05 pm by westfw »
 
The following users thanked this post: tariq

Offline nigelwright7557

  • Frequent Contributor
  • **
  • Posts: 689
  • Country: gb
    • Electronic controls
Re: max bit variable in AVR
« Reply #5 on: July 23, 2021, 12:12:54 am »
I define a list of variables to be used throughout the program

//bits set
#define sb0 1
#define sb1 2 etc etc

//bits reset
#define rb0 0xffffe
#define rb1 0xfffd etc etc


 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8166
  • Country: fi
Re: max bit variable in AVR
« Reply #6 on: July 24, 2021, 03:59:48 pm »
I suggest you invest a bit of time learning the C language, because investing time into a custom C-like vendor specific non-C language might have made sense in 1990's, but IMHO not any more. Most new microcontrollers as developed in 2000's, including the ubiquitous ARM controllers, have only C compilers available.

C, unfortunately, does not have a type for a bit. This being said, AVR, like most CPUs, doesn't have required memory layout and instructions to natively do that anyway, so the compiler did some magic with the bit type.

The easiest standard-compliant and efficient (regarding speed) way is to just use the uint8_t (or char) type instead of bit. Of course, now each bit wastes a full byte of memory, but usually this isn't a problem.

Whenever you need to save memory, group related single-bit things together into a bitfield, for example like this:
var |= 1<<5; // set the fifth bit
var &= ~(1<<3); // clear the third bit
if(var & (1<<0)) // test the zeroth bit

or you can indeed use the C struct bitfields.
« Last Edit: July 24, 2021, 04:01:52 pm by Siwastaja »
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5890
  • Country: es
Re: max bit variable in AVR
« Reply #7 on: July 24, 2021, 06:22:26 pm »
If your compiler includes sdtbool.h then you could use the bool type which is exactly that.

Code: [Select]
#include <stdbool.h>

bool enablePower;
bool cfgDone;
bool ledStatus;
...



Otherwise, my advice is to use bitfields like jenniferkim showed. They're the neatest solution.
The code becomes cryptic when you start masking and bisthifting everything.

You can also avoid the typedef and make your own, so you can name the bits as you wish:
Code: [Select]
typedef union {
    uint8_t data;
    struct{
        unsigned enableLed  :1;
        unsigned enableBeep :1;
        unsigned firstInit  :1;
        unsigned configDone :1;
        unsigned option_A   :1;
        unsigned option_B   :1;
        unsigned option_C   :1;
        unsigned option_D   :1;
    };   
} Settings;

if(!Settings.configDone){
    init();
    Settings.configDone=1;
}
if(Settings.enableLed){
    LED=1;
}


Also, you can make bitfields of any size:
Code: [Select]
typedef union {
    uint8_t data;
    struct{
        unsigned selectedLanguage   :3;    // 0-7
        unsigned screenBrightness   :4;    // 0-15
        unsigned enableSomething    :1;    // 0-1
    };   
} Settings;
« Last Edit: July 24, 2021, 06:38:58 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: max bit variable in AVR
« Reply #8 on: July 25, 2021, 02:26:45 am »
Quote
If your compiler includes sdtbool.h then you could use the bool type which is exactly that.
"bool" is never a bit, AFAIK.  C does not support bits directly, because you can't have a pointer to a bit.  C really doesn't believe in types that you can't have a pointer to.

The Codevision C compiler puts "bits" in the AVR GPIO registers (and maybe a CPU register if they run out of bit-addressable GPIO registers.)In AVR, there are a couple of registers in the peripheral space for which there are single-bit instructions (set/clear/test/etc sort-of like 8051) - being usable from C is a nice feature, even if it's non-standard.  Although the AVR also has enough memory and normal registers that I don't recall ever seeing the GPIO registers use much even in asm...
 

Offline ozzee

  • Newbie
  • Posts: 7
  • Country: au
Re: max bit variable in AVR
« Reply #9 on: July 25, 2021, 06:08:08 am »
I happen to be working on a C++ BitFields library for microcontrollers and I'm starting with AVR and the ATmega328P.

Here's an example - this will be part of a header file specific to the ATmega328P - see:
https://bitbucket.org/owebeeone/ardoinus/src/master/ardOinus/src/sys/mcu/avr/ardo_supplemental_atmega328p_dev.h

This is a snippet from that file:
/**
 * Controls for timer output compare register modes.
 */
enum class EnumCOMn : unsigned char {
  disconnect = 0b00,
  toggle = 0b01, // Reserved for Fast PWM mode on COM2A
  clear = 0b10,
  set = 0b11
};

/**
 * Bit field definitions for the COMnA and COMnB fields.
 */
using BitsCOM0A = setl::BitsRW<
  setl::SemanticType<setl::hash("COM0A"), EnumCOMn>, ccCOM0A1, ccCOM0A0>;
using BitsCOM0B = setl::BitsRW<
  setl::SemanticType<setl::hash("COM0B"), EnumCOMn>, ccCOM0B1, ccCOM0B0>;

...

// Define register TCCR0AB.
using FieldsTCCR0AB = setl::BitFields<
  BitsCOM0A, BitsCOM0B,
  BitsWGM0_210,
  BitsFOC0A_16, BitsFOC0B_16,
  BitsCS01_16>;
using rrTCCR0AB = rrTCCR0A::ForType<std::uint16_t>;
using RegisterTCCR0AB = Register<FieldsTCCR0AB, rrTCCR0AB>;

So not you can set and get all the bitfields of interest in one read or ReadModifyWrite cycle.

e.g.
RegisterTCCR0AB::ReadModifyWrite(BitsCS01_16{ EnumCS0::clk8}, BitsWGM_16{ EnumWGM::fast_pwm_icr });
or
BitsCOM0A com0a;
BitsWGM0_210 wgm;
Assign(com0a, wgm) = RegisterTCCR0AB::Read();

Will write the CS and WGM bits in a single RMW operation. (although this is actually defined as a 16 bit register so its happening as a 2 8 bit reads followed by 2 8 bit writes).

It also allows the creation of a selection of registers where you can simply write all the values you want to write in one statement and the bitfield library will find the corresponding registers and write all the values to corresponding to the value types given.

It's still a work in progress when it comes to the AVR interfaces, I've only done the GPIO and and most of the timers interfaces, however the bitfield library I think is mostly done and generic so it should work on anything with C++14 and higher language support.

In theory, user/application code will never do anything with the bitfields interface, that should all be done in the MCU support library so all this bitfield madness is to make that code more easily reusable across different processors.  Hence I'll be ripping out the generic bits of ardo_supplemental_atmega328p_dev.h into another file soon..ish.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf