Autor Tema: error programa 12f675 en XC8  (Leído 2420 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
error programa 12f675 en XC8
« en: 08 de Octubre de 2013, 22:42:15 »
Hola, hay un programita que me esta volviendo loco y no puedo hacer andar bien. Tengo un sensor de ultrasonido HC-08. El mismo tiene 2 pines, TRG y ECO. El funcionamiento es el siguiente, pongo en alto la señal de TRG, espero 10us, pongo en 0 la ceñal de TRG. Con esto disparamos el sensor. Éste emite unos pulsos de ultrasonido y pone en 1 la señal ECO. Cuando recive el rebote de los pulsos de us pone en 0 la señal de eco. Yo pretendo hacer una plaquita para adosarle al sensor y que este constantemente chequeando si "VE" un objeto dentro del rango establecido.
Para ello cree el siguiente código:

main.c

Código: [Seleccionar]

/*
 * File:   main.c
 * Author: elgarbe
 *
 * Created on 12 de junio de 2013, 19:01
 */

#define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro
//Funciones para delay's. No son muy precisas por lo que vi en el osciloscopio
//REVISAR
#pragma intrinsic(_delay)
extern void _delay(unsigned long);
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>         // Librería XC8. Este include termina incluyendo al 16F883.h

//Includes locales, configuracion de fusibles y del IO
#include "configuracion_de_fuses.c"
#include "configuracion_hard.c"
#include "funciones.c"


/*------------------------DECLARACION DE FUNCIONES---------------------------*/

void conf_oscilador (void); // Configuracion del oscilador
void conf_puertos (void);   // Configuracion de puertos I/O
void conf_timer0 (void);    // Configuracion registros TIMER0

/********** Funcion para la ISR (Rutina de Servicio de Interrupcion) **********/
void interrupt interrupciones (void) {
    //Verifico que interrupcion se disparó

/* el resto de las interrupciones utilizadas se deben analizar a coninuacion*/
}

/*************************** Programa Principal ******************************/
 void main(void) {
    conf_oscilador ();
    conf_puertos ();
//    conf_timer0 ();
    //conf_timer1 ();

//    INTCONbits.TMR0IE = 1;       //Habilito interrupcion por TMR0
//    INTCONbits.PEIE = 1;         //Habilito las interrupciones de los perifericos

    INTCONbits.GIE = 0;          //Habilito Interrupcion Global
//    int Dist=0;

    LED=1;
    __delay_ms(1000);
    LED=0;

    /*-------------------------- Bucle infinito ------------------------------*/
    do{
//        ADCON0bits.GO_nDONE=1;          //Arranco la conversion
//        while(ADCON0bits.GO_nDONE);     //Espero a que termine
//        Dist=ADRESH;
        TRG=1;
        __delay_us(10);
        TRG=0;
        while(ECO==0);
        __delay_ms(3);
        if(ECO==0){
            LED=1;
        }else{
            LED=0;
        }
        __delay_ms(100);
    }while(1);
}


configuracion_hardware.c

Código: [Seleccionar]
/************** DEFINICIONES *************/

#define LED GPIObits.GP0 // Define el pin A0 para Salida LED

#define REF GPIObits.GP2 // Define el pin a2 para entrada de referencia distancia

#define ECO GPIObits.GP4 // Define el pin a4 para Eco del US
#define TRG GPIObits.GP5 // Define el pin a5 para Triger del US


configuracion_de_fuses.c

Código: [Seleccionar]

#include <xc.h>

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)


funciones.c

Código: [Seleccionar]
/*------------------------------FUNCIONES------------------------------------*/

/* Funcion para la configuracion del oscilador del pic16f88 */
void conf_oscilador (void) {

}
/* Funcion para la configuracion de los puertos entrada salida del pic 16f88 */
void conf_puertos (void) {

    ADCON0bits.ADFM=0;
    ADCON0bits.VCFG=0;
    ADCON0bits.CHS1=1;
    ADCON0bits.CHS0=0;

    ANSEL=0b00010100;   //Eligo AN2 como entrada analogica y el tiempo de convrsion

    TRISIO=0b01011110; //RA0 y RA5 salidas

    GPIO=0;
}

/* Funcion para la configuracion del modulo Timer0 como temporizador */
void conf_timer0 (void) {

    // Configuración del timer 0. Con Osc de 4MHz la frecuencia de entrada del TMR
    // es 1MHz, con el prescaler en 256 tenemos una cuenta cada 256uSeg. Al ser
    // de 8 bits tenemos interrupcion cada 65,535 mSeg.
    TMR0 = 0;
    OPTION_REGbits.PS0 = 1;
    OPTION_REGbits.PS1 = 1;
    OPTION_REGbits.PS2 = 1;     //Prescaler en 256
    OPTION_REGbits.PSA = 0;     //Prescaler al TMR0 y no al WDT
    OPTION_REGbits.T0CS = 0;    //Clock Source es el Ciclo de Instruccion
}

/* Funcion para la configuracion del modulo Timer1 como temporizador */
void conf_timer1 (void) {

    // Configuración del timer 1. Con Osc de 4MHz la frecuencia de entrada del TMR
    // es 1MHz, con el prescaler en 1 tenemos una cuenta cada 1uSeg. Al ser
    // de 16 bits tenemos interrupcion cada 65,535 mSeg.
    // El timer 1 se usa como base de tiempos de CCP2
    TMR1 = 0;
    T1CONbits.T1CKPS = 0x00;    //Prescaler en 2 -> XX00
    T1CONbits.TMR1ON = 0;       //Enable Timer1
}


El problema que estoy teniendo es que el LED parpadea cuando detecta algo en el rango de los 3ms.
El programa pone a 1 trg, espera 10us y pone a 0 trg.
Espera a que el ECO se ponga en 1.
Luego espera 3ms y consulta si el ECO ya esta en 0. si esta en 0 es porque en esos 3ms se recivio el rebote de los pulsos de us. si no esta en 0 es porque aún esta viajando la señal y por lo tanto no hay objetos el rango.

Pongo el osciloscopio en la salida y veo que el led se apaga el tiempo exacto que pongo en el delay (3ms en el ejemplo). si aumento ese tiempo, aumenta el tiempo apagado del led....

alguna idea????

por otra parte en la placa hay un preset y por medio del ADC quería poder varial el rango de deteccion. El tema es que __delay_ms solo acepta constantes, no variables... solucion???

saludos y gracias!
-
Leonardo Garberoglio

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: error programa 12f675 en XC8
« Respuesta #1 en: 09 de Octubre de 2013, 22:01:43 »
Hola, hay un programita que me esta volviendo loco y no puedo hacer andar bien. Tengo un sensor de ultrasonido HC-08. El mismo tiene 2 pines, TRG y ECO. El funcionamiento es el siguiente, pongo en alto la señal de TRG, espero 10us, pongo en 0 la ceñal de TRG. Con esto disparamos el sensor. Éste emite unos pulsos de ultrasonido y pone en 1 la señal ECO. Cuando recive el rebote de los pulsos de us pone en 0 la señal de eco. Yo pretendo hacer una plaquita para adosarle al sensor y que este constantemente chequeando si "VE" un objeto dentro del rango establecido.
Para ello cree el siguiente código:

main.c

Código: [Seleccionar]

/*
 * File:   main.c
 * Author: elgarbe
 *
 * Created on 12 de junio de 2013, 19:01
 */

#define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro
//Funciones para delay's. No son muy precisas por lo que vi en el osciloscopio
//REVISAR
#pragma intrinsic(_delay)
extern void _delay(unsigned long);
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>         // Librería XC8. Este include termina incluyendo al 16F883.h

//Includes locales, configuracion de fusibles y del IO
#include "configuracion_de_fuses.c"
#include "configuracion_hard.c"
#include "funciones.c"


/*------------------------DECLARACION DE FUNCIONES---------------------------*/

void conf_oscilador (void); // Configuracion del oscilador
void conf_puertos (void);   // Configuracion de puertos I/O
void conf_timer0 (void);    // Configuracion registros TIMER0

/********** Funcion para la ISR (Rutina de Servicio de Interrupcion) **********/
void interrupt interrupciones (void) {
    //Verifico que interrupcion se disparó

/* el resto de las interrupciones utilizadas se deben analizar a coninuacion*/
}

/*************************** Programa Principal ******************************/
 void main(void) {
    conf_oscilador ();
    conf_puertos ();
//    conf_timer0 ();
    //conf_timer1 ();

//    INTCONbits.TMR0IE = 1;       //Habilito interrupcion por TMR0
//    INTCONbits.PEIE = 1;         //Habilito las interrupciones de los perifericos

    INTCONbits.GIE = 0;          //Habilito Interrupcion Global
//    int Dist=0;

    LED=1;
    __delay_ms(1000);
    LED=0;

    /*-------------------------- Bucle infinito ------------------------------*/
    do{
//        ADCON0bits.GO_nDONE=1;          //Arranco la conversion
//        while(ADCON0bits.GO_nDONE);     //Espero a que termine
//        Dist=ADRESH;
        TRG=1;
        __delay_us(10);
        TRG=0;
        while(ECO==0);
        __delay_ms(3);
        if(ECO==0){
            LED=1;
        }else{
            LED=0;
        }
        __delay_ms(100);
    }while(1);
}


configuracion_hardware.c

Código: [Seleccionar]
/************** DEFINICIONES *************/

#define LED GPIObits.GP0 // Define el pin A0 para Salida LED

#define REF GPIObits.GP2 // Define el pin a2 para entrada de referencia distancia

#define ECO GPIObits.GP4 // Define el pin a4 para Eco del US
#define TRG GPIObits.GP5 // Define el pin a5 para Triger del US


configuracion_de_fuses.c

Código: [Seleccionar]

#include <xc.h>

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)


funciones.c

Código: [Seleccionar]
/*------------------------------FUNCIONES------------------------------------*/

/* Funcion para la configuracion del oscilador del pic16f88 */
void conf_oscilador (void) {

}
/* Funcion para la configuracion de los puertos entrada salida del pic 16f88 */
void conf_puertos (void) {

    ADCON0bits.ADFM=0;
    ADCON0bits.VCFG=0;
    ADCON0bits.CHS1=1;
    ADCON0bits.CHS0=0;

    ANSEL=0b00010100;   //Eligo AN2 como entrada analogica y el tiempo de convrsion

    TRISIO=0b01011110; //RA0 y RA5 salidas

    GPIO=0;
}

/* Funcion para la configuracion del modulo Timer0 como temporizador */
void conf_timer0 (void) {

    // Configuración del timer 0. Con Osc de 4MHz la frecuencia de entrada del TMR
    // es 1MHz, con el prescaler en 256 tenemos una cuenta cada 256uSeg. Al ser
    // de 8 bits tenemos interrupcion cada 65,535 mSeg.
    TMR0 = 0;
    OPTION_REGbits.PS0 = 1;
    OPTION_REGbits.PS1 = 1;
    OPTION_REGbits.PS2 = 1;     //Prescaler en 256
    OPTION_REGbits.PSA = 0;     //Prescaler al TMR0 y no al WDT
    OPTION_REGbits.T0CS = 0;    //Clock Source es el Ciclo de Instruccion
}

/* Funcion para la configuracion del modulo Timer1 como temporizador */
void conf_timer1 (void) {

    // Configuración del timer 1. Con Osc de 4MHz la frecuencia de entrada del TMR
    // es 1MHz, con el prescaler en 1 tenemos una cuenta cada 1uSeg. Al ser
    // de 16 bits tenemos interrupcion cada 65,535 mSeg.
    // El timer 1 se usa como base de tiempos de CCP2
    TMR1 = 0;
    T1CONbits.T1CKPS = 0x00;    //Prescaler en 2 -> XX00
    T1CONbits.TMR1ON = 0;       //Enable Timer1
}


El problema que estoy teniendo es que el LED parpadea cuando detecta algo en el rango de los 3ms.
El programa pone a 1 trg, espera 10us y pone a 0 trg.
Espera a que el ECO se ponga en 1.
Luego espera 3ms y consulta si el ECO ya esta en 0. si esta en 0 es porque en esos 3ms se recivio el rebote de los pulsos de us. si no esta en 0 es porque aún esta viajando la señal y por lo tanto no hay objetos el rango.

Pongo el osciloscopio en la salida y veo que el led se apaga el tiempo exacto que pongo en el delay (3ms en el ejemplo). si aumento ese tiempo, aumenta el tiempo apagado del led....

alguna idea????

por otra parte en la placa hay un preset y por medio del ADC quería poder varial el rango de deteccion. El tema es que __delay_ms solo acepta constantes, no variables... solucion???

saludos y gracias!

  Puede ser que haya alguna variación de lo que esté detectando... tal vez está "detectando" y "no detectando" alternadamente y por ello el parpadeo.

  Para el tema de una función de delay que acepte parámetros podrías hacer algo así...

Código: C
  1. void mi_delay(unsigned int tiempo) // retardo en ms
  2. {
  3.   unsigned int _tiempo;
  4.   for (_tiempo = tiempo; _tiempo > 0; _tiempo--)
  5.   {
  6.     __delay_ms(1);
  7.   }
  8. }

  En realidad el retardo será un poco mayor que al pasado como parámetro, debido al consumo propio del ciclo for. Pero tal vez se pueda usar "__delay_us()" para lograr una aproximación mayor.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re: error programa 12f675 en XC8
« Respuesta #2 en: 09 de Octubre de 2013, 22:31:24 »
Podría ser, pero cuando le pongo el osciloscopio veo que el tiempo que se apaga el led es exactamente el tiempo del delay_ms y si varío ese tiempo varía el parpadeo...

Como no podía avanzar probe el siguiente código en CCS:

Código: [Seleccionar]
#include <12F675.h>

#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc NO I/O
#FUSES NOMCLR                   //Master Clear pin disabled

#use delay(clock=4000000)

#define LED   PIN_A0
#define ECO   PIN_A4
#define TRG   PIN_A5
#define REF   PIN_A2

#use fast_io(A)

#byte PORTA = 0x5
#byte TRISA=0x85

long lADC=0;        //Valor leido del ADC

//*****************************************************************************
//                            COMIENZA EL PROGRAMA PRINCIPAL
//*****************************************************************************
void main()
{

   TRISA=0b00010100;      //Todo Salidas
   setup_adc(ADC_CLOCK_INTERNAL);
   //Voy a usar el pin 2 (AN2) para la Batería, la referencia es GND y +5V
   setup_adc_ports(sAN2 | VSS_VDD);
   //Dentro de los puertos usados (solo el 0) elijo el canal 2 para convertir
   set_adc_channel(2);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
     
//   enable_interrupts(INT_TIMER0);
//   enable_interrupts(GLOBAL);
   
   PORTA = 0;

   output_high(LED);
   delay_ms(1000);
   output_low(LED);
   
   do{
      lADC=read_adc(ADC_START_AND_READ);
      delay_ms(1);
      lADC=lADC*5;
     
      output_high(TRG);
      delay_us(10);
      output_low(TRG);
      while(input(ECO)==0);
      delay_us(lADC);
      if(input(ECO)==0){
         output_high(LED);
      }else{
         output_low(LED);
      }
      delay_ms(100);
   }while(TRUE);
}

Le agregue la lectura del ADC para regular la distancia a detectar. Este código anda de 10, no hay parpadeo del led... es muy raro lo del XC8... la linea problemática es:

Código: [Seleccionar]
        while(ECO==0);
        __delay_ms(3);
        if(ECO==0){

ese delay despues del while... no se, ya le di vueltas por todos lados y no logro hacerlo andar... por ahora quedará el firmware hecho en CCS.

Saludos!
-
Leonardo Garberoglio