C ++ рдореЗрдВ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ 10 ++ рддрд░реАрдХреЗ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, IAR рдФрд░ Cortex M)

рд╕рдмрд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд рд░рд╛рд╕реНрддрд╛ рдЪреБрдирдирд╛
рдЕрдВрдЬреАрд░ред рдЖрдИ рдХрд┐рдпреЛрдХреЛ

рд╕рднреА рдХреЛ рдЕрдЪреНрдЫрд╛ рд╕реНрд╡рд╛рд╕реНрдереНрдп!

рдЖрдкрдХреЛ рд╢рд╛рдпрдж рджрд╛рдврд╝реА рд╡рд╛рд▓рд╛ рдХрд┐рд╕реНрд╕рд╛ рдпрд╛рдж рд╣реИ, рдФрд░ рд╢рд╛рдпрдж рдПрдХ рд╕рдЪреНрдЪреА рдХрд╣рд╛рдиреА рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдПрдХ рдЫрд╛рддреНрд░ рд╕реЗ рдмреИрд░реЛрдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдорд╛рд░рдд рдХреА рдКрдВрдЪрд╛рдИ рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрдЫрд╛ рдЧрдпрд╛ рдерд╛ред рдЫрд╛рддреНрд░ рдиреЗ рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рд▓рдЧрднрдЧ 20 рдпрд╛ 30 рддрд░реАрдХреЛрдВ рдХрд╛ рд╣рд╡рд╛рд▓рд╛ рджрд┐рдпрд╛, рдЬрд┐рд╕рдореЗрдВ рд╢рд┐рдХреНрд╖рдХ рджреНрд╡рд╛рд░рд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рдкреНрд░рддреНрдпрдХреНрд╖ (рджрдмрд╛рд╡ рдореЗрдВ рдЕрдВрддрд░) рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдП рдмрд┐рдирд╛ред

рд▓рдЧрднрдЧ рдПрдХ рд╣реА рдирд╕ рдореЗрдВ, рдореИрдВ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕реА ++ рдХреЗ рдЙрдкрдпреЛрдЧ рдкрд░ рдЪрд░реНрдЪрд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рд╕реА ++ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдФрд░ рдореИрдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рддрдХ рд╕реБрд░рдХреНрд╖рд┐рдд рдкрд╣реБрдВрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЖрд╕рд╛рди рд░рд╛рд╕реНрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдореИрдВ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рднреА рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖реЛрдВ рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рдпрджрд┐ рдЖрдк рдЕрдзрд┐рдХ рддрд░реАрдХреЗ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдЙрдиреНрд╣реЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдлреЗрдВрдХ рджреЗрдВред рддреЛ рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

рд╡рд┐рдзрд┐ 1. рд╕реНрдкрд╖реНрдЯ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ


рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдзрд┐, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ C ++ рдореЗрдВ рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдирд┐рд░реНрдорд╛рддрд╛ рд╕реЗ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рд░рдЬрд┐рд╕реНрдЯрд░ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП, рдореИрдВ STM32F411 рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рджреЛ рдкреЛрд░реНрдЯ рдП рд░рдЬрд┐рд╕реНрдЯрд░ (ODR - рдЖрдЙрдЯрдкреБрдЯ рдбреЗрдЯрд╛ рд░рдЬрд┐рд╕реНрдЯрд░ рдФрд░ IDR - рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рд░рдЬрд┐рд╕реНрдЯрд░) рд▓реЗ рдЬрд╛рдКрдВрдЧрд╛ рддрд╛рдХрд┐ рдореИрдВ "рдХрдврд╝рд╛рдИ" "рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб" рдХрд░ рд╕рдХреВрдВ - рдПрд▓рдИрдбреА рдХреЛ рдмреНрд▓рд┐рдВрдХ рдХрд░реЗрдВред

int main() { GPIOA->ODR ^= (1 << 5) ; GPIOA->IDR ^= (1 << 5) ; //,      } 

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдбрд┐рдЬрд╝рд╛рдЗрди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдорд╛рдЗрдХреНрд░реЛрдкреНрд░реЛрд╕реЗрд╕рд░ рд╣реЗрдбрд░ рдореЗрдВ GPIO_TypeDef рд╕рдВрд░рдЪрдирд╛ рдФрд░ рдЗрд╕ GPIOA рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реВрдЪрдХ рдкрд░рд┐рднрд╛рд╖рд╛ GPIOA рд╣реИред рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 typedef struct { __IO uint32_t MODER; //port mode register, Address offset: 0x00 __IO uint32_t OTYPER; //port output type register, Address offset: 0x04 __IO uint32_t OSPEEDR; //port output speed register, Address offset: 0x08 __IO uint32_t PUPDR; //port pull-up/pull-down register, Address offset: 0x0C __IO uint32_t IDR; //port input data register, Address offset: 0x10 __IO uint32_t ODR; //port output data register, Address offset: 0x14 __IO uint32_t BSRR; //port bit set/reset register, Address offset: 0x18 __IO uint32_t LCKR; //port configuration lock register, Address offset: 0x1C __IO uint32_t AFR[2]; //alternate function registers, Address offset: 0x20-0x24 } GPIO_TypeDef; #define PERIPH_BASE 0x40000000U //Peripheral base address in the alias region #define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000U) #define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000U) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) 

рдЗрд╕реЗ рд╕рд╛рдзрд╛рд░рдг рдорд╛рдирд╡ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдХрд╣реЗрдВ, рддреЛ GPIO_TypeDef рдкреНрд░рдХрд╛рд░ рдХреА рдкреВрд░реА рд╕рдВрд░рдЪрдирд╛ GPIO_TypeDef рдкрддреЗ рдкрд░ "рд▓реЗрдЯ" GPIOA_BASE , рдФрд░ рдЬрдм рдЖрдк рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдкрддреЗ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рддреЗ рд╣реИрдВ - рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдПрдХ рддрддреНрд╡ рдХреЛ рдСрдлрд╕реЗрдЯ рдХрд░реЗрдВред рдпрджрд┐ рдЖрдк #define GPIOA , рддреЛ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

 ((GPIO_TypeDef *) GPIOA_BASE)->ODR ^= (1 << 5) ; ((GPIO_TypeDef *) GPIOA_BASE)->IDR ^= (1 << 5) ; // 

C ++ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ, рдкреВрд░реНрдгрд╛рдВрдХ рдкрддрд╛ GPIO_TypeDef рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдкреЙрдЗрдВрдЯрд░ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди C ++ рдореЗрдВ, C рд░реВрдкрд╛рдВрддрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдХрдВрдкрд╛рдЗрд▓рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИ:

  • const_cast
  • static_cast
  • рд╕реНрдерд┐рд░_рдХрд╛рд╕реНрдЯ const_cast рдХреЗ рдмрдЧрд▓ рдореЗрдВ,
  • reinterpret_cast
  • const_cast рдХреЗ рдмрдЧрд▓ рдореЗрдВ reinterpret_cast

рдпрд╛рдиреА рдпрджрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ const_cast рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛, рддреЛ рд╡рд╣ static_cast рдФрд░ рдЗрддрдиреЗ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИред рдирддреАрдЬрддрди, рдХреЙрд▓:

 ((GPIO_TypeDef *) GPIOA_BASE)->ODR ^= (1 << 5) ; 

рдРрд╕рд╛ рдХреБрдЫ рдирд╣реАрдВ рд╣реИ:

 reinterpret_cast<GPIO_TypeDef *> (GPIOA_BASE)->ODR ^= (1 << 5) ; 

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕реА ++ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рд╕реЗ рдкрддреЗ рдкрд░ рд╕рдВрд░рдЪрдирд╛ рдХреЛ "рдЦреАрдВрдЪ" рдХрд░рдирд╛ рд╕рд╣реА рд╣реЛрдЧрд╛:

 GPIO_TypeDef * GPIOA{reinterpret_cast<GPIO_TypeDef *>(GPIOA_BASE)} ; 

рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдЯрд╛рдЗрдк рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рдХрд╛рд░рдг, C ++ рдХреЗ рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдПрдХ рдмрдбрд╝рд╛ рдЛрдг рд╣реИред рдпрд╣ рдЗрд╕ рддрдереНрдп рдореЗрдВ constexpr рд╣реИ рдХрд┐ reinterpret_cast рдЙрдкрдпреЛрдЧ рди рддреЛ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ constexpr рдФрд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рди рд╣реА рдЯреЗрдореНрдкрд▓реЗрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ, рдФрд░ рдпрд╣ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░реНрд╕ рдХреЗ рд▓рд┐рдП C ++ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдХрд╛рдлреА рдХрдо рдХрд░рддрд╛ рд╣реИред
рдореИрдВ рдЗрд╕реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдордЭрд╛рдКрдВрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ:

  struct Test { const int a; const int b; } ; template<Test* mystruct> constexpr const int Geta() { return mystruct->a; } Test test{1,2}; int main() { Geta<&test>() ; } 

рд▓реЗрдХрд┐рди рдЖрдк рдРрд╕рд╛ рдкрд╣рд▓реЗ рд╕реЗ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ:

 template<GPIO_TypeDef * mystruct> constexpr volatile uint32_t GetIdr() { return mystruct->IDR; } int main() { //GPIOA  reinterpret_cast<GPIO_TypeDef *> (GPIOA_BASE) //  ,        GetIdr<GPIOA>() ; // } //      : struct Port { constexpr Port(GPIO_TypeDef * ptr): port(*ptr) {} GPIO_TypeDef & port ; } //  GPIOA  reinterpret_cast,   //  constexpr      constexpr Port portA{GPIOA}; //    

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдкреНрд░рддреНрдпрдХреНрд╖ рдЙрдкрдпреЛрдЧ C ++ рдХреЗ рдЙрдкрдпреЛрдЧ рдкрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддрд╛ рд╣реИред рд╣рдо рдЙрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ рдЬреЛ рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ ROM рдореЗрдВ GPIOA рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдРрд╕реА рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рд▓рд╛рдн рдирд╣реАрдВ рд▓реЗ рдкрд╛рдПрдВрдЧреЗред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рд╡рд┐рдзрд┐ рд╕реБрд░рдХреНрд╖рд╛ рдирд╣реАрдВ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╢реНрдЪрд┐рдореА рд╕рд╛рдереА рдХрд╣рддреЗ рд╣реИрдВ)ред рдЖрдЦрд┐рд░рдХрд╛рд░, рдХреБрдЫ рдЧреИрд░-рдордЬрд╝рд╛ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ
рдЙрдкрд░реЛрдХреНрдд рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ, рд╣рдо рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВ:

рдЖрдХрд░реНрд╖рдг рдЖрддреЗ рд╣реИрдВ


  • рдирд┐рд░реНрдорд╛рддрд╛ рд╕реЗ рд╣реЗрдбрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдпрд╣ рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ)
  • рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдЗрд╢рд╛рд░реЗ рдФрд░ рд▓рд╛рдЧрдд рдирд╣реАрдВ рд╣реИрдВ, рдЖрдк рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ
  • рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА
  • рд╣рд░ рдХреЛрдИ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдЬрд╛рдирддрд╛ рдФрд░ рд╕рдордЭрддрд╛ рд╣реИред
  • рдХреЛрдИ рдЙрдкрд░рд┐ рдирд╣реАрдВ

рд╡рд┐рдкрдХреНрд╖


  • рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рд╕реАрдорд┐рдд рдЙрдкрдпреЛрдЧ
  • рдХреЙрдиреНрд╕реНрдЯреИрдХреНрд╕ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрдерддрд╛
  • рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рд░реИрдо рдХреА рдЕрддрд┐рд░рд┐рдХреНрдд рдЦрдкрдд рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдПрдХ рдЙрджреНрджреЗрд╢реНрдп рд╣реИ
  • рдЖрдк рдмреЗрд╡рдХреВрдл рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ
рдЕрдм рдЖрдЗрдП рд╡рд┐рдзрд┐ рд╕рдВрдЦреНрдпрд╛ 2 рджреЗрдЦреЗрдВ

рд╡рд┐рдзрд┐ 2. рдХреНрд░реВрд░


рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдПрдореНрдмреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕рднреА рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рд▓рд┐рдП рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдкрддреЗ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рд╣рдореЗрд╢рд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:

 *reinterpret_cast<volatile uint32_t *>(GpioaOdrAddr) ^= (1 <<5) ; *reinterpret_cast<volatile uint32_t *>(GpioaIdrAddr) ^= (1 <<5) ; // 

рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдХрд╣реАрдВ рднреА, рдЖрдк рд╣рдореЗрд╢рд╛ volatile uint32_t рд░рдЬрд┐рд╕реНрдЯрд░ рдкрддреЗ рдкрд░ рд░реВрдкрд╛рдВрддрд░рдг рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХрдо рд╕реЗ рдХрдо рдХреБрдЫ рд╡рд╣рд╛рдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣рд╛рдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХреЛрдИ рдкреНрд▓рд╕ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрди minuses рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд╛ рдкрддрд╛ рдЦреБрдж рдХреЛ рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рд╡рд┐рдзрд┐ рд╕рдВрдЦреНрдпрд╛ 3 рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВред

рд╡рд┐рдзрд┐ 3. рд╕реНрдкрд╖реНрдЯ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдзрд┐рдХ рд╕рд╣реА


рдпрджрд┐ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдВрд░рдЪрдирд╛ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрддреА рд╣реИ, рддреЛ рд╕рдВрд░рдЪрдирд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдкреВрд░реНрдгрд╛рдВрдХ рд╕рдВрд░рдЪрдирд╛ рдкрддреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдкрддрд╛ рдирд┐рд░реНрдорд╛рддрд╛ рд╕реЗ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, GPIOA рдХреЗ рд▓рд┐рдП GPIOA_BASE), рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕реЗ рдпрд╛рдж рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдФрд░ рдХреЙрдиреНрд╕реНрдЯреНрд░реЗрдХреНрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕ рдкрддреЗ рдкрд░ рд╕рдВрд░рдЪрдирд╛ рдХреЛ "рдУрд╡рд░рд▓реЗ" рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 template<uint32_t addr, uint32_t pinNum> struct Pin { using Registers = GPIO_TypeDef ; __forceinline static void Toggle() { //     addr Registers *GpioPort{reinterpret_cast<Registers*>(addr)}; GpioPort->ODR ^= (1 << pinNum) ; } }; int main() { using Led1 = Pin<GPIOA_BASE, 5> ; Led1::Toggle() ; } 

рдореЗрд░реА рджреГрд╖реНрдЯрд┐ рд╕реЗ, рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдордВрддреНрд░ рдирд╣реАрдВ рд╣реИрдВред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдПрдХ рдХрд╛рд░реНрдп рд╡рд┐рдХрд▓реНрдкред рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдЖрдЗрдП рдЕрдиреНрдп рддрд░реАрдХреЛрдВ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рд╡рд┐рдзрд┐ 4. рдПрдХреНрд╕реЛрдЯреЗрд░рд┐рдХ рд░реИрдк


рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рдХреЛрдб рдХреЗ рдкрд╛рд░рдЦреА рдХреЗ рд▓рд┐рдП, рдЖрдк рд░рдЬрд┐рд╕реНрдЯрд░ рдкрд░ рдПрдХ рдЖрд╡рд░рдг рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдПрдХреНрд╕реЗрд╕ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рдФрд░ "рд╕реБрдВрджрд░" рджрд┐рдЦреЗрдВ, рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ:

 class Register { public: explicit Register(uint32_t addr) : ptr{ reinterpret_cast<volatile uint32_t *>(addr) } { } __forceinline inline Register& operator^=(const uint32_t right) { *ptr ^= right; return *this; } private: volatile uint32_t *ptr; //    }; int main() { Register Odr{GpioaOdrAddr}; Odr ^= (1 << 5); Register Idr{GpioaIdrAddr}; Idr ^= (1 << 5); // } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╕реЗ рдЖрдкрдХреЛ рдпрд╛ рддреЛ рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдкреВрд░реНрдгрд╛рдВрдХ рдкрддреЗ рдпрд╛рдж рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ, рдпрд╛ рдЙрдиреНрд╣реЗрдВ рдХрд╣реАрдВ рд╕реЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдЖрдкрдХреЛ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рд░рдЬрд┐рд╕реНрдЯрд░ рдкрддреЗ рдкрд░ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╕реЗ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ, рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдирд╛, рдлрд┐рд░ рд╕реЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ
рдХреБрдЫ рдиреБрдХрд╕рд╛рди, рдФрд░ рдЗрд╕ рддрдереНрдп рд╕реЗ рдХрд┐ рдкрд╣рд▓реЗ рдФрд░ рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд░реИрдо рдореЗрдВ 4 рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд░рдЬрд┐рд╕реНрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдПрдХ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВред рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВред

рд╡рд┐рдзрд┐ 4,5ред рдкреИрдЯрд░реНрди рдХреЗ рд╕рд╛рде рдПрдХреНрд╕реЛрдЯреЗрд░рд┐рдХ рд▓рдкреЗрдЯреЗрдВ


рд╣рдо рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдПрдХ рдЕрдирд╛рдЬ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд▓рд╛рдн рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ рдкрд┐рдЫрд▓реЗ рдПрдХ рд╕реЗ рд╣реА рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ, рд╣рдо рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЛ рдкрддрд╛ рджреЗрддреЗ рд╕рдордп рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдкрд░ рдереЛрдбрд╝реА рдмрдЪрдд рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдЪреНрдЫрд╛ рд╣реИ:

 template<uint32_t addr> class Register { public: Register() : ptr{reinterpret_cast<volatile uint32_t *>(addr)} { } __forceinline inline Register &operator^=(const uint32_t right) { *ptr ^= right; return *this; } private: volatile std::uint32_t *ptr; }; int main() { using GpioaOdr = Register<GpioaOdrAddr>; GpioaOdr Odr; Odr ^= (1 << 5); using GpioaIdr = Register<GpioaIdrAddr>; GpioaIdr Idr; Idr ^= (1 << 5); // } 

рдФрд░ рдЗрд╕рд▓рд┐рдП, рдПрдХ рд╣реА рд░реЗрдХ, рд╕рд╛рдЗрдб рд╡реНрдпреВред

рд╡рд┐рдзрд┐ 5. рдЙрдЪрд┐рдд


рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЖрдкрдХреЛ рдкреЙрдЗрдВрдЯрд░ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЪрд▓реЛ рдРрд╕рд╛ рд╣реА рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рдХрдХреНрд╖рд╛ рд╕реЗ рд╣рдЯрд╛ рджреЗрдВред

 template<uint32_t addr> class Register { public: __forceinline Register &operator^=(const uint32_t right) { *reinterpret_cast<volatile uint32_t *>(addr) ^= right; return *this; } }; using GpioaOdr = Register<GpioaOdrAddr>; GpioaOdr Odr; Odr ^= (1 << 5); using GpioaIdr = Register<GpioaIdrAddr>; GpioaIdr Idr; Idr ^= (1 << 5); // 

рдЖрдк рдпрд╣рд╛рдВ рд░рд╣ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдереЛрдбрд╝рд╛ рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╡рд┐рдзрд┐ рддреБрд░рдВрдд 2 рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рддреА рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╡рд┐рдзрд┐ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рдереАрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЕрдм рдореИрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ Register рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рдФрд░ рджреВрд╕рд░реА рдмрд╛рдд, рдореИрдВ рдЗрд╕реЗ constexrp рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдкрд╛рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред

 template<Register * register> void Xor(uint32_t mask) { *register ^= mask ; } Register<GpioaOdrAddr> GpioaOdr; int main() { Xor<&GpioaOdr>(1 << 5) ; //  } //   struct Port { constexpr Port(Register& ref): register(ref) {} Register & register ; } constexpr Port portA{GpioaOdr}; 

рдмреЗрд╢рдХ, рдпрд╣ рдлрд┐рд░ рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдпрд╛ рддреЛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдкрддреЗ рдХреЗ рд▓рд┐рдП рдИрдбрд┐рдЯрд┐рдХ рдореЗрдореЛрд░реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рднреА рдкрддреЗ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдлрд╛рдЗрд▓ рдореЗрдВ рдХрд╣реАрдВ рдФрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ ...

рдЖрдХрд░реНрд╖рдг рдЖрддреЗ рд╣реИрдВ


  • рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА
  • рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛
  • рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдмрд┐рд▓реНрдбрд░реЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛

рд╡рд┐рдкрдХреНрд╖


  • рдирд┐рд░реНрдорд╛рддрд╛ рд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
  • рдЖрдкрдХреЛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рднреА рдкрддреЗ рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ
  • рдЖрдкрдХреЛ рдХрдХреНрд╖рд╛ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреА рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
  • рдЖрдк рдмреЗрд╡рдХреВрдл рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ

рдмрдврд╝рд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрднреА рднреА рдмрд╣реБрдд рд╕рд╛рд░реЗ рдордВрддреНрд░реА рд╣реИрдВ ...

рд╡рд┐рдзрд┐ 6. рдЙрдЪрд┐рдд рд╕реЗ рдЕрдзрд┐рдХ рдЪрд┐рдХрдирд╛


рдкрд┐рдЫрд▓реА рдкрджреНрдзрддрд┐ рдореЗрдВ, рд░рдЬрд┐рд╕реНрдЯрд░ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛, рдпрд╣ рд░реИрдо рдФрд░ рд░реЛрдо рдХрд╛ рдПрдХ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЕрдкрд╢рд┐рд╖реНрдЯ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрд╡рд░рдг рдХрд░рддреЗ рд╣реИрдВред

 template<uint32_t addr> class Register { public: __forceinline inline static void Xor(const uint32_t mask) { *reinterpret_cast<volatile uint32_t *>(addr) ^= mask; } }; int main() { using namespace Case6 ; using Odr = Register<GpioaOdrAddr>; Odr::Xor(1 << 5); using Idr = Register<GpioaIdrAddr>; Idr::Xor(1 << 5); // } 

рдПрдХ рдкреНрд▓рд╕ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛
  • рдХреЛрдИ рдЙрдкрд░рд┐ рдирд╣реАрдВред рдлрд╛рд╕реНрдЯ рдХреЙрдореНрдкреИрдХреНрдЯ рдХреЛрдб, рд╡рд┐рдХрд▓реНрдк 1 рдореЗрдВ рд╕рдорд╛рди (рдЬрдм рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рд░реИрдо рд▓рд╛рдЧрдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рдмрд┐рдирд╛ рд╕реНрдерд┐рд░ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)
рдЖрдЧреЗ рдмрдврд╝реЛ ...

рд╡рд┐рдзрд┐ 7. рдореВрд░реНрдЦрддрд╛ рдХреЛ рджреВрд░ рдХрд░реЗрдВ


рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдореИрдВ рд▓рдЧрд╛рддрд╛рд░ рдХреЛрдб рдореЗрдВ NON-FUNNY рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рдХреБрдЫ рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдареАрдХ рд╣реИ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд▓реЗрдХрд┐рди STUPIDness рдирд┐рд╖рд┐рджреНрдз рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдмрдХрд╡рд╛рд╕ рдХрд░рдиреЗ рд╕реЗ рдордирд╛ рдХрд░реЗрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рд╣рд╛рдпрдХ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддреЗ рд╣реИрдВ:

  struct WriteReg {}; struct ReadReg {}; struct ReadWriteReg: public WriteReg, public ReadReg {}; 

рдЕрдм рд╣рдо рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд░рдЬрд┐рд╕реНрдЯрд░ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВ:

 template<uint32_t addr, typename RegisterType> class Register { public: //       WriteReg,    // ,  ,       __forceinline template <typename T = RegisterType, class = typename std::enable_if_t<std::is_base_of<WriteReg, T>::value>> Register &operator^=(const uint32_t right) { *reinterpret_cast<volatile uint32_t *>(addr) ^= right; return *this; } }; 

рдЕрдм рдЖрдЗрдП рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ Idr рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рд▓рд┐рдП ^= рдСрдкрд░реЗрдЯрд░ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ:

  int main() { using GpioaOdr = Register<GpioaOdrAddr, WriteReg> ; GpioaOdr Odr ; Odr ^= (1 << 5) ; using GpioaIdr = Register<GpioaIdrAddr, ReadReg> ; GpioaIdr Idr ; Idr ^= (1 << 5) ; //,  Idr    } 

рддреЛ, рдЕрдм рдЕрдзрд┐рдХ pluses рд╣реИрдВ ...

рдЖрдХрд░реНрд╖рдг рдЖрддреЗ рд╣реИрдВ


  • рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА
  • рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛
  • рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдмрд┐рд▓реНрдбрд░реЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛
  • рдлрд╛рд╕реНрдЯ рдХреЙрдореНрдкреИрдХреНрдЯ рдХреЛрдб, рд╡рд┐рдХрд▓реНрдк 1 рдореЗрдВ рд╕рдорд╛рди
  • рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рд░реИрдо рд▓рд╛рдЧрдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдЯреИрдЯрд┐рдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдП рдмрд┐рдирд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
  • рдЖрдк рдореВрд░реНрдЦрддрд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ

рд╡рд┐рдкрдХреНрд╖


  • рдирд┐рд░реНрдорд╛рддрд╛ рд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
  • рдЖрдкрдХреЛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рднреА рдкрддреЗ рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ
  • рдЖрдкрдХреЛ рдХрдХреНрд╖рд╛ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреА рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

рддреЛ рдЖрдЗрдП рдЕрдзрд┐рдХ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдирд┐рдХрд╛рд▓реЗрдВ

рд╡рд┐рдзрд┐ 8. рдмрд┐рдирд╛ NONSENSE рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдХреНрд▓рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ


рддреБрд░рдВрдд рдХреЛрдб:

  struct WriteReg {}; struct ReadReg {}; struct ReadWriteReg: public WriteReg, public ReadReg {}; template<uint32_t addr, typename T> class Register { public: __forceinline template <typename T1 = T, class = typename std::enable_if_t<std::is_base_of<WriteReg, T1>::value>> inline static void Xor(const uint32_t mask) { *reinterpret_cast<volatile int*>(addr) ^= mask; } }; int main { using GpioaOdr = Register<GpioaOdrAddr, WriteReg> ; GpioaOdr::Xor(1 << 5) ; using GpioaIdr = Register<GpioaIdrAddr, ReadReg> ; GpioaIdr::Xor(1 << 5) ; //,  Idr    } 

рд╣рдо рдПрдХ рдФрд░ рдкреНрд▓рд╕ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рд╣рдо рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЖрдЧреЗ рдмрдврд╝реЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднреА рднреА рд╡рд┐рдкрдХреНрд╖ рд╣реИ

рд╡рд┐рдзрд┐ 9. рд╕рдВрд░рдЪрдирд╛ рдПрдХреАрдХрд░рдг рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ 8


рдкрд┐рдЫрд▓реА рдкрджреНрдзрддрд┐ рдореЗрдВ, рдХреЗрд╡рд▓ рдорд╛рдорд▓реЗ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд▓реЗрдХрд┐рди рд╡рд┐рдзрд┐ 1 рдореЗрдВ, рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдореЗрдВ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдореЙрдбреНрдпреВрд▓ рджреНрд╡рд╛рд░рд╛ рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХреЗрдВред рдЪрд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ ...

 namespace Case9 { struct WriteReg {}; struct ReadReg {}; struct ReadWriteReg: public WriteReg, public ReadReg {}; template<uint32_t addr, typename T> class Register { public: __forceinline template <typename T1 = T, class = typename std::enable_if_t<std::is_base_of<WriteReg, T1>::value>> inline static void Xor(const uint32_t mask) { *reinterpret_cast<volatile int*>(addr) ^= mask; } }; template<uint32_t addr> struct Gpio { using Moder = Register<addr, ReadWriteReg>; //      using Otyper = Register<addr + OtyperShift, ReadWriteReg> ; using Ospeedr = Register<addr + OspeedrShift,ReadWriteReg> ; using Pupdr = Register<addr + PupdrShift,ReadWriteReg> ; using Idr = Register<addr + IdrShift, ReadReg> ; using Odr = Register<addr + OdrShift, WriteReg> ; }; int main() { using Gpioa = Gpio<GPIOA_BASE> ; Gpioa::Odr::Xor(1 << 5) ; Gpioa::Idr::Xor((1 << 5) ); //,  Idr    } 

рдпрд╣рд╛рдВ рдорд╛рдЗрдирд╕ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдирдП рд╕рд┐рд░реЗ рд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдФрд░ рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдСрдлрд╕реЗрдЯ рдХреЛ рдХрд╣реАрдВ рди рдХрд╣реАрдВ рдпрд╛рдж рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдСрдлрд╕реЗрдЯ рдХрдВрдкрд╛рдЗрд▓рд░ рджреНрд╡рд╛рд░рд╛ рд╕реЗрдЯ рдХрд┐рдП рдЧрдП рдереЗ, рдФрд░ рд╡реНрдпрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╛рдж рдореЗрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдо рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧреА рджреНрд╡рд╛рд░рд╛ рд╕реБрдЭрд╛рдП рдЧрдП рдПрдХ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рддрд░реАрдХреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред

рд╡рд┐рдзрд┐ 10. рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдПрдХ рд╕рджрд╕реНрдп рдХреЛ рд╕реВрдЪрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд░рдЬрд┐рд╕реНрдЯрд░ рдкрд░ рд▓рдкреЗрдЯреЗрдВ


рдпрд╣рд╛рдВ рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдПрдХ рд╕рдВрдХреЗрддрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдПрдХ рд╕рджрд╕реНрдп рдФрд░ рдЙрди рддрдХ рдкрд╣реБрдВрдЪ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ ред

 template<uint32_t addr, typename T> class RegisterStructWrapper { public: __forceinline template<typename P> inline static void Xor(PT::*member, int mask) { reinterpret_cast<T*>(addr)->*member ^= mask ; //   ,     . } } ; using GpioaWrapper = RegisterStructWrapper<GPIOA_BASE, GPIO_TypeDef> ; int main() { GpioaWrapper::Xor(&GPIO_TypeDef::ODR, (1 << 5)) ; GpioaWrapper::Xor(&GPIO_TypeDef::IDR, (1 << 5)) ; // return 0 ; } 

рдЖрдХрд░реНрд╖рдг рдЖрддреЗ рд╣реИрдВ


  • рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА
  • рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛
  • рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдмрд┐рд▓реНрдбрд░реЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛
  • рдлрд╛рд╕реНрдЯ рдХреЙрдореНрдкреИрдХреНрдЯ рдХреЛрдб, рд╡рд┐рдХрд▓реНрдк 1 рдореЗрдВ рд╕рдорд╛рди
  • рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рд░реИрдо рд▓рд╛рдЧрдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдЯреИрдЯрд┐рдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рдП рдмрд┐рдирд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
  • рдирд┐рд░реНрдорд╛рддрд╛ рд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░ рдкрддреЗ рдХреЛ рд╕реНрд╡рдпрдВ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
  • рдХрдХреНрд╖рд╛ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреА рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ

рд╡рд┐рдкрдХреНрд╖


  • рдЖрдк рдореВрд░реНрдЦрддрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХреЛрдб рдХреА рд╕рдордЭ рдкрд░ рднреА рдЕрдЯрдХрд▓реЗрдВ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рд╡рд┐рдзрд┐ 10.5ред рд╡рд┐рдзрд┐ 9 рдФрд░ 10 рдХреЛ рдорд┐рд▓рд╛рдПрдВ


рд╕рдВрд░рдЪрдирд╛ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреА рдкрд╛рд░реА рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рд╕реВрдЪрдХ рдХреЛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рджрд╕реНрдп рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: volatile uint32_t T::*member , рдпрд╣ рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рдЗрд╕рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рджрд╕реНрдп рдХреА рдСрдлрд╕реЗрдЯ рд▓реМрдЯрд╛рдПрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ GPIO_TypeDef рд╕рдВрд░рдЪрдирд╛ рд╣реИ, рдлрд┐рд░ рдкрддрд╛ &GPIO_TypeDef::ODR 0x14 рд╣реЛрдЧрд╛ред
рд╣рдо рдЗрд╕ рдЕрд╡рд╕рд░ рдХреЛ рд╣рд░рд╛ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рдзрд┐ 9 рд╕реЗ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдкрддреЗ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ:

 struct WriteReg {}; struct ReadReg {}; struct ReadWriteReg: public WriteReg, public ReadReg {}; template<uint32_t addr, typename T, volatile uint32_t T::*member, typename RegType> class Register { public: __forceinline template <typename T1 = RegType, class = typename std::enable_if_t<std::is_base_of<WriteReg, T1>::value>> inline static void Xor(const uint32_t mask) { reinterpret_cast<T*>(addr)->*member ^= mask ; } }; template<uint32_t addr, typename T> struct Gpio { using Moder = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::ODR, ReadWriteReg>; using Otyper = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::OTYPER, ReadWriteReg>; using Ospeedr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::OSPEEDR, ReadWriteReg>; using Pupdr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::PUPDR, ReadWriteReg>; using Idr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::IDR, ReadReg>; using Odr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::ODR, WriteReg>; } ; 

рдЖрдк рдЕрдзрд┐рдХ рдЙрддреНрдХреГрд╖реНрдЯ рд░реВрдк рд╕реЗ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 using namespace Case11 ; using Gpioa = Gpio<GPIOA_BASE, GPIO_TypeDef> ; Gpioa::Odr::Xor(1 << 5) ; //Gpioa::Idr::Xor((1 << 5) ); //,  Idr    

рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдпрд╣рд╛рдВ рд╕рднреА рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдлрд╛рдЗрдЯрди рдореЗрдВ рдХреБрдЫ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреНрд╡рд╛рд░рд╛, рдЗрдирдкреБрдЯ рдореЗрдВ рдХреБрдЫ stm32f411xe.h рдХреА рддрд░рд╣ C ++ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЖрдкрдХреА рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ред
рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╣реИрдВ рдЬреЛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдмреЛрдирд╕ред рд╣рдо Phyton рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рднрд╛рд╖рд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдФрд░ рдкрд╛рд░реНрд╕рд┐рдо рдХреЛрдб рдкреЗрд╢ рдХрд░рддреЗ рд╣реИрдВ


C ++ рдореЗрдВ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛рдлреА рд╕рдордп рд╕реЗ рд╣реИред рд▓реЛрдЧ рдЗрд╕реЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рд╕реЗ рд╣рд▓ рдХрд░рддреЗ рд╣реИрдВред рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рднрд╛рд╖рд╛ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдирд╛рдо рдмрджрд▓рдиреЗ рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреА рд╣реИред рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдХрд╣рддреЗ рд╣реИрдВ, рдЕрдЧрд░ рдпрд╣ рдЗрд╕ рддрд░рд╣ рдереЗ:

 template<classname = [PortName]> class Gpio[Portname] { __forceinline inline static void Xor(const uint32_t mask) { GPIO[PortName]->ODR ^= mask ; } }; int main() { using GpioA = Gpio<"A"> ; GpioA::Xor(5) ; } 

рд▓реЗрдХрд┐рди рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдпрд╣ рднрд╛рд╖рд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЬреЛ рд╕рдорд╛рдзрд╛рди рд▓реЛрдЧ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рд╡рд╣ рдкрд╛рдпрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╣реИред рдпрд╛рдиреА рдХреБрдЫ рднрд╛рд╖рд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдХреЛрдб рдХреЛ рдкрд╛рдпрдерди рдкрд╛рд░реНрд╕рд░ рдХреЛ рдЦрд┐рд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕реЗ C ++ рдХреЛрдб рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред рдРрд╕рд╛ рдХреЛрдб рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ: (рдПрдХ рдЙрджрд╛рд╣рд░рдг рдореЙрдбрдо рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ; рдпрд╣рд╛рдВ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рд╣реИрдВ ):

 %% set port = gpio["port"] | upper %% set reg = "GPIO" ~ port %% set pin = gpio["pin"] class Gpio{{ port ~ pin }} : public Gpio { __forceinline inline static void Xor() { GPIO{{port}}->ODR ^= 1 << {{pin}} ; } } //        class Gpio5 : public Gpio { __forceinline inline static void Xor() { GPIO->ODR ^= 1 << 5 ; } } //     using Led = Gpio5; Led::Xor(); 


рдЕрдкрдбреЗрдЯ: рдмреЛрдирд╕ рдПрд╕рд╡реАрдбреА рдлрд╛рдЗрд▓реЗрдВ рдФрд░ рдкреИрдЯрди рдкрд░ рдкрд╛рд░реНрд╕рд░


рдПрдХ рдФрд░ рд╡рд┐рдХрд▓реНрдк рдЬреЛрдбрд╝рдирд╛ рднреВрд▓ рдЧрдПред рдПрдЖрд░рдПрдо рдкреНрд░рддреНрдпреЗрдХ рдПрд╕рд╡реАрдбреА рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рд╡рд░рдг рдлрд╝рд╛рдЗрд▓ рдЬрд╛рд░реА рдХрд░рддрд╛ рд╣реИред рдЬрд┐рд╕рд╕реЗ рдЖрдк рдлрд┐рд░ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде C ++ рдлрд╝рд╛рдЗрд▓ рдЬрдирд░реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреЙрд▓ рдУрд╕рдмреЛрд░реНрди рдиреЗ рдЗрди рд╕рднреА рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдЧрд┐рдЯрд╣рдм рдкрд░ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рд╣реИ ред рдЙрдиреНрд╣реЛрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рдпрдерди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рднреА рд▓рд┐рдЦреАред

рдпрд╣ рд╕рдм ... рдореЗрд░реА рдХрд▓реНрдкрдирд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдИ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрднреА рднреА рд╡рд┐рдЪрд╛рд░ рд╣реИрдВ, рддреЛ рдмреЗрдЭрд┐рдЭрдХред рд╕рднреА рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдБ рдирд┐рд╣рд┐рдд рд╣реИред

рд╕рдВрджрд░реНрдн


C ++ рдореЗрдВ рдЯрд╛рдЗрдкрд╕реЗрдл рд░рдЬрд┐рд╕реНрдЯрд░ рд░рдЬрд┐рд╕реНрдЯрд░ рдПрдХреНрд╕реЗрд╕
рдЪреАрдЬреЗрдВ рдмрдирд╛рдирд╛ C-++ рд╕реЗ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░-рд╕рд╛рдорд╛рди рдХрд░рдирд╛
рд╕рд╛рдорд╛рди рдмрдирд╛рдирд╛ рд╕рд╛рдорд╛рди - рднрд╛рдЧ 3
рд╕рд╛рдорд╛рди рдмрдирд╛рдирд╛ - рд╕рдВрд░рдЪрдирд╛ рдУрд╡рд░рд▓реЗ

Source: https://habr.com/ru/post/hi459204/


All Articles