Autor Tema: Problema con Interrupción externa con PIC24F  (Leído 1557 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Deode

  • PIC10
  • *
  • Mensajes: 11
Problema con Interrupción externa con PIC24F
« en: 04 de Febrero de 2013, 05:14:09 »
Hola a todos,

Tengo un problema a la hora de usar la Interrupción externa (INT0) del pic24F04KA200. Quiero realizar un pequeño proyecto y he empezado por configurar el hadware. Concreta mente uso un PWM, el convertidor ADC y la interrupción externa. El ADC lo tengo en comentario, pues de momento prefiero ir por partes, y el PWM me funciona bien (en proteus lo compruebo moviendo un servo).

El problema reside en que cuando hago uso del pin que activa la interrupción externa, se ejecuta una rutina que debería de togglear (Cambiar de estado) a una LED, pero lo que hace es atascarse :S.

Supongo que el problema estará en la configuración del INT0. (Mirar "void IniINT(void)" en el codigo)

Tengo una duda, que aunque haya leído el datasheet no me queda claro. Y es que ¿El pin de INT0 hay que declararlo como Input o no? He probado en ambos casos y mientras que se declara como input, no hace nada y el servo funciona con normalidad. Y si lo declaro como output, el led togglea solo una vez y luego el servo se vuelve loco  :shock:

El funcionamiento debería de ser un servo moviéndose en "semicírculos" de un lado al otro y con la INT0 togglear el LED.

Os pongo el código para que podáis echar un vistazo: (Por cierto uso MPLAB X IDE con XC16 como compilador)

Código: [Seleccionar]
#include <p24F04KA200.h>
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

#include <adc.h>
#include <Timer.h>
#include <ports.h>

#include <spi.h>
#include <i2c.h>
#include <uart.h>



/* Definiciones */
#define Timer1_20ms 0x61A/2
#define PWM_Period 0x61A7

/* Variables */

unsigned int Channel, PinConfig, Scanselect, Adcon3_reg, Adcon2_reg,
Adcon1_reg;

unsigned int FlagPwm_Ascnd = 0, FlagPwm_Descnd = 1, increment = 10;

/* Funciones */
void IniClock(void);
void IniADC(void);                            
void IniINT(void);                            
void DisableComunications(void);              
void Timer1INI(void);                          
void PWM_INI(void);
void __attribute__((__interrupt__)) _T1Interrupt(void);
void __attribute__((__interrupt__)) _INT0Interrupt(void);

void PI_Corriente(void);                          
/*Main*/

int main() {
IniClock();
// Configuracion de los PINes
TRISBbits.TRISB9 = 0;
TRISBbits.TRISB8 = 1;
TRISAbits.TRISA6 = 0;
TRISAbits.TRISA4 = 1;

TRISBbits.TRISB15 = 0;

PORTBbits.RB9 = 0;
// Ejecucion de las funciones
//IniADC();
IniINT();
DisableComunications();
Timer1INI();
PWM_INI();

PORTBbits.RB9 = 1;

while(1) {



}
CloseTimer1();
return 0;
}

/* Funciones */
void IniClock(void) {

#include <xc.h>

// FBS

// FGS
#pragma config GWRP = OFF               // General Segment Code Flash Write Protection bit (General segment may be written)
#pragma config GCP = OFF                // General Segment Code Flash Code Protection bit (No protection)

// FOSCSEL
#pragma config FNOSC = PRI              // Oscillator Select (Primary oscillator (XT, HS, EC))
#pragma config IESO = OFF               // Internal External Switch Over bit (Internal External Switchover mode disabled (Two-Speed Start-up disabled))

// FOSC
#pragma config POSCMOD = HS             // Primary Oscillator Configuration bits (HS Oscillator mode selected)
#pragma config OSCIOFNC = OFF           // CLKO Enable Configuration bit (CLKO output signal active on the OSCO pin; primary oscillator must be disabled or configured for the External Clock mode (EC) for the CLKO to be active (POSCMD<1:0>))
#pragma config POSCFREQ = HS            // Primary Oscillator Frequency Range Configuration bits (Primary oscillator/external clock input frequency greater than 8 MHz)
#pragma config SOSCSEL = SOSCHP         // SOSC Power Selection Configuration bits (Secondary oscillator configured for high-power operation)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock switching is disabled, Fail-Safe Clock Monitor is disabled)

// FWDT
#pragma config WDTPS = PS32768          // Watchdog Timer Postscale Select bits (1:32,768)
#pragma config FWPSA = PR128            // WDT Prescaler (WDT prescaler ratio of 1:128)
#pragma config WINDIS = OFF             // Windowed Watchdog Timer Disable bit (Standard WDT selected; windowed WDT disabled)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))



}

void IniADC(void) {

    DisableADC1;                                
    ConfigIntADC10(ADC_INT_DISABLE);            

    PinConfig = ENABLE_AN4_ANA;

    Adcon3_reg = ADC_SAMPLE_TIME_10 &
    ADC_CONV_CLK_SYSTEM &
    ADC_CONV_CLK_13Tcy;

    Adcon2_reg = ADC_VREF_AVDD_AVSS &
    ADC_SCAN_OFF &
    ADC_ALT_BUF_OFF &
    ADC_ALT_INPUT_OFF ;

    Adcon1_reg = ADC_MODULE_ON &
    ADC_IDLE_CONTINUE &
    ADC_FORMAT_INTG &
    ADC_CLK_MANUAL &
    ADC_AUTO_SAMPLING_OFF;

    Scanselect = 0x0000;

    OpenADC10(Adcon1_reg, Adcon2_reg,
    Adcon3_reg,PinConfig, Scanselect);            



}

void IniINT(void) {


   INTCON2bits.INT0EP = 0;
   IFS0bits.T1IF = 0;
   IPC0bits.INT0IP = 0b011;
   IEC0bits.INT0IE = 1;
                                
    
   //DisableINT0;                                  
   DisableINT1;                                  
   DisableINT2;                              

}

void DisableComunications(void) {

    CloseSPI1();                                  
    CloseI2C1();                                  
    CloseUART1();                              

}

void Timer1INI(void) {

T1CONbits.TCKPS = 0b11;                          
T1CONbits.TCS = 0b0;
T1CONbits.TSYNC = 0b0;
PR1 = Timer1_20ms;                                
TMR1 = 0x00;                                        
IPC0bits.T1IP = 0b110;                            
IFS0bits.T1IF = 0;                                
IEC0bits.T1IE = 1;                                
T1CONbits.TON = 1;                              
                    
}

void PWM_INI(void){
 T2CON = 0;                              

 PR2 = PWM_Period;
 OC1RS = 1400;
 OC1R = 1400;
 IEC0bits.OC1IE = 1;
 OC1CONbits.OCM = 0b110;


 T2CONbits.TCKPS = 0b01;                            
 T2CONbits.TON = 1;


}

void PI_Corriente(void) {
// PIaren funtzioa
PORTBbits.RB9 = ~PORTBbits.RB9;
}

void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void)
{
/* Rutina de Interrupcion */
IFS0bits.T1IF = 0;                                
TMR1=0;

if (OC1RS == 1200 || FlagPwm_Ascnd == 1){
    OC1RS = OC1RS + increment;
    FlagPwm_Ascnd = 1;
    FlagPwm_Descnd = 0;
}
if (OC1RS >=2550 || FlagPwm_Descnd == 1) {
    OC1RS = OC1RS - increment;
    FlagPwm_Descnd = 1;
    FlagPwm_Ascnd = 0;
}
}

void __attribute__((__interrupt__, no_auto_psv)) _INT0Interrupt(void) {


PI_Corriente();

IFS0bits.INT0IF = 0;


}

No sé si esto seria suficiente.

Muchas Gracias de antemano!

Un Saludo!
« Última modificación: 04 de Febrero de 2013, 09:49:41 por Deode »

Desconectado Deode

  • PIC10
  • *
  • Mensajes: 11
Re: Problema con Interrupción externa con PIC24F
« Respuesta #1 en: 05 de Febrero de 2013, 05:16:02 »
SOLUCIONADO!

Solo necesita un Pull-up en la resistencia del PIN INT0!


 

anything