O degil de tum nesem kacti.Yasama sevincim yok oldu artik.
CCS PCWHD Derleyicide Timer Interrupt Sorunu
DSPIC30F4011 ve CCS PCWHD derleyicisini kullanarak gerçekleştireceğim bir projede TIMER1 kesmesi(interrupt) ile belirli bir periyotta ADC değerlerini okumam gerekti. Son derece basit bir zamanlayıcı uygulaması olan bu iş için aşağıdaki PIC lerle uğraşanların çok aşina oldukları basit kodu yazdım.
TIMER1 setup:
setup_timer1(TMR_INTERNAL | TMR_DIV_BY_64); // Timer1 ayarları yapılıyor set_timer1(0x001); // TMR1 değeri belirleniyor enable_interrupts(INT_timer1); // int_timer1 kesmesini aktif yapar enable_interrupts(INTR_GLOBAL); // Aktif edilen kesmelere izin ver
TIMER1 kesme servisi:
#int_timer1 // Timer1 kesmesi
void timer1_kesme ()
{
int i;
set_tris_D(0x00);
i=i+1;
if (i==5)
output_high(pin_D0);
if (i==10)
{
output_low(pin_D0);
i=0;
}
set_adc_channel(0);
current1=read_adc();
set_adc_channel(1);
voltage1=read_adc();
if (duty<=0x3e0)
duty=0x015e; //d=%35
set_motor_pwm_duty(1,1,(duty));
set_timer1(0x0001); // TMR1 değeri yükleniyor
}
Programı derleyip DSPIC’e yükledikten sonra kesme periyoduna kontrol etmek amacıyla D0 bacağına osiloskop ile baktığımda D0’ın sabit olduğunu yani kesme işleminin gerçekleşmediğini gördüm.
Problemi analiz için programın assembler listesini incelediğim zaman kesme servisinden çıkarken derleyici tarafından reset edilmesi gereken TIMER1 kesme bitinin (0×0084 bit3) reset edilmediğini anladım.
.................... if (duty<=0x3e0) 0142: MOV 806,W4 0144: MOV #3E0,W3 0146: CP W3,W4 0148: BRA LT,14E .................... .................... duty=0x015e;//d=%35 014A: MOV #15E,W4 014C: MOV W4,806 .................... .................... set_motor_pwm_duty(1,1,(duty)); 014E: PUSH 806 0150: POP 1D6 .................... set_timer1(0x0001);//TMR1 değeri belirleniyor 0152: MOV #1,W4 0154: MOV W4,100 .................... .................... .................... }
Aslında derleyici tarafından reset edilmesi gereken bu biti reset etmek için kesme servisinin sonuna clear_interrupt(int_timer1) komutunu ekledim.
if (duty<=0x3e0) duty=0x015e;//d=%35 set_motor_pwm_duty(1,1,(duty)); set_timer1(0x0001);//TMR1 değeri yükleniyor clear_interrupt(int_timer1);
Yeniden derleyip assembler listesini incelediğim zaman ilgili bitin reset edildiğini doğruladım.
.................... set_motor_pwm_duty(1,1,(duty)); 014E: PUSH 806 0150: POP 1D6 .................... set_timer1(0x0001);//TMR1 değeri belirleniyor 0152: MOV #1,W4 0154: MOV W4,100 .................... clear_interrupt(int_timer1); 0156: BCLR.B 84.3 .................... .................... }
Programı DSPIC’e atıp çalıştırdığımda zamanlamanın hesapladığım gibi gerçekleştiğini gördüm.
Tags: CCS derleyici, CCS PCWHD Derleyicide Timer Interrupt Sorunu, DSPIC, Timer1 interrupt, Timer1 kesme problemi, Timer1 kesme sorunu
Trackback from your site.
-
Derman