Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

HPWM Hakkında

Başlatan GamzeDemir, 24 Eylül 2009, 15:23:32

GamzeDemir

Merhabalar

Ben 16f877a nın 2 pwm bacagını da kullanmak istiyorum.. bi kod yazdım tek bacagı için calısıyor simulasyonda(asagıdaki kod)..ben asagıdaki kod da pr2 degerini değilde  ccpr1l nin degerini butona basarak değiştirmek istiyorum ve bu sekilde calıstırmayı denedim ama calısmadı bende mecburen pr2 yi değiştirdim.. ama ben pr2 yi değiştirirsem 2 pwm kanalını da kullandıgımda 2 ayrı kanal için farklı duty cycle lar nasıl elde edebilirim :( umarım derdimi anlatabilmisimdir  :oops:
#include<pic.h>
#include"delay.h"


__CONFIG(WDTDIS&XT&LVPDIS);	

#undef	XTAL_FREQ
#define	XTAL_FREQ	4MHZ		/* Crystal frequency pwmn MHz */


#define AZALT RB2
#define ARTIR RB3


main(void)
{
	int pwm=0;
	TRISB=0b000001100;
	PORTB=0;

	TRISC=0;
	PORTC=0;

	CCPR1L=47; //duty cycle set oldu
	CCP1CON=0b00001100;//pwm modu
	T2CON=0b00000111;//timer on
	PR2=186; //period u set et

	
	for(;;)
	{
		RB4=1;
		DelayMs(250);
		RB4=0;
		DelayMs(250);
		if(AZALT==0)	
		{	
			DelayMs(10);			
			while(AZALT==0);	// Butondan elin çekilmesi bekleniyor
			DelayMs(10);
			pwm+=10;
			if(pwm>=250)
			{
				pwm=250;
			}			
		}
		else if(ARTIR==0)	
		{
			DelayMs(10);			
			while(ARTIR==0);	// Butondan elin çekilmesi bekleniyor
			DelayMs(10);
			pwm-=10;
			if(pwm<=0)
			{
				pwm=0;			
			}		
		}
		PR2=pwm;	
	}
}

Logan

PWM frekansını PR2 registeri ile oynayarak değiştirebilirsin. Fakat atladığın bir nokta var. CCP1L değeri ile oynarsan frekansın iş süresini, PR2 registeri ile oynarsan frekansın kendini değiştirmiş olursun. Bu sebeple biri diğerinin yerine kullanılamaz.

Ayrıca PWM iş süresini sadece CCP1L registeri ile de değiştiremezsin. Unutma ki kullanmakta olduğun PWM 10 bit ve sen CCP1L registerine değer atamakla sadece üst 8 biti değiştirmiş oluyorsun. Bu da saçma sapan çalışmasına sebebiyet verir.

Eğer datasheeti inceleyecek olursan CCP1CON registerinin 4. ve 5. bitlerinin 10 bitlik PWM frekansının ilk iki bitini oluşturduğunu göreceksin. 2. kanal meselesine gelince birinci kanala değer atarken CCP1L registeri ile DC1B1 ve DC1B0 bitlerini, ikinci kanala değer atarken de CCP2L registeri ile DC2B1 ve DC2B0 bitlerini kullanacaksın. Fakat ilk önce 16f877a.inc dosyasını açarak bu bitlerin derleyicide hangi isimlerde kullanıldığını bulmalı ve program içerisinde de o tanımlamaları kullanmalısın.

Umarım açıklayıcı olmuştur.

İyi günler, iyi çalışmalar...
İmza.

GamzeDemir

Alıntı yapılan: "Logan"PWM frekansını PR2 registeri ile oynayarak değiştirebilirsin. Fakat atladığın bir nokta var. CCP1L değeri ile oynarsan frekansın iş süresini, PR2 registeri ile oynarsan frekansın kendini değiştirmiş olursun. Bu sebeple biri diğerinin yerine kullanılamaz.

Ayrıca PWM iş süresini sadece CCP1L registeri ile de değiştiremezsin. Unutma ki kullanmakta olduğun PWM 10 bit ve sen CCP1L registerine değer atamakla sadece üst 8 biti değiştirmiş oluyorsun. Bu da saçma sapan çalışmasına sebebiyet verir.

Eğer datasheeti inceleyecek olursan CCP1CON registerinin 4. ve 5. bitlerinin 10 bitlik PWM frekansının ilk iki bitini oluşturduğunu göreceksin. 2. kanal meselesine gelince birinci kanala değer atarken CCP1L registeri ile DC1B1 ve DC1B0 bitlerini, ikinci kanala değer atarken de CCP2L registeri ile DC2B1 ve DC2B0 bitlerini kullanacaksın. Fakat ilk önce 16f877a.inc dosyasını açarak bu bitlerin derleyicide hangi isimlerde kullanıldığını bulmalı ve program içerisinde de o tanımlamaları kullanmalısın.

Umarım açıklayıcı olmuştur.

İyi günler, iyi çalışmalar...

Acıklamalarınız için teşekkürler.. CCPR1H kısmını cok etkilemez diye dusunerek deger ataması yapmamıstım.. ama sanırım yanılmısım... Bu DC2B1 ve 0 bitlerini ilk defa sizden duydum cahilliğime verin daha once de datasheet de gozume takılmadı hiç.. buraya konu acmadan once hitech  ile yazılmıs pwm orneklerini arastırmıstım..

siz soyledikten sonra dc2b1 seklinde hitech derleyicim içinde arama yaptım

adı pic1677x.h dosya içinde asagıdaki gb bi satıra rastladım..

static volatile bit	DC2B1	@ (unsigned)&CCP2CON*8+5;
static volatile bit	DC2B0	@ (unsigned)&CCP2CON*8+4;


Bu bahsettiğiniz bitler hakkında biraz daha acıklama yapabilirmisiniz datasheet de arattım bahsetmiyor :(

Edit : biraz arastırdım bu bahsettiğiniz bitler için asagıda soyle bi acıklama buldum

Alıntı YapDC2B1, DC2B0 - PWM Duty Cycle Least Significant bits - are only used in PWM mode representing two least significant bits of a 10-bit number. This number determines PWM signal's duty cycle. The rest of bits (8 in total) are stored in the CCPR2L register.

yani bu iki bit benim ccpr1h(yukarıda ccpr2h deki diyor ama sanırım benim programımdaki ccpr1h oluyor) de kaale almadıgım 2 bit mi oluyor? dogru mu anlamısım :oops:

Logan

Sayfa 60;



Kare içerisine aldığım satırlara dikkat edecek olursan aynen şunu anlatıyor;

Bu bitler PWM iş süresinin en küçük iki bitidir. Diğer 8 MSB biti ise CCPRxL registerinde bulunur. Mesai bitti eğer aklına takılan bir yer olursa buradan tekrar devam ederiz.
İmza.

muuzoo

Bu başlık altında yayınlamış olduğum bir HPWM kütüphanesi vardı. Sanırım size bir fikir verecektir. Muhtemelen gözden kaçan hatalar olabilir. Uzun zamandır güncellemedim.
gunluk.muuzoo.gen.tr - Kişisel karalamalarım...

GamzeDemir

Alıntı yapılan: "Logan"Sayfa 60;


Kare içerisine aldığım satırlara dikkat edecek olursan aynen şunu anlatıyor;

Bu bitler PWM iş süresinin en küçük iki bitidir. Diğer 8 MSB biti ise CCPRxL registerinde bulunur. Mesai bitti eğer aklına takılan bir yer olursa buradan tekrar devam ederiz.

Merhabalar

İlginiz için teşekkür ediyorum ama sanırım ben kendimi tam ifade edemedim :( zaten en buyuk sorunum bu benim  :(

Dun bu konuyu tekrar bastan okudum ve gene internette arastırdım biraz.. 2 pwm kanalını  kullanan orneklerde hep ccpr1l(ve bu bahsettiğimiz 2 biti) ve cpr2l(bu bahsettiğimiz 2 biti) nin degerini degistirerek yapıyordu.. ama ben genede sizin soylediğiniz gb pr2 yi degiştirerek nasıl yapabilecegimi dusundum..

mesela ben ccpr1l(+2bit)  ve ccpr2l(+2bit) degerlerini programın basında atasam ve sonsuz bir for dongusu için de ccpr1l ve ccpr2l için ortak olan pr2 degerini değiştirsem ben burda  birbirinden bagımsız 2 kanalı idare etmiş olmuyorum.. 2 sini de aynı anda değiştirmiş oluyorum..

Ama ben gordugum orneklerde oldugu gb direk ccpxrl registerlarına mudahale edebilirsem ikisini de farklı degerlerde ve farklı zamanlarda değiştirme imkanın olacak...

bana bu sekilde yapılmıs bir hitech ornegi gosterebilirmisiniz acaba ama calıstıgına emin oldugunuz cunku nette cok ornek inceledim proteus da simule ettim calısmıyor sinir oldum :(

Yardımlarınız için cok teşekkürler ..

Logan

Sevgili GamzeDemir, ilk olarak PWM'in ne demek olduğundan biraz bahsetmek istiyorum. PWM, Pulse Width Modulation yani Pals Genlik Modülasyonu anlamına geliyor. Temel olarak belirlemiş olduğun bir frekans dahilinde uyguladığın kare dalganın iş süresini değiştirme mantığına dayanıyor. Kabaca çizecek olursak;



Yukarıdaki resimde de görüldüğü gibi, 1 saykılın devrede kalma süresini iş süresi olarak adlandırıyoruz. PWM frekansını hesaplarken de aşağıdaki formülü kullanıyoruz;

PWM period =[(PR2) + 1] x 4 x TOSC x (TMR2 prescale value)


Ön açıklama yaptığımıza göre artık sorularına geçebiliriz. Demişsin ki;

Alıntı Yap
2 pwm kanalını kullanan orneklerde hep ccpr1l(ve bu bahsettiğimiz 2 biti) ve cpr2l(bu bahsettiğimiz 2 biti) nin degerini degistirerek yapıyordu.. ama ben genede sizin soylediğiniz gb pr2 yi degiştirerek nasıl yapabilecegimi dusundum..

mesela ben ccpr1l(+2bit) ve ccpr2l(+2bit) degerlerini programın basında atasam ve sonsuz bir for dongusu için de ccpr1l ve ccpr2l için ortak olan pr2 degerini değiştirsem ben burda birbirinden bagımsız 2 kanalı idare etmiş olmuyorum.. 2 sini de aynı anda değiştirmiş oluyorum.

PR2 registeri formülde de açıkça görüldüğü üzere PWM frekansına etki eden bir değişken. Programın başında CCP1L ve CCP2L registerlerine sabit değer atayarak ve program içerisinde PR2 registeri ile oynayarak bu işin içinden çıkamazsın. Tabi şayet yapmak istediğin sürekli olarak FREKANSI değiştirmek değilse..!

Şimdi bu duruma istinaden yapman gerekenler şunlar olacaktır;

1-) Kullanmak istediğin frekansı belirle.

2-) TMR2, CCP1CON,CCP2CON, PR2 ve TRISC değişkenlerine gerekli değerleri ata.

3-) CCP1L, CCP2L registerleri ile DC1B1, DC1B0, DC2B1 ve DC2B0 bitlerini temizle.

4-) Ana programa geç.

Ana program içerisinde de 1. kanalı değiştirmek istersen CCP1L-DC1B1-DC1B0, 2. kanalın değerini değiştirmek istersen CCP2L-DC2B1-DC2B0 registerlerinin değerlerini değiştir. 10 Bit PWM kullandığın için bu değişkenlere değer atarken "unsigned int" kullanacaksın. Örnek teşkil etmesi açısından programda verelim tam olsun;

CCPR1L=(pwm_value >> 2) & 0xff; x=pwm_value & 0x03;
	switch (x){
			case 0:
				DC1B1=0; DC1B0=0; break;
			case 1:
				DC1B1=0; DC1B0=1; break;
			case 2:
				DC1B1=1; DC1B0=0; break;
			case 3:
				DC1B1=1; DC1B0=1; break;
			default:
				x=0; break;
			}


Kolay gelsin...
İmza.

GamzeDemir

Bilgilendirdiğiniz için cok teşekkür ediyorum.Ögrenmek istediklerim bunlardı  ;)