0

Çift kesme (RB0 ve Timer1) Kullanımı

Başlatan 0nur, 11 Eylül 2013, 12:28:30

0nur

Şimdi bahsettiğiniz işlemi yaptım okuduğum değer 5 rpm diğeri ile aynı sonucu elde ediyorum.


Device 16F877   
Config hs_OSC , WDT_OFF, PWRTE_ON,  BODEN_OFF , LVP_OFF, CP_OFF 

Declare Xtal 20

'============================== LCD TANIMLAMALARI=====================================;

Declare LCD_DTPin = PORTD.4
Declare LCD_RSPin = PORTE.0
Declare LCD_ENPin = PORTE.1
Declare LCD_Interface =  4 ' 4-bit Interface
Declare LCD_Lines =  4
Declare LCD_Type  = alpha
Declare LCD_CommandUs = 2000
Declare LCD_DataUs = 50
All_Digital TRUE
Cls

'==========================================================================================================;           
'=====================================KESME TANIMLAMALARI ================================;             


On_Hardware_Interrupt GoTo bak              'Software int. oluştuğunda INT etiketine git.

OPTION_REG.6=0
T1CON=%00110001    ' -------->>>  |  DİSABLE   |   DİSABLE   |   PS1    |  PS0   |   T1OSCEN  |   T1SYNC   |  TMR1CS   |   TMR1ON   |
         
Symbol INTF = INTCON.1      'RB0 KESME BARAĞI
Symbol INTE = INTCON.4      'RB0 KESME YETKİ
Symbol GIE = INTCON.7       'GLOBAL INT. YETKI
Symbol PEIE=   INTCON.6
Symbol TMR1E=  T1CON.0      ' TMR1 ENABLE BİTİ
Symbol TMR1IF= PIR1.0       ' TMR1 TAŞMA BAYRAĞI
Symbol TMR1IE= PIE1.0


TMR1IE=1 ' TMR1 AŞIMI KESME OLUŞTURMA AKTİF ETME BİTİ
TMR1IF=0 ' TMR1 AŞIM KESME BAYRAĞI
PEIE=1 
INTE=1                      'RB0 Kesmesi aktif
GIE=1                       'Aktif O an Tüm kesmelere Yetki ver     


TMR1H=$0b
TMR1L=$dc

'==========================================================================================================;
'=====================================PWM TANIMLAMALARI ================================; 

CCP1CON=%00001100
Declare CCP1_Pin = PORTC.2   ' Select HPWM port and bit for CCP1 module. i.e. channel 1
Declare CCP2_Pin = PORTC.1   ' Select HPWM port and bit for CCP2 module. i.e. channel 2     
   
'==========================================================================================================;
'============================= GİRİŞ - ÇIKIŞ VE DEĞİŞKENLER ==========================;
     
Input PORTB             
TRISC=0
Dim TICK As Word   
Dim sayac As Word   
             
Dim sure As Word
Dim rpm    As Word
Dim fr   As Word


Symbol mi=PORTC.0
Symbol mg=PORTC.1
Symbol led=PORTC.3
Symbol led2=PORTC.4       
Clear



'==========================================================================================================;
'============================= ANA DÖNGÜ ==============================================;
HPWM 1,128,1000
mi=1
mg=0


basla:

fr=(120*sayac)/(16)
rpm=fr/485

Print At 1,1,"RB0 KESMESI: ",@TICK,"  "
Print At 2,1,"Motor ",@fr," dev/sn "
Print At 3,1,"Saft  ",@rpm," dev/dk "
'Print At 4,1,"Fr: ",@FR,"     "



GoTo basla                 
               
'============================================== KESME ======================================================       
   



Disable

Disable
bak:
Context Save
If TMR1IF=1 Then
TMR1H=$0b
TMR1L=$dc
TMR1IF=0
Inc sure

If sure=10 Then
   sayac=TICK   'sayac ve TICK word tipi olmalıdır , TICK gelen encoder puls adedidir
   TICK=0
   sure=0
EndIf

GoTo CIK
EndIf

'program bu satıra gelebiliyorsa oluşan kesme PORTB.0 kesmesidir. Orada birdaha if INTF=1 diye komut kullanmak gerekmez.
TICK=tick+1
INTF=0 

CIK:
Context Restore
Return




0nur

#16
Maksimum hızda okumam değer 24 rpm iken 6 rpm okumamın sebebi nedir ? Normalde encoder çıkışı 3kHz yani 3000*60=180 000 dev/dk
motor devri ise 180000/16=11250 rpm , redüktör çıkışıda 11250/485=23,19 yaklaşık 24 rpm gibi bir değer olması gerekiyor. Benim okuduğum değerler ise Motor devri 2553 rpm , redüktör çıkışı 5 rpm olarak elde ediyorum.

ete

Şayet motoru PWM sinyali ile sürüyor isen programa göre PWM için %50 Duty kullanıyorsun. Bu maksimum devir sayısının yarısı demektir. Diğer taraftan senin devir hesabını yine anlamadım.
SAYAC okunan puls sayısı, Bunu 16 ya bölünce (encoder tur başına 16 puls üretiyor sanırım) devir'i bulursun.
Bulunan devir Dev/sn dir. Bunu 60 ile çarparsan Dev/dak olarak bulursun. Sen 120 ile neden çarptın ?
AYrıca motorun redüksiyon oranı 1/485 midir?
Daha öncede sormuştum encode redüktör milindemi motor milindemi diye cevap vermedim. benim gördüğüm motorlarda hep motor arka tarafına bağlanıyor yani motor milinde oluyor. Dolayısıyla redüksiyon oranını kullanman gerekmiyor. Ama seninki farklı olabilir tabiiki.

Programında SURE değişkenin Byte cinsinden olsa daha uygun olur.

Ete

0nur

#18
Orada sizin sure=10 500msnlik gecikme için düşündüğümde sure=2 ye cevirmiştim ve en son sure=2 ibaresini kaldırarak anlık okumayı yapmak için 2  ile çarptım (60x2=120). Değişen birşey olmadı. Encoder+motor+redüktör tek modül halinde. Encoder motor miline bağlı. Dolayısıyla gelen palsi 16 ya bölüp motor devrini, motor devrini 485 e bölerek de şaft devrini buluyorum. Motor 6 voltluk bir motor. Elimde 11.1 voltluk lipo var. Maksimum değeri elde etmek için hpwm ile 2 ye böldüm.

Programın son hali aşağıda. Fakat dediğim gibi motor devri olarak 11250 rpm redüktör şaft devri olarakta 24 rpm elde etmem gerekirken, şuan motor devri 19560 şaft devride 40 rpm okuyorum.


Device 16F877   
Config hs_OSC , WDT_OFF, PWRTE_ON,  BODEN_OFF , LVP_OFF, CP_OFF 

Declare Xtal 20

'============================== LCD TANIMLAMALARI=====================================;

Declare LCD_DTPin = PORTD.4
Declare LCD_RSPin = PORTE.0
Declare LCD_ENPin = PORTE.1
Declare LCD_Interface =  4 ' 4-bit Interface
Declare LCD_Lines =  4
Declare LCD_Type  = alpha
Declare LCD_CommandUs = 2000
Declare LCD_DataUs = 50
All_Digital TRUE
Cls

'==========================================================================================================;           
'=====================================KESME TANIMLAMALARI ================================;             


On_Hardware_Interrupt GoTo bak              'Software int. oluştuğunda INT etiketine git.

OPTION_REG.6=0
T1CON=%00110001    ' -------->>>  |  DİSABLE   |   DİSABLE   |   PS1    |  PS0   |   T1OSCEN  |   T1SYNC   |  TMR1CS   |   TMR1ON   |
         
Symbol INTF = INTCON.1      'RB0 KESME BARAĞI
Symbol INTE = INTCON.4      'RB0 KESME YETKİ
Symbol GIE = INTCON.7       'GLOBAL INT. YETKI
Symbol PEIE=   INTCON.6
Symbol TMR1E=  T1CON.0      ' TMR1 ENABLE BİTİ
Symbol TMR1IF= PIR1.0       ' TMR1 TAŞMA BAYRAĞI
Symbol TMR1IE= PIE1.0


TMR1IE=1 ' TMR1 AŞIMI KESME OLUŞTURMA AKTİF ETME BİTİ
TMR1IF=0 ' TMR1 AŞIM KESME BAYRAĞI
PEIE=1 
INTE=1                      'RB0 Kesmesi aktif
GIE=1                       'Aktif O an Tüm kesmelere Yetki ver     


TMR1H=$0b
TMR1L=$dc

'==========================================================================================================;
'=====================================PWM TANIMLAMALARI ================================; 

CCP1CON=%00001100
Declare CCP1_Pin = PORTC.2   ' Select HPWM port and bit for CCP1 module. i.e. channel 1
Declare CCP2_Pin = PORTC.1   ' Select HPWM port and bit for CCP2 module. i.e. channel 2     
   
'==========================================================================================================;
'============================= GİRİŞ - ÇIKIŞ VE DEĞİŞKENLER ==========================;
     
Input PORTB             
TRISC=0
Dim TICK As Word   
Dim sayac As Word   
             
Dim sure As Byte
Dim rpm    As Word
Dim fr   As Word


Symbol mi=PORTC.0
Symbol mg=PORTC.1
Symbol led=PORTC.3
Symbol led2=PORTC.4       
Clear



'==========================================================================================================;
'============================= ANA DÖNGÜ ==============================================;
HPWM 1,128,1000
mi=1
mg=0


basla:

fr=(60)*((sayac)/16)
rpm=fr/485

Print At 1,1,"RB0 KESMESI: ",@TICK,"  "
Print At 2,1,"Motor ",@fr," dev/dk "
Print At 3,1,"Saft  ",@rpm," dev/dk "
'Print At 4,1,"Fr: ",@FR,"     "



GoTo basla                 
               
'============================================== KESME ======================================================       
   




Disable
bak:
Context Save
If TMR1IF=1 Then
TMR1H=$0b
TMR1L=$dc
TMR1IF=0
Inc sure

If sure=10 Then
   sayac=TICK   'sayac ve TICK word tipi olmalıdır , TICK gelen encoder puls adedidir
   TICK=0
   sure=0
EndIf

GoTo CIK
EndIf

Inc TICK
INTF=0 

CIK:
Context Restore
Return


ete

Tersten başa doğru giderek bir hesap yapalım istersen.
Okunması gereken şaft devri=24
O halde motor mili devri = 24 * 485= 11.640 dev/dak
Saniye cinsinden motor devri= 11.640/60=194 dev/sn
Bunun 1 sn deki puls karşılığı = 194 * 16 = 3104 puls/sn.
Şimdi bulduklarımızı irdeleyelim. Puls sayacı (SAYAC) 1 sn de 3104 puls sayması gerekir. Bunu sen hesaplarında kullanıp ,
FR=(60 * SAYAC)/16 =60 x 3104 / 16=11.640 olarak hesaplaman gerekir. Ancak 60x3104 sonucu 16 biti aşmaktadır. Muhtemelen sorun buradan kaynaklanıyor.  Sira 60 x 3014=186240 etmektedir. Bu nedenle taktik değiştirmek gerekecektir.
TEMP AS WORD şeklinde bir değişken tanımla ve hesaplamaları aşağıdaki şekilde yap
TEMP=SAYAC * 60
FR=DIV32 16
RPM=FR/485

veya şu şekilde de yapabilirsin
FR= SAYAC */ 960
RPM=FR/485

Burada */ işlemi nin karşılığı şöyledir. SAYAC değeri 960 ile çarpılıp 256 ya bölünecektir. Zira bu işaret ile yaılan hesaplamada basic  matematiği  SAYAC değerini 960 ile 32 bit olarak çarpar ve sonucu 256 ya bölerek sana verir.
Bu nedenle bende şöyle yaptım 60/16=3,75 bunu 256 ile çarparak 960 değerini buldum. Böylece işlem 32 bit üzerinden yapılacağı için 16 bitin aşılması söz konusu olmayacaktır. Her ikisinide dene istersen.

Ete


0nur

#20
Bahsettiğiniz işlemi öncesinde

fr=(60)*((sayac)/16)
rpm=fr/485

şu şekilde yaparak gerçekleştirdim. Sizin verdiğiniz komutlarla aynı sonucu elde ettim. Ayrıca zannedersem motorda ölçtüğüm değerlerde bir sıkıntı yok, denemeyi kabaca şu şekilde gerçekleştirdim;

motorun ucuna bir setiskur sıktım ve parmağıma ilk temas ettiği anda kronometreyi çalıştırdım, setiskur parmağımla aynı konuma geldiği her anda sayarak 1 dk sonundaki değere baktığımdada 40 rpm değerini elde ettim. Tabiki osilaskopta bunu incelemek en doğrusu fakat şuan için öyle bir imkanım yok.

Burada yön tayini için diğer kanalıda kullanmam gerekiyor o kısmı eklemek istersem kesme içerisinde mi bir denetleme yapmam gerekecek?

Ayrıca timer1 ve rb0 ile yapılan işlemin aynısı protonun counter komutu ilede gerçekleştirdim. Aşağıda her iki kodu da paylaşıyorum bu konu ile ilgili çalışmalarda faydalı olabilir.


Kod: Tmr1 ve Rb0

Device 16F877   
Config hs_OSC , WDT_OFF, PWRTE_ON,  BODEN_OFF , LVP_OFF, CP_OFF 

Declare Xtal 20

'============================== LCD TANIMLAMALARI=====================================;

Declare LCD_DTPin = PORTD.4
Declare LCD_RSPin = PORTE.0
Declare LCD_ENPin = PORTE.1
Declare LCD_Interface =  4 ' 4-bit Interface
Declare LCD_Lines =  4
Declare LCD_Type  = alpha
Declare LCD_CommandUs = 2000
Declare LCD_DataUs = 50
All_Digital TRUE
Cls

'==========================================================================================================;           
'=====================================KESME TANIMLAMALARI ================================;             


On_Hardware_Interrupt GoTo bak              'Software int. oluştuğunda INT etiketine git.

OPTION_REG.6=0
T1CON=%00110001    ' -------->>>  |  DİSABLE   |   DİSABLE   |   PS1    |  PS0   |   T1OSCEN  |   T1SYNC   |  TMR1CS   |   TMR1ON   |
         
Symbol INTF = INTCON.1      'RB0 KESME BARAĞI
Symbol INTE = INTCON.4      'RB0 KESME YETKİ
Symbol GIE = INTCON.7       'GLOBAL INT. YETKI
Symbol PEIE=   INTCON.6
Symbol TMR1E=  T1CON.0      ' TMR1 ENABLE BİTİ
Symbol TMR1IF= PIR1.0       ' TMR1 TAŞMA BAYRAĞI
Symbol TMR1IE= PIE1.0


TMR1IE=1 ' TMR1 AŞIMI KESME OLUŞTURMA AKTİF ETME BİTİ
TMR1IF=0 ' TMR1 AŞIM KESME BAYRAĞI
PEIE=1 
INTE=1                      'RB0 Kesmesi aktif
GIE=1                       'Aktif O an Tüm kesmelere Yetki ver     


TMR1H=$0b
TMR1L=$dc

'==========================================================================================================;
'=====================================PWM TANIMLAMALARI ================================; 

CCP1CON=%00001100
Declare CCP1_Pin = PORTC.2   ' Select HPWM port and bit for CCP1 module. i.e. channel 1
Declare CCP2_Pin = PORTC.1   ' Select HPWM port and bit for CCP2 module. i.e. channel 2     
   
'==========================================================================================================;
'============================= GİRİŞ - ÇIKIŞ VE DEĞİŞKENLER ==========================;
     
Input PORTB             
TRISC=0
Dim TICK As Word   
Dim sayac As Word   
       
Dim sure As Byte
Dim rpm    As Word
Dim fr   As Word


Symbol mi=PORTC.0
Symbol mg=PORTC.1
Symbol led=PORTC.3
Symbol led2=PORTC.4       
Clear



'==========================================================================================================;
'============================= ANA DÖNGÜ ==============================================;
HPWM 1,128,1000
mi=1
mg=0

Print At 1,1,"    RB0 VE TMR1  "


basla:

fr=(60)*((sayac)/16)
rpm=fr/485



Print At 2,1,"Motor ",@fr,
Print At 2,13,"dev/dk"
Print At 3,1,"Saft  ",@rpm,
Print At 3,13,"dev/dk"
Print At 4,1,"RB0 KESMESI: ",@TICK,"  "



GoTo basla                 
               
'============================================== KESME ======================================================       
   




Disable
bak:
Context Save
If TMR1IF=1 Then
TMR1H=$0b
TMR1L=$dc
TMR1IF=0
Inc sure

If sure=10 Then
   sayac=TICK   'sayac ve TICK word tipi olmalıdır , TICK gelen encoder puls adedidir
   TICK=0
   sure=0
EndIf

GoTo CIK
EndIf

Inc TICK
INTF=0 

CIK:
Context Restore
Return





Kod: Counter Komutu

Device 16F877   
Config hs_OSC , WDT_OFF, PWRTE_ON,  BODEN_OFF , LVP_OFF, CP_OFF 
Declare Xtal 20

'============================== LCD TANIMLAMALARI=====================================;

Declare LCD_DTPin = PORTD.4
Declare LCD_RSPin = PORTE.0
Declare LCD_ENPin = PORTE.1
Declare LCD_Interface =  4 ' 4-bit Interface
Declare LCD_Lines =  4
Declare LCD_Type  = alpha
Declare LCD_CommandUs = 2000
Declare LCD_DataUs = 50
All_Digital TRUE
Cls


'==========================================================================================================;
'=====================================PWM TANIMLAMALARI ================================; 

OPTION_REG.6=0
CCP1CON=%00001100
Declare CCP1_Pin = PORTC.2   ' Select HPWM port and bit for CCP1 module. i.e. channel 1
Declare CCP2_Pin = PORTC.1   ' Select HPWM port and bit for CCP2 module. i.e. channel 2     
   
'==========================================================================================================;
'============================= GİRİŞ - ÇIKIŞ VE DEĞİŞKENLER ==========================;
     
Input PORTB             
TRISC=0
Dim T1 As Word       
Dim Sayi  As Word         
Dim T2  As Word         
Dim a  As Word         
Dim hiz  As Word         


Symbol mi=PORTC.0
Symbol mg=PORTC.1
Symbol led=PORTC.3
Symbol led2=PORTC.4       
Symbol enc=PORTB.0       
Symbol c=PORTB.1     

Clear



'==========================================================================================================;
'============================= ANA DÖNGÜ ==============================================;

mi=0
mg=1

Print At 1,1,"  COUNTER KOMUTU   "


basla:

T1=Counter enc,1000


a=(T1/16)*(60)

hiz=a/485

If c=0 Then
HPWM 1,128,1000
EndIf

If c=1 Then
HPWM 1,5,1000
EndIf



Print At 2,1,"MOTOR: ",@a,
Print At 2,16,"RPM"
Print At 3,1,"SAFT : ",@hiz,
Print At 3,16,"RPM"


GoTo basla                 
               
'============================================== KESME ======================================================       
   


0nur

Yön tayini konusunda Rb0 kesmesi yerine B portundaki değişimleri algılayacak kesmeyi kullanmak daha mantıklı olacak gibi geliyor.Fakat kafama takılan nokta tick sayısını şuan her kesmeye girdiğinde arttırıyoruz, diğer türlü her kesmeye girdiğinde yön durumuna baktırıp arttır ve azaltma fonksiyonunu kesme döngüsünün içerisine mi yazmamız lazım?

Bu konunun sonrasında PİD üzerine çalışacağım. Amacım motorun ucunda değişken yük olmasına rağmen sabit torku elde etmek.

ete

Elbette kesme içinde yapman gerekiyor. Yon bilgisi "1" ise artırma "0" ise eksiltme yapman gerekir.
Ete

0nur

#23
Merhaba,

Motorun çıkışı

A B
0  5
5  5
5  0
0  0

ters yönde ise

A B
5  0
5  5
0  5
0  0

şeklinde geliyor.

Şuan Counter komutu ile osilaskoptanda karşılaştırarak birebir frekansı okuyorum. Fakat yön bilgisini alma hususunda bahsettiğiniz xor işlemini burada nasıl kullanacağım onu anlayamadım. Yukarıdaki ilk kombinasyon kısmına bakarsak;


A B
0  5 =1
5  5 =0
5  0 =1
0  0 =0

1-0-1-0 okumuş oluyorum.Tersi durumda


A B
5  0 =1
5  5 =0
0  5= 1
0  0= 0

1-0-1-0 okumuş oluyorum.Diğer konularda A nın ilk okumadaki değeri ve Bnin 2. okumadaki değerini xor ladığımızda yön tayini yapabiliriz demişsiniz. Çapraz olarak baktığımızda dediğiniz gibi yön değerine erişebiliyorz fakat ilk okuma ve ikinci okumayı nasıl yapabiliriz?




ete

Bir defa verdiğin çıkışlar yanlış. Bir yönde doğru olabilir ama tersi yönde bence yanlış.
Encoder çıkışları ve yön tayini aşağıdaki resme göre olmalıdır.


Yön tayini ve değer artırma yada eksiltme için mutlaka encoderin konum değiştirmesi gerekir. Bu nedenle üst üste iki okuma yapılmalıdır. İkinci okumada alınan değer birinci ile aynı ise değişik değer gelinceye kadar okuma devam etmelidir.
Böylece elinde iki farklı değer olur. Örnek verecek olursak,
ILK okuma=%00
Ikınci Okuma=%01 şeklinde olacaktır.
Ikıncinin ilk biti ("0") ile birincinin 2 ci biti  ("1") XOR yapılırsa yön bilgisini verecektir. Buradaki şekle göre 1 XOR 0=1 dir

Encoder ters yöne döner ise ;
Birinci Okuma %00
İkinci Okuma=%10
Yön=0 XOR 0=0 şeklinde bulunacaktır.

Ete

0nur

Merhaba,

Konuyu buraya yazdıktan hemen sonra timer1 ve rb0 kesme programında bahsettiğiniz işlemi şu şekilde gerçekleştirdim ve şuan yön bilgisinide alabiliyorum;

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 24.9.2013                                         *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************

Device 16F877   
Config hs_OSC , WDT_OFF, PWRTE_ON,  BODEN_OFF , LVP_OFF, CP_OFF 

Declare Xtal 20

'============================== LCD TANIMLAMALARI=====================================;

Declare LCD_DTPin = PORTD.4
Declare LCD_RSPin = PORTE.0
Declare LCD_ENPin = PORTE.1
Declare LCD_Interface =  4 ' 4-bit Interface
Declare LCD_Lines =  4
Declare LCD_Type  = alpha
Declare LCD_CommandUs = 2000
Declare LCD_DataUs = 50
All_Digital TRUE
Cls

'==========================================================================================================;           
'=====================================KESME TANIMLAMALARI ================================;             


On_Hardware_Interrupt GoTo bak              'Software int. oluştuğunda INT etiketine git.

OPTION_REG.6=0
T1CON=%00110001    ' -------->>>  |  DİSABLE   |   DİSABLE   |   PS1    |  PS0   |   T1OSCEN  |   T1SYNC   |  TMR1CS   |   TMR1ON   |
         
Symbol INTF = INTCON.1      'RB0 KESME BARAĞI
Symbol INTE = INTCON.4      'RB0 KESME YETKİ
Symbol GIE = INTCON.7       'GLOBAL INT. YETKI
Symbol PEIE=   INTCON.6
Symbol TMR1E=  T1CON.0      ' TMR1 ENABLE BİTİ
Symbol TMR1IF= PIR1.0       ' TMR1 TAŞMA BAYRAĞI
Symbol TMR1IE= PIE1.0


TMR1IE=1 ' TMR1 AŞIMI KESME OLUŞTURMA AKTİF ETME BİTİ
TMR1IF=0 ' TMR1 AŞIM KESME BAYRAĞI
PEIE=1 
INTE=1                      'RB0 Kesmesi aktif
GIE=1                       'Aktif O an Tüm kesmelere Yetki ver     


TMR1H=$0b
TMR1L=$dc

'==========================================================================================================;
'=====================================PWM TANIMLAMALARI ================================; 

CCP1CON=%00001100
Declare CCP1_Pin = PORTC.2   ' Select HPWM port and bit for CCP1 module. i.e. channel 1
Declare CCP2_Pin = PORTC.1   ' Select HPWM port and bit for CCP2 module. i.e. channel 2     
   
'==========================================================================================================;
'============================= GİRİŞ - ÇIKIŞ VE DEĞİŞKENLER ==========================;
     
Input PORTB     
     
Input PORTD         
TRISC=0
Dim T1 As Word   
Dim sayac As Word   
       
Dim sure As Byte

Dim redhiz  As Dword         
Dim motorhiz  As Dword
Dim redtam  As Word         
Dim redonda  As Word
Dim mtam As Dword
Dim monda As Dword
Dim yon As Bit
Dim a As Bit
Dim b As Bit
Dim t11 As Byte
Dim deger As Byte

Symbol yonbilgi=PORTD.1
Symbol mi=PORTC.0
Symbol mg=PORTC.1
Symbol led=PORTC.3
Symbol led2=PORTC.4

Symbol enc=PORTB.0       
Symbol enc2=PORTB.1       
Clear



'==========================================================================================================;
'============================= ANA DÖNGÜ ==============================================;
HPWM 1,255,1000

Print At 1,1,"    RB0 VE TMR1  "
mi=0
mg=1



basla:
motorhiz=((sayac)*3.75)*100       '60/16=3.75
mtam=motorhiz/100
monda=motorhiz//100
redhiz=(sayac*0.7732)             '(60/(485*26))*100~= 0.7732
redtam=redhiz/100
redonda=redhiz//100


Print At 2,1,"MOTOR: ",@mtam,".",Dec2 monda,
Print At 2,16,"RPM"
Print At 3,1,"SAFT : ",@redtam,".",Dec2 redonda,
Print At 3,16,"RPM"
Print At 4,1,"FREQ : ",@sayac,
Print At 4,13,"hz"



If yon=1 Then
Print At 4,16,"Cw ",
Else
Print At 4,16,"Cww",
EndIf






GoTo basla                 
               
'============================================== KESME ======================================================       

Disable
bak:
Context Save
If TMR1IF=1 Then
TMR1H=$0b
TMR1L=$dc
TMR1IF=0
Inc sure

If sure=10 Then
   sayac=T1   'sayac ve TICK word tipi olmalıdır , TICK gelen encoder puls adedidir
   T1=0
   sure=0
EndIf


GoTo CIK
EndIf
Inc T1

t11=T1//2

If t11=1 Then
a=enc
EndIf
If t11=0 Then
b=enc2
EndIf
yon=a^b



INTF=0 

CIK:
Context Restore
Return




Eklediğim ise şu oldu;

ilk ve ikinci okumayı elde etmek için 2 ye göre mod aldım. Kalan sayı ya 1 yada sıfır yani ya ilk yada 2. okuma yapacağıma karar verdim.

t11=T1//2

If t11=1 Then
a=enc
EndIf
If t11=0 Then
b=enc2
EndIf
yon=a^b

kalan 1 ise encoder a kanalını a ya yaz , kalan 0 ise encoderin b kanalını b ye yaz dedim ve xor ladığımda yön bilgisini elde ettim. Fakat bunu counter komutu ile yaptığımda sonuca ulaşamadım sebebide 1 snde kaç tick geliyorsa onu sayıyor ondan dolayı diye düşünüyorum.

Şimdi bu sisteme PİD kontrolu uygulayarak istediğim hızda motoru sabitlemek için şu mantığı nasıl programa dökebilirim;

girdi hızım 10 rpm olduğunu varsayarsak ben hpwm ile hız kontrolünüde gerçekleştiriyorum. Motor zorlandı ve dolayısıyla devri düştü fakat ben bunu hpwm değeri ile mevcut zorlama altında tekrar 10 rpme çekmek istiyorum. Burada encoderdan aldığım devir bilgisi ile mevcut girdiyi karşılaştırıp nasıl bir katsayı ile işleme tabi tutmalıyım.

Maxim

dikkatimi çekti
On_Hardware_Interrupt GoTo bak              'Software int. oluştuğunda INT etiketine git.

bu bir hardware interruptır soft değil
ayrıca int başında ve sonunda disable-enable komutları gereksizdir.

Powered by EzPortal