Microcontrollers рдХреЗ рд▓рд┐рдП C ++ рдореЗрдВ, рдкрд┐рди рдХреА рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ CortexM рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)


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


рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдерд╛ рдХрд┐ рдЖрдк рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдореБрдЭреЗ рддреБрд░рдВрдд рдпрд╣ рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ 2010 рдореЗрдВ рдореЗрд░реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдм рдХреБрдЫ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рддрдп рд╣реЛ рдЪреБрдХрд╛ рдерд╛, рдпрд╣рд╛рдВ рд▓реЗрдЦ рд╣реИ: C ++ рдореЗрдВ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░реНрд╕ рдХреЗ рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рдкреЛрд░реНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ ред рдЬрд┐рд╕ рд╡реНрдпрдХреНрддрд┐ рдиреЗ 2010 рдореЗрдВ рдЗрд╕реЗ рд▓рд┐рдЦрд╛ рд╣реИ, рд╡рд╣ рдХреЗрд╡рд▓ рд╕реБрдВрджрд░ рд╣реИред


рдореИрдВ рдереЛрдбрд╝рд╛ рд╢рд░реНрдорд┐рдВрджрд╛ рдерд╛ рдХрд┐ рдореИрдВ рд╡рд╣реА рдХрд░реВрдВрдЧрд╛ рдЬреЛ 10 рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ 2020 рддрдХ рдЗрдВрддрдЬрд╛рд░ рдирд╣реАрдВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди 2019 рдореЗрдВ рдЗрд╕реЗ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 9 рд╕рд╛рд▓ рдкрд╣рд▓реЗ рддрдХ рдирд┐рд░реНрдгрдп рдХреЛ рджреЛрд╣рд░рд╛рдирд╛ рд╣реЛрдЧрд╛, рдпрд╣ рдЗрддрдирд╛ рдЧреВрдВрдЧрд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред


рдЙрдкрд░реЛрдХреНрдд рд▓реЗрдЦ рдореЗрдВ, рдЯрд╛рдЗрдк рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо C ++ 03 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрдм рдЕрдзрд┐рдХ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдереЗ, рдФрд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рдереЗред рддрдм рд╕реЗ, C ++ рдереЛрдбрд╝рд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЪрд▓рд┐рдП рдРрд╕рд╛ рд╣реА рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди C ++ 17 рдореЗрдВред рдмрд┐рд▓реНрд▓реА рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ:


рдХрд╛рд░реНрдп


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


рджрд░рдЕрд╕рд▓, рд╣рдо рдЬреЛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ рдХреЛрдб рдХреЗ рд╕рд╛рде рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


using Pin1 = Pin<GPIO, 1>; using Pin2 = Pin<GPIOB, 1>; using Pin3 = Pin<GPIOA, 1>; using Pin4 = Pin<GPIOC, 2>; using Pin5 = Pin<GPIOA, 3>; int main() { //    Pin    : //   GPIOA  10 GPIOA->BSRR = 10 ; // (1<<1) | (1 << 3) ; //   GPIOB  2 GPIOB->BSRR = 2 ; // (1 << 1) //   GPIOC  6 GPIOB->BSRR = 6 ; // (1 << 1) | (1 << 2); PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5>::Set() ; return 0; } 

BSRR рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ

рдЬреЛ рд▓реЛрдЧ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдорд╛рдорд▓реЛрдВ рд╕реЗ рдЕрд╡рдЧрдд рдирд╣реАрдВ рд╣реИрдВ, рдЙрдирдХреЗ рд▓рд┐рдП GPIOA->BSRR рд░рдЬрд┐рд╕реНрдЯрд░, рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рдкреИрд░реЛрдВ рдкрд░ рдкрд░рдорд╛рдгреБ рд╕реНрдерд╛рдкрдирд╛ рдпрд╛ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрд╣ рд░рдЬрд┐рд╕реНрдЯрд░ 32 рдмрд┐рдЯ рдХрд╛ рд╣реИред рдкрд╣рд▓реЗ 16 рдмрд┐рдЯреНрд╕ рдкреИрд░реЛрдВ рдкрд░ 1 рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВ, рджреВрд╕рд░реЗ 16 рдмрд┐рдЯреНрд╕ рдкреИрд░реЛрдВ рдкрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирдВрдмрд░ 3 рд▓реЗрдЧ рдХреЛ 1 рдкрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ BSRR рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рддреАрд╕рд░реЗ рдмрд┐рдЯ рдХреЛ 1 рдкрд░ рд╕реЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдирдВрдмрд░ 3 рд▓реЗрдЧ рдХреЛ 0 рдкрд░ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЙрд╕реА BSRR рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ 19 рдмрд┐рдЯреНрд╕ рдХреЛ 1 рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░рдгреЛрдВ рдХреА рдПрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдпреЛрдЬрдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдкреНрд░рд╕реНрддреБрдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ:



рдареАрдХ рд╣реИ, рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ:


рд╕рдВрдХрд▓рдХ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:


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

рдФрд░ рдлрд┐рд░ рдХрд╛рд░реНрдпрдХреНрд░рдо


  • рдпрд╣ рдорд╛рди рд╕реЗрдЯ рдХрд░реЗрдВ

рдФрд░ рдЖрдкрдХреЛ рдЗрд╕реЗ рдпрдерд╛рд╕рдВрднрд╡ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЕрдиреБрдХреВрд▓рди рдХреЗ рдмрд┐рдирд╛ рднреА рдХреЛрдб рдиреНрдпреВрдирддрдо рд╣реЛред рджрд░рдЕрд╕рд▓ рдпрд╣ рдкреВрд░рд╛ рдХрд╛рдо рд╣реИред


рдЪрд▓реЛ рдкрд╣рд▓реА рд╕рдирдХ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ: рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХрд┐ рд╕реВрдЪреА рдореЗрдВ рдЕрджреНрд╡рд┐рддреАрдп рдкрд┐рди рд╣реИред


рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рд╕реВрдЪреА рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ


рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд┐рдВрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИ:


 PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5> ; 

рдЕрдХрд╕реНрдорд╛рдд рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 PinsPack<Pin1, Pin2, Pin3, Pin4, Pin1> ; //     Pin1 

рдореИрдВ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдЗрд╕ рддрд░рд╣ рдХреА рдЧрд▓рддреА рдкрдХрдбрд╝реЗрдВ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд┐рдпрд╛рдиреЛрд╡рд╛рджрдХ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░реЗрдВред


рд╣рдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рд╕реВрдЪреА рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВрдЧреЗ:


  • рд╕реНрд░реЛрдд рд╕реВрдЪреА рд╕реЗ, рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдирдИ рд╕реВрдЪреА рдмрдирд╛рдПрдВ,
  • рдпрджрд┐ рд╕реНрд░реЛрдд рд╕реВрдЪреА рдХрд╛ рдкреНрд░рдХрд╛рд░ рдФрд░ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЗ рдмрд┐рдирд╛ рд╕реВрдЪреА рдХрд╛ рдкреНрд░рдХрд╛рд░ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рд╕реНрд░реЛрдд рд╕реВрдЪреА рдореЗрдВ рдкрд┐рди рд╕рдорд╛рди рдерд╛ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдиреЗ рдЧрд▓рддреА рдХреАред
  • рдпрджрд┐ рд╡реЗ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рдХреЛрдИ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдирд╣реАрдВ рд╣реИред

рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдирдИ рд╕реВрдЪреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рд╣рдпреЛрдЧреА рдиреЗ рдкрд╣рд┐рдпрд╛ рдХреЛ рд╕реБрджреГрдврд╝ рдХрд░рдиреЗ рдФрд░ рд▓реЛрдХреА рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд▓реЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рдирд╣реАрдВ рджреАред рдореЗрд░реЗ рдкрд╛рд╕ рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ рдФрд░ рдЪреБрд░рд╛ рд▓рд┐рдпрд╛ рд╣реИред рд▓рдЧрднрдЧ 2010 рдХреЗ рд╕рдорд╛рди рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рдеред


рд╡рд╣ рдХреЛрдб рдЬреЛ рдПрдХ рд╕рд╣рдпреЛрдЧреА рд╕реЗ рдЙрдзрд╛рд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрд┐рд╕рдиреЗ рд▓реЛрдХреА рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдЙрдзрд╛рд░ рд▓рд┐рдпрд╛ рдерд╛
 namespace PinHelper { template<typename ... Types> struct Collection { }; /////////////////   NoDuplicates   LOKI //////////////// template<class X, class Y> struct Glue; template<class T, class... Ts> struct Glue<T, Collection<Ts...>> { using Result = Collection<T, Ts...>; }; template<class Q, class X> struct Erase; template<class Q> struct Erase<Q, Collection<>> { using Result = Collection<>;}; template<class Q, class... Tail> struct Erase<Q, Collection<Q, Tail...>> { using Result = Collection<Tail...>;}; template<class Q, class T, class... Tail> struct Erase<Q, Collection<T, Tail...>> { using Result = typename Glue<T, typename Erase<Q, Collection<Tail...>>::Result>::Result;}; template <class X> struct NoDuplicates; template <> struct NoDuplicates<Collection<>> { using Result = Collection<>; }; template <class T, class... Tail> struct NoDuplicates< Collection<T, Tail...> > { private: using L1 = typename NoDuplicates<Collection<Tail...>>::Result; using L2 = typename Erase<T,L1>::Result; public: using Result = typename Glue<T, L2>::Result; }; ///////////////// LOKI //////////////// } 

рдЕрдм рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рд╣рд╛рдВ, рдпрд╣ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ:


 using Pin1 = Pin<GPIOC, 1>; using Pin2 = Pin<GPIOB, 1>; using Pin3 = Pin<GPIOA, 1>; using Pin4 = Pin<GPIOC, 2>; using Pin5 = Pin<GPIOA, 3>; using Pin6 = Pin<GPIOC, 1>; int main() { //  Pin1  ,    Pin6      using PinList = Collection<Pin1, Pin2, Pin3, Pin4, Pin1, Pin6> ; using TPins = typename NoDuplicates<PinList>::Result; //  static_assert.        // : Collection<Pin1, Pin2, Pin3, Pin4, Pin1, Pin6> //   : Collection<Pin1, Pin2, Pin3, Pin4> // ,    static_assert(std::is_same<TPins, PinList>::value, ":    ") ; return 0; } 

рдЦреИрд░ рдпрд╛рдиреА рдпрджрд┐ рдЖрдкрдиреЗ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдкрд┐рди рдХреА рд╕реВрдЪреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреА рд╣реИ, рдФрд░ рдЧрд▓рддреА рд╕реЗ рджреЛ рд╕рдорд╛рди рдкрд┐рди рд╕реВрдЪреА рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ, рддреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрдХрд▓рди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗрдЧрд╛: "рдкрд░реЗрд╢рд╛рдиреА: рд╕реВрдЪреА рдореЗрдВ рд╕рдорд╛рди рдкрд┐рдиред"


рд╡реИрд╕реЗ, рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдХреЗ рд▓рд┐рдП рдкрд┐рдВрд╕ рдХреА рд╕рд╣реА рд╕реВрдЪреА рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 //        // PinsPack<Port<GPIOB, 0>, Port<GPIOB, 1> ... Port<GPIOB, 15>> using GpiobPort = typename GeneratePins<15, GPIOB>::type //      using GpioaPort = typename GeneratePins<15, GPIOA>::type int main() { //    :  GPIOA.0  1 Gpioa<0>::Set() ; // GPIOB.1  0 Gpiob<1>::Clear() ; using LcdData = Collection<Gpioa<0>, Gpiob<6>, Gpiob<2>, Gpioa<3>, Gpioc<7>, Gpioa<4>, Gpioc<3>, Gpioc<10>> ; using TPinsLcd = typename NoDuplicates<LcdData>::Result; static_assert(std::is_same<TPinsB, LcdData>::value, ":        LCD") ; // A      LcdData::Write('A'); } 

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


 int main() { return 0 ; } 

рдЖрдЗрдП рдХреБрдЫ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ рдФрд░ рд╕реВрдЪреА рдореЗрдВ рдкрд┐рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Set() рд╡рд┐рдзрд┐ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ Set() ред


рдкреЛрд░реНрдЯ рдкрд┐рди рд╕реНрдерд╛рдкрдирд╛ рд╡рд┐рдзрд┐


рдЪрд▓реЛ рдХрд╛рд░реНрдп рдХреЗ рдмрд╣реБрдд рдЕрдВрдд рддрдХ рдереЛрдбрд╝рд╛ рдЖрдЧреЗ рдЪрд▓рддреЗ рд╣реИрдВред рдЕрдВрддрддрдГ, Set() рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЬреЛ рд╕реВрдЪреА рдореЗрдВ рдкрд┐рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ, рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рдХрд┐рди рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреЛрд░реНрдЯ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдХреЛрдб рдЬреЛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ
 using Pin1 = Pin<GPIOA, 1>; using Pin2 = Pin<GPIOB, 2>; using Pin3 = Pin<GPIOA, 2>; using Pin4 = Pin<GPIOC, 1>; using Pin5 = Pin<GPIOA, 3>; int main() { PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5>::Set() ; //      3   // GPIOA->BSRR = 14 ; // (1<<1) | (1 << 2) | (1 << 3) ; // GPIOB->BSRR = 4 ; // (1 << 2) // GPIOB->BSRR = 2 ; // (1 << 1); } 

рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрдХ рд╡рд░реНрдЧ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдкрд┐рдВрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реЛрдЧреА, рдФрд░ рдЗрд╕рдореЗрдВ рд╣рдо рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╕реНрдереИрддрд┐рдХ рд╡рд┐рдзрд┐ Set() рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред


 template <typename ...Ts> struct PinsPack { using Pins = PinsPack<Ts...> ; public: __forceinline static void Set(std::size_t mask) { } } ; 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, Set(size_t mask) рд╡рд┐рдзрд┐ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдорд╛рди (рдореБрдЦреМрдЯрд╛) рд▓реЗрддреА рд╣реИред рдпрд╣ рдореБрдЦреМрдЯрд╛ рд╡рд╣ рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдореЗрдВ рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдпрд╣ 0xffffffff рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдо рд╕рднреА рдкрд┐рдиреЛрдВ рдХреЛ рд╕реВрдЪреА рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рдЕрдзрд┐рдХрддрдо 32)ред рдпрджрд┐ рдЖрдк рд╡рд╣рд╛рдВ рдПрдХ рдФрд░ рдореВрд▓реНрдп рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 7 == 0b111, рддреЛ рд╕реВрдЪреА рдореЗрдВ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ 3 рдкрд┐рди рд╕реНрдерд╛рдкрд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЗрд╕реА рддрд░рд╣ред рдпрд╛рдиреА рдкрд┐рди рд╕реВрдЪреА рдореЗрдВ рдорд╛рд╕реНрдХ рдУрд╡рд░рд▓реЗрдбред


рдкреЛрд░реНрдЯ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ


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


рд╣рдорд╛рд░реЗ рдкрд┐рди рд╡рд┐рднрд┐рдиреНрди рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдХреЛ рд╕реМрдВрдкреЗ рдЧрдП рд╣реИрдВ:


 using Pin1 = Pin<Port<GPIOA>, 1>; using Pin2 = Pin<Port<GPIOB>, 2>; using Pin3 = Pin<Port<GPIOA>, 2>; using Pin4 = Pin<Port<GPIOC>, 1>; using Pin5 = Pin<Port<GPIOA>, 3>; 

рдЗрди 5 рдкрд┐рдиреЛрдВ рдореЗрдВ рдХреЗрд╡рд▓ 3 рдЕрджреНрд╡рд┐рддреАрдп рдкреЛрд░реНрдЯ (GPIOA, GPIOB, GPIOC) рд╣реИрдВред рдЕрдЧрд░ рд╣рдо PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5> рд╕реВрдЪреА рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЙрд╕рд╕реЗ рддреАрди рдкреЛрд░реНрдЯ рдХреА рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: Collection<Port<GPIOA>, Port<GPIOB>, Port<GPIOC>>


рдкрд┐рди рдХреНрд▓рд╛рд╕ рдореЗрдВ рдкреЛрд░реНрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд╕рд░рд▓реАрдХреГрдд рд░реВрдк рдореЗрдВ рдРрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:


 template<typename Port, uint8_t pinNum> struct Pin { using PortType = Port ; static constexpr uint32_t pin = pinNum ; ... } 

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


 template <typename... Types> struct Collection{} ; 

рдЕрдм рд╣рдо рдЕрджреНрд╡рд┐рддреАрдп рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдкрд┐рди рдХреА рд╕реВрдЪреА рдореЗрдВ рд╕рдорд╛рди рдкрд┐рди рдирд╣реАрдВ рд╣реИрдВред рдпрд╣ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ:


 template <typename ...Ts> struct PinsPack { using Pins = PinsPack<Ts...> ; private: //      using TPins = typename NoDuplicates<Collection<Ts...>>::Result; //           static_assert(std::is_same<TPins, Collection<Ts...>>::value, ":    ") ; //     using Ports = typename NoDuplicates<Collection<typename Ts::PortType...>>::Result; ... } ; 

рдЖрдЧреЗ рдмрдврд╝реЛ ...


рдкреЛрд░реНрдЯ рд▓рд┐рд╕реНрдЯ рдмрд╛рдпрдкрд╛рд╕


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


рдЪреВрдБрдХрд┐ рд╣рдореЗрдВ рдПрдХ рд╕реВрдЪреА рдХреЛ рдмрд╛рдИрдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдХрд╛ рдЖрдХрд╛рд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реЛрдЧрд╛ред


рд╣рдо "рдкреБрдирд░рд╛рд╡рд░реНрддреА" рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЬрд╛рдПрдВрдЧреЗ, рдЬрдмрдХрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдЕрднреА рднреА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рд╣рдо рдЙрд╕реА рдирд╛рдо рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╣реЗрдВрдЧреЗред


 template <typename ...Ts> struct PinsPack { using Pins = PinsPack<Ts...> ; private: __forceinline template<typename Port, typename ...Ports> constexpr static void SetPorts(Collection<Port, Ports...>, std::size_t mask) { // ,       if constexpr (sizeof ...(Ports) != 0U) { Pins::template WritePorts<Ports...>(Collection<Ports...>(), mask) ; } } } 

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


 __forceinline template<typename Port, typename ...Ports> constexpr static void SetPorts(Collection<Port, Ports...>, std::size_t mask) { //      auto result = GetPortValue<Port>(mask) ; //      Port::Set(result) ; if constexpr (sizeof ...(Ports) != 0U) { Pins::template WritePorts<Ports...>(Collection<Ports...>(), mask) ; } } 

рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ mask рдкреИрд░рд╛рдореАрдЯрд░ рдмрд╛рд╣рд░ рд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ рд╣рдо рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ SetPorts() рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рд╕реНрдерд┐рд░рд╛рдВрдХ рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛, SetPorts() рд╡рд┐рдзрд┐ рднреА рд░рдирдЯрд╛рдЗрдо рдкрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдЧреАред


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


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


рдПрдХ рд╕реНрдерд┐рд░ рдореВрд▓реНрдп рдХреЗ рд╕реНрдкрд╖реНрдЯ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдкрд╛рд╕рд┐рдВрдЧ mask рд╕рд╛рде рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВрдЧреЗ:


 __forceinline template<std::size_t mask, typename Port, typename ...Ports> constexpr static void SetPorts(Collection<Port, Ports...>) { using MyPins = PinsPack<Ts...> ; //    compile time,    value    constexpr auto result = GetPortValue<Port>(mask) ; Port::Set(result) ; if constexpr (sizeof ...(Ports) != 0U) { MyPins::template SetPorts<mask,Ports...>(Collection<Ports...>()) ; } } 

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


рдкреЛрд░реНрдЯ рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдорд╛рди рдХреА рдЧрдгрдирд╛


рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреЛрд░реНрдЯ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдкрд┐рди рд╕реВрдЪреА рд╕реЗ рдорд┐рд▓реА рд╣реИ, рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдпрд╣ рдПрдХ рд╕реВрдЪреА рд╣реИ: Collection<Port<GPIOA>, Port<GPIOB>, Port<GPIOC>> ред
рдЖрдкрдХреЛ рдЗрд╕ рд╕реВрдЪреА рдХрд╛ рдПрдХ рддрддреНрд╡ рд▓реЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, GPIOA рдкреЛрд░реНрдЯ, рдлрд┐рд░ рдкрд┐рди рд╕реВрдЪреА рдореЗрдВ рд╡реЗ рд╕рднреА рдкрд┐рди рдвреВрдВрдвреЗрдВ рдЬреЛ рдЗрд╕ рдкреЛрд░реНрдЯ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВ рдФрд░ рдкреЛрд░реНрдЯ рдореЗрдВ рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдлрд┐рд░ рдЕрдЧрд▓реЗ рдкреЛрд░реНрдЯ рдХреЗ рд╕рд╛рде рднреА рдРрд╕рд╛ рд╣реА рдХрд░реЗрдВред


рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рд╕реЗ: рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд┐рди рдХреА рд╕реВрдЪреА рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЕрджреНрд╡рд┐рддреАрдп рдмрдВрджрд░рдЧрд╛рд╣реЛрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
 using Pin1 = Pin<Port<GPIOC>, 1>; using Pin2 = Pin<Port<GPIOB>, 1>; using Pin3 = Pin<Port<GPIOA>, 1>; using Pin4 = Pin<Port<GPIOC>, 2>; using Pin5 = Pin<Port<GPIOA>, 3>; using Pins = PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5> ; 

рддреЛ GPIOA рдкреЛрд░реНрдЯ рдХреЗ рд▓рд┐рдП, рдорд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (1 << 1 ) | (1 << 3) = 10 (1 << 1 ) | (1 << 3) = 10 , рдФрд░ GPIOC рдкреЛрд░реНрдЯ рдХреЗ рд▓рд┐рдП - (1 << 1) | (1 << 2) = 6 (1 << 1) | (1 << 2) = 6 , рдФрд░ GPIOB (1 << 1 ) = 2


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


 template <typename ...Ts> struct PinsPack { using Pins = PinsPack<Ts...> ; private: __forceinline template<class QueryPort> constexpr static auto GetPortValue(std::size_t mask) { std::size_t result = 0; //  ,       // 1. ,        // 2.            // e (.     ), ,  Pin   0  //        10,      //    ( )  (1 << 10)    // 3.    1   // 4.   1-3      pass{(result |= ((std::is_same<QueryPort, typename Ts::PortType>::value ? 1 : 0) & mask) * (1 << Ts::pin), mask >>= 1)...} ; return result; } } ; 

рдкреНрд░рддреНрдпреЗрдХ рдкреЛрд░реНрдЯ рдХреЗ рдкреЛрд░реНрдЯ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдХрд▓рд┐рдд рдорд╛рди рд╕реЗрдЯ рдХрд░рдирд╛


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


 template <typename ...Ts> struct PinsPack { using Pins = PinsPack<Ts...> ; __forceinline static void Set(std::size_t mask) { //        SetPorts(Ports(), mask) ; } } 

рдЬреИрд╕рд╛ рдХрд┐ SetPorts() рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ SetPorts() рдПрдХ рд╕реНрдерд┐рд░ рдХреЗ рд░реВрдк рдореЗрдВ mask рдХреЗ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВрдЧреЗ, рдЗрд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛ рдореЗрдВ рдкрд╛рд╕ рдХрд░реЗрдВрдЧреЗред


 template <typename ...Ts> struct PinsPack { using Pins = PinsPack<Ts...> ; //    0xffffffff,      32  __forceinline template<std::size_t mask = 0xffffffffU> static void Set() { SetPorts<mask>(Ports()) ; } } 

рдЕрдВрддрд┐рдо рд░реВрдк рдореЗрдВ, рдкрд┐рди рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:
 using namespace PinHelper ; template <typename ...Ts> struct PinsPack { using Pins = PinsPack<Ts...> ; private: using TPins = typename NoDuplicates<Collection<Ts...>>::Result; static_assert(std::is_same<TPins, Collection<Ts...>>::value, ":    ") ; using Ports = typename NoDuplicates<Collection<typename Ts::PortType...>>::Result; template<class Q> constexpr static auto GetPortValue(std::size_t mask) { std::size_t result = 0; auto rmask = mask ; pass{(result |= ((std::is_same<Q, typename Ts::PortType>::value ? 1 : 0) & mask) * (1 << Ts::pin), mask>>=1)...}; pass{(result |= ((std::is_same<Q, typename Ts::PortType>::value ? 1 : 0) & ~rmask) * ((1 << Ts::pin) << 16), rmask>>=1)...}; return result; } __forceinline template<typename Port, typename ...Ports> constexpr static void SetPorts(Collection<Port, Ports...>, std::size_t mask) { auto result = GetPortValue<Port>(mask) ; Port::Set(result & 0xff) ; if constexpr (sizeof ...(Ports) != 0U) { Pins::template SetPorts<Ports...>(Collection<Ports...>(), mask) ; } } __forceinline template<std::size_t mask, typename Port, typename ...Ports> constexpr static void SetPorts(Collection<Port, Ports...>) { constexpr auto result = GetPortValue<Port>(mask) ; Port::Set(result & 0xff) ; if constexpr (sizeof ...(Ports) != 0U) { Pins::template SetPorts<mask, Ports...>(Collection<Ports...>()) ; } } __forceinline template<typename Port, typename ...Ports> constexpr static void WritePorts(Collection<Port, Ports...>, std::size_t mask) { auto result = GetPortValue<Port>(mask) ; Port::Set(result) ; if constexpr (sizeof ...(Ports) != 0U) { Pins::template WritePorts<Ports...>(Collection<Ports...>(), mask) ; } } __forceinline template<std::size_t mask, typename Port, typename ...Ports> constexpr static void WritePorts(Collection<Port, Ports...>) { Port::Set(GetPortValue<Port>(mask)) ; if constexpr (sizeof ...(Ports) != 0U) { Pins::template WritePorts<mask, Ports...>(Collection<Ports...>()) ; } } public: static constexpr size_t size = sizeof ...(Ts) + 1U ; __forceinline static void Set(std::size_t mask ) { SetPorts(Ports(), mask) ; } __forceinline template<std::size_t mask = 0xffffffffU> static void Set() { SetPorts<mask>(Ports()) ; } __forceinline static void Write(std::size_t mask) { WritePorts(Ports(), mask) ; } __forceinline template<std::size_t mask = 0xffffffffU> static void Write() { WritePorts<mask>(Ports()) ; } } ; 

рдирддреАрдЬрддрди, рдкреВрд░реА рдЪреАрдЬ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ:


 using Pin1 = Pin<GPIOC, 1>; using Pin2 = Pin<GPIOB, 1>; using Pin3 = Pin<GPIOA, 1>; using Pin4 = Pin<GPIOC, 2>; using Pin5 = Pin<GPIOA, 3>; using Pin6 = Pin<GPIOA, 5>; using Pin7 = Pin<GPIOC, 7>; using Pin8 = Pin<GPIOA, 3>; int main() { //1.   ,     3 ,  : // GPIOA->BSRR = (1 << 1) | (1 << 3) // GPIOB->BSRR = (1 << 1) // GPIOC->BSRR = (1 << 1) | (1 << 2) PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5>::Set() ; //   Set<0xffffffffU>() //2.   ,  3 ,  : // GPIOA->BSRR = (1 << 1) // GPIOB->BSRR = (1 << 1) // GPIOC->BSRR = (1 << 1) | (1 << 2) PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5, Pin6>::Set<7>() ; //3.          , //   someRunTimeValue     ,  //  SetPorts   constexpr    PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5>::Set(someRunTimeValue) ; using LcdData = PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5, Pin6, Pin7, Pin8> ; LcdData::Write('A') ; } 

рдПрдХ рдФрд░ рдкреВрд░рд╛ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдБ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
https://onlinegdb.com/r1eoXQBRH


рдЧрддрд┐


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдХреЛ рдпрд╛рдж рд╣реИ, рд╣рдо рдЕрдкрдиреА рдХреЙрд▓ рдХреЛ 3 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ, рдП 10 рдХреЛ рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░реЗрдВ, рдкреЛрд░реНрдЯ рдмреА - 2 рдФрд░ рдкреЛрд░реНрдЯ рд╕реА - 6


 using Pin1 = Pin<GPIO, 1>; using Pin2 = Pin<GPIOB, 1>; using Pin3 = Pin<GPIOA, 1>; using Pin4 = Pin<GPIOC, 2>; using Pin5 = Pin<GPIOA, 3>; int main() { //    Pin    : //   GPIOA  10 GPIOA->BSRR = 10 ; // (1<<1) | (1 << 3) ; //   GPIOB  2 GPIOB->BSRR = 2 ; // (1 << 1) //   GPIOC  6 GPIOB->BSRR = 6 ; // (1 << 1) | (1 << 2); PinsPack<Pin1, Pin2, Pin3, Pin4, Pin5>::Set() ; return 0; } 

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рдЬреЛ рд╣реБрдЖ рд╡рд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрдВрдж рд╣реЛ рдЧрдпрд╛ред



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


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕рдм рд╣реИред рдХреМрди рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИ, рдХреЛрдб рдпрд╣рд╛рдБ рд╣реИ ред


рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдБ рд╣реИ ред


https://onlinegdb.com/ByeA50wTS

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


All Articles