merhaba arkadaşlar,
her türlü yöntemi denedim ama olmadı. interrupt işlemiyor. rb4 pinine bağlı butona basılınca interrupt ın devreye girip motorlarımın durmasını , butondan çekince ise tekrar motorlarımın dönebilmesini istiyorum. her yöntemi denedim diyebilirim. lütfen yardımcı olun..
#include <p18f452.h>
#include <pwm.h>
#include <stdlib.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <stdio.h>
#include <adc.h>
#include <portb.h>
#pragma config OSC = XT, PWRT = ON, WDT = OFF, LVP = OFF, DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF, WRTB = OFF,WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF
void motor (int);
void int_handler(void);
int x;
#pragma code high_vector=0x08
void high_interrupts (void) {
_asm GOTO int_handler _endasm
}
#pragma code low_vector=0x18
void low_interrupts (void) {
_asm GOTO int_handler _endasm
}
#pragma code
#pragma interrupt int_handler
void int_handler(void) {
if(PORTBbits.RB4 == 0) // PORTB Change Interrupt
{
PORTDbits.RD0 = 1;
PORTDbits.RD1 = 1;
PORTDbits.RD2 = 1;
PORTDbits.RD3 = 1;
INTCONbits.RBIF = 0;
}
if(PORTBbits.RB4 != 0)
{
motor(x);
}
}
#pragma code
void main(void){
TRISB = 0xff;
PORTB = 0;
TRISC=0x80;
PORTC=0;
TRISD=0;
PORTD=0;
ADCON1 = 0x0F; // All channels Digital
//Enables all interrupts & the RB port change interrupt
INTCONbits.GIE = 1; // Interrupts generell erlauben
INTCONbits.RBIF = 0; // Interrupt on Change Flag aus
INTCONbits.RBIE = 1; // Interrupt on Change an den PINs
OpenRB0INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT);
OpenUSART(USART_TX_INT_OFF & // usart konfigürasyon ayarlarý
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,207);
OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 );
OpenPWM1(249); // Period
OpenPWM2(249);
SetDCPWM1(0);
SetDCPWM2(0);
INTCONbits.GIE = 1;
RCONbits.IPEN = 0; // priority // enable interrupt
INTCONbits.RBIE = 1;
if((BusyUSART()));
while(1)
{
x=ReadUSART();
while (!DataRdyUSART());
motor(x);
}
}
void motor (int x)
{
if(x=='S')
{
SetDCPWM1(0);
SetDCPWM2(0);
PORTDbits.RD0 = 0;
PORTDbits.RD1 = 0;
PORTDbits.RD2 = 0;
PORTDbits.RD3 = 0;
PORTDbits.RD6 = 1;
PORTDbits.RD7 = 0;
}
if(x=='F')
{
SetDCPWM1(498);
SetDCPWM2(498);
PORTDbits.RD0 = 0;
PORTDbits.RD1 = 1;
PORTDbits.RD2 = 0;
PORTDbits.RD3 = 1;
PORTDbits.RD6 = 1;
PORTDbits.RD7 = 0;
}
if(x=='V')
{
SetDCPWM1(498);
SetDCPWM2(498);
PORTDbits.RD0 = 1;
PORTDbits.RD1 = 0;
PORTDbits.RD2 = 1;
PORTDbits.RD3 = 0;
PORTDbits.RD6 = 1;
PORTDbits.RD7 = 0;
}
if(x=='R')
{
SetDCPWM1(124);
SetDCPWM2(498);
PORTDbits.RD0 = 0;
PORTDbits.RD1 = 1;
PORTDbits.RD2 = 0;
PORTDbits.RD3 = 1;
PORTDbits.RD6 = 1;
PORTDbits.RD7 = 0;
}
if(x=='L' )
{
SetDCPWM1(498);
SetDCPWM2(124);
PORTDbits.RD0 = 0;
PORTDbits.RD1 = 1;
PORTDbits.RD2 = 0;
PORTDbits.RD3 = 1;
PORTDbits.RD6 = 1;
PORTDbits.RD7 = 0;
}
}
(http://s22.postimg.cc/84u303c1p/scheme.jpg) (http://postimg.cc/image/84u303c1p/)
Kodu detaylı incelemedim ama ilk bakışta göze çarpan birkaç hata, daha doğrusu usulsüz yazım var.
Öncelikle, çıkış amacıyla PORT'lara erişirken PORT değil LAT register'larını kullanmalısın. Özellikle PORT register'ları üzerinden bitlere yapılan arka arkaya erişim tehlikeli. Komutların kendilerinden önceki komutları geçersiz kılma ihtimali var. Senin kodunda arka arkaya gelen PORTDbits.RD0 = 1; PORTDbits.RD1 = 1; gibi satırlardan bahsediyorum. Bu işlemleri LATDbits üzerinden yap. Tabi bu dediğim sadece yazmalar için. Bacakları okumak gerektiğinde yine PORTD kullanılacak.
Kesme kodu içinde her kesme türü için ayrı bir if bloğu açıp, if (bayrak == 1 && izin == 1) şeklinde kontrol etmek usuldendir. Buna uymazsan, tespit etmesi güç hatalarla karşılaşabilirsin.
OpenRB0INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT);
Aklımda çok net kalmamış olabilir ama bu satır bana yanlış gözüktü. Buradaki iki ayrı ayar, sanki iki farklı kesme türü için gibi. PORTB kesmesi hem düşen hem yükselen kenarda çalışır, yani sadece düşen kenarda çalışsın diyemezsin. İkinci ayar seçeneği sanki diğer kesme için gibi duruyor (PIC16'larda RB0 kesmesi olarak bilinen kesme, PIC18'lerde EXT0 veya INT0 gibi bir ismi vardı ve galiba 2 veya 3 adet vardı bunlardan, pek hatırlamıyorum şimdi). PORTB değişim kesmesi ile çalışırken dikkatli olmak lazım, hata yapmak kolay.
Adım adım hata ayıklama işlemi yapman gerekiyor. Öncelikle program akışının kesme kodunun içine girip girmediğine bak. Kesme olunca bir LED yakıp söndür. Ben hep öyle yaparım.
Son olarak, C18 güncelliğini yitirdi. Sana tavsiyem XC8'e geçmen. Kullanımının daha kolay olduğunu söyleyebilirim, özellikle de C18'e alışmış biri için.
hocam bir kısım değişiklikler yaptım dediğiniz bu şekilde mi oluyor ?
"Kesme kodu içinde her kesme türü için ayrı bir if bloğu açıp, if (bayrak == 1 && izin == 1) şeklinde kontrol etmek usuldendir. Buna uymazsan, tespit etmesi güç hatalarla karşılaşabilirsin." kısmını anlayamadım bir örnek verebilirmisiniz?
#pragma code
#pragma interrupt int_handler
void int_handler(void) {
if(PORTBbits.RB4 == 0) // PORTB Change Interrupt
{
LATDbits.LATD0 ^= 1;
LATDbits.LATD1 ^= 1;
LATDbits.LATD2 ^= 1;
LATDbits.LATD3 ^= 1;
INTCONbits.RBIF = 0;
}
if(PORTBbits.RB4 != 0)
{
motor(x);
}
}
#pragma code
void main(void){
TRISB = 0xff;
PORTB = 0;
TRISC=0x80;
PORTC=0;
TRISD=0;
PORTD=0;
ADCON1 = 0x0F; // All channels Digital
//Enables all interrupts & the RB port change interrupt
INTCONbits.GIE = 1; // Interrupts generell erlauben
INTCONbits.RBIF = 0; // Interrupt on Change Flag aus
INTCONbits.RBIE = 1; // Interrupt on Change an den PINs
OpenRB0INT(PORTB_CHANGE_INT_ON);
mesaj birleştirme:: 27 Ocak 2014, 23:33:33
hocam en son şekliyle bu şekilde yaptım fakat yine çalışmıyor . bir bakabilirmisiniz..
#include <p18f452.h>
#include <pwm.h>
#include <stdlib.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <stdio.h>
#include <adc.h>
#include <portb.h>
#pragma config OSC = XT, PWRT = ON, WDT = OFF, LVP = OFF, DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF, WRTB = OFF,WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF
void motor (int);
void int_handler(void);
int x;
#pragma code high_vector=0x08
void high_interrupts (void) {
_asm GOTO int_handler _endasm
}
#pragma code low_vector=0x18
void low_interrupts (void) {
_asm GOTO int_handler _endasm
}
#pragma code
#pragma interrupt int_handler
void int_handler(void) {
if(INTCONbits.RBIF==1 && PORTBbits.RB4 == 0) // PORTB Change Interrupt
{
LATDbits.LATD0 ^= 1;
LATDbits.LATD1 ^= 1;
LATDbits.LATD2 ^= 1;
LATDbits.LATD3 ^= 1;
INTCONbits.RBIF = 0; //Clear the PORTB RBIF flag
PORTDbits.RD5=1;
}
if( PORTBbits.RB4 != 0) // PORTB Change Interrupt
{
motor(x);
}
}
void EnableInterrupts (void)
{
INTCONbits.RBIE = 1; //Ensure PORTB interrupts enabled
INTCONbits.RBIF = 0; //Clear the PORTB interrupt flag
INTCONbits.PEIE = 1; //Enable peripheral interrupts (don't think i really need this one
INTCONbits.GIE = 1; //Enable all interrupts
}
void main(void){
TRISB = 0xff;
PORTB = 0;
TRISC=0x80;
PORTC=0;
TRISD=0;
PORTD=0x80;
ADCON1 = 0x0F; // All channels Digital
OpenPORTB(PORTB_CHANGE_INT_ON);
EnableInterrupts(); //Setup the interrupts
OpenUSART(USART_TX_INT_OFF & // usart konfigürasyon ayarlarý
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,207);
OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 );
OpenPWM1(249); // Period
OpenPWM2(249);
SetDCPWM1(0);
SetDCPWM2(0);
if((BusyUSART()));
while(1)
{
x=ReadUSART();
while (!DataRdyUSART());
motor(x);
}
}
void motor (int x)
{
if(x=='S')
{
SetDCPWM1(0);
SetDCPWM2(0);
LATDbits.LATD0 ^= 0;
LATDbits.LATD1 ^= 0;
LATDbits.LATD2 ^= 0;
LATDbits.LATD3 ^= 0;
LATDbits.LATD6 ^= 1;
LATDbits.LATD7 ^= 0;
}
if(x=='F')
{
SetDCPWM1(498);
SetDCPWM2(498);
LATDbits.LATD0 ^= 0;
LATDbits.LATD1 ^= 1;
LATDbits.LATD2 ^= 0;
LATDbits.LATD3 ^= 1;
LATDbits.LATD6 ^= 1;
LATDbits.LATD7 ^= 0;
}
if(x=='V')
{
SetDCPWM1(498);
SetDCPWM2(498);
LATDbits.LATD0 ^= 1;
LATDbits.LATD1 ^= 0;
LATDbits.LATD2 ^= 1;
LATDbits.LATD3 ^= 0;
LATDbits.LATD6 ^= 1;
LATDbits.LATD7 ^= 0;
}
if(x=='R')
{
SetDCPWM1(124);
SetDCPWM2(498);
LATDbits.LATD0 ^= 0;
LATDbits.LATD1 ^= 1;
LATDbits.LATD2 ^= 0;
LATDbits.LATD3 ^= 1;
LATDbits.LATD6 ^= 1;
LATDbits.LATD7 ^= 0;
}
if(x=='L' )
{
SetDCPWM1(498);
SetDCPWM2(124);
LATDbits.LATD0 ^= 0;
LATDbits.LATD1 ^= 1;
LATDbits.LATD2 ^= 0;
LATDbits.LATD3 ^= 1;
LATDbits.LATD6 ^= 1;
LATDbits.LATD7 ^= 0;
}
}
Kesme kodu girişi şu şekilde olmalıydı:
if(INTCONbits.RBIF==1 && INTCONbits.RBIE==1)
Yani izin biti dediğim, sonu IE ile biten kesme açma kapama (izin) biti. Bloğun içine girdikten sonra yine istiyorsan PORT durumlarına göre istediğin kontrolü yaparsın, o ayrı.
LAT bitlerini ayarlarken neden ^= kullandın? Amacın doğrudan atama yapmak değil miydi?
Benim senin programın üzerinde uzaktan hata ayıklama yapmam pek mümkün değil. Ben sadece yol gösterebilirim, hata çok bariz olmadığı sürece tespit edemem. Dediğim gibi, ilk kontrol etmen gereken şey, istediğin şartlar oluştuğunda kodun kesme bölümüne dallanıp dallanmadığını görmen. Bunu en basit şekilde bir LED yakarak gözlemleyebilirsin.
@smail
Pogramını kesmeye girip girmediğini (Kesme izinlerini doğru yapılandırıp yapılandırmadığını) kontrol etmeyi dener misin?Böylece sorunun nerede olduğu daha net anlaşılır.
Kesmeye girdiğinde led yaksın veya printf debug yap.
Bir tavsiyem var;
Bu tarz sorunlarda, kimse kodları alıp da proje oluşturup, simülasyon oluşturup, derleyip denemez.
Siz projeyi ve simülasyonun proje halini yükleyip, link verseydiniz, çok daha fazla kişi ilgilenecekti. Sorun çözüldüğünde de yararlananların sayısı çok olacaktı.
değerli hocalarım, aşağıdaki siteye kodlar, hex ve proteus dosyalarını yükledim. ben kendi yazdığım bir yazılımla programı kontrol ediyordum. onu göndersem birde ek olarak sanal port programı yüklemeniz gerekiyordu. bende proteusa virtual terminal ekledim. virtual terminal açıkken f tuşuna basınca ileri s tuşuna basınca durması gerekiyor. en çokda takıldığım konu rb4 pinindeki buton kapalı durumdayken motorların hiç çalışmaması gerekiyor. ben kodları mplab da derledim. ilgilendiğiniz için çok teşekkür ederim.
http://www.dosya.tc/server23/jIhILm/interrupt.rar.html (http://www.dosya.tc/server23/jIhILm/interrupt.rar.html)
http://elektrokod.wordpress.com/2013/10/12/portb-change-interrupt-portb-degisim-kesmesi/ (http://elektrokod.wordpress.com/2013/10/12/portb-change-interrupt-portb-degisim-kesmesi/)
Register bazında şematik olarak anlatım ve uygulama var. Faydalı olması ümidiyle..
selim hocamın verdiği örneğe çok benzer biçimde yaptım. şu an sonuca sanki çok yaklaştım. butona basıldığında interrupt devreye giriyor fakat buton hala basılı durumdayken basarsam yine döngüden çıkıp motorlar dönmeye devam ediyor. ben ise buton basılı durumdayken ne olursa olsun motorlar çalışmasın istiyorum.. selim hocanın kodlarına göre düzenlediğim son kodlar şu şekilde oldu:
#pragma interrupt int_handler
void int_handler(void) {
if(INTCONbits.RBIF) // RBIF bayrağı oluşmuşsa
{
INTCONbits.RBIF=0; // RBIF bayrağını sil
if(!PORTBbits.RB4)
PORTD=0x20;
else
motor(x);
}
}
void main(void){
TRISB = 0x10;
INTCONbits.GIE=1; // bütün kesmelere izin ver
INTCONbits.RBIE=1; // PORTB değişim kesmesine izin ver
INTCONbits.RBIF=0; // RBIF bayrağını temizle
PORTB = 0;
TRISC = 0x80;
PORTC = 0;
TRISD = 0;
PORTD = 0x80;
Buton hala basılı iken basmak nasıl oluyor?
While ile yapabilirsin.
while(portdbits.rd0); gibi.
Yada bayrak ekleye de bilirsin.
yani şuan sadece butona basıldığı anda interrupt fonksiyonuna giriyor sonra elim hala butona basılı olmasına rağmen, yani hala if(!PORTBbits.RB4) olmasına rağmen, motorları hareket ettirebiliyorum. dediğiniz gibi while(!PORTBbits.RB4) şeklinde yazdım , bu seferde rb4 deki interrupt butonundan elimi çeksem dahi fonksiyon ordan geri çıkamadı. yani bu seferde program tamamen kilitlenip interrupt fonksiyonun içinde kaldı.
Benim de aklıma gelen çözüm bayrak oldu. Yoksa sürekli olarak kesmede kalmak gerekir ki bu saçma. Kesme ne de olsa hem düşen hem de yükselen kenarda gelecek, bu durumda hem düğmeye basılmasını hem de çekilmesini algılayacaktır. Kesmenin yapması gereken şey bayrağın terslemekten (toggle) ibaret. Ancak, ana döngünün, bayrağı tatmin edici bir sıklıkta kontrol etmesi gerekir.
Elbette düğmenin fiziksel olarak temiz bir sinyal vermeyeceği de göz önünde bulundurulmalı ve gereken önlemler alınmalı (debounce diye aratılabilir).
Düğmenin basılı olması fiziksel olarak bir güvenlik önlemi ise, bu işe PIC'i karıştırmayıp harici bir AND kapısı kullanmak daha doğru olabilir.
Ben yazarken @Tagli yanıtlamış.O halde main içinde flag kontrolü ile de yapabilirsin.Eğer main dolu değilse interruptu kapatıp flag kontrolü yapabilirsin.
RBIF flagını kontrol ederekmi yapayım ? tam olarak ne yazmalıyım örnek kod yazabilirmisiniz? while 'ı hiç bir şekilde yutturamadım.
Alıntı yapılan: smail - 28 Ocak 2014, 17:29:49
RBIF flagını kontrol ederekmi yapayım ?
Benim önerim bu yönde idi
hocam şimdi nasıl bir düzenleme yapıcağız kodlarda lütfen bi söyleseniz. main içine yada interrupt fonksiyonunda tam olarak nasıl bir değişiklik yapmalıyız?
if(INTCONbits.RBIF) // RBIF bayrağı oluşmuşsa
{
INTCONbits.RBIF=0; // RBIF bayrağını sil
if(!PORTBbits.RB4)
PORTD=0x20;
}
}
void main(void){
TRISB = 0x10;
INTCONbits.GIE=1; // bütün kesmelere izin ver
INTCONbits.RBIE=1; // PORTB değişim kesmesine izin ver
INTCONbits.RBIF=0; // RBIF bayrağını temizle
PORTB = 0;
TRISC = 0x80;
PORTC = 0;
TRISD = 0;
PORTD = 0x80;
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,207);
OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 );
OpenPWM1(249); // Period
OpenPWM2(249);
SetDCPWM1(0);
SetDCPWM2(0);
if((BusyUSART()));
Kesme bayrağını;
INTCONbits.RBIF=0; // RBIF bayrağını sil
işin bittiğinde temizle. Butona bastığında us ler süresinde işlemi yapıp arktan dolayı tekrar kesme algılayabilir. İşlerini yap ondan sonra bu bayrağı temizle. İlla kesme içinde temizlenecek diye bir durum yok.
kesme içinde;
if(!PORTB.B4) <motor döndür>
if(PORTB.B4) <motor durdur>
diyebilirsin. Çünkü her kenar değişiminde kesme algılar.
selim hocam dediğiniz gibi RBIF flagının yeri ile ilgili problem var. "INTCONbits.RBIF=0; " kodunu herhangi bir yere koyarsam program direk kilitlenip döngüye dahi girmiyor. ama aşağıdaki gibi "if(PORTBbits.RB4) den sonra INTCONbits.RBIF=0;" yazarsam program buton basılıncaya kadar çalışıyor. basılınca interrupt devreye giriyor. fakat burdada butondan çekildikten sonra interruptan çıkamayıp program kilitleniyor.
void int_handler(void) {
if(INTCONbits.RBIF) // RBIF bayragi olusmussa
{
if(!PORTBbits.RB4)
PORTD=0x20;
if(PORTBbits.RB4)
{
INTCONbits.RBIF=0; // RBIF bayragini sil
motor(x);
}
}
}
void main(void){
TRISB = 0x10;
INTCONbits.GIE=1; // bütün kesmelere izin ver
INTCONbits.RBIE=1; // PORTB degisim kesmesine izin ver
PORTB = 0;
TRISC = 0x80;
PORTC = 0;
TRISD = 0;
PORTD = 0x80;
Bayrak sıfırlamanın yeri yanlış. Bir blok dışarıda olmalı. Mevcut durumda, RB4 sıfır ise, kesme bayrağı sıfırlanmıyor.
Hocam bir blok dışarı derken ne kastettiğinizi anlayamadım. ama ben şöyle 3 farklı durum denedim :
1. durum : bu durumda kesmeye girildiğini led den anlıyorum fakat buton basılı durumda olsa bile hala motorlar devam edebiliyor.
void int_handler(void) {
if(INTCONbits.RBIF) // RBIF bayragi olusmussa
{
if(!PORTBbits.RB4){
PORTD=0x20;
}
if(PORTBbits.RB4)
{
motor(x);
}
}
INTCONbits.RBIF=0;
}
2. durum: bu durumda çok acaip saçma şeyler yapıyor ..
void int_handler(void) {
if(INTCONbits.RBIF) // RBIF bayragi olusmussa
{
if(!PORTBbits.RB4){
PORTD=0x20;
INTCONbits.RBIF=0;
}
if(PORTBbits.RB4)
{
motor(x);
}
}
}
3. durum: 1. durumla aynı sonuç çıkıyor..
void int_handler(void) {
if(INTCONbits.RBIF) // RBIF bayragi olusmussa
{
if(!PORTBbits.RB4){
PORTD=0x20;
}
if(PORTBbits.RB4)
{
motor(x);
}
INTCONbits.RBIF=0;
}
}
if bloğu içine 200ms kadar bekleme koysan (buton arkı için),
birde butona paralel 100nf kond. eklesen duruma baksan.
Benim dediğim 3. durum idi.
Bu arada, PORTD=0x20; yerine LATD=0x20; yazmayı alışkanlık haline getir. Bu dediğim sadece çıkışlar için. Girişler yine PORT üzerinden okunacak.
arkadaşlar sonunda sorun çözülmüştür. verdiğiniz çok değerli fikirler için çok teşekkür ederim. inşallah benim gibi böyle bir sorun yaşayan kişiye faydalı olur.. interrupt dan çıktıktan sonra while(1) döngüsü içinde ikinci bir defa daha kontrol yaptırarak sorunu çözdüm. yani şu şekilde:
while(1)
{
x=ReadUSART();
while (!DataRdyUSART());
if(!PORTBbits.RB4)
LATD=0x40;
if(PORTBbits.RB4)
motor(x);
}
tüm kodlar ise şu şekilde oldu:
#include <p18f452.h>
#include <pwm.h>
#include <stdlib.h>
#include <usart.h>
#include <timers.h>
#include <delays.h>
#include <stdio.h>
#include <adc.h>
#include <portb.h>
#pragma config OSC = XT, PWRT = ON, WDT = OFF, LVP = OFF, DEBUG = OFF
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF, WRTB = OFF,WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF
void motor (int);
int x;
void int_handler(void);
#pragma code high_vector=0x08
void high_interrupts (void) {
_asm GOTO int_handler _endasm
}
#pragma code low_vector=0x18
void low_interrupts (void) {
_asm GOTO int_handler _endasm
}
#pragma code
#pragma interrupt int_handler
void int_handler(void) {
if(INTCONbits.RBIF) // RBIF bayragi olusmussa
{
if(!PORTBbits.RB4)
LATD=0x40;
if(PORTBbits.RB4)
{
motor(x);
}
}
INTCONbits.RBIF=0;
}
void main(void){
TRISB = 0x10;
INTCONbits.GIE=1; // bütün kesmelere izin ver
INTCONbits.RBIE=1; // PORTB degisim kesmesine izin ver
PORTB = 0;
TRISC = 0x80;
PORTC = 0;
TRISD = 0;
PORTD = 0x40;
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,207);
OpenTimer2 ( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 );
OpenPWM1(249); // Period
OpenPWM2(249);
SetDCPWM1(0);
SetDCPWM2(0);
if((BusyUSART()));
while(1)
{
x=ReadUSART();
while (!DataRdyUSART());
if(!PORTBbits.RB4)
LATD=0x40;
if(PORTBbits.RB4)
motor(x);
}
}
void motor (int x)
{
if(x=='S')
{
SetDCPWM1(0);
SetDCPWM2(0);
PORTD= 0x80;
}
if(x=='F')
{
SetDCPWM1(498);
SetDCPWM2(498);
PORTD=0x8A;
}
if(x=='V')
{
SetDCPWM1(498);
SetDCPWM2(498);
PORTD=0x85;
}
if(x=='R')
{
SetDCPWM1(124);
SetDCPWM2(498);
PORTD=0x8A;
}
if(x=='L' )
{
SetDCPWM1(498);
SetDCPWM2(124);
PORTD=0x8A;
}
}