C

HPWM sorunu

Başlatan CaD, 19 Aralık 2012, 02:47:34

CaD

Merhaba.
Pic olarak 16f876a kullanıyorum. Motor sürücü olarak da L298N. HPWM olarak çalıştırmaya çalıştım.

MicroCode Studio'nun help kısmındaki örnek kodları da denedim ama gene olmadı. Sizce ne yapmalıyım ?

PicBasic ile denedim HPWM'i ama CCS C ile de anlatırsanız yapabilirim

Şimdiden teşekkürler.

mierdogan

Deneme yaptığını kodlarınızı da ekleyin isterseniz birde devre şemasını tabii
"Doğal bir esin arzulu bir isteğe dönüştüğünde, insan hedefine dev adımlarla ulaşır..."

ete

Derslerde bu konuyu işlemiştim ama anlamadığını varsayarak biraz daha detay vererek açıklamak istiyorum.
Her şeyin başı HPWM özelliği olan bir işlemci ile çalışmaktır.
Şimdilik tek HPWM çıkışı olan bir işlemciyi ele alalım. Mesela 16F628. İki kanallı olanlarda durum değişmiyor. Bütün iş birinci için ne yapılıyor ise aynısını ikinci kanal içinde yapmak.
Biliyorsunuz HPWM sistemi işlemcinin ana programdan bağımsız olarak geri planda işlettiği bir sistemdir. Siz yalnızca frekans ve duty değeri ile oynarsınız işlemcide geriden bunlara uygun sinyali üretip ilgili çıkışından çıkartır.
Bu işi adımlar halinde anlatacağım daha kolay anlarsın.
1. adımda sinyali aktive etmek gerekir. CCP1CON registerine %00001100 değerini vererek sinyali aktif ediyoruz. Verilen değere bakarsanız CCP1CON registerinin 2 ve 3 nolu bitlerini high yaptık.
2. Sonra çalışma frekansını belirlemeniz gerekecektir. Motor kontrol devrelerinde tercihen 5Khz ile 10Khz arasında bir frekans kullanılması uygun olur. Frekans düştükçe küçük devirlerde motordan inleme sesi gelir. Bunu önlemek için en düşük 5Khz lik bir frekans kullanılması uygun olur. Diyelimki 5Khz lik bir frekans kullanacağız. Sistem sinyali üretmek için TMR2 sayacını kullanır. Bu sayacın PR2 denilen bir Periyod registeri vardır.  Bu registere verilecek değer frekansı belirlemektedir.
Önce frekans üzerinden PR2 nasıl hesaplanır ona bakalım.
Frekans=1/Peryot (T) dir. O halde T=1/F dir. Formülde 1 değeri 1 saniyeyi göstermektedir. Us cinsinden değer 1.000.000 alınmalıdır. F değeride Hz cinsinden yazılmalıdır. Frekansımız 5000 Hz olduğuna göre peryod T=1000000/5000=200us olarak bulunur.
Data sheete bakarsanız PWM peryodu olarak şu formül verilmiştir.  PWM Period = [(PR2) +1] * 4 * Tosc * (TMR2 Bölücü Değeri). Bu formülü kullanarak PR2 değerimizi hesaplayacağız.  TMR2 bölme oranını 1/1 alalım ve Osc frekansımızda 4Mhz olsun. Tosc=1/Fosc olduğundan  T=1/4=0,25 olarak bulunur. Yerine koyarsak

200=[(PR2+1)*4*0,25
200=(PR2+1)*1 ve buradan PR2=199 olarak bulunur.
Şayet hesapladığımız PR2 değeri 255 den büyük çıkar ise bölme oranını değiştirmemiz gerektiğini anlamanız gerekir. O zaman bir alt konumda olan 1/2 bölme oranını almak gerekir. Yine sonuç 255 den büyük çıkarsa bu sefer 1/4 bölme oranını kullanmak gerekir. Her neyse devam edelim.
Programda PR2=199 değerini de vereceğiz bu değiştirilmeyen (frekans değişmedikçe) bir değer olup programın başına yerleştirilmesi gerken bir komut satırıdır.
Hesaplamada TMR2 bölme oranını 1/1 aldık dolayısıyla TMR2 control registerine bu değeride vermemiz gerekiyor.
T2CON=%00000010 şeklinde değer verdik .
Şimdi sırada Duty değerini hesaplamaya geliyor. Epeyce karmaşık bir işlem bu zira yalnızca bit sayısını hesaplamak için
Bits=Log((Fosc/Fpwm)/Log(2) şeklinde bir formül kullanmak gerekiyor. Bu nedenle bu tür işlemler için hazır program kullanmak en iyisi olmaktadır. Bu konuda PicMultiCalc.exe isimli programı öneririm. PWM seçeneğine tıkladıktan sonra frekansınızı , işlemci frekansını seçtiğiniz zaman size PR2 değerini ve Max Duty değerini vermektedir.
Bu program ile baktığımızda 5Khz için Max Duty değerinin 800 olacağını görebiliyoruz.
Toparlarsak, Programın başına;
- PR2 değerini verdik.
- T2CON registerine değer verdik.
- Sinyali hemen açacak isek CCP1CON registerinin 2 ve 3 nolu bitlerini HIGH yaptık.
Bu aşamadan sonraki işler tamamen program içinde yürütülebilir. Yapılması gereken sinyalin duty değerine bağlı olarak ilgili registerlere değer vermek şeklinde olacaktır.

PWM sinyalinin şeklini ayarlayan 10 bitlik duty değerini işlemciye bir şekilde vermemiz gerekiyor.
Bu işlem iki ayrı register kullanılarak yapılabiliyor. 10 bitlik Duty değeri 8bitlik Highbyte ve 2
bitlik LowByte olarak iki parçaya ayrılıyor. Registerinin ilk iki biti (LowByte kısmı) CCP1CON
registerinin 4 ve 5 inci bitlerine yerleştiriliyor (bunlar 10 bitlik registerin alçak bitleri (LSB)
olmaktadır) ve 10 bitlik registerin kalan 8 biti ise (HighByte) CCPR1L registerine
yerleştirilmektedir. BU hemen hemen bir çok işlemci için standarttır. İyice öğrenilmesini tavsiye
ediyorum.
Bizim örneğimizde , 5 Khz lik bir sinyal için Duty registeri maksimum 800 değerini alabilmektedir.
Bu %100 duty değerine karşılık gelmektedir.
Diyelimki PWM frekansını 5Khz olarak ayarladık ve sinyali %50 duty değeri ile çalıştıracağız.
O halde duty değeri 400 olacaktır. Bunu şimdi ilgili registerlere bölelim ve bu iş için X değişkenini
kullanalım. (X=400 ).      400 değerinin ilk 2 biti CCP1CON, 4 ve 5 nolu bitlerine yerleşecektir.
CCP1CON.4=X.0
CCP1CON.5=X.1 şeklinde bu işlemi yapabiliriz.
Geri kalan 8 bit ise CCPR1L registerine yerleşecektir. CCPR1L registeri 8 bitlik register olduğu için
X değişkeninin ilk 2 bitini kullandıktan sonra değişken bitlerini 2 bit Sağa kaydırarak kalan 8 biti
net olarak alabiliriz.
CCPR1L=X>>2 böylece MSB bitleride kendi yerine yerleşmiş olur . Bu yerleşimin hemen ardından
çıkan sinyalin Duty değeri %50 olarak görülecektir.
Konuyu toparlarsak;
Vermek istediğimiz duty değerini önce bir X değişkenine atamak gerekiyor. X=DUTY
Daha sonra X değişkeninin ilk 2 bitini CCP1CON 4 ve 5 nolu bitlerine eşitliyoruz.
CCP1CON.4=X.0
CCP1CON.5=X.1
daha sonra kalan 8 biti 2 bit sağa kaydırarak CCPR1L registerine yerleştiriyoruz. CCPR1L=X>>2

Bazen duty değeri %duty olarak da kullanılabilir. Örneğin Ben sinyale %30 luk bir duty değeri vererek çıkartmak istiyorum. Ne yapacağım.
İşte formül.   X=(PR2+1) * %duty/25
X=(200) * 30/25=240
Aynı işi orantı kullanarak da yapabilirdik. %100 değeri 800 ise %30 değeri  X=(30 * 800)/100=240 olaqrak bulunabilirdi.
Bu şekilde X değerini yukarıdaki gibi yerine koyarsak otomatikman sinyal %30 duty değeri ile ilgili pinden çıkacaktır.

CCP1CON.4=X.0
CCP1CON.5=X.1
CCPR1L=X>>2

Hepsi bu kadar . Umarım anlaşılmıştır.

Ete




CaD

Bende ki L298'in bacağı kırılmış çok dikkatli inceleyince farkettim yeni L298 takınca tekrar denicem

mustafa

Erol bey merhaba ;
Konuyu çok güzel anlatmışsınız ancak burada kafama takılan şey şu oldu ;
Doğrudan Hpwm kanal,duty,frekans komutunu vermektense bu şekilde registerlere değerler vererek  bu işlemi yapmanın amacını anlayamadım.
İyi akşamlar.

ete

İşin püf noktası çözünürlük. Bütün işlerde PWM çözünürlüğünün en yüksek değerde olması istenir. Senin verdiğin komut da çözünürlük 0-255 arasıdır. Yani 256 kademeli bi rPWM sinyali üretebilirsin.
Benim veridiğim sistemde ise bunun 4 katı fazlasını 0-1023 yani 1024 kademeli bir PWM sinyali üretirsin. Diyelimki motora hız veriyorsun. Birinde daha ayar vereyim derken maksimum hıza ulaşırsın diğerinde epeyce bir ayar aralığın olur.

Ete

mustafa

Teşekkür ederim Erol bey sorduğum sorunun karşılığını tam olarak aldım.

Powered by EzPortal