Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

12/10/2015 #1


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. 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.
12/10/2015 #2
Moderador

Avatar de D@rkbytes

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.
12/10/2015 #3


Gracias por responder, el programa no responde sin ni siquiera realizar una llamada a las interrupciones.

Código 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__((interruptauto_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__((interruptauto_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.
12/10/2015 #4
Moderador

Avatar de D@rkbytes

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.
12/10/2015 #5


Código 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

Código 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
12/10/2015 #6
Moderador

Avatar de D@rkbytes

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.
12/10/2015 #7


No tengo mucha idea de como realizar un icd, tengo un pickit3.
12/10/2015 #8
Moderador

Avatar de D@rkbytes

Con ese mismo se puede. Ve la documentación que ofrece Microchip o lee los manuales del PICKit 3.

A mi el PICKit 3 me ha sido de gran ayuda con la depuración ICD.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.