Haz una pregunta
  Foros de Electrónica » Diseño digital » Interfaces y Programación
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

25/05/2016 #21


Uf tremendo gracias pero hay ciertas cosas que no entiendo todabía. No sé si podrías hacerme el favor de responderlas.

Después estás mezclando directivas de PIC C Compiler en XC8:
#INT_RB No es reconocido por el compilador XC8
Y la información de compilación lo indica con otra advertencia:
warning: (107) illegal # directive "INT_RB"
Si yo no poní la directiva #INT_RB luego de la variable global "variable" y antes de la función de interrupción no me tomaba la variable como global, es decir, el cambio que se producía en la función interrupción no era posible visualizarla en el main o en la función cuenta(). Como puedo hacer eso? es decir modificar el valor de la variable y mantener esa modificación externamente, ya que al parecer MPLAB no permite trabaajar con punteros y tampoco no sé como pasarselo a esa función.

Ahora vamos al problema principal.
Dices que el eco lo recibes por cambio de estado en RB4, pero la configuración de registros en la rutina de servicio de interrupción, no es correcta.
El bit RBIE del registro INTCON, habilita o deshabilita la interrupción por cambio de estado en el los bits <RB7:RB4>
Pero tú lo estás usando para determinar si se incrementa la variable "variable" (Redundante, pero así la nombraste)
En C, es más simple escribir; variable ++; que variable = variable + 1;
Claro es RBIF, lo que pasa es que he cambiado tanto el código que ya no pensaba y decidí pedir ayuda.

Ahora el código quedó de la siguiente manera:
Código:

#include <xc.h>

// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power-up Timer is disabled)
#pragma config CP = OFF         // Code Protection bit (Code protection disabled

#define _XTAL_FREQ 3582056


#define SALIDA PORTBbits.RB2

volatile int variable=0;


void interrupt isr(void) 
{ 
   INTCONbits.GIE=0;
if(INTCONbits.RBIF) 
{	
    variable++;
    
}
 INTCONbits.GIE=1;
 INTCONbits.RBIF=0;
 return;
}

int cuenta (void)
{ 
    int i=0; 
    int c=1;
     __delay_us(15); 
     PORTA=0xFF; 
     __delay_us(15); 
     PORTA=0x00; 
    
      while(c)
        {
              i++;      
             __delay_us(50);
             if(variable>0) 
             { 
                c=0;   
             }   
        } 
     variable=0;
     return (i);
}

void main(void) {
    

        TRISB=0b11110000; 
        TRISA=0x00; 
        INTCON=0x98;
        OPTION_REG=0x98;
        int d1=0;
        int l1=0;
         
        d1=cuenta();
           l1=d1;
             while(1)
             {
              l1=cuenta();   
              
             if(l1!=d1) 
             {
                 SALIDA=1; 
        __delay_ms(1000); 
      
             }
               variable=0;
             }
}
Pero sigo teniendo el mismo problema, es raro ya que cuando entra al while(1) asigna las distancias a l1 y a d1 con los valores obtenidos de la espera del eco pero hay veces que se prende el led y queda prendido, de manera que detecta distancias diferentes pero nada se interpone.
25/05/2016 #22


julian403 dijo: Ver Mensaje
Uf tremendo gracias pero hay ciertas cosas que no entiendo todabía. No sé si podrías hacerme el favor de responderlas.



Si yo no poní la directiva #INT_RB luego de la variable global "variable" y antes de la función de interrupción no me tomaba la variable como global, es decir, el cambio que se producía en la función interrupción no era posible visualizarla en el main o en la función cuenta(). Como puedo hacer eso? es decir modificar el valor de la variable y mantener esa modificación externamente, ya que al parecer MPLAB no permite trabaajar con punteros y tampoco no sé como pasarselo a esa función.


Claro es RBIF, lo que pasa es que he cambiado tanto el código que ya no pensaba y decidí pedir ayuda.

Ahora el código quedó de la siguiente manera:
Código:

#include <xc.h>

// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power-up Timer is disabled)
#pragma config CP = OFF         // Code Protection bit (Code protection disabled

#define _XTAL_FREQ 3582056


#define SALIDA PORTBbits.RB2

volatile int variable=0;


void interrupt isr(void) 
{ 
   INTCONbits.GIE=0;
if(INTCONbits.RBIF) 
{	
    variable++;
    
}
 INTCONbits.GIE=1;
 INTCONbits.RBIF=0;
 return;
}

int cuenta (void)
{ 
    int i=0; 
    int c=1;
     __delay_us(15); 
     PORTA=0xFF; 
     __delay_us(15); 
     PORTA=0x00; 
    
      while(c)
        {
              i++;      
             __delay_us(50);
             if(variable>0) 
             { 
                c=0;   
             }   
        } 
     variable=0;
     return (i);
}

void main(void) {
    

        TRISB=0b11110000; 
        TRISA=0x00; 
        INTCON=0x98;
        OPTION_REG=0x98;
        int d1=0;
        int l1=0;
         
        d1=cuenta();
           l1=d1;
             while(1)
             {
              l1=cuenta();   
              
             if(l1!=d1) 
             {
                 SALIDA=1; 
        __delay_ms(1000); 
      
             }
               variable=0;
             }
}
Pero sigo teniendo el mismo problema, es raro ya que cuando entra al while(1) asigna las distancias a l1 y a d1 con los valores obtenidos de la espera del eco pero hay veces que se prende el led y queda prendido, de manera que detecta distancias diferentes pero nada se interpone.
Pues si quieres mira este código que esta bien explicado; esta en Proton pero el objetivo es el mismo. CODIGO HC-SR04.

Por cierto, se dice: yo puse, no, yo poní.
25/05/2016 #23


He leido la explicación pero eso mismo he implementado, al parecer mi error es de código y la verdad que el mplab es bastante caprichoso.

Si observan mi código, luego de las configuraciones el algoritmo es este. Se llama a la función cuenta que envía un pulso al trigger y cuenta hasta que llega el flanco descendente del eco (a mi no me interesa medir distancia sino detección o cambio de distancia), una vez obtenido el valor de la cuenta, almacenado en la variable d1, entra al while donde se observa nuevamente la distancia y se almacena en l1 y se compara con d1 (que es la distancia anterior), si es diferente prende led sino nada y dicho hecho se vuelve a repetir indefinidamente.

El problema es que el led siempre está prendido y tendría que prender solamente cuando algo se interponga entre el sensor.
25/05/2016 #24


julian403 dijo: Ver Mensaje
He leido la explicación pero eso mismo he implementado, al parecer mi error es de código y la verdad que el mplab es bastante caprichoso.

Si observan mi código, luego de las configuraciones el algoritmo es este. Se llama a la función cuenta que envía un pulso al trigger y cuenta hasta que llega el flanco descendente del eco (a mi no me interesa medir distancia sino detección o cambio de distancia), una vez obtenido el valor de la cuenta, almacenado en la variable d1, entra al while donde se observa nuevamente la distancia y se almacena en l1 y se compara con d1 (que es la distancia anterior), si es diferente prende led sino nada y dicho hecho se vuelve a repetir indefinidamente.

El problema es que el led siempre está prendido y tendría que prender solamente cuando algo se interponga entre el sensor.
El lenguaje C no me gusta; con Proton el programa que quieres, lo haces en 3 minutos.
25/05/2016 #25


Pues creo que el problema puede estar en variable. Fijensen que cuando ocurre la primera vez la interrupción, para setear d1, variable es modificada aumentando en una unidad. Y cuando sucede eso, sale del while dentro de la función cuenta, quedando seteada la cuenta en la variable c. Luego pongo a cero la variable "variable" pero no sé si se mantiene globalmente ese cero luego de que sale de cuenta() o no.

Código:
#include <xc.h>
#include <stdint.h>

// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power-up Timer is disabled)
#pragma config CP = OFF         // Code Protection bit (Code protection disabled

#define _XTAL_FREQ 3582056


#define SALIDA PORTBbits.RB2

volatile char variable=0;


void interrupt isr(void) 
{ 
    if(PORTBbits.RB4==0) 
    {
    variable++;
    } 
    INTCONbits.RBIF = 0;    //clear interrupt request flag
}


char cuenta (void)
{ 
   
    char c=0;
     __delay_us(15); 
     PORTA=0xFF; 
     __delay_us(15); 
     PORTA=0x00; 
    
     while(!(variable))
     {
         c++;
         __delay_us(100);
     }
     variable=0;
     return c;
}

void main(void) {
    

        TRISB=0b11110000; 
        TRISA=0x00; 
        INTCON=0x98;
        OPTION_REG=0x98;
        char d1=0;
        char l1=0;
         
        d1=cuenta();
        l1=d1;
        while(1)
        {
            l1=cuenta();   
              
            if(l1!=d1) 
            {
                SALIDA=1; 
                __delay_ms(1000); 
      
             }
            d1=cuenta();
           
        }
}
No sé si me doy a entender lo que quiero decir. En sí, tampoco entiendo la parte de que en la interrupción tengo que leer el puerto.
25/05/2016 #26
Moderador

Avatar de D@rkbytes

Te iba a mencionar sobre el servicio de interrupción, pero veo que ya lo modificaste.
Ahora prueba de ésta forma:
Código PHP:
void interrupt isr (void

    if(
INTCONbits.RBIF
    {    
        if(!
PORTBbits.RB4)
        {
            
variable++;
        }
        
INTCONbits.RBIF 0;
        
PORTB = (PORTB 0xF0);
    }

En la subrutina "cuenta" debes poner un "break;" cuando quieras salir.
Por ejemplo, en esta parte:
Código PHP:
             if(variable 0
             { 
                
0;
                break;
             } 
De otra forma el ciclo seguirá y no retornará de ahí.

Recomendaciones:
Activa las resistencias pull-up del puerto B en el registro OPTION_REG.
Puedes hacer uso de Proteus para entrar en modo de depuración y ver la ejecución del programa paso a paso.
Cuando entras al modo de depuración, podrás ver el valor de las variables y el estado de los registros.
25/05/2016 #27


Excelente al parecer ha mejorado el funcionamiento, debo seguir puliéndolo . Es decir ahora puse que muestre por el puerto RB1 cuando no halla cambio y por el RB2 cuando hay un cambio y de vez en cuando me tira que hay un cambio cuando no lo hay. Por cierto veo que con

PORTB = (PORTB & 0xF0);
guardas los valores de la parte alta del puerto B ¿por qué?

En la subrutina "cuenta" debes poner un "brake;" cuando quieras salir.
Por ejemplo, en esta parte:
ahi no entiendo lo que decis ya que la subrutina cuenta tiene la siguiente forma:

Código:
int cuenta (void)
{ 
   
    int c=0;
     __delay_us(15); 
     PORTA=0xFF; 
     __delay_us(15); 
     PORTA=0x00; 
    
     while(!(variable))
     {
         c++;
         __delay_ms(1);
     }
     variable=0;
     return c;
}
¿donde dice que debo poner el break? yo pensaba que el break era solo para salir por un imprevisto o condición pero en este caso se sale del while cuando la variable pasa a tener el valor 1.

¿Es muy importante que ponga los capacitores de 27pF entre el cristal?
25/05/2016 #28
Moderador

Avatar de D@rkbytes

julian403 dijo: Ver Mensaje
Por cierto, veo que con

PORTB = (PORTB & 0xF0);
guardas los valores de la parte alta del puerto B ¿por qué?
Es para restablecer un valor al puerto B, bits <RB7:RB4> para un nuevo cambio de estado en esos bits.
Suele pasar que si no se hace eso, no se logra salir del servicio de interrupción.


julian403 dijo: Ver Mensaje
No entiendo lo que decís, ya que la subrutina cuenta tiene la siguiente forma:

Código:
int cuenta (void)
{ 
   
    int c=0;
     __delay_us(15); 
     PORTA=0xFF; 
     __delay_us(15); 
     PORTA=0x00; 
    
     while(!(variable))
     {
         c++;
         __delay_ms(1);
     }
     variable=0;
     return c;
}
¿donde dice que debo poner el break? yo pensaba que el break era solo para salir por un imprevisto o condición pero en este caso se sale del while cuando la variable pasa a tener el valor 1.
El break sirve precisamente para romper una condición, pero lo mencioné al ver el código anterior.
Este nuevo código no lo he analizado y eso era para el código anterior.
julian403 dijo: Ver Mensaje
¿Es muy importante que ponga los capacitores de 27pF entre el cristal?
Si, pero depende del tipo de cristal, ya que existen unos que los tienen internos y ya no hacen falta.
Pero sirven para mantener una oscilación estable y también para ajustar la frecuencia.
Colocalos de todas formas. (Con un frecuencímetro puedes encontrar el valor correcto)
25/05/2016 #29


Es para restablecer un valor al puerto B, bits <RB7:RB4> para un nuevo cambio de estado en esos bits.
Suele pasar que si no se hace eso, no se logra salir del servicio de interrupción
Claro eso es lo que no entiendo, según lo que he visto de la hoja de datos hay que leer el puerto para que se produzca la interrupción. Eso me han dicho en el foro de microchip y en el datasheet dice esto:

The inputs pins (of RB7:RB4) are compared with the old value latched on the last read of PORTB.

El traductor me dice:
Los pines de entradas ( de RB7 : RB4 ) se comparan con el valor antiguo enclavado en la última lectura del PORTB.

Lo que pasa es que el RB4 hay un pulso y la interrupción según el OPTION_REG se producen en el flanco descendente, así que la última lectura sería un valor positivo. O sería el último valor del flanco descendente?
26/05/2016 #30
Moderador

Avatar de D@rkbytes

julian403 dijo: Ver Mensaje
Claro eso es lo que no entiendo, según lo que he visto de la hoja de datos hay que leer el puerto para que se produzca la interrupción. Eso me han dicho en el foro de microchip y en el datasheet dice esto:

The inputs pins (of RB7:RB4) are compared with the old value latched on the last read of PORTB.

El traductor me dice:
Los pines de entradas ( de RB7 : RB4 ) se comparan con el valor antiguo enclavado en la última lectura del PORTB.
Así es, pero por ser una interrupción por cambio de estado, se puede producir en cualquier condición.
O sea que el flanco de interrupción no se establece en ningún registro.
Es decir, no es como la interrupción por RB0 en donde si se puede elegir si se dará por flanco ascendente o por flanco descendente.
En este caso la interrupción se ejecutará cuando cualquier pin <RB7:RB4> cambie de estado.
Y se puede ejecutar cuando se lee el puerto B.
Por eso no es recomendable usar lecturas del puerto cuando se usa esta interrupción.
Por lo tanto, la configuración del registro OPTION_REG para establecer un flanco de interrupción, no tiene ningún efecto en esta interrupción.

julian403 dijo: Ver Mensaje
Lo que pasa es que el RB4 hay un pulso y la interrupción según el OPTION_REG se producen en el flanco descendente, así que la última lectura sería un valor positivo.
¿O sería el último valor del flanco descendente?
Por lo explicado anteriormente, durante el servicio de interrupción se debe leer el puerto B y así determinar cuál fue el pin que cambió de estado, y esto se determina por la lógica de estados basados en resistencias pull-up o pull-down en <RB7:RB4> y conforme al estado lógico ingresado a cada pin.

Una comparación sobre el estado esperado es suficiente para tomar decisiones y posteriormente salir de la rutina, ya que desde que se inicia el programa se dará la interrupción por cambio de estado.

Sobre lo expuesto, agrego lo siguiente:
El bit INTEDG del registro OPTION_REG, es únicamente para establecer el flanco de interrupción del bit 0 del puerto B (RB0)
Por lo cual, su configuración no tiene efecto sobre los pines <RB7:RB4>
27/05/2016 #31


Lo que me parece raro es como se observa en la siguiente imágen, en la posición de memoria de programa 0x04 (donde va al interrupción) NO HAY UN SALTO (goto a alguna parte) y eso está mal según lo que entiendo porque el pic16f84 solo recerva solo una posición ahi, así que si se usa la interrupción hay que hacer un salto a otra parte para implementar la rutina de la interrupción.

Con razón no me funciona, eso debe ser pero es el compilador el que genera eso. ¿Qué puedo hacer?
Imágenes Adjuntas
Tipo de Archivo: jpg interrupción.jpg (69,3 KB (Kilobytes), 5 visitas)
27/05/2016 #32
Moderador

Avatar de D@rkbytes

Es más fácil que uses el Timer 1 para contar el tiempo que tarda el eco y posteriormente lo conviertas a distancia.
27/05/2016 #33


¿Y cómo lo podría implementar en C? Pienso en lo siguiente, como ya debes saber la distancia es proporcional al ancho del pulso por lo tanto:
Código:
void interrupt isr(void) 
{ 
    
  if(INTCONbits.RBIF) 
  {
      if(PORTBbits.RB4) 
      {
          //acá iría una función que maneja el timer pero desconozco que lo inicialice
      }
       if (!PORTBbits.RB4) 
        {
          //acá daría fin al timer y lo guardaría en la variable variable
         }
  }
    INTCONbits.RBIF = 0;   
     PORTB = (PORTB & 0xF0);//clear interrupt request flag
}
27/05/2016 #34
Moderador

Avatar de D@rkbytes

Buscando un poquito, encontré algo sobre lo que te mencioné:
Interfacing HC-SR04 Ultrasonic Sensor with PIC Microcontroller

Ahí encontrarás un programa para XC8.
28/05/2016 #35


Ok buenisimo, pero en el pic16f84 ¿cómo enciendo el timer? ¿poniendo a 1 TOIE? y lo apago poniendo a cero TOIE. Quedando guardada la cuenta en TMR0

Porque veo que en el pic16f877 en el programa lo enciende con: TMR1ON = 1;
28/05/2016 #36
Moderador

Avatar de D@rkbytes

Ahí hay un detalle. El 16F84 no tiene Timer 1, sólo Timer 0, y eso si es un problema porque no se obtendrá la misma respuesta usando el Timer 0, porque el Timer 1 es de 16 bits y el Timer 0 es de 8 bits.
28/05/2016 #37


Si me parecía, no tengo el 16f877 pero tengo el 18f2550 pero el problema que tengo ahí es la configuración de los fusibles. Si me pasas la configuración de los fusible para dicho pic, no molestaré más. Enserio, la configuración para usarlo como un pic de la linea 16f, con cristal externo y sin preescaler, sin usb. bien básico.
28/05/2016 #38
Moderador

Avatar de D@rkbytes

Esta sería la palabra de configuración para el PIC18F2550:
Código PHP:
#pragma config CONFIG1L CPUDIV = OSC1_PLL2, PLLDIV = 1, USBDIV = 1
#pragma config CONFIG1H FCMEN = OFF, IESO = OFF, FOSC = XT_XT
#pragma config CONFIG2L PWRT = ON, VREGEN = OFF, BORV = 3, BOR = ON 
#pragma config CONFIG2H WDTPS = 32768, WDT = OFF
#pragma config CONFIG3H CCP2MX = ON, PBADEN = OFF, MCLRE = ON, LPT1OSC = ON
#pragma config CONFIG4L STVREN = ON, DEBUG = OFF, LVP = OFF, XINST = OFF
#pragma config CONFIG5L CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF
#pragma config CONFIG5H CPB = OFF, CPD = OFF
#pragma config CONFIG6L WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
#pragma config CONFIG6H WRTB = OFF, WRTC = OFF, WRTD = OFF
#pragma config CONFIG7L EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
#pragma config CONFIG7H EBTRB = OFF

#define _XTAL_FREQ 3582056 
Coloqué todos los fuses por si necesitas cambiar alguno, pero la palabra de configuración se puede acortar permitiendo que el compilador use los que tiene por defecto.
Así como está, es la configuración que requieres. (XT: Cristal menor a 4 MHz.)

Los fuses y la descripción de cada uno, la puedes encontrar en el archivo "18f2550.html"
Esa documentación se encuentra en la carpeta "C:/Program Files/Microchip/xc8/v1.37/docs/chips/"
En mi caso en la "v.137" pero eso depende de la versión XC8 que tengas.
30/05/2016 #39

Avatar de Ardogan

D@rkbytes dijo: Ver Mensaje
...
D@rkbytes, te merecés un monumento a la paciencia .

@julian403: tratá de no empezar desde 0 con muchas cosas a la vez. Parecía que tu duda era específicamente con el HC-SR04 pero después tenías problemas con el compilador y sus directivas, después con las interrupciones y finalmente con el timer 0.
Empezá de a poco, resolvé de a 1 cosa a la vez, no todo al mismo tiempo.

Primero: estás pasando del compilador CCS al compilador XC8 (aparentemente) -->fijate las diferencias entre uno y otro, como se configura micro (pragma), como se declara una rutina de interrupción etc.
Si ya tuviste experiencia con el CCS probá "traducir" un programa que sabés que funciona al XC8.

Luego, manejo del HC-SR04: requiere manejar 1 salida, 1 entrada y medir tiempo.
  1. Tu primer programa podría ser prender y apagar un led (aprendemos a manejar 1 salida).
    No puedo dejar de enfatizar lo importante que es este primer paso, ¿por que?, porque con esto ya estás comprobando que tenés tu proyecto bien configurado, que el compilador genera bien el programa y/o el .hex, que el reloj está bien configurado, que el micro está bien alimentado, que el programador/depurador funciona, que configuraste bien el pin usando los registros correctos, que no falto conectar ningún pin imprescindible del pic, etc.
  2. El segundo programa que el led se encienda y apague cada x milisegundos.
  3. El 3ro que el led se prenda y se apague al apretar un botón (un tact switch por ejemplo), acá incorporas el manejo de 1 entrada).
  4. Luego (si querés, podría no hacer falta) el manejo de una interrupción--> mismo ejemplo del botón pero que el apagado y encendido se haga a través de la rutina de interrupción del pic.
No quiero alargar demasiado, pero la idea es: avanzar de a poco, un pasito atrás del otro, ir de menor a mayor. Cada cosita nueva que hacés ya sabés que lo que hiciste anteriormente funciona (ya lo probaste, esta testeado!!!).
Si hay un problema tenés que buscarlo en lo último que hiciste, nada más, no hace falta revisar el proyecto completo.
Si ponés 3 o 4 cosas juntas y enchufaste algo nuevo, no sabés si el error es en hardware (algo mal conectado), en software, en configuración, si lo que funciona mal es la rutina de interrupción o el programa del while(1), etc.

Es algo que siempre pasa en el foro, pero bueno, me puse en viejo renegón. No pasa nada, yo al principio también quería tener un programa completo funcionando (hey!!!, la simulación anda, por qué no va a andar en la placa física? ) y después al querer programarlo no funcionaba nada.

Buena suerte!!!!.

--------------------------------------
Addendum:
Ojo!!!, eso no significa que siempre hay que diseñar bottom-up y nunca top-down (filosofía de diseño). Hay un lugar para trabajar de arriba para abajo, y de abajo hacia arriba. Pero si se tiene el hardware a mano es mejor aprender a manejar el hardware y conocer mejor las capacidades básicas (eso es bottom-up) y después pasar al esquema top-down, ver que necesitamos realmente e implementarlo.
Si uno hace bottom-up solamente vas a terminar con un montón de funciones que no vas a usar nunca, sobre-diseñando y haciendo el código mucho más complicado; cuando lo que se busca es tener algo lo más sencillo posible que cumpla con nuestras necesidades.
27/09/2016 #40


Problemas con mikroc, timer 1
Realicé el programa con el compilador MikroC, con el pic 16f887 y utilicé el timer 1.
Lo compilé y no hubo errores, pero al momento de probarlo, no realiza la condición, como si no hiciera la detección.

Mi circuito físico está bien conectado en sus respectivos pines, pero necesito saber en qué falla.
Uso el módulo ultrasónico HC-SR04 y no descubro el problema.

Menciono que RA1_bit es el pin echo y RB1_bit es el trigger
Código PHP:
// prueba del sensor ultrasónico con PIC 16F887

unsigned int ConteoH;
unsigned char ConteoL;
unsigned int ConteoF;
int Distancia;


void main() {

Ansel=0;
Anselh=0;
TrisA=1;
TrisB=0;
Portb=0;
Porta=0;


T1CON.T1OSCEN=0// Deshabilitar oscilador externo
T1CON.TMR1CS=0;

while (
1){

TMR1H=0X8E// VALOR INICIAL 0X8EB7=36535 CONTEO
TMR1L=0XB7;

Delay_us(5);
RB1_bit=1;     //Pulso inicial al sensor
Delay_us(10);
RB1_bit=0;

while(!
RA1_bit); // Mientras no haya respuesta del sensor no se hará nada

RB3_bit=0;
T1CON.TMR1ON=1// Encender Timer

while(RA1_bit &amp;&amp; !T1CON.TMR0IF); // Espera de regreso de finalizado del pulso del sensor
// TMR1IF es el conteo máximo o desborde, indicando que no se detectó un objeto
// Mientras RA1 siga alto y el timer no desborde no se hará nada

T1CON.TMR1ON=0// Desactivar Timer
T1CON.TMR0IF=0// Eliminar desborde(conteo máximo)

ConteoHTMR1H// Leer máximo conteo de TMR1H
ConteoLTMR1L// Leer máximo conteo de TMR1L

ConteoHConteoH <<8// Dezplazar posiciones para poder juntar con el otro registro
ConteoFConteoH ConteoL// ConteoF= Conteo final
// Sumar los 2 registros

Distancia= ((ConteoF-0x8eb7)/29)/2// Operación para obtener la distancia en cm según la detección del sensor

// Condiciones

if(Distancia<=20){
RB2_bit=1//encender LED
Delay_ms(2000);
RB2_bit=0;
}
}

Por favor, ¿Alguien podría resolver mi duda?
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Buscar más temas sobre:
Lupa Interfaces y Programación

Lenguajes de programación, gestión y manejo de puertos

Cerrar
Foros de Electrónica » Diseño digital » Interfaces y Programación

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