Stm32f103 PB12 External Interrupt manuel acıp/kapatmak

Başlatan M_B, 17 Eylül 2025, 11:54:13

M_B

Merhabalar,
STM32F103C8T6 PB12 nolu pinden External Interrupt ile Düşen ve Yükselen kenar tetiklemeli
sinyal okuyorum.
İnterruptla veri alımı yapıldıktan sonra tekrar dan girmesin diye manuel olarak interrupt kapatıp işlemlerimi yaptıktan sonra tekrar devreye almak istiyorum ne denediysem bir turlu başarılı olamadım.

Kod parcacıklarım.
stm32f1xx_it.c iceriğinde

/**
  * @brief This function handles EXTI line[15:10] interrupts.
  */
void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */

  /* USER CODE END EXTI15_10_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(PB12_Pin);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}

gpio.c iceriğindeki ayarım.

void MX_GPIO_Init(void){
    
     GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
    
    __HAL_RCC_AFIO_CLK_ENABLE();  // AFIO saatini aç
/*---------------------------------------------------------------------*/
    AFIO->EXTICR[3] &= ~(0xF << 16);  // EXTI12 için temizle
    AFIO->EXTICR[3] |= (0x1 << 16);   // Port B'ye bagla
/*---------------------------------------------------------------------*/
  GPIO_InitStruct.Pin = PB12_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(PB12_GPIO_Port, &GPIO_InitStruct)
     /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
    
}

main.c

/*---------------------------------------------------------------------------------------
 *                                     EXTI callback fonksiyonu               
 --------------------------------------------------------------------------------------*/

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
        if (GPIO_Pin != PB12_Pin) return;
         uint32_t currentTime = htim1.Instance->CNT;
    uint8_t currentState = HAL_GPIO_ReadPin(PB12_GPIO_Port, PB12_Pin);
    pulseWidth = calculatePulseWidth(currentTime, lastTime);
      if (currentState == GPIO_PIN_SET) {  // Rising edge
        switch (captureState) {
            case STATE_KEY_DATA:
                if (bitCount < KEY_DATA_LEN) {
                    appendBit(&keyData, pulseWidth, SHORT_PULSE_THRESHOLD);
                    bitCount++;
                    if (bitCount == KEY_DATA_LEN) {
                        captureState = STATE_GAP;
                        // keyDataReady = 1; // opsiyonel
                    }
                }
                break;

            case STATE_DISPLAY_DATA:
                if (bitCount < DISPLAY_DATA_LEN) {
                    appendBit(&displayData, pulseWidth, SHORT_PULSE_THRESHOLD);
                    bitCount++;
                    if (bitCount == DISPLAY_DATA_LEN) {
                        captureState = STATE_FRAME_END;
                        displayDataReady = 1;
                    }
                }
                break;

            case STATE_WAITING:
                captureState = STATE_KEY_DATA;
                bitCount = 0;
                keyData = 0;
                break;
        }
    } else {  // Falling edge
        if (captureState == STATE_GAP && pulseWidth >= GAP_THRESHOLD) {
            captureState = STATE_DISPLAY_DATA;
            bitCount = 0;
            displayData = 0;
        } else if (captureState == STATE_FRAME_END && pulseWidth >= FRAME_END_THRESHOLD) {
            captureState = STATE_WAITING;
        }
    }

    lastTime = currentTime;
    lastPinState = currentState;   
}

void main(){

        if (IsDisplayDataReady())
                        {
                                disable_exti_interrupt();
                                EXTI->IMR &= ~(1 << 12);   // kapat
                                data = GetDisplayData(); 
                        }
        taskDisplayStatus();
    //    .... Başka fonksiyonlarda var.
        
}

void taskDisplayStatus(void)
{
    if(data == KAPALI){
                        ssd1306_SetCursor(5, 0);
                        ssd1306_WriteString("KAPALI   ", Font_11x18, White);   
                        ssd1306_UpdateScreen();   
                        HAL_Delay(500);
                        enable_exti_interrupt();
                        EXTI->IMR |= (1 << 12);
                    }

    
    if(data == ACIK){
                        ssd1306_SetCursor(5, 0);
                        ssd1306_WriteString("ACIK   ", Font_11x18, White);   
                        ssd1306_UpdateScreen();   
                        HAL_Delay(500);
                        enable_exti_interrupt();
                        EXTI->IMR |= (1 << 12);
                    }
}

void enable_exti_interrupt(void) {
                AFIO->EXTICR[3] &= ~(0xF << 16);  // EXTICR[3] ? EXTI12 için
                AFIO->EXTICR[3] |= (0x1 << 16);   // 0x1 = Port B
                __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_12);         // Pending bayragini temizle
                EXTI->IMR |= (1 << 12);                        // EXTI maskesini aç
                HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
                if (EXTI->PR & (1 << 12)) {
                EXTI->PR = (1 << 12);  // Bayragi temizle
            }
}

void disable_exti_interrupt(void) {
        EXTI->IMR &= ~(1 << 12);                       // EXTI maskesini kapat
    HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
}

main.c icindeki Hazır HAL interrupt fonksiyonları kullandım - Register seviyesinde yazdım bir turlu olmadı.
Nerde nasıl bir hata yapıyorum acaba.

Teşekkürler.
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

RaMu

https://community.st.com/t5/stm32-mcus-products/disable-enable-exti-interrupts-using-hal/td-p/420622
Burada son mesajdaki gibi pini yeniden init etmen gerekiyor olabilir.

https://github.com/STMicroelectronics/STM32CubeG4/issues/6
Buradada daha detaylı bahsediliyor ama 5 sene öncenin, belki yrni fonksiyonlar eklemişlerdir bu iş için.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

mehmet

EXTI -> EMR |= EXTI_IMR_MR12;
ile bekletebilmeniz gerekli. Gerekli olduğunda ise;
EXTI -> EMR &= ~EXTI_IMR_MR12;
ile çalıştırabilirsiniz.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

Benzer Konular (5)