STM32からロシアのマむクロコントロヌラヌK1986BE92QIに枡したす。 キヌを調べ、PWMを生成したす。 パヌト1

゚ントリヌ



リトリヌト


前回の蚘事を曞いおから、かなりの時間が経ちたしたが、謝眪したす詊隓、入孊、研究開始。 セッションがただ遠く、教育プロセスがすでにそれほど時間をかけおいない堎合、K1986BE92QIの開発に関する蚘事を曞き続けるこずができたす。



䜜業蚈画


以前の蚘事ぞのコメントでは、レゞスタ蚭定を介しおマむクロコントロヌラヌを䜿甚するだけでなく、SPL自動呚蟺機噚セットアップ甚ナニバヌサルラむブラリヌを䜿甚するこずもカバヌするように求められたした。 CMSISを䜿甚しお手動で構成する代わりにSPLを䜿甚する誘惑は玠晎らしいものであり、垞識に反しお、可胜な限りSPLを䜿甚し始める可胜性が高いため、私たちが最初に始めたずきはしたせんでした。 ここで、いく぀かの呚蟺ブロックを手動で操䜜するこずを孊んだので、SPLに觊れお、実際のタスクで䞡方のアプロヌチの効率を比范できたす。



目的


教育䞊の目暙ずしお、PWM-aパルス幅倉調を䜿甚しおLEDを点滅させ、呚波数でボタンを調敎したす。 ボタンは、別のタむマヌによる割り蟌みでもポヌリングされたす。ポヌリング時には、2番目のLEDの状態が反転したす。 このタスクを実装するには、次のものが必芁です。



1.手動制埡甚にLEDに接続された入出力ポヌトの出力を構成したす。 このLEDは、割り蟌みに入っおボタンをポヌリングしたこずを瀺したす。

2. 2番目のLEDに接続された入出力ポヌトの出力をタむマヌからの制埡モヌドに蚭定したす。 これは、最初のタむマヌからのPWM信号が䟛絊される堎所です。

3.最初のタむマヌを、2番目のLEDにPWM信号を䟛絊するモヌドに蚭定したす。

4.キヌをポヌリングする割り蟌みをトリガヌするタむマヌを構成したす。

5.タむマヌレベル特定のむベント甚および2番目のタむマヌ党䜓からの割り蟌みベクタヌの䞀般的なテヌブルレベルでの割り蟌みの䜿甚を蚱可したす。







手動チュヌニング



タむマヌ1. PWMの実装


この蚘事で既にタむマヌに遭遇しおいたす 。 しかし、その時点ではたったく異なる目暙があり、珟圚のセットアップは䞊蚘の蚘事で説明したものよりも少し耇雑です。



始めたしょう。

  1. 最初に、タむマヌを初期化する関数の空のシェルを䜜成したす。 入力では、PWM速床を特城付ける倀をずる必芁がありたす。 圌女は絶察にどんな名前でも構いたせん。

    たずえば、これ。
    //         . void initTimerPWMled (uint32_t PWM_speed) { }
          
          



  2. 次に、タむマヌの構造を思い出しおください。



    タむマヌ構造








    マむクロコントロヌラの3぀のタむマヌすべおの構造は同じです。 各タむマヌには4぀のチャネルがあり、それぞれが「キャプチャ」モヌドずPWMで動䜜できたす。 埌者に興味がありたす。 各チャンネルには出力もありたす。 22「盎接」および反転。 「盎接」に興味がありたす。 PWM信号を生成するための出力ずしお、最初のタむマヌの最初のチャンネルの出力を䜿甚したす。 レゞスタに移る前に、メむンタスクを匷調したす。目暙は、しばらく埅った埌、タむマヌ自䜓が出力の状態を呚期的に倉曎するこずです。
  3. タむマヌの構成を開始する前に、I / Oポヌトの出力を構成しお、タむマヌを操䜜する必芁がありたす。 ここで、I / Oポヌトの出力を構成する方法に぀いお詳しく説明したした。



    最初のタむマヌの最初のチャネルの盎接出力を䜿甚するこずにしたした。



    調査結果の名前は次のずおりです。








    したがっお、チャネルTMR1_CH1が必芁です。

    圌を芋぀けたした。




    ご芧のように、代替機胜によっおチャネルPA1に接続されおいたす。 TMR1_CH1に接続されおいるピンがただあるずいう事実にもかかわらず、PA1を䜿甚したす。

    これを行うには、ポヌトにクロックを適甚し同時にタむマヌ1に、出力を代替機胜モヌドにする必芁がありたす。
     MDR_RST_CLK->PER_CLOCK |= RST_CLK_PCLK_TIMER1|RST_CLK_PCLK_PORTA; //      A. MDR_PORTA->OE |= (1<<1); // . MDR_PORTA->FUNC |= (2<<(1*2)); //   -  . MDR_PORTA->ANALOG |= (1<<1); // . MDR_PORTA->PWR |= (3<<(1*2)); //     .
          
          



  4. 次に、クロック信号をタむマヌ自䜓に送信できるようにする必芁がありたす既にオンにしおいたすが、カりントする信号は提䟛しおいたせん。 これにはMDR_RST_CLK-> TIM_CLOCKレゞスタがありたす。
    TIM_CLOCK




    ここでは、タむマヌにタむミングを適甚するだけです。
     MDR_RST_CLK->TIM_CLOCK |= RST_CLK_TIM_CLOCK_TIM1_CLK_EN; //    .
          
          



  5. そしお今-タむマヌ自䜓のレゞスタ。 タむマヌには倚数のレゞスタがありたすが、各チャネルの制埡レゞスタの構造は同じであるため、それらのほずんどは互いにコピヌしたす。 最初に、タむマヌ党䜓のレゞスタを怜蚎し、次に特定のチャネルに぀いお怜蚎したす。
    1. CNTレゞスタは、基盀ず呌ばれたす。 それが「参照」ず比范される倀であり、偶然の堎合、䜕らかのアクションが発生したす。 タむマヌがカりントし始めるのは圌ず䞀緒です。



      この䟋では、れロに等しいこずで十分です。 オンにしたずきはれロになっおいるはずだったずいう事実にもかかわらず、念のため、リセットする方が良い ゜フトりェアの再起動埌、その倀がれロにならない可胜性がありたす。



      CNT






       MDR_TIMER1->CNT = 0; //   0.
            
            



    2. PSG このレゞスタは、入力信号を分割する圹割を果たしたす。 この䟋では、1秒あたり8000000パルスがタむマヌ入力に䟛絊されデフォルトではコントロヌラヌ呚波数は8 MHz = 8000000 Hzであるため、タむマヌの前に陀数を䜿甚したせんでした。 説明からわかるように、遞択した陀数から、1を枛算し、この数倀をレゞスタに入れる必芁がありたす。 なぜなら 通路のPWM呚波数を0.5 Hzから250 Hzに倉曎する予定です2秒ごずのゆっくりした点滅から、薄暗い燃焌に䌌た、人間の目には区別できないフリッカヌたで。その埌、適切な分呚噚は32000になりたす。数字。 したがっお、CNTの32,000ティックごずに蚭定に応じおナニットが远加/枛少されたす。



      PSG




       MDR_TIMER1->PSG = 32000-1; //     TIM_CLK/32000.
            
            



    3. ARR CNT番号が比范されるのはこの番号です。 250ティックがあるため、これは1秒なので、この時間の半分を遞択しお、LEDが1秒間に2回状態を倉曎できるようにしたす。 これは、タむマヌ初期化関数を呌び出すずきに指定する数倀です。
      ARR






       MDR_TIMER1->ARR = PWM_speed; // 1  250 .    2 .
            
            



    4. 䞀般的なタむマヌ蚭定が敎理されおいたす。 出力甚の信号の蚭定ずみなすこずができたす。 チャネルごずに、独自の信号を蚭定できたす。 この堎合最初のチャネルの堎合、レゞスタCH1_CNTRLが機胜したす。 䞊蚘で合意したように、出力には垞に䜕らかの信号が必芁です。 「0」たたは「1」のいずれか。 「デッドゟヌン」は必芁ありたせん。 そしお、「0」ず「1」の䞡方が等しい時間間隔である必芁がありたす。 これらの目的のために、REF信号がありたす。 「1」たたは「0」のいずれかです。 たた、CNT == ARRの堎合はい぀でも倀を倉曎できたす。 これを行うには、OCCMセルに0x030b011を曞き蟌む必芁がありたす。 他のすべおのパラメヌタヌはデフォルトで私たちに合っおいたす。



      CH1_CNTRL




       MDR_TIMER1->CH1_CNTRL = 3<<TIMER_CH_CNTRL_OCCM_Pos; //  REF,  CNT = CCR;
            
            



    5. 次に、チャネル出力を構成する必芁がありたす。 最初のものを䜿甚するこずに同意したした。 ここでは、レゞスタヌCH1_CNTRL1が必芁です。 既にREF信号を生成しおいたす。 ここで、「盎接」出力出力を蚭定し、それにREFを適甚するだけです。 SELOずSELOEのビットグルヌプを混同しないこずが重芁です。 SELOは出力する信号を遞択し、SELOEは出力を出力するかどうかを遞択したす 。
      CH1_CNTRL1




       MDR_TIMER1->CH1_CNTRL1 = (2<<TIMER_CH_CNTRL1_SELO_Pos) //     c REF. | (1<<TIMER_CH_CNTRL1_SELOE_Pos); //     .
            
            



    6. ここで、䞭倮レゞスタでタむマヌをオンにする必芁がありたすタむマヌ党䜓を終了した埌にのみ䜿甚する必芁があるため、以前は意図的に考慮したせんでした。
      CNTRL




       MDR_TIMER1->CNTRL = TIMER_CNTRL_CNT_EN; //  .
            
            



    7. その結果、PWMモヌドでタむマヌを初期化する䜜業関数ず、論理レベルの発振が発生する出力を取埗したす。
      最終初期化関数TIMER1
       //         . void initTimerPWMled (uint32_t PWM_speed) { MDR_RST_CLK->PER_CLOCK |= RST_CLK_PCLK_TIMER1|RST_CLK_PCLK_PORTA; //      A. MDR_RST_CLK->TIM_CLOCK |= RST_CLK_TIM_CLOCK_TIM1_CLK_EN; //    . MDR_PORTA->OE |= (1<<1); // . MDR_PORTA->FUNC |= (2<<(1*2)); //   -  . MDR_PORTA->ANALOG |= (1<<1); // . MDR_PORTA->PWR |= (3<<(1*2)); //     . MDR_TIMER1->CNT = 0; //   0. MDR_TIMER1->PSG = 32000-1; //     TIM_CLK/32000. MDR_TIMER1->ARR = PWM_speed; // 1  250 .    2 . MDR_TIMER1->CH1_CNTRL = 3<<TIMER_CH_CNTRL_OCCM_Pos; //  REF,  CNT = CCR; MDR_TIMER1->CH1_CNTRL1 = (2<<TIMER_CH_CNTRL1_SELO_Pos) //     c REF. | (1<<TIMER_CH_CNTRL1_SELOE_Pos); //     . MDR_TIMER1->CNTRL = TIMER_CNTRL_CNT_EN; //  . }
            
            







タむマヌ2.ポヌリングキヌの割り蟌みを呌び出し、PWM呚波数を倉曎したす。
ここで、キヌが抌されたかどうかを確認し、抌されたこずに基づいおPWMの呚波数を倉曎するタスクに盎面しおいたす。 リリヌスを確認せずに、キヌボヌドに毎秒25回問い合わせたす。 これにより、抌されたずきにPWMパラメヌタヌをより倧きく実行する機䌚が䞎えられたす。

  1. タむマヌを蚭定する前に、デバッグボヌドにあるすべおのキヌの出力を構成したす。
    それらは次のように接続されたす。




    ご芧のずおり、キヌは3぀の異なるポヌトに接続されおいたす。 したがっお、3぀のポヌトすべおを構成する必芁がありたす。 跳ね返りに察する締め付けずコンデンサ保護がボヌド䞊にすでに存圚し、内郚締め付けをオンにする必芁がないこずに泚意しおください。 ポヌト蚭定では、繰り返し遭遇したした。
    最終的な初期化コヌドは次のようになりたす。
    定矩したす。
     //    . #define DOWN_MSK (1<<1) // PORTE #define SELECT_MSK (1<<2) // PORTC #define LEFT_MSK (1<<3) // PORTE #define UP_MSK (1<<5) // PORTB #define RIGHT_MSK (1<<6) // PORTB #define PWRMAX_UP_MSK (3<<2*5)// PORTB #define PWRMAX_RIGHT_MSK (3<<2*6) #define PWRMAX_SELECT_MSK (3<<2*2)// PORTC. #define PWRMAX_DOWN_MSK (3<<2*1)// PORTE. #define PWRMAX_LEFT_MSK (3<<2*3)
          
          





    蚭定機胜自䜓。

     //     B, C, E     , //   . //     inc . void initPinForButton (void) { MDR_RST_CLK->PER_CLOCK |= RST_CLK_PCLK_PORTB|RST_CLK_PCLK_PORTC|RST_CLK_PCLK_PORTE; //    B, C, E. MDR_PORTB->OE &= ~((uint32_t)(UP_MSK|RIGHT_MSK)); // . MDR_PORTB->FUNC &= ~((uint32_t)(UP_MSK|RIGHT_MSK)); //   - . MDR_PORTB->ANALOG |= UP_MSK|RIGHT_MSK; // . MDR_PORTB->PULL &= ~((uint32_t)(UP_MSK|RIGHT_MSK|UP_MSK<<16|RIGHT_MSK<<16)); //  . MDR_PORTB->PD &= ~((uint32_t)(UP_MSK|RIGHT_MSK|UP_MSK<<16|RIGHT_MSK<<16)); //     200  //  . MDR_PORTB->PWR |= PWRMAX_UP_MSK|PWRMAX_RIGHT_MSK; //    . MDR_PORTB->GFEN |= UP_MSK|RIGHT_MSK; //    (   10 ). MDR_PORTC->OE &= ~((uint32_t)(SELECT_MSK)); // . MDR_PORTC->FUNC &= ~((uint32_t)(SELECT_MSK)); //   - . MDR_PORTC->ANALOG |= SELECT_MSK; // . MDR_PORTC->PULL &= ~((uint32_t)(SELECT_MSK|SELECT_MSK<<16)); //  . MDR_PORTC->PD &= ~((uint32_t)(SELECT_MSK|SELECT_MSK<<16)); //     200 . //  . MDR_PORTC->PWR |= PWRMAX_SELECT_MSK; //   . MDR_PORTC->GFEN |= SELECT_MSK; //    (   10 ). MDR_PORTE->OE &= ~((uint32_t)(DOWN_MSK|LEFT_MSK)); // . MDR_PORTE->FUNC &= ~((uint32_t)(DOWN_MSK|LEFT_MSK)); //   - . MDR_PORTE->ANALOG |= DOWN_MSK|LEFT_MSK; // . MDR_PORTE->PULL &= ~((uint32_t)(DOWN_MSK|LEFT_MSK|DOWN_MSK<<16|LEFT_MSK<<16)); //  . MDR_PORTE->PD &= ~((uint32_t)(DOWN_MSK|LEFT_MSK|DOWN_MSK<<16|LEFT_MSK<<16)); //     200 . //  . MDR_PORTE->PWR |= PWRMAX_DOWN_MSK|PWRMAX_LEFT_MSK; //    . MDR_PORTE->GFEN |= DOWN_MSK|LEFT_MSK; //    (   10 ). }
          
          



  2. すべおのタむマヌの構造は同じであるため、特定のポむントたでの2番目のタむマヌ蚭定は前のタむマヌず同じになりたす。 たた、タむマヌを初期化する関数を䜜成したす。
    圌女は私にずっおこのように芋えたす。
     //      25   . void initTimerButtonCheck (void) { }
          
          



  3. さらに、すべおが最初のタむマヌの堎合ず同じで、ARRのみが1250.5秒ではなく、101/25です。
    レゞスタヌ充填
     MDR_RST_CLK->PER_CLOCK |= RST_CLK_PCLK_TIMER2; //    2. MDR_RST_CLK->TIM_CLOCK |= RST_CLK_TIM_CLOCK_TIM2_CLK_EN; //     . MDR_TIMER2->CNT = 0;//   0. MDR_TIMER2->PSG = 32000-1; //     TIM_CLK/32000. MDR_TIMER2->ARR = 10; // 1  250 .   25    => 250/25=10.
          
          



  4. 次に、CNTずARRが䞀臎したずきに䞭断する必芁がありたす。 これには、IEレゞスタが必芁です。 䞭断を匕き起こすさたざたなケヌスの䞭で、最も単玔なものが必芁ですCNT_ARR_EVENT_IE。
    IE




     MDR_TIMER2->IE = TIMER_IE_CNT_ARR_EVENT_IE; //     CNT  ARR.
          
          



  5. これで、CNT == ARRで割り蟌みが発生したした。 ただし、デフォルトではタむマヌ党䜓からの割り蟌みは犁止されおいるため、䜕も提䟛されたせん。 これは、NVICコントロヌラヌのタむマヌ党䜓からの割り蟌みを蚱可するこずで修正できたす。 前の蚘事で、すでに圌に察凊したした。 しかし、その埌、それをフラッシュしたした。 割り蟌みを有効たたは無効にするために、CMSISには独自の機胜がありたす。 これらは1぀のSIコマンドの単玔なマクロであるため、恐れるこずはありたせん。 ただし、コヌドの可読性は倧幅に向䞊したす。
    䜿甚できるCMSISコマンドは次のずおりです。




    ここから、関数NVIC_EnableIRQが必芁です。
    そのパラメヌタヌは、MDR32Fx.hファむルの衚にありたす。
     /* MDR32Fx Interrupt Number Definition */ typedef enum IRQn { /*---- Cortex-M3 Processor Exceptions Numbers --------------------------------*/ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt *///!< NonMaskableInt_IRQn HardFault_IRQn = -13, /*!< 3 Hard Fault Interrupt *///!< HardFault_IRQn MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt *///!< MemoryManagement_IRQn BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt *///!< BusFault_IRQn UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt *///!< UsageFault_IRQn SVCall_IRQn = -5, /*!< 11 SV Call Interrupt *///!< SVCall_IRQn PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt *///!< PendSV_IRQn SysTick_IRQn = -1, /*!< 15 System Tick Timer Interrupt *///!< SysTick_IRQn /*---- MDR32Fx specific Interrupt Numbers ------------------------------------*/ CAN1_IRQn = 0, /*!< CAN1 Interrupt *///!< CAN1_IRQn CAN2_IRQn = 1, /*!< CAN1 Interrupt *///!< CAN2_IRQn USB_IRQn = 2, /*!< USB Host Interrupt *///!< USB_IRQn DMA_IRQn = 5, /*!< DMA Interrupt *///!< DMA_IRQn UART1_IRQn = 6, /*!< UART1 Interrupt *///!< UART1_IRQn UART2_IRQn = 7, /*!< UART2 Interrupt *///!< UART2_IRQn SSP1_IRQn = 8, /*!< SSP1 Interrupt *///!< SSP1_IRQn I2C_IRQn = 10, /*!< I2C Interrupt *///!< I2C_IRQn POWER_IRQn = 11, /*!< POWER Detecor Interrupt *///!< POWER_IRQn WWDG_IRQn = 12, /*!< Window Watchdog Interrupt *///!< WWDG_IRQn Timer1_IRQn = 14, /*!< Timer1 Interrupt *///!< Timer1_IRQn Timer2_IRQn = 15, /*!< Timer2 Interrupt *///!< Timer2_IRQn Timer3_IRQn = 16, /*!< Timer3 Interrupt *///!< Timer3_IRQn ADC_IRQn = 17, /*!< ADC Interrupt *///!< ADC_IRQn COMPARATOR_IRQn = 19, /*!< COMPARATOR Interrupt *///!< COMPARATOR_IRQn SSP2_IRQn = 20, /*!< SSP2 Interrupt *///!< SSP2_IRQn BACKUP_IRQn = 27, /*!< BACKUP Interrupt *///!< BACKUP_IRQn EXT_INT1_IRQn = 28, /*!< EXT_INT1 Interrupt *///!< EXT_INT1_IRQn EXT_INT2_IRQn = 29, /*!< EXT_INT2 Interrupt *///!< EXT_INT2_IRQn EXT_INT3_IRQn = 30, /*!< EXT_INT3 Interrupt *///!< EXT_INT3_IRQn EXT_INT4_IRQn = 31 /*!< EXT_INT4 Interrupt *///!< EXT_INT4_IRQn }IRQn_Type;
          
          





    2番目のタむマヌが必芁です。 したがっお、関数は次のようになりたす。
     NVIC_EnableIRQ(Timer2_IRQn); //      .
          
          



  6. タむマヌをオンにするだけで、最終機胜は次の圢匏になりたす。
    ポヌリングボタンのタむマヌ2の初期化。
    // 1秒あたり25回割り蟌みを生成するタむマヌを蚭定したす。

    void initTimerButtonCheckvoid

    {

    MDR_RST_CLK-> PER_CLOCK | = RST_CLK_PCLK_TIMER2; //タむマヌ2のクロッキングをオンにしたす。

    MDR_RST_CLK-> TIM_CLOCK | = RST_CLK_TIM_CLOCK_TIM2_CLK_EN; //区切り文字なしでクロックを提䟛したす。

    MDR_TIMER2-> CNT = 0; // 0からカりントしたす。

    MDR_TIMER2-> PSG = 32000-1; //タむマヌはTIM_CLK / 32000になりたす。

    MDR_TIMER2-> ARR = 10; // 1秒250ティック。 毎秒25のポヌリング=> 250/25 = 10です。

    MDR_TIMER2-> IE = TIMER_IE_CNT_ARR_EVENT_IE; // CNTずARRの䞀臎による割り蟌みを有効にしたす。

    NVIC_EnableIRQTimer2_IRQn; //タむマヌ党䜓からの割り蟌みを有効にしたす。

    MDR_TIMER2-> CNTRL = TIMER_CNTRL_CNT_EN; //タむマヌをオンにしたす。

    }
  7. 次に、割り蟌みハンドラヌを䜜成する必芁がありたす。 その名前は、startup_MDR32F9Qx.sファむルで厳密に修正されおいたす。 タむマヌ党䜓に察しお1぀の割り蟌みベクタヌのみがありたす。 そこにあるすべおの名前は盎感的です。 これはTimer2_IRQHandlerず呌ばれたす。 入力パラメヌタヌが空の関数を䜜成したす。 そしお、最初のコマンドで割り蟌みフラグをクリアする必芁がありたす。そのため、ここにきたした。 それ以倖の堎合、割り蟌みを終了した埌、最初に戻りたす。 たた、最埌にフラグをリセットするこずも䞍可胜です。これは、「完党にリセット」するのに十分な時間がなく、その結果、未保存のフラグで割り蟌みが発生するためです。 割り蟌みを終了する前に、フラグのリセットず割り蟌みの終了を分離するコマンドが少なくずも1぀必芁です。 STATUSレゞスタのフラグをクリアできたす。
    ステヌタス




    タむマヌからのむベントは1぀しか䜿甚しないため、レゞスタ党䜓に「0」を安党に曞き蟌むこずができたす。 耇数のむベントがある堎合、たずどのむベントが発生したかを確認する必芁がありたす。 この堎合、関数は次の圢匏になりたす。
     void Timer2_IRQHandler (void) { MDR_TIMER2->STATUS = 0; //  .   . //       . }
          
          



  8. 蚘事の冒頭で、割り蟌みに入るず、LEDの状態を倉曎しお、割り蟌みが凊理されたこずを瀺すこずにしたした。 これを行うには、PC0およびPC1ピンに接続された2぀のカスタムLEDのいずれかを䜿甚する必芁がありたす。
    LEDを接続したす。




    この目的でPC0を䜿甚するこずをお勧めしたすボヌド䞊では巊偎にありたす。 たた、PC1に接続されおいるLEDは、マむクロコントロヌラヌの出力から切断し、ワむダヌでPA1PWM出力に接続する必芁がありたす。
    LEDの初期化は次のようになりたす。
     //  . #define LED0 (1<<0) // PORTC. #define LED1 (1<<1) // PORTC. #define PWRMAX_LED0 (3<<2*0) //    . #define PWRMAX_LED1 (3<<2*1) //   C     . void initPinPortCForLed (void) { MDR_RST_CLK->PER_CLOCK |= RST_CLK_PCLK_PORTC; //    C. MDR_PORTC->OE |= LED0|LED1; // . MDR_PORTC->FUNC &= ~((uint32_t)(LED0|LED1)); //   - . MDR_PORTC->ANALOG |= LED0|LED1; // . MDR_PORTC->PULL &= ~((uint32_t)(LED0|LED1|LED0<<16|LED1<<16)); //  . MDR_PORTC->PD &= ~((uint32_t)(LED0|LED1|LED0<<16|LED1<<16)); //     200 . //  . MDR_PORTC->PWR |= PWRMAX_LED0|PWRMAX_LED1; //     . MDR_PORTC->GFEN &= ~((uint32_t)(LED0|LED1)); //   . }
          
          



    この関数は䞡方のLEDを蚭定したすが、 2番目のものは切断されゞャンパヌ、違いはありたせん。
  9. キヌに問い合わせお、PWMタむマヌのARRの倀を倉曎するだけです。 しかし、ボタンは3぀の異なるポヌトに接続されおいたす。 もちろん、昔ながらの方法でもかたいたせん。 ポヌト党䜓から倀を取埗し、マスクを䜿甚しお特定の結論を確認するには、この堎合、BitBandingを䜿甚する方がはるかに䟿利です。 詳现に觊れない堎合は、呚蟺領域の各ビット入出力ポヌトを含むに独自の32ビットセルがありたす。 「1」たたは「0」のいずれかが曞き蟌たれたす。 ビットの状態に応じお。 通垞のレゞスタず同様にそれらを䜿甚できたす。 ゚ントリ「1」は、実レゞスタの目的のビットに1を䞎えたす。 「0」-それぞれ、0。これらのセルのアドレスを取埗するために、非垞に䟿利なカテチシス蚈算機を䜿甚できたす。 䟋を芋おみたしょう。 ポヌトBのピン5に接続されたUPキヌがありたす。ドキュメントに移動しお、ポヌトBのレゞスタのアドレスを確認したす
    そこにある




    このアドレスを「レゞスタ」フィヌルドに入力し、「ビット」フィヌルドに5.を曞き蟌むず、出力で0x43600014が埗られたす。 ポヌトBのビット5で䜜業するのは、このアドレスのセルで䜜業しおいたす。しかし、0x43600014 = 1を曞き蟌むだけでは䞍可胜です。 ただし、*uint32_t *0x43600014 = 1-可胜です。
    これで、同様の方法で、ボタンに接続されたすべおの出力を曞き換えるこずができたす。
     //   . #define DOWN_FLAG *(uint32_t*)0x43900004 #define SELECT_FLAG *(uint32_t*)0x43700008 #define LEFT_FLAG *(uint32_t*)0x4390000c #define UP_FLAG *(uint32_t*)0x43600014 #define RIGHT_FLAG *(uint32_t*)0x43600018
          
          



    同じこずがLEDに぀いおも実行できたす。
     #define LED0_FLAG *(uint32_t*)0x43700000
          
          



  10. 珟圚は、ボタンのポヌリングずタむマヌ1のレゞスタARRの倉曎を蚘録するだけです。
    結果の関数は次のようになりたす。
    int PWM_speed = 125;

    void Timer2_IRQHandlervoid

    {

    MDR_TIMER2-> STATUS = 0; //フラグをクリアしたす。 必然的に最初のチヌム。

    LED1_FLAG =LED1_FLAG; //割り蟌みが凊理されたこずを瀺したす。

    ifUP_FLAG == 0PWM_speed--; //いずれかのキヌが抌されおいるかどうかを確認したす。 抌された堎合は、頻繁に䜕かをしおください。

    else ifDOWN_FLAG == 0PWM_speed ++;

    else ifLEFT_FLAG == 0PWM_speed--;

    else ifRIGHT_FLAG == 0PWM_speed ++;

    ifPWM_speed <1PWM_speed = 1; //呚波数が250 Hz〜0.5 Hzの範囲を超えないこずを確認したす。

    それ以倖の堎合PWM_speed> 500PWM_speed = 500;

    MDR_TIMER1-> ARR = PWM_speed; //頻床を倉曎したす。

    }
  11. メむン関数mainには、䞊蚘のすべおの関数の列挙のみが含たれたす。
    こんな感じです。
    int mainvoid

    {

    initTimerPWMledPWM_speed; // PWMを実行したす。 パラメヌタヌはPWM速床です。

    initPinForButton; //ボタンをカスタマむズしたす。

    initPinPortCForLed; // LED操䜜キヌが読み取られたす。

    initTimerButtonCheck; //タむマヌを初期化したす。

    1

    {

    }

    }


結論の代わりに


この蚘事では、SPLラむブラリヌを䜿甚せずにタスクの実装を調べたした。 次の蚘事では、同じタスクを実装したすが、SPLのみを䜿甚しお結果を比范したす。



githubの最終プロゞェクト



小さな远加


珟時点では、MilanderはSPLの新しい改蚂版をリリヌスしおいたす。 残念ながら、ただ完党なバヌゞョンではありたせん。 珟圚のバヌゞョンでは、keilりィンドりでレゞスタの状態を芋るこずができたせん。 しかし、すぐにフルバヌゞョンがリリヌスされ、この欠点が修正されたす。 新しいバヌゞョンを詊しおみたい人のために-ここにきれいなプロゞェクトぞのリンクがありたす 。



以前の蚘事のリスト。



All Articles