RB0 girişinden timer0 ile DUTY ölçümü

Başlatan Maxim, 17 Ekim 2007, 15:32:57

Maxim

bu konuda bilgisi tecrübesi olan varmı ?

timer0 veya timer1 ile RB0 girişinden interrupt kullanarak ,
pwm sinyalin periodunu ölçmem yeterli ,

Yani " TIME_ON " zamanı " TIME_OFF " zamanı ,

A1 = TIME_ON + TIME_OFF
DUTY =( TIME_ON / A1) * 100


Maxim

arkadaşlar harbiden kafayı yemek üzereyim ,
sanki akan sular kurudu ,
hiç anlayabildiğim örnek bulamıyorum ,
sanki kimse sinyalin periodunu ölçmemiş ,ilgilenmemiş .

nereden başlayayım ,ne yapayım ?
RB0 girişinden pulslerin yüksek ve sonrada düşük kenar sürelerini ölçmek lazım ,

arslan74

Alıntı yapılan: "maxiboost"arkadaşlar harbiden kafayı yemek üzereyim ,
sanki akan sular kurudu ,
hiç anlayabildiğim örnek bulamıyorum ,
sanki kimse sinyalin periodunu ölçmemiş ,ilgilenmemiş .

nereden başlayayım ,ne yapayım ?
RB0 girişinden pulslerin yüksek ve sonrada düşük kenar sürelerini ölçmek lazım ,

-Tam olarak neyi ölçmek istiyorsun. Periyodu mu ölçmek istiyorsun. Eğer sadece "PULS REPETİTİON TİME" ölçmek istiyorsan, onu en iyi picin timer1 veya time2'in Capure ile ölcebilirsin.

-Eğer sadece "TIME ON" süresini ölçmek istiyorsan o zaman bunu bir kaç değişik yolla ölçebilirsin.
1) RBIF (RB Port Change Interrupt Flag bit) interruptunu kullanarak RB bacaklarındaki her değişiklik için bir interrupt oluşturursun. Sonra interrupt altında kullandığın giriş baçağına bakarsın, eğer 1 ise timer1 başlatırsın. 0 olduğunda ise timer1 değerini okursun.
2) RB0 interruptunu yükselen kenar olarak ayarlarsın. 1 olduğunda interrupt oluşur. interrupt altında timer1 başlatırsın ve rb0 interruptunu düşen kenar olarak ayarlarsın ve interruptan cıkarsın. 0 olduğunda tekrar interrupt oluşur, bu interruptada timer1 değerini okursun. sonra aynı işlemleri tekrar başlatırsın.

Selamlar

Maxim

Arslan ,
valla kafam çok karıştı ,(seninle ilgisi yok )
inan 15 - 20 tane farklı çalışma yaptım ,
nedense sonuca ulaşamıyorum ,tahminim bunun nedeni interrupt üzerine tecrübem olmadığından .

Hayır, Pulse repetition time ölçmek istemiyorum ,
Time on ve Time off değerlerini ms cinsinden ayrı ayrı ölçmek istiyorum ,
zaten bu yüzde olarak duty hesabı için gereken şey .Sonrası kolay .

Normalde pulsin komutu ile zaten ölçebiliyorum ,
fakat pulsin komutu yavaş ve işleyen programı dahada yavaşlamasını sağlıyor ,üstelik girişte sinyal yoksa döngünüz iyice yavaşlıyor .

Başka bir picbasic kodundan yararlanıp ,
if`lerle wend lerle bir kod oluşturdum ,interruptsız
çok güzel çalışıyor ama dediğim gibi girişte sinyal yoksa döngünün devam etmesi lazım ,çalışan başka şeyler olduğu için .
yani eğer girişte sinyal yoksa ve "While PORTA.1=0 : Wend" komutunu kullanıyorsak orada girişe sinyal gelene kadar bekleriz .

Sonra CCP1 girişini denemeye hardware capture kullanmak için uğraştım olmadı ,olmadı derken saçma şeyler ölçtü .

Timer0 ve timer1 i kullanarak RB0 girişinden ölçmeye uğraştım .


Giriş ferkansım ,5 hz ile 1khz arasında ,düşük sayılabilecek bir değer dimi ? o yüzden timer0 yani 8 bitlik timer bu iş için uygun olabileceğini düşünmekteyim ,ama eminde değilim .

arslan74

Alıntı yapılan: "maxiboost"Arslan ,
valla kafam çok karıştı ,(seninle ilgisi yok )
inan 15 - 20 tane farklı çalışma yaptım ,
nedense sonuca ulaşamıyorum ,tahminim bunun nedeni interrupt üzerine tecrübem olmadığından .

Hayır, Pulse repetition time ölçmek istemiyorum ,
Time on ve Time off değerlerini ms cinsinden ayrı ayrı ölçmek istiyorum ,
zaten bu yüzde olarak duty hesabı için gereken şey .Sonrası kolay .

Normalde pulsin komutu ile zaten ölçebiliyorum ,
fakat pulsin komutu yavaş ve işleyen programı dahada yavaşlamasını sağlıyor ,üstelik girişte sinyal yoksa döngünüz iyice yavaşlıyor .

Başka bir picbasic kodundan yararlanıp ,
if`lerle wend lerle bir kod oluşturdum ,interruptsız
çok güzel çalışıyor ama dediğim gibi girişte sinyal yoksa döngünün devam etmesi lazım ,çalışan başka şeyler olduğu için .
yani eğer girişte sinyal yoksa ve "While PORTA.1=0 : Wend" komutunu kullanıyorsak orada girişe sinyal gelene kadar bekleriz .


Ben basic te kod yazmadığım için sana basic olarak yardım edemem. Eğer interrupt işlemlerini kontrol ve mudahele edebiliyorsan o zaman cok yapabilirsin.


Alıntı yapılan: "maxiboost"

Sonra CCP1 girişini denemeye hardware capture kullanmak için uğraştım olmadı ,olmadı derken saçma şeyler ölçtü .


Bununla ilgili yapılmış bir cok örnek kodlar var. Microchip'in kendi sitesini incele orada bulabilirsin.


Alıntı yapılan: "maxiboost"


Timer0 ve timer1 i kullanarak RB0 girişinden ölçmeye uğraştım .


Giriş ferkansım ,5 hz ile 1khz arasında ,düşük sayılabilecek bir değer dimi ? o yüzden timer0 yani 8 bitlik timer bu iş için uygun olabileceğini düşünmekteyim ,ama eminde değilim .

Burada cok büyük hatan var.

8bit timer sana en fazla 256 basamak yapar. 5hz ile 1000hz arasını 256 böldüğünda oratama 4 cıkar. Tabii uç değerlere yaklaşmak için, bu oaranı artırman gerek. 10lı basamaklar halinda ölcebilirsin. Bu durumda cok kaba bir ölçüm yapmış olursun.

16bit timerde 65535 basamak var. Eğer 16bit timer kullanırsan o zaman 1hz altında bir hassasiyetle ölçmüş olursun.

Bana göre senin yapman gerek öncelikli iş. PIC hardware iyi kullanmayı öğrenmek. Eğer iyi kullanmayı becerebildiğin zaman, sorunun cözümü sen kendin kimseye sormadanda yapabilirsin.

Selamlar

OG

interrupt kullanmana gerek varmı, lojik seviyeyi gözleyerek yapabilirsin.


TMR yi dahili komut cevrimini saymaya kurarsın, bölme oranlarını period sürelerine göre OPTION_REG ile ayarlarsın.

deger_1 ' TMR nin anlık değeri
deger_2 ' TMR nin taşma sonucu artacak deger

deger_1=0
deger_2=0

L seviye ölçecek isen
Ölçümün hemen öncesi;
TMR0=0
INTCON.2=0

while port.x=0

if INTCON.2=1 then ' Tekrar tekrar taşacak kadar süre uzun ise deger_2 word veya üçüncü, dorduncu bir sayıyı arttırır.
deger_2=deger_2+1
INTCON.2=0
endif
wend
deger_1=TMR0

elde edilen deger= (deger_2*255)+deger_1
Bu değeri dahili komut saykıl süresi ve bölme oranına göre zamana cevirirsin.

Düz bir mantık ile yapılmış döngü.

Protondan örnek;
http://www.picbasic.org/forum/showthread.php?t=8428
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

arslan74

Alıntı yapılan: "OG"interrupt kullanmana gerek varmı, lojik seviyeyi gözleyerek yapabilirsin.


TMR yi dahili komut cevrimini saymaya kurarsın, bölme oranlarını period sürelerine göre OPTION_REG ile ayarlarsın.

deger_1 ' TMR nin anlık değeri
deger_2 ' TMR nin taşma sonucu artacak deger

deger_1=0
deger_2=0

L seviye ölçecek isen
Ölçümün hemen öncesi;
TMR0=0
INTCON.2=0

while port.x=0

if INTCON.2=1 then ' Tekrar tekrar taşacak kadar süre uzun ise deger_2 word veya üçüncü, dorduncu bir sayıyı arttırır.
deger_2=deger_2+1
INTCON.2=0
endif
wend
deger_1=TMR0

elde edilen deger= (deger_2*255)+deger_1
Bu değeri dahili komut saykıl süresi ve bölme oranına göre zamana cevirirsin.

Düz bir mantık ile yapılmış döngü.

Protondan örnek;
http://www.picbasic.org/forum/showthread.php?t=8428

Sizin yazılımla yapmaya çalıştığınız uygulamayı timer1 zaten sahib. Yazdığınız bu kodlara hiç gerek yok. timer1 sonucu direkt 16bit olarak veriyor.

Ama anladığım kadarıyla arkadaşın sorunu, bu ölçümü yapmak değil, PIC aynı zamanda başla işlerinde yapmasını istiyor. Eğer sinyal girişini sürekli kontrol edeerse. O zaman başka işleri yapmasına imkan yok. Bu durumda mecburen interrupt kullanması gerek.

Selamlar

Maxim

Aslan usta ,
tam ben yazacaktım sen önce davrandın ,
evet yapılan başka işler var ,sinyali beklersem döngü duruyor olduğu yerde ,

şimdi gene birşeyler yapmaya çalışıyorum ilerleyince buraya koyarım ,

neden timer0 diye tutturuyorum ?
çünkü çoook önce gene böyle bir çalışma yapmaya kalkmıştım ,
hatta 1 seneden fazla oldu galiba ,zaten içimde ukte kaldı bu olay .

elimde hazır yapılmış bir devre var ,
adam 16F84A kullanmış ,10mhz ,RB0 girişinden mis gibi duty ölçümü yapıyor ,16F84 de sadece timer0 var ,yani 8 bitle işi bitirmiş .

OG

Alıntı YapSizin yazılımla yapmaya çalıştığınız uygulamayı timer1 zaten sahib. Yazdığınız bu kodlara hiç gerek yok. timer1 sonucu direkt 16bit olarak veriyor.
OK, mantığını anlatmak için TMR0 örneği verdim.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

Maxim

basamak basamak gitmek en mantıklısı galiba ,

önce bana bu iş için gerekli olan tanımlamaları yaptım ,
bir bakabilirmisiniz ?
bu kullandığım tanımlamalar dışında bana gerekli olabilecek birşey varmı ?
yanlışım varmı ?
slm

EDIT1:UPDATE EDİLDİ
EDIT2:UPDATE EDİLDİ
EDIT3:UPDATE EDİLDİ

'Amaç :
'RB0 girişinden interrupt kullanarak 5hz-1khz aralığındaki sinyali,
'8 bitlik Timer0 kullanarak T_on ve T_off değerini ölçmek ve duty değerini hesaplamak.
'Bu işlem sırasında ekranda sayıcınında çalışıyor olması lazım.
'
'
'        T_on
'        _____                    _____
'       |     |                  |     |
'       |     |                  |     |
'       |     |      T_off       |     |
'_______|     |__________________|     |_______
'
'

Device 16F628A
XTAL 4

Config INTRC_OSC_NOCLKOUT,WDT_OFF,PWRTE_ON,LVP_OFF,CP_OFF,MCLRE_OFF,BODEN_ON
ALL_DIGITAL = TRUE
CMCON=7

LCD_DTPIN PORTA.0     
LCD_RSPIN PORTA.7 
LCD_ENPIN PORTA.6 
LCD_INTERFACE 4 
LCD_LINES 4

Print At 1,8, "Test1"
DelayMS 500
Cls

TRISA = %00100000
TRISB = %00000001

Dim T_ON As Word
Dim T_OFF As Word
Dim say As Byte

Input PORTB.0

Symbol INTEDG = OPTION_REG.6        'RB0 INT EDGE SELECT BIT ,1=Rising 0=Falling 

Symbol PS0 = OPTION_REG.0           ' Prescaler ratio bit-0 
Symbol PS1 = OPTION_REG.1           ' Prescaler ratio bit-1 
Symbol PS2 = OPTION_REG.2           ' Prescaler ratio bit-2 

Symbol GIE = INTCON.7				'Global Interrupt Enable-Disable Bit

Symbol INT0IE =INTCON.4             'RB0/INT EXT enable bit
Symbol INT0IF =INTCON.1             'RB0/INT EXT flag bit

Symbol T0IE = INTCON.5		         'TMR0 overflow enable bit
Symbol TMR0IF = INTCON.2		     'TMR0 overflow flag bit

Clear
Clear T_ON
Clear T_OFF
Clear say

'---------Timer0 prescale --------------
PS0 = 1                             ' Set the prescaler 
PS1 = 1                             ' to increment TMR0 
PS2 = 1                             ' every 1:256 instruction cycle

'   PS0 PS1 PS2
'    0   0   0  = 1 : 2                       
'    0   0   1  = 1 : 4                        
'    0   1   0  = 1 : 8                        
'    0   1   1  = 1 : 16                      
'    1   0   0  = 1 : 32                     
'    1   0   1  = 1 : 64                    
'    1   1   0  = 1 : 128    
'    1   1   1  = 1 : 256  
'-----------------------------------------       


on_interrupt GoTo int


INTEDG = 0     ' interrupt on on falling edge
INT0IE = 1     ' enable portb.0 interrupts
INT0IF = 0     ' clear the flag to start with
GIE = 1        ' enable global interrupts

GoTo Main

Disable

int:'------------------------

Clear TMR0               
T0IE = 1                
T_ON = TMR0
Print At 3,1,"T_on:",Dec T_ON,"    "

INTEDG = 0
TMR0IF = 0
INT0IF = 0
T0IE = 0

Clear TMR0                 
T0IE = 1                
T_OFF = TMR0
Print At 4,1,"T_off:",Dec T_OFF,"    "               

Resume
Enable


Main:'-----------------------
say = say +1
If say = 250 Then
say = 0
EndIf

Print At 1,1,"Count:",Dec say,"  "  'sadece 0 dan 255 3 kadar sayar,başka işi yoktur.
  
DelayMS 200                         
GoTo Main
'----------------------------

Maxim


Maxim

sanırım aslanın dediği gibi 8 bitlik timer ile ms cinsinden bu ölçüm mümkün değil ,hatta örnek 4.38 ms nasıl ölçeceğiz ?
tabiki ölçemeyiz ,

ama yanlış yolda olduğumu anladım ,
ms olarak görmemize gerek yokki ,
bana duty lazım ,
herhangi bir değerde açık ve kapalı kalma süresi yeterli ,
sonuçta gerçek duty çıksında gerisi önemli değil .

Maxim

Sormak istediğim birşeyler var ,

1-timer0 prescale ile watch dog timerın ne gibi bir ilişkisi var ?
wdt yi açınca işlemci neden sürekli reset atar ?

2-yukarıdaki kodda interrupt oluştuktan sonra program neden en başa döner ? kaldığı yerden devam etmesi gerekmezmi ?

FUNKY

maxiboost bu projeni bitirip netice aldınmı ? uzun zaman olmuş ama..

perojen ilgimi çekti   kodlarını yayınlarsan  memnun olurum....

Maxim

bu bir proje değildi zaten ,
lanet olsun kafayı yedim bıraktım bunu ben .