ูˆุตูˆู„ ุขู…ู† ู„ุชุณุฌูŠู„ ุงู„ุญู‚ูˆู„ ููŠ C ++ ุฏูˆู† ุงู„ุชุถุญูŠุฉ ุจุงู„ูƒูุงุกุฉ (ุจุงุณุชุฎุฏุงู… CortexM ูƒู…ุซุงู„)

ุตูˆุฑุฉ
ุงู„ุชูŠู†. ู…ุฃุฎูˆุฐุฉ ู…ู† www.extremetech.com/wp-content/uploads/2016/07/MegaProcessor-Feature.jpg

ุตุญุฉ ุฌูŠุฏุฉ ู„ู„ุฌู…ูŠุน!

ููŠ ู…ู‚ุงู„ุฉ ุณุงุจู‚ุฉ ุŒ ุฏุฑุณุช ู…ุณุฃู„ุฉ ุงู„ูˆุตูˆู„ ุฅู„ู‰ ุณุฌู„ุงุช ู…ุชุญูƒู… ู…ุน ูƒูˆุฑุชูŠูƒุณู… ูƒูˆุฑ ููŠ ุณูŠ + + ูˆุฃุธู‡ุฑุช ุญู„ูˆู„ุงู‹ ุจุณูŠุทุฉ ู„ุจุนุถ ุงู„ู…ุดุงูƒู„.

ุฃุฑูŠุฏ ุงู„ูŠูˆู… ุฃู† ุฃูˆุถุญ ููƒุฑุฉ ุนู† ูƒูŠููŠุฉ ุฌุนู„ ุงู„ูˆุตูˆู„ ุฅู„ู‰ ุงู„ุณุฌู„ ูˆุญู‚ูˆู„ู‡ ุขู…ู†ู‹ุง ุฏูˆู† ุงู„ุชุถุญูŠุฉ ุจุงู„ูƒูุงุกุฉ ุŒ ูˆุฐู„ูƒ ุจุงุณุชุฎุฏุงู… ูุฆุงุช C ++ ุงู„ุชูŠ ุชู… ุฅู†ุดุงุคู‡ุง ู…ู† ู…ู„ูุงุช SVD.

ูƒู„ ู…ู† ูŠู‡ู…ูƒ ุงู„ุฃู…ุฑ ุŒ ู…ุฑุญุจุง ุจูƒู… ููŠ ุงู„ู‚ุท. ุณูŠูƒูˆู† ู‡ู†ุงูƒ ุงู„ูƒุซูŠุฑ ู…ู† ุงู„ุชุนู„ูŠู…ุงุช ุงู„ุจุฑู…ุฌูŠุฉ.

ู…ู‚ุฏู…ุฉ


ููŠ ู…ู‚ุงู„ุฉ C ++ Hardware Access Access Redux ุŒ ุฃูˆุถุญ ูƒูŠู† ุณู…ูŠุซ ูƒูŠููŠุฉ ุงู„ุนู…ู„ ุจุฃู…ุงู† ูˆูƒูุงุกุฉ ู…ุน ุงู„ุณุฌู„ุงุช ุŒ ูˆุญุชู‰ ุฃุธู‡ุฑู‡ุง ู…ุน github.com/kensmith/cppmmio ูƒู…ุซุงู„.
ุซู… ุทูˆุฑ ุงู„ุนุฏูŠุฏ ู…ู† ุงู„ุฃุดุฎุงุต ู‡ุฐู‡ ุงู„ููƒุฑุฉ ุŒ ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ู‚ุงู… Niklas Hauser ุจุฅุฌุฑุงุก ู…ุฑุงุฌุนุฉ ุฑุงุฆุนุฉ ูˆุงู‚ุชุฑุญ ุนุฏุฉ ุทุฑู‚ ุฃุฎุฑู‰ ู„ู„ูˆุตูˆู„ ุฅู„ู‰ ุงู„ุณุฌู„ุงุช ุจุฃู…ุงู†.

ู„ู‚ุฏ ุชู… ุจุงู„ูุนู„ ุชู†ููŠุฐ ุจุนุถ ู‡ุฐู‡ ุงู„ุฃููƒุงุฑ ููŠ ู…ูƒุชุจุงุช ู…ุฎุชู„ูุฉ ุŒ ูˆุฎุงุตุฉ ููŠ ุงู„ู…ูˆุฏู… . ู…ู† ุฃุฌู„ ุงู„ุฎูŠุฑ ุŒ ูŠู…ูƒู†ูƒ ุงุณุชุฎุฏุงู… ูƒู„ ู‡ุฐู‡ ุงู„ุฌู…ู„ ููŠ ุงู„ุญูŠุงุฉ ุงู„ุญู‚ูŠู‚ูŠุฉ. ูˆู„ูƒู† ููŠ ูˆู‚ุช ุชุทูˆูŠุฑ ู‡ุฐู‡ ุงู„ู…ูƒุชุจุงุช ุŒ ุจุฏุฃุช ุชูˆุญุฏ ุงู„ุฃูˆุตุงู ุงู„ุทุฑููŠุฉ ูˆุงู„ุณุฌู„ุงุช ู„ุชูˆุญูŠุฏู‡ุง ุŒ ูˆุจุงู„ุชุงู„ูŠ ุชู… ุงู„ู‚ูŠุงู… ุจุจุนุถ ุงู„ุฃุดูŠุงุก ุจู‡ุฏู ุฃู† ูŠูƒูˆู† ุงู„ุนู…ู„ ุงู„ุฑุฆูŠุณูŠ ููŠ ูˆุตู ุงู„ุณุฌู„ุงุช ู…ุน ุงู„ู…ุจุฑู…ุฌ. ุฃูŠุถุง ุŒ ุจุนุถ ุงู„ุญู„ูˆู„ ู„ูŠุณุช ูุนุงู„ุฉ ู…ู† ุญูŠุซ ุงู„ูƒูˆุฏ ูˆู…ูˆุงุฑุฏ ู…ุชุญูƒู….

ุงู„ูŠูˆู… ุŒ ุชูˆูุฑ ูƒู„ ุดุฑูƒุฉ ุชุตู†ูŠุน ู…ุชุญูƒู… ARM ูˆุตูู‹ุง ู„ุฌู…ูŠุน ุงู„ุณุฌู„ุงุช ุจุชู†ุณูŠู‚ SVD. ูŠู…ูƒู† ุฅู†ุดุงุก ู…ู„ูุงุช ุงู„ุฑุฃุณ ู…ู† ู‡ุฐู‡ ุงู„ุฃูˆุตุงู ุ› ู„ุฐู„ูƒ ุŒ ู„ุง ูŠู…ูƒู† ุฅู†ุดุงุก ูˆุตู ุจุณูŠุท ู„ู„ุณุฌู„ุงุช ุŒ ุจู„ ูˆุตู ุฃูƒุซุฑ ุชุนู‚ูŠุฏู‹ุง ุŒ ูˆู„ูƒู† ููŠ ู†ูุณ ุงู„ูˆู‚ุช ุŒ ู…ู…ุง ุณูŠุฒูŠุฏ ู…ู† ู…ูˆุซูˆู‚ูŠุฉ ุงู„ูƒูˆุฏ. ูˆู…ู† ุงู„ุฑุงุฆุน ุฃู† ูŠูƒูˆู† ู…ู„ู ุงู„ุฅุฎุฑุงุฌ ุจุฃูŠ ู„ุบุฉ ุฃูˆ ู„ุบุฉ C ุฃูˆ C ++ ุฃูˆ ุญุชู‰ D

ู„ูƒู† ู„ู†ุฃุฎุฐ ุงู„ุฃู…ุฑ ุจุชุฑุชูŠุจ ุงู„ูˆุตูˆู„ ุงู„ุขู…ู† ุฅู„ู‰ ุงู„ุณุฌู„ุงุช ุŒ ูˆู„ู…ุงุฐุง ูŠุนุฏ ุถุฑูˆุฑูŠู‹ุง ุนู„ู‰ ุงู„ุฅุทู„ุงู‚. ูŠู…ูƒู† ุนุฑุถ ุงู„ุชูุณูŠุฑ ุนู„ู‰ ุฃู…ุซู„ุฉ ุงุตุทู†ุงุนูŠุฉ ุจุณูŠุทุฉ ุŒ ุนู„ู‰ ุงู„ุฃุฑุฌุญ ุบูŠุฑ ู…ุญุชู…ู„ุฉ ุŒ ูˆู„ูƒู† ู…ู† ุงู„ู…ู…ูƒู† ุญุฏูˆุซู‡ุง ุชู…ุงู…ู‹ุง:

int main(void) { //      GPIOA //,    AHB1ENR RCC->APB1ENR |= RCC_AHB1ENR_GPIOAEN ; //    ,      RCC->AHB1ENR = RCC_AHB1ENR_GPIOAEN; //,  TIM1    APB2 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB2ENR_TIM1EN; // - ,        . auto result = GPIOA->BSRR ; if (result & GPIO_BSRR_BS1) { //do something } //-     .   ... GPIOA->IDR = GPIO_IDR_ID5 ; } 

ูƒู„ ู‡ุฐู‡ ุงู„ุญุงู„ุงุช ู…ู…ูƒู†ุฉ ููŠ ุงู„ู…ู…ุงุฑุณุฉ ุงู„ุนู…ู„ูŠุฉ ุŒ ูˆุฃู†ุง ุจุงู„ุชุฃูƒูŠุฏ ุดุงู‡ุฏุช ุดูŠุฆู‹ุง ูƒู‡ุฐุง ู…ู† ุทู„ุงุจูŠ. ุณูŠูƒูˆู† ุฃู…ุฑุง ุฑุงุฆุนุง ุฅุฐุง ุฃู…ูƒู†ูƒ ุฃู† ุชู…ู†ุน ุงุฑุชูƒุงุจ ู…ุซู„ ู‡ุฐู‡ ุงู„ุฃุฎุทุงุก.

ูŠุจุฏูˆ ู„ูŠ ุฃูŠุถู‹ุง ุฃู†ู‡ ุฃูƒุซุฑ ู…ุชุนุฉ ุนู†ุฏู…ุง ูŠุจุฏูˆ ุงู„ุฑู…ุฒ ุฃู†ูŠู‚ู‹ุง ูˆู„ุง ูŠุญุชุงุฌ ุฅู„ู‰ ุชุนู„ูŠู‚ุงุช. ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ุญุชู‰ ู„ูˆ ูƒู†ุช ุชุนุฑู ู…ุชุญูƒู… STM32F411 ุฌูŠุฏู‹ุง ุŒ ูู„ูŠุณ ู…ู† ุงู„ู…ู…ูƒู† ุฏุงุฆู…ู‹ุง ูู‡ู… ู…ุง ูŠุญุฏุซ ููŠ ู‡ุฐุง ุงู„ุฑู…ุฒ:

 int main() { uint32 temp = GPIOA->OSPEEDR ; temp &=~ GPIO_OSPEEDR_OSPEED0_Msk ; temp = (GPIO_OSPEEDR_OSPEED0_0 | GPIO_OSPEEDR_OSPEED0_1) ; GPIOA->OSPEEDR = temp; } 

ู„ุง ุชุนู„ูŠู‚ ู‡ู†ุง ู„ุง ูŠู…ูƒู† ุงู„ู‚ูŠุงู… ุจู‡. ูŠุนูŠู† ุงู„ุฑู…ุฒ ุชุฑุฏุฏ ุชุดุบูŠู„ ู…ู†ูุฐ GPIOA.0 ุฅู„ู‰ ุงู„ุญุฏ ุงู„ุฃู‚ุตู‰ (ุชูˆุถูŠุญ ู…ู† mctMaks : ููŠ ุงู„ูˆุงู‚ุน ุŒ ุชุคุซุฑ ู‡ุฐู‡ ุงู„ู…ุนู„ู…ุฉ ุนู„ู‰ ูˆู‚ุช ุตุนูˆุฏ ุงู„ู…ู‚ุฏู…ุฉ (ุจู…ุนู†ู‰ ุŒ ุฏุฑุฌุฉ ุงู†ุญุฏุงุฑู‡ุง) ุŒ ูˆุชุนู†ูŠ ุฃู†ู‡ ูŠู…ูƒู† ู„ู„ู…ู†ูุฐ ู…ุนุงู„ุฌุฉ ุฅุดุงุฑุฉ ุฑู‚ู…ูŠุฉ ุจุดูƒู„ ุทุจูŠุนูŠ ุนู†ุฏ ุฅุดุงุฑุฉ ู…ุนูŠู†ุฉ (VeryLow \ Low \ Medium \ ุนุงู„ูŠุฉ) ุงู„ุชุฑุฏุฏ).

ุฏุนูˆู†ุง ู†ุญุงูˆู„ ุงู„ุชุฎู„ุต ู…ู† ู‡ุฐู‡ ุงู„ุนูŠูˆุจ.

ุณุฌู„ ุงู„ุชุฌุฑูŠุฏ


ุจุงุฏุฆ ุฐูŠ ุจุฏุก ุŒ ุชุญุชุงุฌ ุฅู„ู‰ ู…ุนุฑูุฉ ู…ุง ู‡ูˆ ุงู„ุณุฌู„ ู…ู† ูˆุฌู‡ุฉ ู†ุธุฑ ุงู„ู…ุจุฑู…ุฌ ูˆุงู„ุจุฑู†ุงู…ุฌ.

ูŠุญุชูˆูŠ ุงู„ุณุฌู„ ุนู„ู‰ ุนู†ูˆุงู† ุฃูˆ ุทูˆู„ ุฃูˆ ุญุฌู… ูˆุทุฑูŠู‚ุฉ ูˆุตูˆู„: ูŠู…ูƒู† ูƒุชุงุจุฉ ุจุนุถ ุงู„ุณุฌู„ุงุช ูˆุงู„ุจุนุถ ุงู„ุขุฎุฑ ูŠู…ูƒู† ู‚ุฑุงุกุชู‡ุง ูู‚ุท ูˆูŠู…ูƒู† ู‚ุฑุงุกุฉ ู…ุนุธู…ู‡ุง ูˆูƒุชุงุจุชู‡ุง.

ุจุงู„ุฅุถุงูุฉ ุฅู„ู‰ ุฐู„ูƒ ุŒ ูŠู…ูƒู† ุชู…ุซูŠู„ ุงู„ุณุฌู„ ูƒู…ุฌู…ูˆุนุฉ ู…ู† ุงู„ุญู‚ูˆู„. ูŠู…ูƒู† ุฃู† ูŠุชูƒูˆู† ุงู„ุญู‚ู„ ู…ู† ุจุช ูˆุงุญุฏ ุฃูˆ ุนุฏุฉ ุจุชุงุช ูˆูŠู‚ุน ููŠ ุฃูŠ ู…ูƒุงู† ููŠ ุงู„ุณุฌู„.

ู„ุฐู„ูƒ ุŒ ูุฅู† ุฎุตุงุฆุต ุงู„ุญู‚ู„ ุงู„ุชุงู„ูŠุฉ ู…ู‡ู…ุฉ ุจุงู„ู†ุณุจุฉ ู„ู†ุง: ุงู„ุทูˆู„ ุฃูˆ ุงู„ุญุฌู… ( ุงู„ุนุฑุถ ุฃูˆ ุงู„ุญุฌู… ) ุŒ ุงู„ุฅุฒุงุญุฉ ู…ู† ุจุฏุงูŠุฉ ุงู„ุชุณุฌูŠู„ ( ุงู„ุฅุฒุงุญุฉ ) ุŒ ูˆุงู„ู‚ูŠู…ุฉ.

ู‚ูŠู… ุงู„ุญู‚ูˆู„ ู‡ูŠ ู…ุณุงุญุฉ ู„ูƒู„ ุงู„ูƒู…ูŠุงุช ุงู„ู…ู…ูƒู†ุฉ ุงู„ุชูŠ ูŠู…ูƒู† ุฃู† ูŠุฃุฎุฐู‡ุง ุงู„ุญู‚ู„ ูˆูŠุนุชู…ุฏ ุฐู„ูƒ ุนู„ู‰ ุทูˆู„ ุงู„ุญู‚ู„. ุฃูŠ ุฅุฐุง ูƒุงู† ุงู„ุญู‚ู„ ุจุทูˆู„ 2 ุŒ ูู‡ู†ุงูƒ 4 ู‚ูŠู… ุญู‚ู„ ู…ู…ูƒู†ุฉ (0ุŒ1ุŒ2ุŒ3). ู…ุซู„ ุงู„ุณุฌู„ ุŒ ุชุญุชูˆูŠ ุงู„ุญู‚ูˆู„ ูˆู‚ูŠู… ุงู„ุญู‚ู„ ุนู„ู‰ ูˆุถุน ูˆุตูˆู„ (ู‚ุฑุงุกุฉ ูˆูƒุชุงุจุฉ ูˆู‚ุฑุงุกุฉ ูˆูƒุชุงุจุฉ)

ู„ุฌุนู„ู‡ุง ุฃูƒุซุฑ ูˆุถูˆุญู‹ุง ุŒ ุฏุนู†ุง ู†ุฃุฎุฐ ุณุฌู„ TIM1 CR1 ู…ู† ู…ุชุญูƒู… STM32F411. ุจุดูƒู„ ุชุฎุทูŠุทูŠ ุŒ ูŠุจุฏูˆ ูƒู…ุง ูŠู„ูŠ:

ุตูˆุฑุฉ

  • ุจุช 0 CEN: ุชู…ูƒูŠู† ุนุฏุงุฏ
    0: ุชู…ูƒูŠู† ุงู„ุนุฏุงุฏ: ุชุนุทูŠู„
    1: ุนุฏุงุฏ: ุชู…ูƒูŠู†
  • UDIS ุจุช 1: ุชู…ูƒูŠู† / ุชุนุทูŠู„ ุญุฏุซ UEV
    0: ุชู… ุชู…ูƒูŠู† ุญุฏุซ UEV: ุชู…ูƒูŠู†
    1: ุญุฏุซ ุฎุงุฑุฌ UEV: ุชุนุทูŠู„
  • ุจุช URS 2: ุญุฏุฏ ู…ุตุงุฏุฑ ุชูˆู„ูŠุฏ ุฃุญุฏุงุซ UEV
    0: ูŠุชู… ุฅู†ุดุงุก UEV ุนู†ุฏู…ุง ุชููŠุถ ุฃูˆ ุนู†ุฏ ุชุนูŠูŠู† UG: ุฃูŠ ุจุช
    1: ูŠุชู… ุฅู†ุดุงุก UEV ูู‚ุท ุนู„ู‰ ุชุฌุงูˆุฒ ุงู„ุณุนุฉ : ุชุฌุงูˆุฒ ุงู„ุณุนุฉ
  • ุจุช 3 OPM: ุชุดุบูŠู„ ู…ุฑุฉ ูˆุงุญุฏุฉ
    0: ูŠุณุชู…ุฑ ุงู„ู…ูˆู‚ุช ููŠ ุงู„ุงุนุชู…ุงุฏ ุฃูƒุซุฑ ุจุนุฏ ุงู„ุญุฏุซ UEV: ContinueAfterUEV
    1: ุชูˆู‚ู ุงู„ู…ูˆู‚ุช ุจุนุฏ ุงู„ุญุฏุซ UEV : StopAfterUEV
  • ุจุช 4 DIR: ุงุชุฌุงู‡ ุงู„ุนุฏ
    0: ุงู„ุญุณุงุจ ุงู„ู…ุจุงุดุฑ: Upcounter
    1: ุงู„ุนุฏ ุงู„ุชู†ุงุฒู„ูŠ : Downcounter
  • ุจุช 6: 5 ุณู…: ูˆุถุน ุงู„ู…ุญุงุฐุงุฉ
    0: ูˆุถุน ุงู„ู…ุญุงุฐุงุฉ 0: CenterAlignedMode0
    1: ูˆุถุน ุงู„ู…ุญุงุฐุงุฉ 1: CenterAlignedMode1
    2: ูˆุถุน ุงู„ู…ุญุงุฐุงุฉ 2: CenterAlignedMode2
    3: ูˆุถุน ุงู„ู…ุญุงุฐุงุฉ 3: CenterAlignedMode3
  • ุจุช 7 APRE: ูˆุถุน ุงู„ุชุญู…ูŠู„ ุงู„ู…ุณุจู‚ ู„ุชุณุฌูŠู„ ARR
    0: ู„ุง ูŠุชู… ุชุฎุฒูŠู† ุณุฌู„ TIMx_ARR ู…ุคู‚ุชู‹ุง: ARRNotBuffered
    1: ู„ุง ูŠุชู… ุชุฎุฒูŠู† ุณุฌู„ TIMx_ARR ู…ุคู‚ุชู‹ุง: ARRBuffered
  • ุจุช 8: 9 ูƒุฏ: ู…ู‚ุณู… ุงู„ุณุงุนุฉ
    0: tDTS = tCK_INT: ClockDevidedBy1
    1: tDTS = 2 * tCK_INT: ClockDevidedBy2
    2: tDTS = 4 * tCK_INT: ClockDevidedBy4
    3: ู…ุญููˆุธุฉ: ู…ุญููˆุธุฉ

ู‡ู†ุง ุŒ ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ CEN ู‡ูˆ ุญู‚ู„ 1 ุจุช ู…ุน ุฅุฒุงุญุฉ 0 ู†ุณุจุฉ ุฅู„ู‰ ุจุฏุงูŠุฉ ุงู„ุชุณุฌูŠู„. ูˆ Enable (1) ูˆ Disable (0) ู‡ู…ุง ู‚ูŠู…ุชู‡ู…ุง ุงู„ู…ู…ูƒู†ุฉ.

ู„ู† ู†ุฑูƒุฒ ุนู„ู‰ ู…ุง ูŠุชุญู…ู„ู‡ ูƒู„ ุญู‚ู„ ููŠ ู‡ุฐุง ุงู„ุณุฌู„ ุจุดูƒู„ ุฎุงุต ุŒ ู…ู† ุงู„ู…ู‡ู… ุจุงู„ู†ุณุจุฉ ู„ู†ุง ุฃู† ูŠูƒูˆู† ู„ูƒู„ ุญู‚ู„ ูˆุญู‚ู„ ู‚ูŠู…ุฉ ุงุณู… ูŠุญู…ู„ ู…ุนู†ู‰ ุฏู„ุงู„ูŠู‹ุง ูˆูŠู…ูƒู† ู…ู† ุฎู„ุงู„ู‡ ูู‡ู… ู…ุง ูŠู‚ูˆู… ุจู‡ ู…ู† ุญูŠุซ ุงู„ู…ุจุฏุฃ.

ูŠุฌุจ ุฃู† ูŠูƒูˆู† ู„ุฏูŠู†ุง ุญู‚ ุงู„ูˆุตูˆู„ ุฅู„ู‰ ูƒู„ ู…ู† ุงู„ุณุฌู„ ูˆุงู„ู…ูŠุฏุงู† ูˆู‚ูŠู…ุชู‡. ู„ุฐู„ูƒ ุŒ ููŠ ุดูƒู„ ุชู‚ุฑูŠุจูŠ ู„ู„ุบุงูŠุฉ ุŒ ูŠู…ูƒู† ุชู…ุซูŠู„ ุชุฌุฑูŠุฏ ุงู„ุณุฌู„ ุจุงู„ูุฆุงุช ุงู„ุชุงู„ูŠุฉ:

ุตูˆุฑุฉ

ุจุงู„ุฅุถุงูุฉ ุฅู„ู‰ ุงู„ูุตูˆู„ ุงู„ุฏุฑุงุณูŠุฉ ุŒ ู…ู† ุงู„ู…ู‡ู… ุฃูŠุถู‹ุง ุฃู† ูŠูƒูˆู† ู„ู„ุณุฌู„ุงุช ูˆุงู„ุญู‚ูˆู„ ุงู„ูุฑุฏูŠุฉ ุฎุตุงุฆุต ู…ุนูŠู†ุฉ ุฃูˆ ุฃู† ุงู„ุณุฌู„ ู„ู‡ ุนู†ูˆุงู† ุฃูˆ ุญุฌู… ุฃูˆ ูˆุถุน ูˆุตูˆู„ (ู„ู„ู‚ุฑุงุกุฉ ูู‚ุท ุฃูˆ ู„ู„ูƒุชุงุจุฉ ูู‚ุท ุฃูˆ ูƒู„ุงู‡ู…ุง).
ูŠุญุชูˆูŠ ุงู„ุญู‚ู„ ุนู„ู‰ ุงู„ุญุฌู… ูˆุงู„ุฅุฒุงุญุฉ ูˆูˆุถุน ุงู„ูˆุตูˆู„ ุฃูŠุถู‹ุง. ุจุงู„ุฅุถุงูุฉ ุฅู„ู‰ ุฐู„ูƒ ุŒ ูŠุฌุจ ุฃู† ูŠุญุชูˆูŠ ุงู„ุญู‚ู„ ุนู„ู‰ ุฑุงุจุท ุฅู„ู‰ ุงู„ุณุฌู„ ุงู„ุฐูŠ ูŠู†ุชู…ูŠ ุฅู„ูŠู‡.

ูŠุฌุจ ุฃู† ุชุญุชูˆูŠ ู‚ูŠู…ุฉ ุงู„ุญู‚ู„ ุนู„ู‰ ุงุฑุชุจุงุท ุฅู„ู‰ ุงู„ุญู‚ู„ ูˆุณู…ุฉ ุฅุถุงููŠุฉ - ุงู„ู‚ูŠู…ุฉ.

ู„ุฐู„ูƒ ุŒ ููŠ ุฅุตุฏุงุฑ ุฃูƒุซุฑ ุชูุตูŠู„ุงู‹ ุŒ ุณูŠุจุฏูˆ ุงู„ุชุฌุฑูŠุฏ ู„ุฏูŠู†ุง ูƒู…ุง ูŠู„ูŠ:



ุจุงู„ุฅุถุงูุฉ ุฅู„ู‰ ุงู„ุณู…ุงุช ุŒ ูŠุฌุจ ุฃู† ูŠูƒูˆู† ู„ุฏูŠู†ุง ุงู„ุชุฌุฑูŠุฏ ุฃุณุงู„ูŠุจ ุงู„ุชุนุฏูŠู„ ูˆุงู„ูˆุตูˆู„. ู„ู„ุจุณุงุทุฉ ุŒ ู†ุญู† ู†ู‚ุชุตุฑ ุนู„ู‰ ุทุฑู‚ ุงู„ุชุซุจูŠุช / ุงู„ูƒุชุงุจุฉ ูˆุงู„ู‚ุฑุงุกุฉ.

ุตูˆุฑุฉ

ุนู†ุฏู…ุง ู‚ุฑุฑู†ุง ุชุฌุฑูŠุฏ ุงู„ุญุงู„ุฉ ุŒ ู†ุญุชุงุฌ ุฅู„ู‰ ุงู„ุชุญู‚ู‚ ู…ู† ุชูˆุงูู‚ ู‡ุฐุง ุงู„ุชุฌุฑูŠุฏ ู…ุน ู…ุง ู‡ูˆ ู…ูˆุตูˆู ููŠ ู…ู„ู SVD.

ุนุฑุถ ูˆุตู ุงู„ู†ุธุงู… (SVD) ู…ู„ู


ุชู†ุณูŠู‚ ูˆุตู ุงู„ุนุฑุถ ุงู„ุชู‚ุฏูŠู…ูŠ ู„ู†ุธุงู… CMSIS (CMSIS-SVD) ู‡ูˆ ูˆุตู ุฑุณู…ูŠ ู„ุณุฌู„ุงุช ู…ุชุญูƒู… ูŠุนุชู…ุฏ ุนู„ู‰ ู…ุนุงู„ุฌ ARM Cortex-M. ุงู„ู…ุนู„ูˆู…ุงุช ุงู„ูˆุงุฑุฏุฉ ููŠ ุฃูˆุตุงู ุชู…ุซูŠู„ ุงู„ู†ุธุงู… ุŒ ูŠุชูˆุงูู‚ ุนู…ู„ูŠุง ู…ุน ุงู„ุจูŠุงู†ุงุช ุงู„ู…ูˆุฌูˆุฏุฉ ููŠ ุงู„ุฃุฏู„ุฉ ุงู„ู…ุฑุฌุนูŠุฉ ู„ู„ุฃุฌู‡ุฒุฉ. ูŠู…ูƒู† ุฃู† ูŠุญุชูˆูŠ ูˆุตู ุงู„ุณุฌู„ุงุช ููŠ ู…ุซู„ ู‡ุฐุง ุงู„ู…ู„ู ุนู„ู‰ ู…ุนู„ูˆู…ุงุช ุฑููŠุนุฉ ุงู„ู…ุณุชูˆู‰ ูˆุงู„ุบุฑุถ ู…ู† ุฌุฒุก ูˆุงุญุฏ ูู‚ุท ู…ู† ุงู„ุญู‚ู„ ููŠ ุงู„ุณุฌู„.

ู…ู† ุงู„ู†ุงุญูŠุฉ ุงู„ุชุฎุทูŠุทูŠุฉ ุŒ ูŠู…ูƒู† ูˆุตู ู…ุณุชูˆูŠุงุช ุชูุงุตูŠู„ ุงู„ู…ุนู„ูˆู…ุงุช ููŠ ู…ุซู„ ู‡ุฐุง ุงู„ู…ู„ู ู…ู† ุฎู„ุงู„ ุงู„ู…ุฎุทุท ุงู„ุชุงู„ูŠ ุŒ ุงู„ุฐูŠ ุชู… ุงุชุฎุงุฐู‡ ุนู„ู‰ ู…ูˆู‚ุน Keil :

ุตูˆุฑุฉ

ูŠุชู… ุชูˆููŠุฑ ู…ู„ูุงุช SVD ุงู„ูˆุตู ู…ู† ู‚ุจู„ ุงู„ุดุฑูƒุงุช ุงู„ู…ุตู†ุนุฉ ูˆูŠุชู… ุงุณุชุฎุฏุงู…ู‡ุง ุฃุซู†ุงุก ุชุตุญูŠุญ ุงู„ุฃุฎุทุงุก ู„ุนุฑุถ ู…ุนู„ูˆู…ุงุช ุญูˆู„ ู…ุชุญูƒู… ูˆุณุฌู„ุงุช. ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ูŠุณุชุฎุฏู…ู‡ู… IAR ู„ุนุฑุถ ุงู„ู…ุนู„ูˆู…ุงุช ููŠ ู„ูˆุญุฉ View-> Registers. ุงู„ู…ู„ูุงุช ู†ูุณู‡ุง ู…ูˆุฌูˆุฏุฉ ููŠ ุงู„ู…ุฌู„ุฏ Program Files (x86) \ IAR Systems \ Embedded Workbench 8.3 \ arm \ config \ debugger.

ูŠุณุชุฎุฏู… Clion ู…ู† JetBrains ุฃูŠุถู‹ุง ู…ู„ูุงุช svd ู„ุนุฑุถ ู…ุนู„ูˆู…ุงุช ุงู„ุชุณุฌูŠู„ ุฃุซู†ุงุก ุชุตุญูŠุญ ุงู„ุฃุฎุทุงุก.

ูŠู…ูƒู†ูƒ ุฏุงุฆู…ู‹ุง ุชู†ุฒูŠู„ ุงู„ุฃูˆุตุงู ู…ู† ู…ูˆุงู‚ุน ุงู„ุดุฑูƒุฉ ุงู„ู…ุตู†ุนุฉ. ู‡ู†ุง ูŠู…ูƒู†ูƒ ุฃู† ุชุฃุฎุฐ ู…ู„ู SVD ู„ู„ุชุญูƒู… ุงู„ุฏู‚ูŠู‚ STM32F411

ุจุดูƒู„ ุนุงู… ุŒ ุชู†ุณูŠู‚ SVD ู‡ูˆ ุงู„ู…ุนูŠุงุฑ ุงู„ุฐูŠ ุชุฏุนู…ู‡ ุงู„ุดุฑูƒุงุช ุงู„ู…ุตู†ุนุฉ. ุฏุนูˆู†ุง ู†ุฑู‰ ู…ุง ู‡ูŠ ู…ุณุชูˆูŠุงุช ุงู„ูˆุตู ููŠ SVD.

ููŠ ุงู„ู…ุฌู…ูˆุน ุŒ ูŠุชู… ุชู…ูŠูŠุฒ 5 ู…ุณุชูˆูŠุงุช ุŒ ูˆู…ุณุชูˆู‰ ุงู„ุฌู‡ุงุฒ ุŒ ูˆู…ุณุชูˆู‰ ู…ุชุญูƒู… ุŒ ูˆู…ุณุชูˆู‰ ุงู„ุชุณุฌูŠู„ ุŒ ูˆู…ุณุชูˆู‰ ุงู„ุญู‚ู„ ุŒ ูˆู…ุณุชูˆู‰ ุงู„ู‚ูŠู… ุงู„ู…ุฐูƒูˆุฑุฉ.

  • ู…ุณุชูˆู‰ ุงู„ุฌู‡ุงุฒ : ูˆุตู ุงู„ู…ุณุชูˆู‰ ุงู„ุนู„ูˆูŠ ู„ุนุฑุถ ุงู„ู†ุธุงู… ู‡ูˆ ุงู„ุฌู‡ุงุฒ. ููŠ ู‡ุฐุง ุงู„ู…ุณุชูˆู‰ ุŒ ูŠุชู… ุชูˆุถูŠุญ ุงู„ุฎุตุงุฆุต ุงู„ู…ุชุนู„ู‚ุฉ ุจุงู„ุฌู‡ุงุฒ ูƒูƒู„. ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ุงุณู… ุงู„ุฌู‡ุงุฒ ุฃูˆ ุงู„ูˆุตู ุฃูˆ ุงู„ุฅุตุฏุงุฑ. ูˆุญุฏุฉ ุงู„ุญุฏ ุงู„ุฃุฏู†ู‰ ุนู†ูˆู†ุฉ ุŒ ูˆูƒุฐู„ูƒ ุนู…ู‚ ุจุช ู†ุงู‚ู„ ุงู„ุจูŠุงู†ุงุช. ูŠู…ูƒู† ุชุนูŠูŠู† ุงู„ู‚ูŠู… ุงู„ุงูุชุฑุงุถูŠุฉ ู„ุณู…ุงุช ุงู„ุณุฌู„ ุŒ ู…ุซู„ ุญุฌู… ุงู„ุชุณุฌูŠู„ ุŒ ูˆู‚ูŠู…ุฉ ุฅุนุงุฏุฉ ุงู„ุชุนูŠูŠู† ุŒ ูˆุฃุฐูˆู†ุงุช ุงู„ูˆุตูˆู„ ุŒ ู„ู„ุฌู‡ุงุฒ ุจุฃูƒู…ู„ู‡ ููŠ ู‡ุฐุง ุงู„ู…ุณุชูˆู‰ ุŒ ูˆุชูƒูˆู† ู…ูˆุฑูˆุซุฉ ุถู…ู†ูŠุงู‹ ุจู…ุณุชูˆูŠุงุช ู…ู†ุฎูุถุฉ ู…ู† ุงู„ูˆุตู.
  • ู…ุณุชูˆู‰ ู…ุชุญูƒู…: ูŠุตู ู‚ุณู… ูˆุญุฏุฉ ุงู„ู…ุนุงู„ุฌุฉ ุงู„ู…ุฑูƒุฒูŠุฉ ุฌูˆู‡ุฑ ู…ุชุญูƒู… ูˆู…ูŠุฒุงุชู‡. ู‡ุฐุง ุงู„ู‚ุณู… ู…ุทู„ูˆุจ ุฅุฐุง ุชู… ุงุณุชุฎุฏุงู… ู…ู„ู SVD ู„ุฅู†ุดุงุก ู…ู„ู ุฑุฃุณ ุงู„ุฌู‡ุงุฒ.
  • ุงู„ุทุจู‚ุฉ ุงู„ู…ุญูŠุทูŠุฉ : ุงู„ุฌู‡ุงุฒ ุงู„ู…ุญูŠุทูŠ ุนุจุงุฑุฉ ุนู† ู…ุฌู…ูˆุนุฉ ู…ุณู…ุงุฉ ู…ู† ุงู„ุณุฌู„ุงุช. ูŠุชู… ุชุนูŠูŠู† ุงู„ุฌู‡ุงุฒ ุงู„ู…ุญูŠุทูŠ ุฅู„ู‰ ุนู†ูˆุงู† ุฃุณุงุณูŠ ู…ุญุฏุฏ ููŠ ู…ุณุงุญุฉ ุนู†ูˆุงู† ุงู„ุฌู‡ุงุฒ.
  • ู…ุณุชูˆู‰ ุงู„ุชุณุฌูŠู„ : ุงู„ุณุฌู„ ู‡ูˆ ู…ูˆุฑุฏ ู‚ุงุจู„ ู„ู„ุจุฑู…ุฌุฉ ู…ุณู…ู‰ ูŠู†ุชู…ูŠ ุฅู„ู‰ ุฌู‡ุงุฒ ุทุฑููŠ. ูŠุชู… ุชุนูŠูŠู† ุงู„ุณุฌู„ุงุช ุฅู„ู‰ ุนู†ูˆุงู† ู…ุญุฏุฏ ููŠ ู…ุณุงุญุฉ ุนู†ูˆุงู† ุงู„ุฌู‡ุงุฒ. ุงู„ุนู†ูˆุงู† ู…ุฑุชุจุท ุจุงู„ุนู†ูˆุงู† ุงู„ู…ุญูŠุทูŠ ุงู„ุฃุณุงุณูŠ. ุฃูŠุถุง ุŒ ู„ู„ุณุฌู„ ุŒ ูŠุดุงุฑ ุฅู„ู‰ ูˆุถุน ุงู„ูˆุตูˆู„ (ุงู„ู‚ุฑุงุกุฉ / ุงู„ูƒุชุงุจุฉ).
  • ู…ุณุชูˆู‰ ุงู„ุญู‚ู„ : ูƒู…ุง ุฐูƒุฑ ุฃุนู„ุงู‡ ุŒ ูŠู…ูƒู† ุชู‚ุณูŠู… ุงู„ุณุฌู„ุงุช ุฅู„ู‰ ุฃุฌุฒุงุก ู…ู† ูˆุธุงุฆู ู…ุฎุชู„ูุฉ - ุงู„ุญู‚ูˆู„. ูŠุญุชูˆูŠ ู‡ุฐุง ุงู„ู…ุณุชูˆู‰ ุนู„ู‰ ุฃุณู…ุงุก ุงู„ุญู‚ูˆู„ ุงู„ูุฑูŠุฏุฉ ููŠ ู†ูุณ ุงู„ุณุฌู„ ุŒ ูˆุญุฌู…ู‡ุง ุŒ ูˆุงู„ุฅุฒุงุญุงุช ุงู„ู…ุชุนู„ู‚ุฉ ุจุจุฏุงูŠุฉ ุงู„ุณุฌู„ ุŒ ูˆูƒุฐู„ูƒ ูˆุถุน ุงู„ูˆุตูˆู„.
  • ู…ุณุชูˆู‰ ู‚ูŠู… ุงู„ุญู‚ูˆู„ ุงู„ุชูŠ ุชู… ุชุนุฏุงุฏู‡ุง : ููŠ ุงู„ูˆุงู‚ุน ุŒ ูŠุชู… ุชุณู…ูŠุฉ ู‡ุฐู‡ ุงู„ู‚ูŠู… ุจู‚ูŠู… ุงู„ุญู‚ู„ ุงู„ุชูŠ ูŠู…ูƒู† ุงุณุชุฎุฏุงู…ู‡ุง ู„ู„ุฑุงุญุฉ ููŠ C ูˆ C ++ ูˆ D ูˆู…ุง ุฅู„ู‰ ุฐู„ูƒ.

ููŠ ุงู„ูˆุงู‚ุน ุŒ ู…ู„ูุงุช SVD ู‡ูŠ ู…ู„ูุงุช xml ุนุงุฏูŠุฉ ู…ุน ูˆุตู ูƒุงู…ู„ ู„ู„ู†ุธุงู…. ู‡ู†ุงูƒ ู…ุญูˆู„ุงุช ู…ู„ูุงุช svd ุฅู„ู‰ ุฑู…ุฒ C ุŒ ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ู‡ู†ุง ุŒ ูˆุงู„ุชูŠ ุชูˆู„ุฏ ุฑุคูˆุณ ูˆู‡ูŠุงูƒู„ ู…ู„ุงุฆู…ุฉ ู„ู€ C ู„ูƒู„ ู…ุญูŠุท ูˆุชุณุฌูŠู„.

ูŠูˆุฌุฏ ุฃูŠุถู‹ุง ู…ุญู„ู„ cmsis-svd ู„ู…ู„ูุงุช SVD ู…ูƒุชูˆุจ ุจู„ุบุฉ Phyton ุŒ ูˆู‡ูˆ ูŠู‚ูˆู… ุจุดูŠุก ู…ุง ู…ุซู„ ุฅู„ุบุงุก ุชุณู„ุณู„ ุงู„ุจูŠุงู†ุงุช ู…ู† ู…ู„ู ุฅู„ู‰ ูƒุงุฆู†ุงุช ูุฆุฉ ููŠ Phython ุŒ ูˆุงู„ุชูŠ ูŠุชู… ุงุณุชุฎุฏุงู…ู‡ุง ุจุนุฏ ุฐู„ูƒ ููŠ ุจุฑู†ุงู…ุฌ ุฅู†ุดุงุก ุงู„ุดูุฑุฉ.

ูŠู…ูƒู† ุงู„ุงุทู„ุงุน ุนู„ู‰ ู…ุซุงู„ ู„ูˆุตู ุณุฌู„ ู…ุชุญูƒู… STM32F411 ุชุญุช ุงู„ู…ูุณุฏ:

ู…ุซุงู„ ุณุฌู„ ู…ุคู‚ุช CR1 TIM1
 <peripheral> <name>TIM1</name> <description>Advanced-timers</description> <groupName>TIM</groupName> <baseAddress>0x40010000</baseAddress> <addressBlock> <offset>0x0</offset> <size>0x400</size> <usage>registers</usage> </addressBlock> <registers> <register> <name>CR1</name> <displayName>CR1</displayName> <description>control register 1</description> <addressOffset>0x0</addressOffset> <size>0x20</size> <access>read-write</access> <resetValue>0x0000</resetValue> <fields> <field> <name>CKD</name> <description>Clock division</description> <bitOffset>8</bitOffset> <bitWidth>2</bitWidth> </field> <field> <name>ARPE</name> <description>Auto-reload preload enable</description> <bitOffset>7</bitOffset> <bitWidth>1</bitWidth> </field> <field> <name>CMS</name> <description>Center-aligned mode selection</description> <bitOffset>5</bitOffset> <bitWidth>2</bitWidth> </field> <field> <name>DIR</name> <description>Direction</description> <bitOffset>4</bitOffset> <bitWidth>1</bitWidth> </field> <field> <name>OPM</name> <description>One-pulse mode</description> <bitOffset>3</bitOffset> <bitWidth>1</bitWidth> </field> <field> <name>URS</name> <description>Update request source</description> <bitOffset>2</bitOffset> <bitWidth>1</bitWidth> </field> <field> <name>UDIS</name> <description>Update disable</description> <bitOffset>1</bitOffset> <bitWidth>1</bitWidth> </field> <field> <name>CEN</name> <description>Counter enable</description> <bitOffset>0</bitOffset> <bitWidth>1</bitWidth> </field> </fields> </register> <register> 


ูƒู…ุง ุชุฑูˆู† ุŒ ู‡ู†ุงูƒ ูƒู„ ุงู„ู…ุนู„ูˆู…ุงุช ุงู„ู„ุงุฒู…ุฉ ู„ุชุฌุฑูŠุฏู†ุง ุŒ ุจุงุณุชุซู†ุงุก ูˆุตู ู‚ูŠู… ุงู„ุจุชุงุช ุงู„ู…ุญุฏุฏุฉ ู„ู„ุญู‚ูˆู„.

ู„ุง ูŠุฑุบุจ ุฌู…ูŠุน ุงู„ู…ุตู†ู‘ุนูŠู† ููŠ ู‚ุถุงุก ุจุนุถ ุงู„ูˆู‚ุช ููŠ ูˆุตู ูƒุงู…ู„ ู„ู†ุธุงู…ู‡ู… ุŒ ู„ุฐุง ูƒู…ุง ุชุฑู‰ ุŒ ู„ู… ุชุฑุบุจ ST ููŠ ูˆุตู ู‚ูŠู… ุงู„ุญู‚ูˆู„ ูˆู†ู‚ู„ ู‡ุฐุง ุงู„ุนุจุก ุฅู„ู‰ ู…ุจุฑู…ุฌูŠ ุงู„ุนู…ู„ุงุก. ู„ูƒู† TI ุชู‡ุชู… ุจุนู…ู„ุงุฆู‡ุง ูˆุชุตู ุงู„ู†ุธุงู… ุจุงู„ูƒุงู…ู„ ุŒ ุจู…ุง ููŠ ุฐู„ูƒ ุฃูˆุตุงู ู‚ูŠู… ุงู„ุญู‚ูˆู„.

ู…ุง ูˆุฑุฏ ุฃุนู„ุงู‡ ูŠูˆุถุญ ุฃู† ุชู†ุณูŠู‚ ูˆุตู SVD ู…ุชูˆุงูู‚ ุฌุฏู‹ุง ู…ุน ุชุฌุฑูŠุฏ ู‚ุถูŠุชู†ุง. ูŠุญุชูˆูŠ ุงู„ู…ู„ู ุนู„ู‰ ุฌู…ูŠุน ุงู„ู…ุนู„ูˆู…ุงุช ุงู„ู„ุงุฒู…ุฉ ู…ู† ุฃุฌู„ ูˆุตู ุงู„ุณุฌู„ ุจุงู„ูƒุงู…ู„.

ุชุทุจูŠู‚


ุชุณุฌูŠู„


ุงู„ุขู† ูˆุจุนุฏ ุฃู† ู‚ู…ู†ุง ุจุงู„ุชุฌุฑูŠุฏ ู…ู† ุงู„ุณุฌู„ ูˆู„ุฏูŠู†ุง ูˆุตู ู„ู„ุณุฌู„ุงุช ููŠ ุดูƒู„ ู…ู„ู svd ู…ู† ุงู„ุดุฑูƒุงุช ุงู„ู…ุตู†ุนุฉ ุงู„ุชูŠ ุชุชู†ุงุณุจ ุจุดูƒู„ ู…ุซุงู„ูŠ ู…ุน ู‡ุฐุง ุงู„ุชุฌุฑูŠุฏ ุŒ ูŠู…ูƒู†ู†ุง ุงู„ุงู†ุชู‚ุงู„ ู…ุจุงุดุฑุฉ ุฅู„ู‰ ุงู„ุชู†ููŠุฐ.

ูŠุฌุจ ุฃู† ูŠูƒูˆู† ุชู†ููŠุฐู†ุง ูุนุงู„ู‹ุง ู…ุซู„ ุฑู…ุฒ C ูˆุณู‡ู„ ุงู„ุงุณุชุฎุฏุงู…. ุฃุฑุบุจ ููŠ ุฃู† ูŠูƒูˆู† ุงู„ูˆุตูˆู„ ุฅู„ู‰ ุงู„ุณุฌู„ุงุช ูˆุงุถุญู‹ุง ู‚ุฏุฑ ุงู„ุฅู…ูƒุงู† ุŒ ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ู…ุซู„ ู‡ุฐุง:

  if (TIM1::CR1::CKD::DividedBy2::IsSet()) { TIM1::ARR::Set(10_ms) ; TIM1::CR1::CEN::Enable::Set() ; } 

ุชุฐูƒุฑ ุฃู†ู‡ ู…ู† ุฃุฌู„ ุงู„ูˆุตูˆู„ ุฅู„ู‰ ุนู†ูˆุงู† ุงู„ุชุณุฌูŠู„ ุงู„ุตุญูŠุญ ุŒ ุชุญุชุงุฌ ุฅู„ู‰ ุงุณุชุฎุฏุงู… reinterpret_cast:

 *reinterpret_cast<volatile uint32_t *>(0x40010000) = (1U << 5U) ; 

ุชู… ุจุงู„ูุนู„ ูˆุตู ูุฆุฉ ุงู„ุณุฌู„ ุฃุนู„ุงู‡ ุŒ ูˆูŠุฌุจ ุฃู† ูŠูƒูˆู† ู„ู‡ุง ุนู†ูˆุงู† ูˆุญุฌู… ูˆูˆุถุน ูˆุตูˆู„ ุŒ ุจุงู„ุฅุถุงูุฉ ุฅู„ู‰ ุทุฑูŠู‚ุชูŠู† Get() ูˆ Set() :

 //      template<uint32_t address, size_t size, typename AccessMode> struct RegisterBase { static constexpr auto Addr = address ; using Type = typename RegisterType<size>::Type ; // Set     , //     __forceinline template<typename T = AccessMode, class = typename std::enable_if_t<std::is_base_of<WriteMode, T>::value>> inline static void Set(Type value) { *reinterpret_cast<volatile Type *>(address) = value ; } // Get    , //    ,    __forceinline template<typename T = AccessMode, class = typename std::enable_if_t<std::is_base_of<ReadMode, T>::value>> inline static Type Get() { return *reinterpret_cast<volatile Type *>(address) ; } } ; 

ู†ู‚ูˆู… ุจุชู…ุฑูŠุฑ ุงู„ุนู†ูˆุงู† ูˆุทูˆู„ ุงู„ุชุณุฌูŠู„ ูˆูˆุถุน ุงู„ูˆุตูˆู„ ุฅู„ู‰ ู…ุนู„ู…ุงุช ุงู„ู‚ุงู„ุจ (ู‡ุฐู‡ ุฃูŠุถู‹ุง ูุฆุฉ). ุจุงุณุชุฎุฏุงู… ุขู„ูŠุฉ SFINAE ุŒ ูˆู‡ูŠ enable_if enable_if ุŒ ุณู†ู‚ูˆู… ุจู€ "ุงู„ุชุฎู„ุต" ู…ู† ูˆุธุงุฆู ุงู„ูˆุตูˆู„ Set() ุฃูˆ Get() ู„ู„ุณุฌู„ุงุช ุงู„ุชูŠ ู„ุง ูŠู†ุจุบูŠ ุฃู† ุชุฏุนู…ู‡ุง. ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ุฅุฐุง ูƒุงู† ุงู„ุณุฌู„ ู„ู„ู‚ุฑุงุกุฉ ูู‚ุท ุŒ ูุณู†ู‚ูˆู… ReadMode ู†ูˆุน ReadMode ุฅู„ู‰ ู…ุนู„ู…ุฉ ุงู„ู‚ุงู„ุจ ุŒ ูˆุณูˆู ูŠู‚ูˆู… enable_if ุจุงู„ุชุญู‚ู‚ ู…ู…ุง ุฅุฐุง ูƒุงู† ุงู„ูˆุตูˆู„ ู‡ูˆ ุฎู„ูŠูุฉ ReadMode ูˆุฅุฐุง ู„ู… ูŠูƒู† ุงู„ุฃู…ุฑ ูƒุฐู„ูƒ ุŒ ูุณูŠุคุฏูŠ ุฐู„ูƒ ุฅู„ู‰ ุฅู†ุดุงุก ุฎุทุฃ ู…ุญูƒูˆู… ุนู„ูŠู‡ (ู„ู† ูŠุชู… ุนุฑุถ ุงู„ู†ูˆุน T) ุŒ ูˆู„ู† ูŠุชุถู…ู† ุงู„ู…ุชุฑุฌู… ุทุฑูŠู‚ุฉ Set() ู„ู…ุซู„ ู‡ุฐุง ุงู„ุณุฌู„. ุงู„ุดูŠุก ู†ูุณู‡ ูŠู†ุทุจู‚ ุนู„ู‰ ุณุฌู„ ู…ุฎุตุต ู„ู„ูƒุชุงุจุฉ ูู‚ุท.

ู„ู„ุชุญูƒู… ููŠ ุงู„ูˆุตูˆู„ ุŒ ุณูˆู ู†ุณุชุฎุฏู… ุงู„ูุตูˆู„ ุงู„ุฏุฑุงุณูŠุฉ:

 //    struct WriteMode {}; struct ReadMode {}; struct ReadWriteMode: public WriteMode, public ReadMode {}; 

ุชุฃุชูŠ ุงู„ุณุฌู„ุงุช ุจุฃุญุฌุงู… ู…ุฎุชู„ูุฉ: 8 ุŒ 16 ุŒ 32 ุŒ 64 ุจุช. ู„ูƒู„ ู…ู†ู‡ุง ุŒ ู†ุถุน ู†ูˆุนู†ุง:

ู†ูˆุน ุงู„ุณุฌู„ุงุช ุญุณุจ ุงู„ุญุฌู…
 template <uint32_t size> struct RegisterType {} ; template<> struct RegisterType<8> { using Type = uint8_t ; } ; template<> struct RegisterType<16> { using Type = uint16_t ; } ; template<> struct RegisterType<32> { using Type = uint32_t ; } ; template<> struct RegisterType<64> { using Type = uint64_t ; } ; 


ุจุนุฏ ุฐู„ูƒ ุŒ ุจุงู„ู†ุณุจุฉ ุฅู„ู‰ TIM1 ุงู„ู…ุคู‚ุช ุŒ ูŠู…ูƒู†ูƒ ุชุญุฏูŠุฏ ุณุฌู„ CR1 ุŒ ูˆุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ุณุฌู„ EGR ุจู‡ุฐู‡ ุงู„ุทุฑูŠู‚ุฉ:

 struct TIM1 { struct CR1 : public RegisterBase<0x40010000, 32, ReadWriteMode> { } struct EGR : public RegisterBase<0x40010014, 32, WriteMode> { } } int main() { TIM1::CR1::Set(10) ; auto reg = TIM1::CR1::Get() ; // ,     reg = TIM1::EGR::Get() } 

ู†ุธุฑู‹ุง ู„ุฃู† ุงู„ู…ุญูˆู„ ุงู„ุจุฑู…ุฌูŠ ูŠุนุฑุถ ุฃุณู„ูˆุจ Get() ูู‚ุท ReadMode ูŠุชู… ููŠู‡ุง ุชูˆุฑูŠุซ ูˆุถุน ุงู„ูˆุตูˆู„ ู…ู† ReadMode ุŒ ูˆุทุฑู‚ Set() ุงู„ุฎุงุตุฉ WriteMode ูŠุชู… ููŠู‡ุง ุชูˆุฑูŠุซ ูˆุถุน ุงู„ูˆุตูˆู„ ู…ู† WriteMode ุŒ ููŠ ุญุงู„ุฉ ุงู„ุงุณุชุฎุฏุงู… ุบูŠุฑ ุงู„ุตุญูŠุญ ู„ุฃุณุงู„ูŠุจ ุงู„ูˆุตูˆู„ ุŒ ุณุชุชู„ู‚ู‰ ุฎุทุฃ ููŠ ู…ุฑุญู„ุฉ WriteMode . ูˆุฅุฐุง ูƒู†ุช ุชุณุชุฎุฏู… ุฃุฏูˆุงุช ุงู„ุชุทูˆูŠุฑ ุงู„ุญุฏูŠุซุฉ ุŒ ู…ุซู„ Clion ุŒ ุญุชู‰ ููŠ ู…ุฑุญู„ุฉ ุงู„ุชุฑู…ูŠุฒ ุŒ ุณุชุฑู‰ ุชุญุฐูŠุฑู‹ุง ู…ู† ู…ุญู„ู„ ุงู„ุดูุฑุฉ:

ุตูˆุฑุฉ

ุญุณู†ู‹ุง ุŒ ุฃุตุจุญ ุงู„ูˆุตูˆู„ ุฅู„ู‰ ุงู„ุณุฌู„ุงุช ุงู„ุขู† ุฃูƒุซุฑ ุฃู…ุงู†ู‹ุง ุŒ ูˆู„ุง ูŠุณู…ุญ ู„ูƒ ุฑู…ุฒู†ุง ุจุงู„ู‚ูŠุงู… ุจุฃุดูŠุงุก ุบูŠุฑ ู…ู‚ุจูˆู„ุฉ ู„ู‡ุฐุง ุงู„ุณุฌู„ ุŒ ู„ูƒู†ู†ุง ู†ุฑูŠุฏ ุงู„ู…ุถูŠ ู‚ุฏู…ู‹ุง ูˆุงู„ุฅุดุงุฑุฉ ุฅู„ู‰ ุงู„ุณุฌู„ ุจุฃูƒู…ู„ู‡ ุŒ ูˆู„ูƒู† ุฅู„ู‰ ุญู‚ูˆู„ู‡.

ุงู„ุญู‚ูˆู„


ูŠุญุชูˆูŠ ุงู„ุญู‚ู„ ุจุฏู„ุงู‹ ู…ู† ุงู„ุนู†ูˆุงู† ุนู„ู‰ ู‚ูŠู…ุฉ ุชุญูˆูŠู„ ู†ุณุจุฉ ุฅู„ู‰ ุจุฏุงูŠุฉ ุงู„ุณุฌู„. ุจุงู„ุฅุถุงูุฉ ุฅู„ู‰ ุฐู„ูƒ ุŒ ู…ู† ุฃุฌู„ ู…ุนุฑูุฉ ุงู„ุนู†ูˆุงู† ุฃูˆ ุงู„ู†ูˆุน ุงู„ุฐูŠ ูŠุฌุจ ุชู‚ุฏูŠู… ู‚ูŠู…ุฉ ุงู„ุญู‚ู„ ุฅู„ูŠู‡ ุŒ ูŠุฌุจ ุฃู† ูŠูƒูˆู† ู„ุฏูŠู‡ ุฑุงุจุท ุฅู„ู‰ ุงู„ุณุฌู„:

 //        template<typename Reg, size_t offset, size_t size, typename AccessMode> struct RegisterField { using RegType = typename Reg::Type ; using Register = Reg ; static constexpr RegType Offset = offset ; static constexpr RegType Size = size ; using Access = AccessMode ; template<typename T = AccessMode, class = typename std::enable_if_t<std::is_base_of<WriteMode, T>::value>> static void Set(RegType value) { assert(value < (1U << size)) ; //CriticalSection cs ; //    RegType newRegValue = *reinterpret_cast<RegType *>(Register::Address) ; //       newRegValue &= ~ (((1U << size) - 1U) << offset); //    newRegValue |= (value << offset) ; //      *reinterpret_cast<RegType *>(Reg::Address) = newRegValue ; } __forceinline template<typename T = AccessMode, class = typename std::enable_if_t<std::is_base_of<ReadMode, T>::value>> inline static RegType Get() { return ((*reinterpret_cast<RegType *>(Reg::Address)) & (((1U << size) - 1U) << offset)) >> offset ; } }; 

ุจุนุฏ ุฐู„ูƒ ุŒ ู…ู† ุงู„ู…ู…ูƒู† ุจุงู„ูุนู„ ุงู„ู‚ูŠุงู… ุจุงู„ุฃู…ูˆุฑ ุงู„ุชุงู„ูŠุฉ:

 struct TIM1 { struct CR1 : public RegisterBase<0x40010000, 32, ReadWriteMode> { using CKD = RegisterField<TIM1::CR1, 8, 2, ReadWriteMode> ; using ARPE = RegisterField<TIM1::CR1, 7, 1, ReadWriteMode> ; using CMS = RegisterField<TIM1::CR1, 5, 2, ReadWriteMode> ; using DIR = RegisterField<TIM1::CR1, 4, 1, ReadWriteMode> ; using OPM = RegisterField<TIM1::CR1, 3, 1, ReadWriteMode> ; using URS = RegisterField<TIM1::CR1, 2, 1, ReadWriteMode> ; using UDIS = RegisterField<TIM1::CR1, 1, 1, ReadWriteMode> ; using CEN = RegisterField<TIM1::CR1, 0, 1, ReadWriteMode> ; } } int main() { //   CR1  9   1,  8  0 TIM1::CR1::CKD::Set(2U) ; auto reg = TIM1::CR1::CEN::Get() ; } 

ุนู„ู‰ ุงู„ุฑุบู… ู…ู† ุฃู† ูƒู„ ุดูŠุก ูŠุจุฏูˆ ุฌูŠุฏู‹ุง ุจุดูƒู„ ุนุงู… ุŒ ุฅู„ุง ุฃู†ู‡ ู„ุง ูŠุฒุงู„ ุบูŠุฑ ูˆุงุถุญ ุชู…ุงู…ู‹ุง ู…ุงุฐุง TIM1::CR1::CKD::Set(2) ุŒ ู…ุงุฐุง ูŠุนู†ูŠ TIM1::CR1::CKD::Set(2) ุงู„ู„ุฐูŠู† ุชู… ุชู…ุฑูŠุฑู‡ู…ุง ุฅู„ู‰ ูˆุธูŠูุฉ Set() ุŸ ูˆู…ุงุฐุง ูŠุนู†ูŠ ุงู„ุฑู‚ู… ุงู„ู…ุฑุชุฌุน ุจูˆุงุณุทุฉ ุทุฑูŠู‚ุฉ TIM1::CR1::CEN::Get() ุŸ

ุงู„ุงู†ุชู‚ุงู„ ุจุณู„ุงุณุฉ ุฅู„ู‰ ู‚ูŠู… ุงู„ุญู‚ู„.

ู‚ูŠู…ุฉ ุงู„ุญู‚ู„


ูŠุนุฏ ุชุฌุฑูŠุฏ ู‚ูŠู…ุฉ ุงู„ุญู‚ู„ ุญู‚ู„ู‹ุง ุฃุณุงุณูŠู‹ุง ุฃูŠุถู‹ุง ุŒ ูˆู„ูƒู†ู‡ ู‚ุงุฏุฑ ุนู„ู‰ ู‚ุจูˆู„ ุญุงู„ุฉ ูˆุงุญุฏุฉ ูู‚ุท. ุชุชู… ุฅุถุงูุฉ ุงู„ุณู…ุงุช ุฅู„ู‰ ุชุฌุฑูŠุฏ ุงู„ุญู‚ู„ - ุงู„ู‚ูŠู…ุฉ ุงู„ูุนู„ูŠุฉ ูˆุฑุงุจุท ุฅู„ู‰ ุงู„ุญู‚ู„. ุทุฑูŠู‚ุฉ Set() ู‚ูŠู…ุฉ ุงู„ุญู‚ู„ ู…ุทุงุจู‚ุฉ ู„ุทุฑูŠู‚ุฉ Set() ุงู„ุญู‚ู„ ุŒ ุจุงุณุชุซู†ุงุก ุฃู† ุงู„ู‚ูŠู…ุฉ ู†ูุณู‡ุง ู„ุง ุชุญุชุงุฌ ุฅู„ู‰ ุฃู† ุชู†ุชู‚ู„ ุฅู„ู‰ ู‡ุฐู‡ ุงู„ุทุฑูŠู‚ุฉ ุŒ ูู‡ูŠ ู…ุนุฑูˆูุฉ ู…ู‚ุฏู…ู‹ุง ุŒ ุชุญุชุงุฌ ูู‚ุท ุฅู„ู‰ ุถุจุท. ู„ูƒู† ุฃุณู„ูˆุจ Get() ู„ุง ู…ุนู†ู‰ ู„ู‡ ุ› ูˆุจุฏู„ุงู‹ ู…ู† ุฐู„ูƒ ุŒ ู…ู† ุงู„ุฃูุถู„ ุงู„ุชุญู‚ู‚ ู…ู…ุง ุฅุฐุง ูƒุงู†ุช ู‡ุฐู‡ ุงู„ู‚ูŠู…ุฉ ู…ุญุฏุฏุฉ ุฃู… ู„ุง ุŒ IsSet() ู‡ุฐู‡ ุงู„ุทุฑูŠู‚ุฉ ุจุฃุณู„ูˆุจ IsSet() .

 //        template<typename Field, typename Field::Register::Type value> struct FieldValueBase { using RegType = typename Field::Register::Type ; template<typename T = typename Field::Access, class = typename std::enable_if_t<std::is_base_of<WriteMode, T>::value>> static void Set() { RegType newRegValue = *reinterpret_cast<RegType *>(Field::Register::Address) ; newRegValue &= ~ (((1U << Field::Size) - 1U) << Field::Offset); newRegValue |= (value << Field::Offset) ; *reinterpret_cast<RegType *>(Field::Register::Address) = newRegValue ; } __forceinline template<typename T = typename Field::Access, class = typename std::enable_if_t<std::is_base_of<ReadMode, T>::value>> inline static bool IsSet() { return ((*reinterpret_cast<RegType *>(Field::Register::Address)) & static_cast<RegType>(((1U << Field::Size) - 1U) << Field::Offset)) == (value << Field::Offset) ; } }; 

ูŠู…ูƒู† ุงู„ุขู† ูˆุตู ุญู‚ู„ ุงู„ุณุฌู„ ุจู…ุฌู…ูˆุนุฉ ู…ู† ู‚ูŠู…ู‡:

ุชุณุฌู„ ู‚ูŠู… CR1 ุญู‚ูˆู„ ุงู„ู…ุคู‚ุช TIM1
 template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_CKD_Values: public RegisterField<Reg, offset, size, AccessMode> { using DividedBy1 = FieldValue<TIM_CR_CKD_Values, 0U> ; using DividedBy2 = FieldValue<TIM_CR_CKD_Values, 1U> ; using DividedBy4 = FieldValue<TIM_CR_CKD_Values, 2U> ; using Reserved = FieldValue<TIM_CR_CKD_Values, 3U> ; } ; template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_ARPE_Values: public RegisterField<Reg, offset, size, AccessMode> { using ARRNotBuffered = FieldValue<TIM_CR_ARPE_Values, 0U> ; using ARRBuffered = FieldValue<TIM_CR_ARPE_Values, 1U> ; } ; template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_CMS_Values: public RegisterField<Reg, offset, size, AccessMode> { using CenterAlignedMode0 = FieldValue<TIM_CR_CMS_Values, 0U> ; using CenterAlignedMode1 = FieldValue<TIM_CR_CMS_Values, 1U> ; using CenterAlignedMode2 = FieldValue<TIM_CR_CMS_Values, 2U> ; using CenterAlignedMode3 = FieldValue<TIM_CR_CMS_Values, 3U> ; } ; template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_DIR_Values: public RegisterField<Reg, offset, size, AccessMode> { using Upcounter = FieldValue<TIM_CR_DIR_Values, 0U> ; using Downcounter = FieldValue<TIM_CR_DIR_Values, 1U> ; } ; template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_OPM_Values: public RegisterField<Reg, offset, size, AccessMode> { using ContinueAfterUEV = FieldValue<TIM_CR_OPM_Values, 0U> ; using StopAfterUEV = FieldValue<TIM_CR_OPM_Values, 1U> ; } ; template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_URS_Values: public RegisterField<Reg, offset, size, AccessMode> { using Any = FieldValue<TIM_CR_URS_Values, 0U> ; using Overflow = FieldValue<TIM_CR_URS_Values, 1U> ; } ; template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_UDIS_Values: public RegisterField<Reg, offset, size, AccessMode> { using Enable = FieldValue<TIM_CR_UDIS_Values, 0U> ; using Disable = FieldValue<TIM_CR_UDIS_Values, 1U> ; } ; template <typename Reg, size_t offset, size_t size, typename AccessMode> struct TIM_CR_CEN_Values: public RegisterField<Reg, offset, size, AccessMode> { using Disable = FieldValue<TIM_CR_CEN_Values, 0U> ; using Enable = FieldValue<TIM_CR_CEN_Values, 1U> ; } ; 


ุจุนุฏ ุฐู„ูƒ ุŒ ุณูŠุชู… ุจุงู„ูุนู„ ูˆุตู ุณุฌู„ CR1 ู†ูุณู‡ ุนู„ู‰ ุงู„ู†ุญูˆ ุงู„ุชุงู„ูŠ:

 struct TIM1 { struct CR1 : public RegisterBase<0x40010000, 32, ReadWriteMode> { using CKD = TIM_CR1_CKD_Values<TIM1::CR1, 8, 2, ReadWriteMode> ; using ARPE = TIM_CR1_ARPE_Values<TIM1::CR1, 7, 1, ReadWriteMode> ; using CMS = TIM_CR1_CMS_Values<TIM1::CR1, 5, 2, ReadWriteMode> ; using DIR = TIM_CR1_DIR_Values<TIM1::CR1, 4, 1, ReadWriteMode> ; using OPM = TIM_CR1_OPM_Values<TIM1::CR1, 3, 1, ReadWriteMode> ; using URS = TIM_CR1_URS_Values<TIM1::CR1, 2, 1, ReadWriteMode> ; using UDIS = TIM_CR1_UDIS_Values<TIM1::CR1, 1, 1, ReadWriteMode> ; using CEN = TIM_CR1_CEN_Values<TIM1::CR1, 0, 1, ReadWriteMode> ; } ; } 

ุงู„ุขู† ูŠู…ูƒู†ูƒ ุชุนูŠูŠู† ูˆู‚ุฑุงุกุฉ ู‚ูŠู…ุฉ ุญู‚ู„ ุงู„ุชุณุฌูŠู„ ู…ุจุงุดุฑุฉ: ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ุฅุฐุง ูƒู†ุช ุชุฑุบุจ ููŠ ุชู…ูƒูŠู† ุงู„ู…ุคู‚ุช ุนู„ู‰ ุงู„ุญุณุงุจ ุŒ ู…ุง ุนู„ูŠูƒ ุณูˆู‰ ุงู„ุงุชุตุงู„ ุจุงู„ุทุฑูŠู‚ุฉ Set() ุนู„ู‰ Enable ู‚ูŠู…ุฉ ุงู„ุญู‚ู„ CEN ุงู„ุฎุงุต ุจุงู„ุชุณุฌูŠู„ CR1 ู…ู† ุงู„ู…ุคู‚ุช TIM1: TIM1::CR1::CEN::Enable::Set() ; . ููŠ ุงู„ูƒูˆุฏ ุŒ ุณูŠุจุฏูˆ ูƒู…ุง ูŠู„ูŠ:

 int main() { if (TIM1::CR1::CKD::DividedBy2::IsSet()) { TIM1::ARR::Set(100U) ; TIM1::CR1::CEN::Enable::Set() ; } } 

ู„ู„ู…ู‚ุงุฑู†ุฉ ุŒ ู†ูุณ ุงู„ุดูŠุก ุจุงุณุชุฎุฏุงู… ุฑุฃุณ C:
 int main() { if((TIM1->CR1 & TIM_CR1_CKD_Msk) == TIM_CR1_CKD_0) { TIM1->ARR = 100U ; regValue = TIM1->CR1 ; regValue &=~(TIM_CR1_CEN_Msk) ; regValue |= TIM_CR1_CEN ; TIM1->CR1 = regValue ; } } 


ู„ุฐู„ูƒ ุŒ ุชู… ุฅุฌุฑุงุก ุงู„ุชุญุณูŠู†ุงุช ุงู„ุฑุฆูŠุณูŠุฉ ุŒ ูŠู…ูƒู†ู†ุง ุงู„ูˆุตูˆู„ ุฅู„ู‰ ุงู„ุณุฌู„ ุจุทุฑูŠู‚ุฉ ุณู‡ู„ุฉ ูˆู…ูู‡ูˆู…ุฉ ูˆู…ุฌุงู„ุงุชู‡ ูˆู‚ูŠู…ู‡. , , , , .

, . , :

 int main() { uint32_t regValue = TIM1->CR1 ; regValue &=~(TIM_CR1_CKD_Msk | TIM_CR1_DIR) ; regValue |= (TIM_CR1_CEN | TIM_CR1_CKD_0 | TIM_CR1_CKD_0) ; TIM1->CR1 = regValue ; } 

Set(...) , , . ุฃูŠ :

 int main() { // 1,      Set() TIM1::CR1::Set(TIM1::CR1::DIR::Upcounter, TIM1::CR1::CKD::DividedBy4, TIM1::CR1::CEN::Enable) ; // 2,     TIM1::CR1<TIM1::CR1::DIR::Upcounter, TIM1::CR1::CKD::DividedBy4, TIM1::CR1::CEN::Enable>::Set() ; } 

, , , , .

. :

 //    ,          template<uint32_t address, size_t size, typename AccessMode, typename ...Args> class Register { private: ... 

, :

  1. , .
  2. .

constexpr , :

 //    ,          template<uint32_t address, size_t size, typename AccessMode, typename ...Args> class Register { private: // ,    //     . __forceinline template<typename T> static constexpr auto GetIndividualMask() { Type result = T::Mask << T::Offset ; return result ; } // ,    //       . static constexpr auto GetMask() { //       const auto values = {GetIndividualMask<Args>()...} ; Type result = 0UL; for (auto const v: values) { //       result |= v ; } return result ; } //    __forceinline template<typename T> static constexpr auto GetIndividualValue() { Type result = T::Value << T::Offset ; return result ; } static constexpr auto GetValue() { const auto values = {GetIndividualValue<Args>()...}; Type result = 0UL; for (const auto v: values) { result |= v ; } return result ; } }; 

Set() IsSet() :

 //    ,          template<uint32_t address, size_t size, typename AccessMode, typename ...Args> class Register { public: using Type = typename RegisterType<size>::Type; template<typename T = AccessMode, class = typename std::enable_if_t<std::is_base_of<WriteMode, T>::value>> static void Set() { Type newRegValue = *reinterpret_cast<Type *>(address) ; //GetMask()    ,     newRegValue &= ~GetMask() ; //GetValue()    ,     newRegValue |= GetValue() ; //     *reinterpret_cast<Type *>(address) = newRegValue ; } template<typename T = AccessMode, class = typename std::enable_if_t<std::is_base_of<ReadMode, T>::value>> static bool IsSet() { Type newRegValue = *reinterpret_cast<Type *>(address) ; return ((newRegValue & GetMask()) == GetValue()) ; } private: ... 

, :

 int main() { // ,     TIM1::CR1 TIM1::CR1<TIM2::CR1::Enabled, TIM1::CR2::OIS1::OC1OutputIs0>::Set() ; } 

, - , , , , FieldValueBaseType . , FieldValueBaseType :

 template<uint32_t address, size_t size, typename AccessMode, typename FieldValueBaseType, typename ...Args> class Register { private: //     BaseType     FieldValueBaseType,    . __forceinline template<typename T, class = typename std::enable_if_t<std::is_same<FieldValueBaseType, typename T::BaseType>::value>> static constexpr auto GetIndividualMask() { Type result = T::Mask << T::Offset ; return result ; } static constexpr auto GetMask() { const auto values = {GetIndividualMask<Args>()...} ; Type result = 0UL; for (auto const v: values) { result |= v ; } return result ; } //     BaseType     FieldValueBaseType,    . __forceinline template<typename T, class = typename std::enable_if_t<std::is_same<FieldValueBaseType, typename T::BaseType>::value>> static constexpr auto GetIndividualValue() { Type result = T::Value << T::Offset ; return result ; } static constexpr auto GetValue() { const auto values = {GetIndividualValue<Args>()...}; Type result = 0UL; for (const auto v: values) { result |= v ; } return result ; } }; 


, SFINAE , , , , , .

CR1 TIM1, :

 struct TIM1 { struct TIM1CR1Base {} ; struct CR1 : public RegisterBase<0x40010000, 32, ReadWriteMode> { using CKD = TIM_CR_CKD_Values<TIM1::CR1, 8, 2, ReadWriteMode, TIM1CR1Base> ; using ARPE = TIM_CR_ARPE_Values<TIM1::CR1, 7, 1, ReadWriteMode, TIM1CR1Base> ; using CMS = TIM_CR_CMS_Values<TIM1::CR1, 5, 2, ReadWriteMode, TIM1CR1Base> ; using DIR = TIM_CR_DIR_Values<TIM1::CR1, 4, 1, ReadWriteMode, TIM1CR1Base> ; using OPM = TIM_CR_OPM_Values<TIM1::CR1, 3, 1, ReadWriteMode, TIM1CR1Base> ; using URS = TIM_CR_URS_Values<TIM1::CR1, 2, 1, ReadWriteMode, TIM1CR1Base> ; using UDIS = TIM_CR_UDIS_Values<TIM1::CR1, 1, 1, ReadWriteMode, TIM1CR1Base> ; using CEN = TIM_CR_CEN_Values<TIM1::CR1, 0, 1, ReadWriteMode, TIM1CR1Base> ; } ; } 

, , . , , , .

, :

 int main(void) { //     GPIOA //,    AHB1ENR RCC->APB1ENR |= RCC_AHB1ENR_GPIOAEN ; //    ,      RCC->AHB1ENR = RCC_AHB1ENR_GPIOAEN; //,  TIM1    APB2 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB2ENR_TIM1EN; // - ,        . auto result = GPIOA->BSRR ; if (result & GPIO_BSRR_BS1) { //do something } //-     .   ... GPIOA->IDR = GPIO_IDR_ID5 ; 

ูˆุญุงูˆู„ ุฃู† ุชูุนู„ ุงู„ุดูŠุก ู†ูุณู‡ ู…ุน ุงู„ู†ู‡ุฌ ุงู„ุฌุฏูŠุฏ:

 int main(void) { //     GPIOA // ,   APB1ENR   GPIOAEN RCC::APB1ENR::GPIOAEN::Enable::Set() ; // ,     GPIOA RCC::AHB1ENR::GPIOAEN::Enable::Set() ; // , RCC::APB2ENR::TIM1EN::Enable  //   APB1ENR RCC::APB1ENRPack<RCC::APB1ENR::TIM2EN::Enable, RCC::APB2ENR::TIM1EN::Enable>::Set(); // ,  BSRR    auto result = GPIOA::BSRR::Get() ; // ,  Reset    if (GPIOA::BSRR::BS1::Reset::IsSet()) { //do something } // ,       GPIOA::IDR::IDR5::On::Set() } 

ููŠ ูƒู„ ุญุงู„ุฉ ู…ู† ู‡ุฐู‡ ุงู„ุญุงู„ุงุช ุŒ ุญุตู„ู†ุง ุนู„ู‰ ุฎุทุฃ ููŠ ู…ุฑุญู„ุฉ ุงู„ุชุฌู…ูŠุน ุŒ ูˆู‡ุฐุง ุจุงู„ุถุจุท ู…ุง ุญู‚ู‚ู†ุงู‡.

ุญุณู†ู‹ุง ุŒ ู„ู‚ุฏ ู‚ุฏู…ู†ุง โ€‹โ€‹ูˆุตูˆู„ุงู‹ ุฌู…ูŠู„ุงู‹ ูˆุขู…ู†ุงู‹ ุฅู„ู‰ ุงู„ุณุฌู„ ูˆู…ุฌุงู„ุงุชู‡ ุŒ ู„ูƒู† ู…ุงุฐุง ุนู† ุงู„ุณุฑุนุฉุŸ

ุณุฑุนุฉ


ู„ู„ู…ู‚ุงุฑู†ุฉ ุŒ ูƒู… ู‡ูˆ ุฃูุถู„ ู†ู‡ุฌู†ุง ุŒ ุณู†ุณุชุฎุฏู… ูƒูˆุฏ C ูˆ C ++ ุงู„ุฐูŠ ูŠุบุฐูŠ ุงู„ุณุงุนุฉ ู„ู„ู…ู†ูุฐ A ุŒ ูˆูŠุถุจุท ุงู„ู…ู†ุงูุฐ ุงู„ุซู„ุงุซุฉ ุนู„ู‰ ูˆุถุน ุงู„ุฅุฎุฑุงุฌ ุŒ ูˆูŠุนูŠู† ู…ู†ุงูุฐ ุงู„ุฅุฎุฑุงุฌ ููŠ ู‡ุฐู‡ ุงู„ู…ู†ุงูุฐ ุงู„ุซู„ุงุซุฉ 1:

ุฑู…ุฒ C:
 int main() { uint32_t res = RCC->AHB2ENR; res &=~ RCC_AHB1ENR_GPIOAEN_Msk ; res |= RCC_AHB1ENR_GPIOAEN ; RCC->AHB2ENR = res ; res = GPIOA->MODER ; res &=~ (GPIO_MODER_MODER5 | GPIO_MODER_MODER4 | GPIO_MODER_MODER1) ; res |= (GPIO_MODER_MODER5_0 | GPIO_MODER_MODER4_0 | GPIO_MODER_MODER1_0) ; GPIOA->MODER = res ; GPIOA->BSRR = (GPIO_BSRR_BS5 | GPIO_BSRR_BS4 | GPIO_BSRR_BS1) ; return 0 ; } 


ุฑู…ุฒ C ++:
 int main() { RCC::AHB1ENR::GPIOAEN::Enable::Set() ; GPIOA::MODERPack< GPIOA::MODER::MODER5::Output, GPIOA::MODER::MODER4::Output, GPIOA::MODER::MODER1::Output>::Set() ; GPIOA::BSRRPack< GPIOA::BSRR::BS5::Set, GPIOA::BSRR::BS4::Set, GPIOA::BSRR::BS1::Set>::Write() ; return 0 ; } 


IAR. : :

:

ุตูˆุฑุฉ

C++ :

ุตูˆุฑุฉ

18 , , .

, :

ุตูˆุฑุฉ

13 .

++ :

ุตูˆุฑุฉ

: , .

, . , ?


, , . . , . , , . , . SVD , , , .

, , , , enum, . , , .
ุตูˆุฑุฉ


ูŠุคุฏูŠ


, , . , gpioa rcc, :

 #include "gpioaregisters.hpp" //for GPIOA #include "rccregisters.hpp" //for RCC int main() { RCC::AHB1ENR::GPIOAEN::Enable::Set() ; GPIOA::MODER::MODER15::Output::Set() ; GPIOA::MODERPack< GPIOA::MODER::MODER12::Output, GPIOA::MODER::MODER14::Analog >::Set() ; } 

, SVD , , .

, , , SVD , - ST , :

 template <typename Reg, size_t offset, size_t size, typename AccessMode, typename BaseType> struct GPIOA_MODER_MODER_Values: public RegisterField<Reg, offset, size, AccessMode> { using Value0 = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 0U> ; using Value1 = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 1U> ; using Value2 = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 2U> ; using Value3 = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 3U> ; } ; 

, Value, - :

 template <typename Reg, size_t offset, size_t size, typename AccessMode, typename BaseType> struct GPIOA_MODER_MODER_Values: public RegisterField<Reg, offset, size, AccessMode> { using Input = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 0U> ; using Output = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 1U> ; using Alternate = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 2U> ; using Analog = FieldValue<GPIOA_MODER_MODER_Values, BaseType, 3U> ; } ; 

.

, ST , 0.

, , enum .

, .

IAR 8.40.1

ยซ Online GDBยป

PS: putyavka RegisterField::Get()
Ryppka assert.


Typesafe Register Access in C++
One Approach to Using Hardware Registers in C++
SVD Description (*.svd) Format

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


All Articles