The ARM Cortex M3 STM32F103c8t6 microcontroller is widely distributed as a 32-bit microcontroller for amateur projects. As for almost any microcontroller, there is an SDK for it, including, among other things, the C ++ header files for determining the periphery of the controller./* =========================================================================*/ typedef struct { __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ . . . __IO uint32_t ISR; /*!< USART Interrupt and status register, ... */ } USART_TypeDef; // USART_Type . /* =========================================================================*/ #define USART1_BASE (APBPERIPH_BASE + 0x00013800) . . . #define USART1 ((USART_TypeDef *) USART1_BASE) #define USART1_BASE 0x400xx000U // ---------------------------------------------------------------------------- if (USART1->ISR & (ONE_ISR_FLAG & OTHER_ISR_FLAG)) { } // ---------------------------------------------------------------------------- USART_TypeDef & Usart1 = *USART1; // ---------------------------------------------------------------------------- if (Usart1.ISR & (ONE_ISR_FLAG & OTHER_ISR_FLAG)) { } /* =========================================================================*/ typedef struct { . . . } RCC_TypeDef; /* =========================================================================*/ __IO uint32_t CR; /* =========================================================================*/ #define RCC ((RCC_TypeDef *)RCC_BASE) // ---------------------------------------------------------------------------- RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // ---------------------------------------------------------------------------- RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN; // ---------------------------------------------------------------------------- Rcc.PortOn(Port::A); // ---------------------------------------------------------------------------- Rcc.PortOn<Port::A, Port::B>(); // ---------------------------------------------------------------------------- TRcc & Rcc = *static_cast<TRcc *>RCC; // ============================================================================ enum class GPort : uint32_t { A = RCC_APB2ENR_IOPAEN, B = RCC_APB2ENR_IOPBEN, C = RCC_APB2ENR_IOPCEN, }; // ---------------------------------------------------------------------------- class TRcc: public ::RCC_TypeDef { private: TRcc() = delete; ~TRcc() = delete; // ======================================================================== public: template<GPort... port> inline void PortOn(void) // (inline) { // -Og -O0 APB2ENR |= SetBits<(uint32_t)port...>(); } // ------------------------------------------------------------------------ #define BITMASK 0x01 // , #define MASKWIDTH 1 // . // #undef. private: // (fold) . template<uint8_t bitmask> inline constexpr uint32_t SetBits(void) { // , GPort enum // (, , bitmask ). // static_assert(bitmask < 16, " ."); return bitmask; } template<uint8_t bit1, uint8_t bit2, uint8_t... bit> inline constexpr uint32_t SetBits(void) { return SetBits<bit1>() | SetBits<bit2, bit...>(); } }; #undef BITMASK #undef MASKWIDTH // ------------------------------------------------------------------------ TRcc & Rcc = *static_cast<TRcc *>RCC; Rcc.PortOn<GPort::A>(); ldr r3, [pc, #376] ; (0x8000608 <main()+392>) ldr r0, [r3, #24] orr.w r0, r0, #4 str r0, [r3, #24] Rcc.PortOn<GPort::A, GPort::B, GPort::C>(); ldr r3, [pc, #380] ; (0x8000614 <main()+404>) ldr r0, [r3, #24] orr.w r0, r0, #4 ; APB2ENR |= GPort::A str r0, [r3, #24] ldr r0, [r3, #24] orr.w r0, r0, #28 ; APB2ENR |= Gport::B | GPort::C str r0, [r3, #24] #24] // ---------------------------------------------------------------------------- class TRcc: public ::RCC_TypeDef { private: TRcc() = delete; // , ~TRcc() = delete; // . // ======================================================================== public: template<GPort... port> inline void PortOn(void) // (inline) { // -Og -O0 APB2ENR |= SetBits17<(uint32_t)port...>(); } // ------------------------------------------------------------------------ #define BITMASK 0x01 // , #define MASKWIDTH 1 // . // #undef. private: // (fold) . ++ 17. template<uint8_t... bitmask> inline constexpr uint32_t SetBits17(void) { return (bitmask | ...); // ... | bit } }; #undef BITMASK #undef MASKWIDTH ldr r2, [pc, #372] ; (0x800060c <main()+396>) ldr r0, [r2, #24] orr.w r0, r0, #28 ; APB2ENR |= Gport::A | Gport::B | GPort::C str r0, [r3, #24] Rcc.PortOn<Port::A, Port::B, Port::C>(); RCC->APB2 |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN; ldr r2, [pc, #372] ; (0x800060c <main()+396>) [ RCC] ldr r0, [r2, #0] ; r0 = RCC->APB2 // [ APB2] orr.w r0, r0, #160 ; r0 |= 0x10100000 str r0, [r2, #0] ; RCC->APB2 = r0 
Picture STM32F103c8t6 of CubeMX.Source: https://habr.com/ru/post/448288/
All Articles