if deyimi false olsada çalışıyor :S

Başlatan engineer, 24 Aralık 2014, 00:17:27

engineer

Merhaba, STM32F100 kullanıyorum şimdiye kadar bir sıkıntı yoktu ancak sorun başlıkta belirttiğim gibi if deyimi içerisindeki ifade false olsada if bloğu çalışıyor. Debug yaparkende normal çalışırkende bu şekilde ancak bazen çalışıyor bazen çalışmıyor. Kısaca algoritmadan bahsedecek olursam; interrupt geldiğinde IntFlag adlı değişken SET ediliyor ve interrupt rutini sona eriyor. Main'e döndüğünde IntFlag SET ise gerekli işleri yaptırıyorum değilsede diğer işlemleri. Sorun acaba kodumun hantallaşmasından mı anlıyamadım, 2000 satırı geçti, sürekli if'ler else'ler var, 7 tane interrupt 9 tane timer vsvs ..

main()
{
   while(1){
      if(IntFlag == SET){
         IntFlag = RESET;
      }
      else{
      }
   }
}


M.Salim GÜLLÜCE

interrupt rutinin fazla zaman alıyorsa daha rutinden çıkamadan yeni interrupt algılamasıyla yeniden interrupt rutinene gömüleceğinden sıkıntı yaşayabilirsin.
İnterrupt içindeki kodlarını kısaltmanı öneririm. (Görmeden afaki yorum yapıyorum)
umarım işine yarar bilgilendirmişimdir.

Gökhan BEKEN

7 tane interrupt ve 9 tane timer kısmı nasıl? Her birinin kesmesi için yukarıdaki gibi if mi kullandınız, yoksa kesmenin içine kod mu yazdınız?
Her interrupt ne kadar zaman da bir geliyor?
Projeyi olduğu gibi kopyalayın(eski kodları yedekleyin)
interrupt fonksiyonlarının içinde sadece bayrak set edin,
main'nin içinde de sadece bayrakları if ile kontrol edin, başka hiç birşey yazmadan debug edin, bahsettiğiniz sorun düzeldiyse yavaş yavaş ekleme yaparak kontrol edin, sorunun kaynağını bulabilirsiniz.
Özel mesaj okumuyorum, lütfen göndermeyin.

yamak


engineer

@Mehmet Salim GÜLLÜCE
Interrupt rutinlerim çok kısa ve az zaman alıyorlar, ayrıca swo üzerinden adım adım tüm bilgileri basıyorum, interrupta girdi çıktı şunu set etti bunu resetledi vs. Dolayısıyla olan biten herşeyi görüyorum ve yalnızca tek interrupt rutinine giriyor ve onu bitiriyor.

@meftun
Her interrupt'ın kendi rutini var, bu kodu kullanmamdaki amaç şu; bir adet pır sensörüm var ve sistem kapalıyken sensör hareket algıladıysa açıldığında interrupt'a girmicek çünkü interruptım yükselen kenar tetiklemeli. Ayrıca her interrupt bir event oluşturuyor ve IntFlag'i set ediyor. Main'de IntFlag set ise bir EventHandler fonksiyonu çağırıyorum oda gelen event'ları işliyor, sistem kabaca bu şekilde çalışıyor. Eğer IntFlag set değilse bende pır sensörün bağlı olduğu portu kontrol ediyorum eğer 1 ise hareketle ilgili bir event oluştur ve EventHandler'ı çağır diyorum. Başta bunu software interrupt'la pir'in kendi interrupt'ını çağırarak yapmıştım ancak düzgün çalışmadı sonra pir ile ilgili bitakım kodları buraya eklemek zorunda kaldım.

@yamak
Denedim ama sonuç yine aynı :(

İlgilendiğiniz için hepinize ayrı ayrı teşekkür ederim.




mir_as82

Hocam IntFlag değişkenin türü ve SET, RESET değişkenlerinin türü uyumsuz olabilir mi?

engineer

FlagStatus adında bir tip tanımladım, bu tiplede SET ve RESET'i enumerate ettim. IntFlag değişkeninin türüde FlagStatus tipinde, o yüzden bir problem yok. Asm kodlarınada bakıyorum herşey düzgün :S

elektronart

F100 için hangi geliştirme ortamını kullanıyorsunuz?
Açık Elektronik

engineer


engineer

ilgili kod aşağıdaki şekilde hocam. Bu kodda mesela else'den sonra tekrar bi if koyup yine koşulu test etsem ve yine false olsa çalışıyor. Else 'i kaldırıp doğrudan if yazsam yine aynı. Acaba else içerisinde kullandığım if'in deyimi çok mu uzun, orda problem yaşıyor olabilir miyim.

Main
int main(void){
	SysInit();
	SW_Status();
	while(1){
		if(IntFlag == SET){
			#ifdef DEBUG_SWO
				printf("If Icerisinde\n");
			#endif
			/* Clear Button Interrupt Flag */
			IntFlag = RESET;
			EventHandler(Event);
		}
		else{
			if(((SysCache.CH1_Status == ON) && (SysCache.CH1_Mode == Sensor)) || ((SysCache.CH2_Status == ON) && (SysCache.CH2_Mode == Sensor))){
					if((GPIOA->IDR & 0x0080) == 0x0000){
						while(TIM7->CNT != 0x0000);
//						EXTI->SWIER = (uint32_t)EXTI_SWIER_SWIER7;
						
							SensorFlag = SET;
							/* Sensor & GroupIn & RTC Interrupt Masked */ 
							EXTI->IMR &= (uint32_t)~(EXTI_IMR_MR5 | EXTI_IMR_MR7 | EXTI_IMR_MR17);

							#ifdef DEBUG_SWO
								printf("RTC Interrupt Disable (Main)\n");
							#endif
							
							/* GroupOut Enable */
							GPIOA->ODR |= (uint16_t)GPIO_ODR_ODR6;
							
							IntFlag = SET;
							Event = PIR;
							#ifdef DEBUG_SWO
								printf("Sensor\n");
							#endif
					}
					else 
						if((GPIOA->IDR & 0x0020) == 0x0000){
							while(TIM7->CNT != 0x0000);
//							EXTI->SWIER = (uint32_t)EXTI_SWIER_SWIER5;
							
								GroupFlag = SET;
								/* Sensor & GroupIn & RTC Interrupt Masked */ 
								EXTI->IMR &= (uint32_t)~(EXTI_IMR_MR5 | EXTI_IMR_MR7 | EXTI_IMR_MR17);

								#ifdef DEBUG_SWO
									printf("RTC Interrupt Disable (Main)\n");
								#endif
								
								/* GroupOut Enable */
								GPIOA->ODR |= (uint16_t)GPIO_ODR_ODR6;
								
								IntFlag = SET;
								Event = PIR;
								#ifdef DEBUG_SWO
									printf("Group\n");
								#endif
						}
			}
		}
	}
}


Interrupt
void EXTI9_5_IRQHandler(void)
{
	if((EXTI->PR & EXTI_PR_PR5) == EXTI_PR_PR5){
		EXTI->PR = (uint32_t)EXTI_PR_PR5;
		#ifdef DEBUG_SWO
			printf("GroupIn Interrupt'a Girdi. \n");
		#endif
		GroupFlag = SET;
	}
	else{
		EXTI->PR = (uint32_t)EXTI_PR_PR7;
		#ifdef DEBUG_SWO
			printf("Sensor Interrupt'a Girdi. \n");
		#endif
		SensorFlag = SET;
	}
	
	/* Sensor & GroupIn & RTC Interrupt Masked */ 
	EXTI->IMR &= (uint32_t)~(EXTI_IMR_MR5 | EXTI_IMR_MR7 | EXTI_IMR_MR17);

	#ifdef DEBUG_SWO
		printf("RTC Interrupt Disable (SGI)\n");
	#endif
	
	/* GroupOut Enable */
	GPIOA->ODR |= (uint16_t)GPIO_ODR_ODR6;
	
	Event = Null;
	if((GroupFlag == SET) && (SensorFlag == SET) && (PIRFlag == RESET)){
		IntFlag = RESET;
		#ifdef DEBUG_SWO
			printf("Group ve Sensor Int. Olustu.\n");
		#endif
	}
	else{
		IntFlag = SET;
		Event = PIR;
		#ifdef DEBUG_SWO
			printf("Event = PIR (SGI)\n");
		#endif
	}
	
	if(PIRFlag == SET) 
		PIR2Flag = SET;
	
	#ifdef DEBUG_SWO
		printf("Interrupttan Cikti.\n");
	#endif
}

kayatech

C 'yi çok iyi bilmiyorum ve kodları fazla incelemedim ancak dikkatimi çekti ; Tek if içinde hem "VE" hem de "VEYA" olabiliyor mu ? Sorun buradan kaynaklı olmasın ?

if(((SysCache.CH1_Status == ON)  &&           
(SysCache.CH1_Mode == Sensor))  ||             
((SysCache.CH2_Status == ON)     &&
(SysCache.CH2_Mode == Sensor)))
{

mir_as82

hocam içerideki ifade lojik bir ifade olduğu sürece olabilir. Orada sıkıntı olmaz.

engineer

@kayatech

if içerisinde istediğin koşulu sınayabilirsin, sonuç 0 mı değil mi önemli olan o. Ben o satırda ilk olarak CH1 ile ilgili durumları değerlendiriyorum, her iki durumda true ise veya' dan sonraki durumları test etmeye gerek kalmıyor, direk bloğun içine giriyor. Şayet CH1 ile ilgili koşullardan biri bile false ise o zaman CH2 ile ilgili durumları değerlendiriyor.

İstersen if içerisindeki ifadeleri böl iç içe bir sürü if kullan yine aynı kapıya çıkıyor, aynı asm kodları üretiliyor. Ayrıca if içerisinde deyim olarak fonksiyonda kullanabilirsin, bu durumda fonksiyonun geri döndürdüğü değeri sınamış olursun. İllaki bir deyim kullanmanada gerek yok sabit, değişken yada pointer'da koyabilirsin.

yamak

Optimizasyonu eğer level 0'da değilse level 0 düşürüp dener misiniz?

engineer

@yamak

Optimizasyonu hiç kullanmıyorum, başım çok ağrıdı zamanında o yüzden hep level 0'da duruyor.