Adc-Hpwm algoritması

Başlatan sinasos, 15 Şubat 2016, 13:52:59

sinasos

merhabalar arkadaşlar, ADC ve HPWM konusunda Ete hocamızın ders-5 ve ders-11 konularını okudum. Takıldığım yerler oldu, sizin fikirlerinizi almak istedim.
aşağıdaki şemada görüldüğü gibi pic ADC girişine uyguladığım 4-5 adet direnç bağlı komütatörle seçim yapılan 200 Hz sinyali frekansını değiştirmeden duty sürelerini değiştirmek istiyorum. Ete hocamın derslerinde %50 olarak konu üzerinde durulmuş. ve ben de formüllerin içerisinden çıkamadığım için bir türlü halledemedim. Formülleri excell de yapmaya çalıştım olmadı. bu konuda yardımcı olabilirmisiniz ?

ete

#1
Ben olsam öye Excel tabloları ile falan uğraşmazdım. Yaptığın çalışma orada kalır. Önemli olan akılda bir şeyler kalmasıdır.
Bu işin pratik yolu şöyle;
Öncelikle işlemci frekansını belirle.
Ardından PWM frekansını belirle.
Bu iki bilgiyi kullanarak, PicMultiCalc isimli programdan PWM Calc seçeneğini seçerek açılan ekranda sol üstte yer alan işlemci frekansını belirlenen frekans olarak gir. Sonra ortada yer alan Frequency  hanesine çalışacağın PWM frekansını gir.
Diyelimki 4 Mhz işlemci frekansında 20Khz lik bir sinyal yaratacaksın. Bu değerleri yerlerine gir. Karşına çıkacak neticeler şunlar olacaktır;
Min Frekans:244,141 Hz
Max Frekans: 500 Khz
Bölme Oranı : 1/1 en büyük çözünürlükte bu bölme oranı daha ideal gözüküyor.
Çözünürlük : 8 bit olabiliyor (Normalde 10 bit dir ancak bu frekans için maksimum 8 bit olabiliyor)
Max. Duty Değerin: 200
PR2 Değeri : 49

Bu değerlere bakarak sinyalin açılması için; (Farzedelimki DUTY=100 yani %50 Duty Cycle veriyoruz)

CCP1CON%00011000
CCP1CON.4=Duty.0
CCP1CON.5=Duty.1
X=DUTY>>2
CCPR1L=X
şeklinde registerlere gerekli değerler verilir. Böylece çıkışta 20 Khz lik ve %50 duty değerine sahip sinyali görebilirsin artık.
Diyelimki %30 luk duty değerine sahip bir sinyal çıkartacağım. %100 için duty değerim max. 200 olabiliyor idi. Basit bir orantı ile ;
100 için 200
30   için   X
DUTY=(30x200)/100 şeklinde %30 duty için verilmesi gereken değeri bulmuş oluruz.
Bunu yine yukarıda açıklandığı gibi ilgili registerlere verince o sinyali çıkışta görebilirsin.

Unutma işlemci frekansı, PWM frekansı bu işte ana parametrelerdir. Bunlara göre PR2 değeri frekansı belirler. Max duty değeri ile diğer duty yüzdelerinde duty değeri ne verilecek kolaylıkla hesaplayabilirsin.

Pic Multicalc programına alışın. Pek çok yerde işinize yarayacak değerleri hesaplamanızı sağlıyor. Elinizi altında dursun sürekli olarak.

Ete

sinasos

Hocam teşekkür ederim, programı indirdim ve çalıştırdım. tıpkı söylediğiniz gibi. ancak kafama takılan soru şu oldu.
örneğin ben 180hz veya 200 hz. sabit bir frekans seçtim diyelim. picmulticalc proğramı 244 hz altında hesap yapmıyor ya !
"işlemciyi bu frekansın altında çalıştıramazsınız anlamını mı taşıyor demek oluyor ?"
çalıştırmak istediğim frekans şu anda 200 hz. bunu orantısal olarak mı hesaplamam gerekiyor ? yani picmulticalc'a 400 hz hesaplatıp çıkan değerlerin yarısını aldığımda işlem doğru oluyormu ?
birde buna örnek basit bir proğram varmıdır aklınızda ? varsa ekleyebilirmisiniz ?
selamlarımla.

ete

#3
İşlemciyi o frekansın altında çalıştırmak ile yakından uzaktan alakası yok. Min frekans , tamamen girilmiş işlmeci (Kristal) frekansı karşılığında üretilebilecek en düşük PWM frekansıdır.  Elbette min PWM frekansı tamamen İşlemci frekansına bağlıdır. Kristal frekansını 4 Mhz girince min frekans 244Hz olarak hesaplanır ve bu değerin altında PWM frekansı üretemezsin.
Ama işlemci (Kristal frekansını) 1Mhz yap bakalım min frekans ne çıkıyor.

İŞlemci frekansını 2 Mhz yaparsan min PWM frekans 122 Hz dolayında çıkarki senin işini görür. Ama bence 1 Mhz kristal kullan ve 9 bitlik bir 200 Hz sinyali elde et en güzeli. (Max Duty=320 çıkması gerek) .
Sonuç olarak düşük frekanslarda PWM üretmek istiyor isen işlemci frekansını da düşürmen gerekiyor.
Benzer şekilde yüksek kristal frekanslarında min frekans da yükselecektir.


Ete

sinasos

pardon hocam şimdi anladım  :-[  :)

sinasos

#5
hocam merhaba
dünkü bahsettiğimiz konuyu HPWM komutu ve birde komütatörle daha stabil bir şekle getirmeye çalıştım. bana %6-%8-%10 ve %13 duty gerekiyor. dört konumlu komütatörden cseçerek bunu yaptım. ancak proteusta çalışan devreyi kurduğumda bir türlü çalıştıramadım. skopta bakıyorum komütatörle seçim değişikliğim işe yaramıyor. kodlarda mı bir yanlış yaptım yardımcı olabilirmisiniz ?

'-----------------------------------------------------------------
'-----------------------------------------------------------------
@ DEVICE PIC16F877A                                                   
@ DEVICE PIC16F877A, WDT_OFF             
@ DEVICE PIC16F877A, PWRT_OFF           
@ DEVICE PIC16F877A, PROTECT_OFF       
@ DEVICE PIC16F877A, XT_OSC             
'-----------------------------------------------------------------
DEFINE OSC 4
CMCON=7
'**************** ADC chanel setting  ************************
DEFINE ADC_BITS 10    ' ADCIN   çözünürlük  (Bits)
DEFINE ADC_CLOCK 1    ' ADC clock kaynağı  (Fosc/8)
DEFINE ADC_SAMPLEUS 3 ' ADC örnekleme zamanı (uSec)
'****************HPWM PRESETİNG*********************
DEFINE CCP1_REG   PORTC    'Hpwm 1 pin port
DEFINE CCP1_BIT     2      'Hpwm 1 pin bit
'DEFINE CCP2_REG   PORTC    'Hpwm 2 pin port
'DEFINE CCP2_BIT     1      'Hpwm 2 pin bit
'******************* DEĞİŞKENLER  ********************

OPTION_REG =%00111111
TRISA =%00011111 :PORTA =0                     
TRISB =%00000000 :PORTB =0                     
TRISC =%00000000 :PORTC =0     
PORTD=0:TRISD=%00000000
ADCON1= %10001110 '
T2CON = %00000101
'PR2=155
PR2=249   'MAX DUTY DEĞERİ 1000 OLABİLİYOR FAZLASI VERİLMEMELİ

X   VAR WORD
DUTY VAR WORD
YUZDE VAR BYTE 
'---------------------------------------------------------------------------   

CCP1CON.2=1    'birinci kanalı açtık
CCP1CON.3=1


Symbol kom1=PORTA.1
Symbol kom2=PORTA.2
Symbol kom3=PORTA.3
Symbol kom4=PORTA.4

test:
for YUZDE=1 to 100  '%1 - %100 DUTY DEĞERİ VERİYORUZ
DUTY=(PR2+1)* DUTY /25
GOSUB pwm_VER
PAUSE 50
NEXT

'dUTY % LERİ %6 - %8 - %10 - %13
BASLA:

if kom1=0 then YUZDE=6
if kom2=0 then YUZDE=8 
if kom3=0 then YUZDE=10
if kom4=0 then YUZDE=13
   
DUTY=(PR2+1)* YUZDE/25 'BU FORMÜL %DUTY  ÜZERİNDEN VERİLEMSİ GEREKEN (0-1000) DUTY DEĞERİNİ HESAPLAR.
GOSUB pwm_ver   
GOTO BASLA
     

pwm_ver:
        X=DUTY
        CCP1CON.4=X.0
        CCP1CON.5=X.1
        CCPR1L=X>>2
        RETURN
       end

ete


Programı değiştirip senin kodlarını silerek üzerine yazdım. Olması gereken budur.
PR2 değerine karşılık gelen max duty değerin 1000 olarak hesaplanıyor.
Bu durumda 0 to 1023 şeklinde bir döngü kuramazsın. Maksimum değerin 1000 olacak çünki.
Duty hesaplamalarında %Duty değeri ile Registere verilmesi gereken Duty değerlerini karıştırmamak gerekir.
Döngüyü  %0 - %100 arasında yüzde değer olarak kurup buradan gerçek Duty değerini de DUTY=(PR2+1)*Yuzde_Duty/25 formülü ile hesaplayıp o değeri registere yazdınmı istediğin frekans çıkıştan çıkacaktır.

Komutatörde de aynı mantığı kullan. Komutatöre bağlı olarak Yüzde Duty değerini ver ve formülden gerçek Duty değerini hesapla ve registere yaz.

Ete

sinasos

#7
sizin önerdiğiniz picmulticalc programı ile 4 mhz kristal, kullanıp 250 hz sabit frekansta

%6   için duty cycle için pr2: 249 - duty register : 60
%8   için duty cycle için pr2: 249 - duty register : 80
%10 için duty cycle için pr2: 249 - duty register : 100
%13 için duty cycle için pr2: 249 - duty register : 130

şeklinde çıkıyor. burada pr2 sabit 249 - duty register değerinide komütatörün her bir konumunda yukarıda yazdığım şekilde olması gerekmiyor mu ?

ben test diye belirttiğim kısımda açılışta tüm duty'leri skopta görmek için koymuştum. periyotları gösterdikten sonra zaten program normal konumuna geçiyor. 1023 yazmamdaki sebep ise 10 bit çalıştığından dolayı idi.
sizin düzenlediğiniz programı aynen olduğu gibi 877 ye yükledim  komütatör yine işe yaramadı hep sabit bir duty veriyor, ama proteusta güzel çalışıyor. skop resmini aşağıya ekliyorum. komütatörün tüm konumları bu şekilde.

ete

Programda kullandığın ayarlar 1Khz lik sinyale ait. İlk mesajımda söylemiştim. İlgili parametreler;
PR2 değeri , Bölme oranı ve Duty değeri.
Sen Bölme oranını atlıyorsun. Multicalc 250 Hz için bölme oranını 1/16 veriyor. Bu durumda T2CON=%00000111 şeklinde ayarlanmalıdır. (1/1=%100, 1/4=%101 ve 1/16=%111)
Bu şekilde ancak o sinyali elde edersin.
Komutatör gerçek devrede çalışmıyor ise mutlaka bir donanım kusurun vardır. Komutatör pinlerinde Pullup direnci olması gerekir. Umarım bağlamayı unutmamışsın. Yoksa isis de çalışıyor ise gerçekte de çalışması gerekir.
Birde komutatörün yalnızca tek bir pine HIGH uygulayıp uygulamadığınada dikkat etmen gerek. Bence kontrol et.

Ete

sinasos

#9
merhaba hocam,
yardımlarınız için minnettarım. donanımsal olarak kontrol ettim bir problem görünmüyor ve hala da çalışmıyor. bu kadar basit bir devreyi nasıl çalıştıramadım bende hayret ediyorum. devre resmi ekte bakabilirseniz sevinirim.
@ DEVICE PIC16F877A                                                    
@ DEVICE PIC16F877A, WDT_OFF             
@ DEVICE PIC16F877A, PWRT_OFF           
@ DEVICE PIC16F877A, PROTECT_OFF       
@ DEVICE PIC16F877A, XT_OSC             
'-----------------------------------------------------------------
DEFINE OSC 4
CMCON=7

'****************HPWM PRESETİNG*********************
DEFINE CCP1_REG   PORTC    'Hpwm 1 pin port
DEFINE CCP1_BIT     2      'Hpwm 1 pin bit
'DEFINE CCP2_REG   PORTC    'Hpwm 2 pin port
'DEFINE CCP2_BIT     1      'Hpwm 2 pin bit
'******************* DEĞİŞKENLER  ********************

OPTION_REG =%00111111
TRISA =%00011111 :PORTA =0                     
TRISB =%00000000 :PORTB =0                     
TRISC =%00000000 :PORTC =0     
PORTD=0:TRISD=%00000000
ADCON1= 7
T2CON=%00000111 'prescaler 1/16 >>>>> 1/1=%100, 1/4=%101 ve 1/16=%111
'T2CON = %00000101
'PR2=155
PR2=249   'MAX DUTY DEĞERİ 1000 OLABİLİYOR FAZLASI VERİLMEMELİ

X   VAR WORD
DUTY VAR WORD
YUZDE VAR BYTE 
'---------------------------------------------------------------------------   

CCP1CON.2=1    'birinci kanalı açtık
CCP1CON.3=1


Symbol kom1=PORTA.1
Symbol kom2=PORTA.2
Symbol kom3=PORTA.3
Symbol kom4=PORTA.4

test:
for YUZDE=1 to 100  '%1 - %100 DUTY DEĞERİ VERİYORUZ
DUTY=(PR2+1)* DUTY /25
GOSUB pwm_VER
PAUSE 50
NEXT

'dUTY % LERİ %6 - %8 - %10 - %13
BASLA:

if kom1=1 then YUZDE=60
if kom2=1 then YUZDE=8 
if kom3=1 then YUZDE=10
if kom4=1 then YUZDE=80
   
DUTY=(PR2+1)* YUZDE/25 'BU FORMÜL %DUTY  ÜZERİNDEN VERİLMESİ GEREKEN (0-1000) DUTY DEĞERİNİ HESAPLAR.
GOSUB pwm_ver   
GOTO BASLA
     

pwm_ver:
        X=DUTY
        CCP1CON.4=X.0
        CCP1CON.5=X.1
        CCPR1L=X>>2
        RETURN

ete

İşlemciye dikkat etmeni öneririm. İsis de 16F877 kullanmışsın. Program 16F877A ya göredir.
İKisi bir birinin aynı gibi gözüksede 877 olanda komparatör yok diğerinde vardır.
Bu nedenle işlemciye göre komut vermek gerekir.

Devreye bakınca hiç bir analog pin kullanılmadığını görüyorum. Ama programda analog pin ayarlaması var. Bunlarıda iptal etmek gerekir.
Ben birazdan o programı bu söylediklerime göre yeniden değiştireceğim. Tekrar denersin.

Ete


sinasos

Günaydın hocam,
işlemci 877a kullanmıştım, akşamdan beri herşeyi denedim çalışmadı ! ancak gece aklıma işlemci geldi ve sabah erkenden gelip işlemciyi değiştirdim. tahmin ettiğim gibi de oldu, işlemci arızalı çıktı ! işlemciyi değiştirince herşey oturdu ve devre çalıştı.
Analog pinleri ben açtım çünkü AN0 girişinden voltaj ölçümü yapacağım. ayrıca size sormak istediğim şey devrede bulunan grafik lcd yi pbp ile çalıştırmam mümkün mü ? mümkünse ve sizde örneği varsa ekleyebilirmisiniz ?
selamlarımla

ete

Grafik LCD yi elbette çalıştırabilirsin ama PBP da bu çok külfetli bir iştir. Direk komutu yok her şeyi registerler ile kendin yapmak zorunda kalırsın. Bence hiç bulaşma.
Yinede bir örnek çalışa ekliyorum. Umarım yardımcı olur. Gerekli açıklama programlar içinde mevcut.

Ete

sinasos

haklısınız hocam Glcd yerine 4x20 Lcd kullanmak sanırım daha kolay ve avantajlı olacaktır. ilginize teşekkür ederim Erol hocam.
selamlarımla.

Powered by EzPortal