durum bilgisini çıkışa aktarmakda sorun

Başlatan bulut_01, 30 Ekim 2013, 21:31:29

bulut_01

iyi aksamlar arkadaslar uzun zamandır ara verdıgım bldc motor devremde kaldıgım yerden devam ediyorum problemim hall sensor aldıgım komutatör bılgısını cıkısa aktarmak ext kesmenısını kullandım bunun ıcın kodu daha sade ve calısır duruma getirmek ıcın neler yapabıllırım  yardımlarınızı beklıyorum

#include <18f1330.h> 
#fuses INTRC_IO,NOWDT,NOMCLR,H4
#use delay(clock=40M)
#use fast_io(a)
#use fast_io(b) 

int16 duty1;
int16 duty2;
int16 duty3;
int16 p=100;
int16 ileri=0;

#INT_EXT
void EXT_kesme()
{
ileri  = input_a()& 0b00000011 ;
ileri |= input_b()& 0b00000100 ;

switch (ileri)
{
case 0b00001001:

output_low(pin_b6);
set_power_pwm0_duty(duty1=P);      // 1.faz
output_high(pin_b4);
break;

case 0b00001000:

set_power_pwm0_duty(duty1=0);   // 2.faz
set_power_pwm4_duty(duty3=P);
output_high(pin_b4);
break;

case 0b00001010:

output_low(pin_b4);               // 3.faz
set_power_pwm4_duty(duty3=P);
output_high(pin_b0);
break;

case 0b00000010:

set_power_pwm4_duty(duty3=0);
set_power_pwm2_duty(duty2=P);    // 4.faz
output_high(pin_b0);
break;

case 0b00000011:

output_low(pin_b0);              // 5.faz
set_power_pwm2_duty(duty2=P);
output_high(pin_b6);
break;

case 0b00000001:

set_power_pwm2_duty(duty2=0);
set_power_pwm0_duty(duty1=P);   // 6.faz
output_high(pin_b6);
break;
default:
}
}



      void main()
{
setup_power_pwm_pins(PWM_odd_on,PWM_odd_on,PWM_odd_on,PWM_odd_on);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,1,0,4095,0,1,0); 
setup_adc_ports(NO_ANALOGS); 
setup_adc( ADC_OFF );
setup_comparator(NC_NC_NC);

ext_int_edge(l_to_h);
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT); 

set_tris_a(0b000000011);
set_tris_b(0b000000100);
OUTPUT_B(0x00);

while(TRUE)
{
}
}
YENİLMEZ..

bulut_01

YENİLMEZ..

bulut_01

Zor soru sormadım arkadaslar bir el atın şu kodları çalıştırayım
YENİLMEZ..

Tagli

Sensörlerden aldığın 3 biti LED'lerde görmek mi istiyorsun? Nerede takıldığını anlamadım. Okuduğun değeri olduğu gibi bir port'a yazdırman yeterli. Bunu zaten kesme kodu içinde de yapabilirsin.
Gökçe Tağlıoğlu

bulut_01

Hall sensörden aldıgım komutatör bilgisine göre pwm alıp motor sürecegim kodu calıstıramadım nerde mantık hatası yapıyorum kodda onu bulamadım.
YENİLMEZ..

Tagli

CCS C bilmedigim icin kodu yorumlamam pek mumkun degil. Ozellikle, derleyicinin power pwm komutlarinin nasil calistigini bilmiyorum. Ama bu PIC ile BLDC denemesi yapmistim. Her 3 cift pwm cikisina da ayni periyod ve is zamani degerlerini veriyordum. O modelde "override" islemi yapan bir register var, pwm cikislarini maskelemeye yariyor. Kesme icinde hall sensorlerinden gelen veriye gore bu override register'inin degerini degistirerek ayni anda sadece 1 alt 1 ust mosfet'e pwm gitmesini saglamistim. Zaten Microchip'in uygulama orneginde de bu sekilde yapilmis.
Gökçe Tağlıoğlu

bulut_01

taglı hocam siz hangi kesmeyi kullandınız benim sıkıntım girişteki hall komutatör bilgisi okuyup o komutatör sırasına denk gelen fazı aktif etmek benım sıkıntım bu sız override nasıl kullandınız ?
YENİLMEZ..

Tagli

Hall sensorlerini PORTB kesmesine baglamistim. Kesme geldiginde bu bacaklari okuyarak faz durumuna gore override register'ini guncelliyordum. Register'in adi tam aklimda degil ama galiba OVRCON gibi birseydi. Bunun bir de durum register'i var. Yani override oldugunda o bacaklardan pwm yerine ne cikacagini belirliyor. Onu da sifirlamak lazim, oyle sabit kalacak. Her fazda 6 cikistan 4'u override olacak, yani 0 kalacak, 2 bacaktan ise pwm cikacak.

Bu arada, bacak sayisi azligi nedeniyle projeyi daha sonra 16F887'ye tasidim. Onda sadece normal pwm oldugundan, tek kanal pwm'i harici bir AND kapisi ile dagitmistim. Su anda ise projeyi yarim haliyle dsPIC'e gecirmeye calisiyorum ama baska islerim de oldugundan pek ilerlemiyor.
Gökçe Tağlıoğlu

bulut_01

aynı dertten bende muzdaripim uzun zaman ara verdim için unutmusum uğraşmadıgım için 1 sene öncekı yaptıgım seyleri bakıyorum ve bişey anlamıyorum   :) RB kesmesiyle yaptım proteus similasyonda calısıyor gercekte motor şaçmalıyordu ve mosfetler uçmuştu dead time dikkat ettiysemde similasyonda calısan kod gercekte tam vasattı bu c daha çok kürek çektirecek bana.
YENİLMEZ..

Tagli

PORTB kesmesiyle ilgili şöyle bir sorun da var: Benim gördüğüm tüm PIC16 ve PIC18'lerde bu kesme bacaklarındaki girişler TTL olarak belirtilmiş. O yüzden sensör parazitinden çok etkileniyorlar. Bacak girişleri değişmediği halde yalancı kesmeler geliyor. Bunu önce farketmedim, çünkü motorun dönmesi sırasında bir sorun oluşturmuyor. Yalancı kesme geldiğinde, kesme kodu bacakları okuyor, bir değişiklik olmadığından eski çıkış değerlerini olduğu gibi tekrar port'a yazıyor. Ne zaman ki hall sensörlerden hız verisi okumaya çalıştım, bu yalancı kesmeleri de o zaman farkettim. Sorunu harici bir Schmitt Trigger girişli kapı koyarak çözdüm (sadece inverter bulabildim, yazılımda tekrar tersleyerek düzelttim). dsPIC'lerde PORTB kesmesi benzeri "change notification" diye birşey var. Ayrıca bu işlemcilerde tüm girişler Schmitt Trigger özelliğine de sahip.
Gökçe Tağlıoğlu

bulut_01

demekki ondan saçmalıyordu peki hall girişlerini pulldown yaparak çözemedin mi benim kodda çalısıyordu kod çok hantal bana göre daha basit yazarak hafifletebilir senin kodu buraya koyabilirmisin örnek teşkil etmesi için
YENİLMEZ..

Tagli

Motordaki hall çıkışlarına zaten pullup yapmak gerekiyor çünkü open drain çıkışlar. Hat üzerinde bir de alçak geçiren filtre konması önerilmişti bir uygulama notunda. Koda evden erişmem zor, yarın işyerine geçince eklerim.
Gökçe Tağlıoğlu

Tagli

PIC18F1330 için yazmış olduğum kodu bulamadım, silmiş olabilirim.  PIC16F887 için olan kodun ilgili bölümlerini ekliyorum. Kesme kodunda, 3 adet harici AND kapısının birer girişleri güncellenerek üst MOSFET'lerden hangisinin PWM alacağı belirleniyor. Alt MOSFET'lere PWM vermedim, doğrudan açıp kapatıyorum.

Kesme Kodu:
void interrupt isr(void){
	if (RBIE == 1 && RBIF == 1){
		char hall = updateHall();
		if (s.direction == 0) PORTA = getCW(hall);
		else if (s.direction == 1) PORTA = getCCW(hall);
		RBIF = 0;
	}
}


Kesme içinde çıkışları belirleyen parça:
char getCW(char hall){
	switch (hall){
		//Phase:    |LLLHHH
		//          |321321
		//Hall:
		//    |1 2 3
		case 0b10000:
			return 0b100001;
		case 0b10001:
			return 0b010001;
		case 0b00001:
			return 0b010100;
		case 0b00101:
			return 0b001100;
		case 0b00100:
			return 0b001010;
		case 0b10100:
			return 0b100010;
		default:
			s.invHall = 1;
			return 0;
	}
}

char getCCW(char hall){
	switch (hall){
		//Phase:    |LLLHHH
		//          |321321
		//Hall:
		//    |1 2 3
		case 0b10000:
			return 0b001100;
		case 0b10001:
			return 0b001010;
		case 0b00001:
			return 0b100010;
		case 0b00101:
			return 0b100001;
		case 0b00100:
			return 0b010001;
		case 0b10100:
			return 0b010100;
		default:
			s.invHall = 1;
			return 0;
	}
}


Kesme kodu içinde hall sensörlerini okuyan kısım. Yalancı kesme gelip gelmediğine de bakıyor.
char updateHall(void){
	char tempHall = (~PORTB) & 0b00010101;
	if (tempHall == oldHall){
		s.falseInt = 1;
	}
	else{
		++phaseCounter;
	}
	oldHall = tempHall;
	return tempHall;
}


Gökçe Tağlıoğlu

bulut_01

Hmm akşam kodu yazdım son halini aksam eve geçince buraya koyarım yalancı kesme işini pulldown dirençleriyle çözerim kodlarımız benziyor bir birine.
YENİLMEZ..

Tagli

Pulldown dirençlerinin sorunu çözeceğini pek sanmıyorum.
Gökçe Tağlıoğlu