stm32f10x PWM kenar tespit

Başlatan mistek, 26 Ocak 2014, 21:49:36

mistek

TIM1 e bağlı olarak tek kanal PWM sinyali üretiyorum. Normalde TIM1 kendi başına belli durumlarda kesme oluşturabiliyor, ancak PWM sinyalinin yükselen veya ve düşen kenarında kesme oluşturmam ve kenar tespiti yapmam gerekiyor.

Datasheet'e göz attım ancak aradığımı tam olarak bulamadım gözden kaçırmışta olabilirim.

Break pinini kullanmadan PWM kenar tespiti yapmak mümkün mü? Mümkün değilse alternatif olarak nasıl bir yöntem önerirsiniz?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

camby

Normal Timer kesmesinde olduğu gibi TIM_IT_Update kesmesini açtığınızda oluyor.

PWM duty'sinin yükselen kenarında kesme üretiyor olması lazım.

mistek

Evet hocam ARR registerı güncellendiğinde kesme oluşuyor ama bana birde düşen kenarı lazım.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

camby

"yükselen veya düşen kenarında" diyince düşen kenara kafa patlatmadım : )

Direk o şekilde aktif edilen bir kanal olmayabilir.

Etrafından dolaş,

Bir timer daha kullan , tüm katsayıları aynı olsun fakat diğer timerın düşen kenarında kesme üretecek şekilde init et onu da.

Timerları aynı anda init et , aynı anda durdur. 1-2 clock farkla elde edersin kesmeyi.


Yada Duty'nin yükselen kenar kesmesinde , yeni bir timer aç , bu timer'ın kesme süresi senin duty süren kadar olsun. Duty sonunda diğer timerdan bir kesme daha üretmiş olursun.

mistek

Alıntı yapılan: camby - 26 Ocak 2014, 22:18:13
"yükselen veya düşen kenarında" diyince düşen kenara kafa patlatmadım : )

Hocam yanlış yazmışım sizin yorumunuzdan sonra fark ettim, düzelttim.

Donanımsal olarak tespit edemiyorsam dediğiniz gibi yeni bir timer kurup öğreneceğim. Teşekkürler.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

mistek

#5
Timer'ı aktif ettikten sonra programın biryerinde pasif yapıyorum. Yani timerı istediğim şekilde açıp kapatmak istiyorum.
Aktif için: TIM_Cmd(TIM2,ENABLE);
Pasif için: TIM_Cmd(TIM2,DISABLE);
Kullanıyorum.

Ancak aktif yaptıktan sonra pasif fonksiyonunu çağırırsam pasif olmuyor timer kesmeleri bozuluyor. Normalde bunun tamamen kapanması gerekmez mi? Yanlış fonksiyonu mu kullanıyorum ?

--
Saat kaynağını kapatıyorum mantıklı olarak Timer duruyor, ama neden sayıcıyı durdurduğumda kesme üretiyor ki bu meret?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

camby

doğru bu şekilde , sürekli açıp kapatıyorum ben bu fonksiyon ile

mistek

TIM_Cmd(TIM2,DISABLE) ile kapattıktan sonra, açmadan önce tekrar init edecekmiyiz? Garip bir şekilde timer çalışmaya ve kendi kafasına göre kesme üretmeye devam ediyor.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

camby

yok init yok , sadece enable disable yapıyorum.

mistek

Gözden kaçırdığım bişeyler var sanırım tekrar kontrol edeyim.

void TIM2_IRQHandler(void)
{
   TIM_IT bitini sil.
   //Falanca işlemleri yap
   TIM_Cmd(TIM2, DISABLE);
}

Şeklinde kullanımda sorun olur mu? Kesmeden çıkarken kendisini kapatmak istiyorum ve TIM1 kesmesinde tekrar açıyorum.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

camby

kodlarıma bakıyorum da ,

bir handler'ın içinde açmışım , başka bir handler içinde kapatmışım.

// Counter Disable
	TIM6->CR1 &=~ 0x0001;            				// Counter Disable


// Clear & Start Timer
	TIM6->CNT = 0;								// TIM6 Clear
	TIM_Cmd(TIM6, ENABLE);						// Enable TIM6


kaparken register seviyesinde yazmışım, ilk zamanlardan kalma bir satırdır ama onun bir şey değiştireceğini sanmıyorum.

mesaj birleştirme:: 28 Ocak 2014, 09:18:08

-------------

o şekilde kullanamazsın :

// Clear Interrupt
	TIM_ClearITPendingBit(TIM6,TIM_IT_Update); 		// Clear Update interrupt flag


Bayrağı temizlemen lazım şu şekilde.

mistek

Alıntı yapılan: camby - 28 Ocak 2014, 09:17:17
o şekilde kullanamazsın :

// Clear Interrupt
	TIM_ClearITPendingBit(TIM6,TIM_IT_Update); 		// Clear Update interrupt flag


Bayrağı temizlemen lazım şu şekilde.

Hocam bayrakları siliyorum temsili olarak o şekilde yazdım.

İnterrupt'ın kendi fonksiyonunda kendisini kapatsam/durdursam neden sorun olduğunu anlamadım. Datasheet'in neresinde yazar bu bilgi?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

camby

#12
Datasheette bu soruna çözüm aramak samanlıkta iğne aramak gibi , ama bakılacak yer tabi referance manuel.

Daha iyi yöntem enable disable işlerinin yapıldığı örnek kodlara bakmak internette , STM hazır kodlarına bakmak varsa böyle bir şey.

Başka bir uygulamada şu şekilde yapmışım :

//====== Coil Test ============================================================
void Coil_Test(void)   
{
	if ( Coil0 == 255 )
	{
		// TIM counter enable 
		TIM_Cmd(TIM1, ENABLE);										
		TIM_Cmd(TIM3, ENABLE); 										
	}
	else
	{
		// TIM counter enable 
		TIM_Cmd(TIM1, DISABLE);										
		TIM_Cmd(TIM3, DISABLE); 									
	}

	if ( Coil1 == 255 )
	{
		TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);					// Ref_Out Enable	
	}
	else
	{
		TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);					// Ref_Out Disable
	}

	
}//============================================================================


mesaj birleştirme:: 28 Ocak 2014, 10:21:21

Bunlar de test edildi sorunsuz çalışıyor , kodlarda bir şeyler gözden kaçmış olabilir.

mistek

Aynı şeyleri yaptım bende ama tekrar bir gözden geçireyim. Zaten bu şekilde kullanılıyorsa muhakkak benim kodlarımda sorun vardır.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

camby

#14
Karşılaştırmak adına  , açıp kapattığım bir timer'ın init fonksiyonu :

//====== TIM6 Init ( MODBUS Timer ) ===========================================
void TIM6_Init(uint32_t MODBUS_3_5_Delay) 
{
	// Timer6 clock 84 MHZ , Prescaler 84 -> 1 us'de bir deger 1 artar.
	
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;				// Struct
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);		// Clock Enable
	TIM_DeInit(TIM6);
	
	TIM_TimeBaseStructure.TIM_Period = MODBUS_3_5_Delay-1;		// Ayarlar
	TIM_TimeBaseStructure.TIM_Prescaler = 84-1;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 				// TIM_CKD_DIV1
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
	
	TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);					// Interrupt
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn;				// NVIC Ayarlari
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
	
}//============================================================================


mesaj birleştirme:: 29 Ocak 2014, 10:28:08

Kesme üretme süresi başka bir fonksiyon tarafından belirleniyor.

   TIM_TimeBaseStructure.TIM_Period = MODBUS_3_5_Delay-1;		// Ayarlar


Çok önemli değil burası 1000 olsa , 1ms 'de bir kesme üretecek.