avr_sfr(3avr)

πŸ’– NAME πŸ’–

avr_sfr β€” this is the <avr/sfr_defs.h> page, aka Special function registers, and it's from section 3avr of the manual. Bestie, this is your backstage pass to poking hardware registers directly. πŸ‘‘


✨ SYNOPSIS ✨

πŸ“š Topics

  • Additional notes from <avr/sfr_defs.h>

πŸ”’ Bit manipulation

#define _BV(bit)

πŸŽ›οΈ IO register bit manipulation

#define bit_is_set(sfr,  bit)
#define bit_is_clear(sfr,  bit)
#define loop_until_bit_is_set(sfr,  bit)
#define loop_until_bit_is_clear(sfr,  bit)

πŸ¦‹ DETAILED DESCRIPTION πŸ¦‹

Okay so picture this: you're working with microcontrollers, and a lot of the job is literally just controlling internal peripherals, or external peripherals that are wired up to the device. And here's the slay β€” the entire IO address space is handed to you as memory-mapped IO, meaning you can get at it with all the MCU instructions that work on normal data memory. No special incantation needed. πŸ’…

For most AVR devices, the IO register space is mapped into the data memory address space with an offset of 0x20, because the bottom of that space is reserved for direct access to the MCU registers. (Real SRAM only shows up behind the IO register area, starting at some specific address that depends on your device. iykyk.)

So like, the user can just access memory-mapped IO registers as if they were globally defined variables, like this:

PORTA = 0x33;
unsigned char foo = PINA;

And the compiler is gonna pick the correct instruction sequence to generate based on the address of the register being accessed. Not me trusting the compiler to be the main character β€” but fr fr, it is. 🫢

The absolute advantage of using memory-mapped registers in C programs is that your programs become way more portable to other C compilers for the AVR platform. Iconic behaviour, honestly.

⚠️ Careful, girl. Special care must be taken when accessing some of the 16-bit timer IO registers, because access can happen from both the main program and from inside an interrupt context. Go read Why do some 16-bit timer registers sometimes get trashed? β€” yes that's the actual name of the note, and yes it's a whole mood. 😭

πŸ’€ Porting programs that use the deprecated sbi/cbi macros

Access to the AVR single bit set and clear instructions is provided via the standard C bit manipulation commands. The sbi and cbi macros are no longer directly supported.

sbi (sfr,bit) can be replaced by sfr |= _BV(bit) .

i.e.: sbi(PORTB, PB1); is now PORTB |= _BV(PB1);

And this actually is more flexible than having sbi directly, because the optimizer will use a hardware sbi if appropriate, or a read/or/write operation if it's not appropriate. So you do not need to keep track of which registers sbi/cbi will operate on. Obsessed with the optimizer carrying the team. ✨

Likewise, cbi (sfr,bit) is now sfr &= ~(_BV(bit));


πŸŽ€ MACRO DEFINITION DOCUMENTATION πŸŽ€

🌈 #define _BV( bit)

Value:

(1 << (bit))

#include <avr/io.h>

Converts a bit number into a byte value. That's it, that's the whole job, and it does it flawlessly. πŸ‘‘

πŸ“ Note: the bit shift is performed by the compiler, which then inserts the result into the code. So there is no run-time overhead when using _BV(). Zero cost, zero stress, all vibes.

🌸 #define bit_is_clear( sfr, bit)

Value:

(!(_SFR_BYTE(sfr) & _BV(bit)))

#include <avr/io.h>

Tests whether bit bit in IO register sfr is clear. It'll return non-zero if the bit is clear, and a 0 if the bit is set. Yes, it's inverted logic and yes it's on purpose β€” read it twice, bestie, we've all been there. πŸ™ˆ

⭐ #define bit_is_set( sfr, bit)

Value:

(_SFR_BYTE(sfr) & _BV(bit))

#include <avr/io.h>

Tests whether bit bit in IO register sfr is set. This one returns a 0 if the bit is clear, and non-zero if the bit is set. The normal one. The wholesome one. πŸ’–

🧚 #define loop_until_bit_is_clear( sfr, bit)

Value:

do { } while (bit_is_set(sfr, bit))

#include <avr/io.h>

Waits until bit bit in IO register sfr is clear. Sit there, do nothing, be patient, it's giving main character waiting room energy. πŸŽ€

πŸ“ #define loop_until_bit_is_set( sfr, bit)

Value:

do { } while (bit_is_clear(sfr, bit))

#include <avr/io.h>

Waits until bit bit in IO register sfr is set. Same deal, opposite direction. ✨


πŸ‘‘ AUTHOR πŸ‘‘

Generated automatically by Doxygen for AVR-LibC from the source code. (Not a human, just a little robot writing docs so you don't have to. We love an automated king. πŸ€–)


Okay that's the whole page, thanks for coming to my TED talk. This was avr_sfr from AVR-LibC, Version 2.2.1 β€” go flash something cute and remember: memory-mapped registers are just variables that are also hardware. Slay. πŸ’…πŸ¦‹β­

πŸ“¦ where this page comes from