Problema durante el arranque con DSPIC30F4013

Buenas tardes,

Llevo ya algun año trabajando con los DSPic, en cuestion con el 30f4013, pero lo que me ha pasado este fin de semana no me ha ocurrido nunca.

Ahora mismo tengo un programa que recibe caracteres ascii a traves de un dispositivo de bluetooth, por tanto tengo activadas las interrupciones por recepcion del uart 1 y del timer 2. El caso es que si alimento el pic seccionando los 5V, es decir, poniendo el interruptor en la parte de CC el pic arranca. En cambio, si secciono la parte de 230Vac, al alimentar el pic se queda "colgado". Esto se soluciona si elimino el código de la interrupcion por uart:unsure:. Al final el codigo lo he dejado en un while infinito. Y he dado con la conclusión anterior. He probado varias opciones, como el reseteo por baja tensión...y el oscilador que tengo es el interno. He pensado que al arrancar seccionando 230V al cargarse todas las capacidades del circuito paulatinamente esto lo hace quedar colgado, y que al hacerlo con 5V el arranque es casi directo, pero lo del código de la interrupcion me tiene mosqueado.

Decir que si arranca va bien todo el código.

Un saludo y gracias de antemano.
 
Revisa el estado de los flags de las interrupciones, puede ser que el programa no esté saliendo del servicio de interrupción.
Ésto lo debes hacer entrando en modo de depuración ICD.
 
Gracias por responder, el programa no responde sin ni siquiera realizar una llamada a las interrupciones.

PHP:
void interrupcion(void){
//PRIMERO FIJAMOS A PARTIR DE QUÉ NIVEL DE PRIORIDAD LA CPU HACE CASO A LAS INTERRUPCIONES
    CORCONbits.IPL3=0;
    SRbits.IPL=0;
    //EN ESTE CASO 001=1, ATIENDE INTERRUPCIONES CON NIVEL DE PRIORIDAD MAYOR QUE 1


    //LOS REGISTROS IFSX SON REGISTROS SEÑALIZADORES DE LAS INTERRUPCIONES.
    //EN ESTE CASO IFS0.BIT9 ES EL FALG QUE SE ACTIVA AL RECIBIR UNA INTERRUPCIÓN DEL RECEPTOR DEL PUERTO SERIE 1

    //LOS REGISTROS IECX SON LOS REGISTROS DE CONTROL DE LAS INTERRUPCIONES
    //EN ESTE CASO IEC0.BIT9 HABILITA LA INTERRUPCIÓN POR RECEPCIÓN DEL PUERTO SERIE 1
    IEC0bits.U1RXIE=1;
      IEC0bits.T2IE=1;

    //LOS REGISTROS ICPX FIJAN EL NIVEL DE PRIORIDAD DE CADA UNA DE LAS FUENTES DE INTERRUPCIONES
    //EN ESTE CASO ICP2.BITS<2:0>
      IPC1bits.T2IP=1;

    INTCON1bits.NSTDIS=0;
    INTCON2bits.ALTIVT=0;
    IFS0bits.T1IF=0;
}

void _ISR __attribute__((interrupt, auto_psv)) _T2Interrupt(void){
//HAY QUE ACTIVAR T2IE PARA HABILITAR LAS INTERRUPCIONES
    //UNA VEZ DENTRO DE LA RUTINA, PONER A CERO EL FLAG PARA QUE NO VUELVA A ENTRAR
    IFS0bits.T2IF=0;
    ref_temp++;


   if((ref_temp>(ref_temp2+tiempo_des)) && aux1==0){
   PORTBbits.RB0=1;
   asm("NOP");
   ref_temp2=ref_temp;
   aux1=1;
   }

   if((ref_temp>(ref_temp2+tiempo_act)) && aux1==1){
   PORTBbits.RB0=0;
   asm("NOP");
   ref_temp2=ref_temp;
   aux1=0;

   }



    TMR2=0;
    T2CONbits.TON=1;
    return;
}

void _ISR __attribute__((interrupt, auto_psv)) _U1RXInterrupt(void){//DESPUES DE 7 HORAS ESTO FUNCIONA
 
    IFS0bits.U1RXIF=0;//LA RUTINA DE INTERRUPCIÓN LEE ESTE FLAG PARA SALTAR AQUÍ, SI NO LO LIMPIAMOS SIEMPRE ESTÁ ENTRANDO
    //DESACTIVAMOS LA RECEPCIÓN TEMPORALMENTE
    IEC0bits.U1RXIE=0;

   dig1=U1RXREG;
   ref_temp5=ref_temp;
    while(IFS0bits.U1RXIF==0){
        if(ref_temp>ref_temp5+500){
            goto salir;
        }
    }
    IFS0bits.U1RXIF=0;
      dig2=U1RXREG;


      aux4=ascii_to_int(dig2);
      if(dig1 == 'A'){
          tiempo_act=aux4*65000;
      }

      if(dig1 == 'D'){
          tiempo_des=aux4*65000;
      }

      salir:
      IFS0bits.U1RXIF=0;
      IEC0bits.U1RXIE=1;
    return;
}

Este es el código que gestiona las interrupciones.
 
Última edición por un moderador:
Sin esquema, es difícil dar una opinión más precisa.

Puede ser la palabra de configuración.
Los valores de los registros en el POR. (Power On Reset)
Una mala configuración del Watch Dog Timer.
Inicialización incorrecta del programa.
Mal diseño del circuito impreso, ruido por filtraje deficiente o incorrecto de alimentación, etc.
 
PHP:
#include "p30f4013.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <p30F4013.h>
#include <libpic30.h>
#include <xc.h>


#pragma config FOSFPR = FRC_PLL8        // Oscillator (FRC w/PLL 8x)
#pragma config FCKSMEN = CSW_FSCM_OFF   // Clock Switching and Monitor (Sw Disabled, Mon Disabled)

// FWDT
#pragma config FWPSB = WDTPSB_16        // WDT Prescaler B (1:16)
#pragma config FWPSA = WDTPSA_512       // WDT Prescaler A (1:512)
#pragma config WDT = WDT_OFF            // Watchdog Timer (Disabled)

// FBORPOR
#pragma config FPWRT = PWRT_OFF         // POR Timer Value (Timer Disabled)
#pragma config BODENV = BORV27          // Brown Out Voltage (Reserved)
#pragma config BOREN = PBOR_OFF         // PBOR Enable (Disabled)
#pragma config MCLRE = MCLR_DIS         // Master Clear Enable (Disabled)

// FGS
#pragma config GWRP = GWRP_OFF          // General Code Segment Write Protect (Disabled)
#pragma config GCP = CODE_PROT_OFF     // General Segment Code Protection (Disabled)

// FICD
#pragma config ICS = ICS_PGD
El WDT está desactivado, el circuito ahora mismo está en la protoboard, alimentado con una fuente de banco estabilizada y comprobada con osciloscopio y un receptor de bluetooth hc-05, pero sin este último hace lo mismo.

Un saludo

PHP:
void activar_UART1(void){

           IPC2bits.U1RXIP=7;
    TRISFbits.TRISF2=1;//RECEPCIÓN
        TRISFbits.TRISF3=0;//TRANSMISIÓN
    //U1BRG=194;            //A 30 MHZ EL CICLO MÁQUINA PARA 9600 BAUDIOS DA UN VALOR DE 194.
    U1BRG=95;
        U1MODE=0x0000;
    U1STAbits.UTXISEL=0;
    U1MODEbits.UARTEN=1;        //SE CONFUGURA LA TRANSMISIÓN, 8 BITS DE DATOS, SIN PARIDAD, Y UNO DE STOP
    U1STAbits.UTXEN=1;              //SE HABILITA LA TRANSMISIÓN
    IFS0bits.U1TXIF=0;

}


void main(void) {

   
    TRISB=0x0000;
    PORTB=0;
    asm("NOP");
    TRISFbits.TRISF0=0;
    PORTFbits.RF0=0;
    activar_UART1();
    
    aux1=1;
    dig1='C';
    dig2='C';


    T2CON=0x0030;
    T2CONbits.TCS=0;        //SE SELECCIÓNA COMO FUENTE DEL TIMER EL RELOJ INTERNO, ESTO HACE QUE SE INCREMENTE UNA UNIDAD CADA CICLO MÁQUINA(30MHz)
    T2CONbits.TCKPS0=0;
    T2CONbits.TCKPS1=0;
    PR2=13305;
    TMR2=0;
 
Última edición por un moderador:
Entonces haz lo que te indiqué al principio.
Depura la inicialización del programa usando ICD.
Con eso podrás ver la ejecución paso a paso desde el principio y sabrás en qué parte se detiene.
 
Atrás
Arriba