STM32 Bit Banding (or bit-banding)
Jump to navigation
Jump to search
In older 8-bit MCUs it was quite common to have instructions to clear or set a bit as one atomic instruction. By atomic it means the read->modify->write can not be interrupted resulting in other bits being set wrongly.
Unfortunately ARM did not implement such instructions in the ARM cores. They did however implement something known as "bit banding" (or bit-banding).
Macro's to Calculate Bit Band Address
#define BITBAND_SRAM_REF 0x20000000 #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_PERIPH_REF 0x40000000 #define BITBAND_PERIPH_BASE 0x42000000 #define bitband_t *(volatile uint32_t*) #define m_BITBAND_SRAM(address,bit) (BITBAND_SRAM_BASE + (((uint32_t)address) - BITBAND_SRAM_REF) * 32 + (bit) * 4) #define m_BITBAND_PERIPH(address,bit) (BITBAND_PERIPH_BASE + (((uint32_t)address) - BITBAND_PERIPH_REF) * 32 + (bit) * 4)
Usage Examples
Considering a variable v, the bits can be individually set/reset like this:
*((uint8_t *)m_BITBAND_SRAM(&v, 7)) = 1; *((uint8_t *)m_BITBAND_SRAM(&v, 6)) = 0; *((uint8_t *)m_BITBAND_SRAM(&v, 5)) = 1; *((uint8_t *)m_BITBAND_SRAM(&v, 4)) = 0; *((uint8_t *)m_BITBAND_SRAM(&v, 3)) = 1; *((uint8_t *)m_BITBAND_SRAM(&v, 2)) = 0; *((uint8_t *)m_BITBAND_SRAM(&v, 1)) = 1; *((uint8_t *)m_BITBAND_SRAM(&v, 0)) = 0;
A peripheral - for example port 13 on GPIOC can be handled like this:
uint8_t *led_pin = (uint8_t *)m_BITBAND_PERIPH(&LED_GPIO_Port->ODR, 13); // Toggle LED *led_pin = !*led_pin;
Miscellaneous Links
To be added