![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink) |
| Hi, everyone I have problem which is quite trivial but has taken me days now. All I want to do is set up a timer interrupt to trigger every 0.9525 milliseconds on a PIC 18F4431. The interrupt routine itself only switches a pin on and off just so I can measure whether the interrupt is working properly or not. I have never used interrupts in C18 before and I’m not too sure if it's set correctly. I've used Priority setup for the ISR although I don't really want too, but these were the only examples I could find. Attached is the code I’ve used, the last bit is just to set up a PWM signal which works fine. Any help would be great as this is driving me crazy. Oh, im writting the program in the new version of MPLAB IDE using the C18 compiler. | |
| |
| | (permalink) |
| below is the code that i'm using.... #include <p18f4431.h> /* header file for PIC18F4431*/ #include <stdio.h> /* CONFIGURATION BIT SET UP (all this is done using the configuration bit setup menu) */ /* Oscillator Set up */ /* All FOSC settings set up the ocilator to use HS mode */ /*control which uses external 16MHz crystal.*/ /*Also fail-safe clock mode disabled so uses the external clock setup.*/ /* RE7 (pin 4) to be set up as an input and not a master clear. */ /* Watchdog timer disabled as it is not required */ /* Low Voltage Program disabled so that pin 38 acts as normal I/O. */ /* Polarity of PWM reversed */ /* function prototypes */ void main(void); /* main code */ void init(void); /* Intialisition of the PIC */ void foo(void); /* Interupt Service Routine */ unsigned char test; #pragma interruptlow foo save = PROD, test void foo (void) { PIR1bits.TMR1IF = 0; /*clear interupt flags */ TMR1H = 0xF1; /* load higher byte */ TMR1L = 0x1D; /* Load lower byte */ } #pragma code lowvector=0x18 void lowvector(void) { _asm goto foo _endasm } #pragma code #pragma code highvector=0x08 void highvector(void) { _asm goto foo _endasm } #pragma code void main() { init(); /* Intialisation for EUSART control */ while(1) /*Continous Loop*/ { Nop(); } } void init() { /* Interrupt Setup */ INTCON = 0x00; /* Clear Registers */ PIR1 = 0x00; PIE1 = 0x00; TMR1L = 0x00; TMR1H = 0x00; T1CON = 0x00; RCON = 0x00; RCONbits.IPEN = 1; /* Set Priorities */ INTCONbits.GIEH = 1; /* Enable global Interupt */ INTCONbits.GIEL = 1; /* Enable peripheral interrupt */ T1CONbits.RD16 = 1; /* Enable 16bit read/write of timer. */ T1CONbits.T1CKPS1 = 0; /* Set Prescaler 1:1 */ T1CONbits.T1CKPS0 = 0; T1CONbits.TMR1CS = 0; /* Increment every instructrion cycle */ T1CONbits.TMR1ON = 1; /* Enable the timer */ PIE1bits.TMR1IE = 1; /* Enable timer1 interrupt */ /* Load timer for interupt every 0.9525m seconds */ TMR1H = 0xF1; /* Load timer1 higher byte */ TMR1L = 0x1D; /* Load timer1 lower byte */ //PIE1.TMR1IE = 1; /* Port Set Up*/ TRISA = 0x00; /* Set all pins for ouputs. */ TRISB = 0x00; TRISC = 0x00; TRISD = 0x00; TRISE = 0x00; /* PWM Setup */ PTCON0 = 0x03; /* 1:1 post and prescaler. Continuos up/down*/ /*mode with double updates.*/ PTCON1 = 0x80; //PTCON.PTEN = 1; /* Turn on the time base. */ PWMCON0 = 0x40; /* Enable PWM 0,1,2,3,4 and 5 pins for PWM. */ /*And put them in complementry output mode. */ //UNDIS = 0; /* Enable updates of duty cycle. */ PTPERH = 0x07; /* Load the time base perod (1050Hz) */ PTPERL = 0x71; PDC0H = 0x07; /* Duty Cycle of Half */ PDC0L = 0x71; PDC1H = 0x07; PDC1L = 0x71; PDC2H = 0x07; PDC2L = 0x71; } | |
| |
| | (permalink) |
| Check the C18 user guide on the Microchip website. I used that guide and the datasheet to set up a 1second pulse I hope to turn into a frequency counter. The LED blinks at about 1second but the rest isn't tested yet. Also, make sure your ADC's and comparators are off #include<p18f4680.h> #include<timers.h> #include<delays.h> #include<xlcd.h> void timer_isr (void); //prototype void counter_isr(void); static int overflow; static double freq; #pragma code low_vector=0x18 // set instruction mem to low vector location void low_interrupt(void) //define function at location 0x18 { _asm GOTO counter_isr _endasm //jump to timer_isr } #pragma code //resume normal memory #pragma code high_vector=0x08 //set mem to high vector void high_interrupt(void) { _asm GOTO timer_isr _endasm //jump to counter_isr } #pragma code #pragma interruptlow counter_isr //define goto point void counter_isr(void) { //counter interrupt overflow++; PORTCbits.RC2=~PORTCbits.RC2; //toggle LED Delay1KTCYx(100); PORTCbits.RC2=~PORTCbits.RC2; //toggle LED Delay1KTCYx(100); PORTCbits.RC2=~PORTCbits.RC2; INTCONbits.TMR0IF=0; //clear flag } #pragma interrupt timer_isr //define goto point void timer_isr(void) //actual interrupt routine { overflow++; T0CONbits.TMR0ON=0; //disable counter PIE1=0x00; //disable timer1 interrupt PIR1=0x00; //clear flag T1CONbits.TMR1ON=0; //disable timer 1 PORTCbits.RC2=~PORTCbits.RC2; //toggle LED freq=ReadTimer0(); //read current count freq+=overflow*0xFFFF; //multiply # of overflows+1 by 16bits //and add to current count overflow=0; //clear registers and overflow TMR0L=0x00; TMR0H=0x00; TMR1H=0x80; //pre load timer 1 TMR1L=0x00; PIE1=0x01; //enable interrupt T0CONbits.TMR0ON=1; //enable counter T1CONbits.TMR1ON=1; //enable timer 1 } /* used to hold 16-bit timer value */ union Timers { unsigned int lt; char bt[2]; }; unsigned int ReadTimer0(void) { union Timers timer; timer.bt[0] = TMR0L; // Copy Timer0 low byte into union timer.bt[1] = TMR0H; // Copy Timer0 high byte into union return (timer.lt); // Return the int } void main(void) { //led on RC2 overflow=0; ADCON1=0x0F; //ADC init to digital CMCON=0x07; //comparators off PORTA=0x00; TRISA=0x10; T0CON=0x38; TMR0L=0x00; TMR0H=0x00; RCON=0x80; //interrupt configure INTCON=0xC0; //High en, peripheral en, Timer0 dis //Timer0 flag INTCONbits.TMR0IF <2> INTCON2=0x00; //tmr0 low priority PIR1=0x01; PIE1=0x01; IPR1=0x01; TRISC=0x00; //I/O port init PORTC=0x00; PORTCbits.RC2=1; //set indicator high T1CON=0xCE; //Timer 1 module configure TMR1H=0x80; //pre load timer 1 TMR1L=0x00; T0CONbits.TMR0ON-1; //enable timer 0 T1CONbits.TMR1ON=1; //enable timer 1 while(1); //loop forever } | |
| |
| | (permalink) | ||
| Quote:
Quote:
Code: IPR1bits.TMR1IP = 1; // default
;...
INTCONbits.GIEL = 0; // disable low priority interrupts
INTCONbits.GIEH = 1; // enable high priority interrupts
;...
#pragma interrupt foo
void foo (void)
{
PIR1bits.TMR1IF = 0; /*clear interupt flags */
TMR1H = 0xF1; /* load higher byte */
TMR1L = 0x1D; /* Load lower byte */
} | |||
| |
| | (permalink) |
| Thanks so much eng1. Code is now working. Just for interest heres the whole of my code... #include <p18f4431.h> /* header file for PIC18F4431*/ #include <stdio.h> /* CONFIGURATION BIT SET UP (all this is done using the configuration bit setup menu) */ /* Oscillator Set up */ /* All FOSC settings set up the ocilator to use HS mode */ /*control which uses external 16MHz crystal.*/ /*Also fail-safe clock mode disabled so uses the external clock setup.*/ /* RE7 (pin 4) to be set up as an input and not a master clear. */ /* Watchdog timer disabled as it is not required */ /* Low Voltage Program disabled so that pin 38 acts as normal I/O. */ /* Polarity of PWM reversed */ /* function prototypes */ void main(void); /* main code */ void init(void); /* Intialisition of the PIC */ void foo(void); /* Interupt Service Routine */ unsigned char test; #pragma interrupt foo void foo (void) { PIR1bits.TMR1IF = 0; /*clear interupt flags */ test++; /* Toggle portA just to test timer frequency */ if (test == 0x03) { PORTA = 0x00; test = 0x00; } if (test == 0x01) { PORTA = 0xFF; test = 0x02; } TMR1H = 0xF1; /* load higher byte */ TMR1L = 0x1D; /* Load lower byte */ } #pragma code highvector=0x08 void highvector(void) { _asm goto foo _endasm } #pragma code void main() { init(); /* Intialisation for EUSART control */ while(1) /*Continous Loop*/ { Nop(); } } void init() { test = 0x00; /* Interrupt Setup */ INTCON = 0x00; /* Clear Registers */ PIR1 = 0x00; PIE1 = 0x00; TMR1L = 0x00; TMR1H = 0x00; T1CON = 0x00; RCON = 0x00; RCONbits.IPEN = 1; /* Set Priorities */ INTCONbits.GIEL = 0; /* disable low priority interrupts */ INTCONbits.GIEH = 1; /* enable high priority interrupts */ T1CONbits.RD16 = 1; /* Enable 16bit read/write of timer. */ T1CONbits.T1CKPS1 = 0; /* Set Prescaler 1:1 */ T1CONbits.T1CKPS0 = 0; T1CONbits.TMR1CS = 0; /* Increment every instructrion cycle */ IPR1bits.TMR1IP = 1; /* Make high priority interrupt */ T1CONbits.TMR1ON = 1; /* Enable the timer */ PIE1bits.TMR1IE = 1; /* Enable timer1 interrupt */ /* Load timer for interupt every 0.9525m seconds */ TMR1H = 0xF1; /* Load timer1 higher byte */ TMR1L = 0x1D; /* Load timer1 lower byte */ /* Port Set Up*/ TRISA = 0x00; /* Set all pins for ouputs. */ TRISB = 0x00; TRISC = 0x00; TRISD = 0x00; TRISE = 0x00; /* PWM Setup */ PTCON0 = 0x03; /* 1:1 post and prescaler. Continuos up/down*/ /*mode with double updates.*/ PTCON1 = 0x80; //PTCON.PTEN = 1; /* Turn on the time base. */ PWMCON0 = 0x40; /* Enable PWM 0,1,2,3,4 and 5 pins for PWM. */ /*And put them in complementry output mode. */ //UNDIS = 0; /* Enable updates of duty cycle. */ PTPERH = 0x07; /* Load the time base perod (1050Hz) */ PTPERL = 0x71; PDC0H = 0x07; /* Duty Cycle of Half */ PDC0L = 0x71; PDC1H = 0x07; PDC1L = 0x71; PDC2H = 0x07; PDC2L = 0x71; } | |
| |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Title | Starter | Forum | Replies | Latest |
| Problem about the Interrupt in PIC16F84A... pls pls~~ help!! | Gundam82 | Micro Controllers | 9 | 2nd October 2004 05:14 AM |
| Interrupt on GP Change problem | Dan East | Micro Controllers | 2 | 22nd May 2004 06:12 PM |
| Timer: Interrupt Flag (IF) and Interrupt Enable (IE) | patricktran | Micro Controllers | 0 | 25th April 2004 06:11 AM |
| timer problem HEEELLLPP!!!!!!!!!!! | qyc88 | Electronic Projects Design/Ideas/Reviews | 7 | 16th January 2004 08:42 PM |
| Interrupt problem | huanyong | Micro Controllers | 1 | 1st November 2003 02:26 AM |