STM32 EXTI Problemim

Başlatan Eren Eraslan, 06 Temmuz 2017, 17:13:43

Eren Eraslan

Merhabalar

STM32F030 işlemcisinde external interrupt kullanmaya çalışıyorum. Bir sorunum var, sorun mu değil mi orayı anlamadım. Şöyleki;

İşlemcinin exti0 pinine buton bağlı ve bu butona her bastığımda bu interrupta girip işlemi yapıp kaldığı yerden devam etmesini bekliyoruz değil mi?
Fakat gerçekte butona bastığım sürece sürekli exti interruptına giriyor. Bu normal mi ? Exti interrupt ına her düşen yada yükselen kenar gerçekleştiğinde olmuyor muydu ben mi yanlış hatırlıyorum.
İstiyorum ki butona istediğim kadar basayım. İlk düşen kenar detect olduğunda interrupt rutine girsin ve bir sonraki düşen kenara kadar girmesin istiyorum
Neden böyle olmuyor?
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(HAL_GPIO_ReadPin(INT_SOURCE_GPIO_Port,INT_SOURCE_Pin) == 0)
	{
		for(uint32_t i=0;i<300000;i++);
		HAL_GPIO_TogglePin(STATE_LED1_GPIO_Port,STATE_LED1_Pin);
		return;
	}
}


daha sonra alttaki kodu deniyorum.İnterrupta 1 kere giriyor ve birdaha girmiyor. Bunun sebebi nedir?
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(HAL_GPIO_ReadPin(INT_SOURCE_GPIO_Port,INT_SOURCE_Pin) == 0)
	{
		for(uint32_t i=0;i<300000;i++);
		HAL_GPIO_TogglePin(STATE_LED1_GPIO_Port,STATE_LED1_Pin);
		__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
	
	return;
}



insanın içine işleyen şarkılar ;  https://soundcloud.com/reeraslan

kimlenbu

Hal library kullanmıyorum, vereceğim cevap hatalı olabilir ama gördüğüm kadarıyla kütüphaneyi yanlış kullanıyorsun.


init fonksiyonunun içeriği nasıl ?
call back'den önce yazdığın irq handler nerde ?

JOKERAS

Stm Arm Marm anlamam.Bilen arkadaşlar yardımcı olur sanırım.
Ama mantalite hatası var gibi.


İnterrupt rutininde for döngüsü veya gecikme kullanmak hiç iyi bir fikir değil!
Ayrıca Buton okuma kodunuz ortada yokki.


Buton hattı iddle durumda bekliyor,butona bastınız hat Logic 0 oldu.Bu Size göre.
Ama işlemciye göre sayısız defa 1 - 0 olur.Buton arkı Debounce.
Eğer interrupt bayrağını temizliyorsanız defalarca interupt rutinine girer ve çıkar.
İnterrupt bayrağını temizlemiyorsanız bir kere girer orada takılır kalır.
-----------------------------------------------------------------------------

Olay şöyle olmalı...
Butona bastığınız anda ilk düşen kenar geldiğinde İnterrupt rutinine girer
ilgili interrupt Enable kapatılır.Görev yerine getirilir(Bu isteğe bağlı,sonrada yapılabilinir)
PC ilgili bayrağı temizler ve çıkar.

Tam o sırada interrupt rutininin içinde bir Timer sayıcı ya sıfırlanır yada başlatılır önemli değil.
Bu bir kaç instruction cycle kadar bir sürede olur biter.


Timer saymaya başladı........hala sayıyor......daha bitmedi.........birazdan taşacak.

Bu sırada buton hattında bir sürü 1 - 0 gelir,gelse ne olurki?
Ext inti kapattıkya!Aha Timer taştı ve interrupt oluşturdu.
Tekrar interrupt rutinine girerek if else merdivenin Timer bloğuna girerek
Ext int Bayrağını Enable yapar.Burada dikkat edilmesi gereken nokta Ext inti Enable yapmadan önce
Ext int bayrağını temizlemek gerekir.Bu yapılmazsa Ext int açıldığı anda Ext int bayrağı set olur.
Bu False interrupt oluşturur.


Timer'a vereceğiniz değer Buton arkı Debounce için
geçen süreyi belirler.


Yani iki iş var,biri açıyor biri kapatıyor.
Sizin kullandığınız işlemcinin başka özellikleri varsa bilmiyorum.


if Buton sıfırsa falan demenize de gerek yok.O kodun anlamı yok!


şöyle olmalı herhalde


if(Ext int Flag && Ext int Enable) {


    Toogle Pin(0);
    DisableExtint();
    ClearTimer();
 
} else if (Timer Flag && Timer Enable) {
   
    EnableExint();
  
} else {


     continue;
   
}



Bir deneyin.








MC_Skywalker

#3
Benzer bir durumu bende ADC için yaşıyorum. INT oluşuyor  dönüşüm yapıyor fakat girişte değer değişsede bir daha yeni dönüşümmü alamıyorum.

ferdem

HAL kütüphanesini hiç kullanmadım. Buton olayında tipik "contact bounce" olayı vardır, buna önlem aldınız mı? Eğer STM32F0 discovery kit kullanıyorsanız oradaki butonda bu problem oluyor, problem şu: siz butona 1 defa bastığınızı düşünüyorsunuz ancak milisaniyeler içinde onlarca basılmış gibi olur.
Alıntı yapılan: Eren Eraslan - 06 Temmuz 2017, 17:13:43
İşlemcinin exti0 pinine buton bağlı ve bu butona her bastığımda bu interrupta girip işlemi yapıp kaldığı yerden devam etmesini bekliyoruz değil mi?
Evet, öyle olması gerekir.
Alıntı yapılan: Eren Eraslan - 06 Temmuz 2017, 17:13:43
Fakat gerçekte butona bastığım sürece sürekli exti interruptına giriyor. Bu normal mi ?
Kesmeye sebep olay olduğunda ilgili "Interrupt pending bit" lojik 1 olur, mikrodenetleyici bu biti görür görmez kesme programına dallanır. Kesme içinde eğer bu biti lojik 0 yapmazsanız kesmeden çıkar çıkmaz tekrar girer, sürekli kesmeye gider. Kesme içinde pinin lojik durumu da kontrol edilmiş, basılı tutma olayı onla ilgili, o şartı kaldırırsanız bir defa basıldığında bıraksanız bile sürekli toggle eder.
Alıntı yapılan: Eren Eraslan - 06 Temmuz 2017, 17:13:43
Exti interrupt ına her düşen yada yükselen kenar gerçekleştiğinde olmuyor muydu ben mi yanlış hatırlıyorum.
Evet, ya yükselen ya düşen kenar olarak seçiliyor, sanırım her iki kenara da kurulabiliyor. FTSR, RTSR register leriyle belirleniyor.

Alıntı yapılan: Eren Eraslan - 06 Temmuz 2017, 17:13:43
İstiyorum ki butona istediğim kadar basayım. İlk düşen kenar detect olduğunda interrupt rutine girsin ve bir sonraki düşen kenara kadar girmesin istiyorum
Neden böyle olmuyor?
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(HAL_GPIO_ReadPin(INT_SOURCE_GPIO_Port,INT_SOURCE_Pin) == 0)
	{
		for(uint32_t i=0;i<300000;i++);
		HAL_GPIO_TogglePin(STATE_LED1_GPIO_Port,STATE_LED1_Pin);
		return;
	}
}


daha sonra alttaki kodu deniyorum.İnterrupta 1 kere giriyor ve birdaha girmiyor. Bunun sebebi nedir?
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(HAL_GPIO_ReadPin(INT_SOURCE_GPIO_Port,INT_SOURCE_Pin) == 0)
	{
		for(uint32_t i=0;i<300000;i++);
		HAL_GPIO_TogglePin(STATE_LED1_GPIO_Port,STATE_LED1_Pin);
		__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
	
	return;
}



Son fonksiyon doğru yazılmış görünüyor... tekrar girmemesinin nedenini bilmiyorum.