Stm32f103 PB12 External Interrupt manuel acıp/kapatmak

  • Konuyu başlatan Konuyu başlatan M_B
  • Başlama tarihi Başlama tarihi

M_B

Üye
Katılım
16 Şubat 2023
Mesajlar
281
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
Kod:
/**
  * @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.
Kod:
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 ici.
Kod:
/*---------------------------------------------------------------------------------------
 *                                     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.
 
HAL_GPIO_EXTI_Callback fonksiyonunun sonunda pending flag'ı temizleyip dener misin?
 

Forum istatistikleri

Konular
8,912
Mesajlar
145,000
Üyeler
3,590
Son üye
yakupk

Son kaynaklar

Back
Top