Translate

REVOLUCIONES POR MINUTO CON PIC16F877A

En este programa veremos como podemos medir mediante una entrada externa la frecuencia que ingresa, cabe destacar que es un frecuencímetro en el cual se realiza una equivalencia para obtener las revoluciones por minuto de la entrada seleccionada.

Como primera medida hay que destacar que se debe realizar un circuito externo para poder medir la frecuencia de por ejemplo: un motor. Con lo cual veremos ese circuito a continuación, el cual será conectado a una entrada del pic16f877a y podremos visualizar su frecuencia para su posterior conversión a rpm.

Sensores: proyecto de diseño de detectores de proximidad de bajo ...
Este circuito no es mas que un detector de obstáculos, en cual si tenemos por ejemplo: un motor con una o mas hélices, el circuito este detectará cuando esta hélice se interpongan, por lo tanto generara que el circuito se cierre y de esta forma enviaremos la salida del comparador a la entrada del pic.

Respecto del Pic16f877A, la entrada funcionará de la siguiente forma, cuando se detecte el primer flanco ascendente de la señal, este comenzará la cuenta del Timer 1, el cual contara hasta que este detecte el segundo flanco ascendente. Con esto obtendremos el periodo de la señal entrante, pudiendo tener lo más exacta posible la frecuencia que ingresa. 

Con la siguiente imagen ilustraremos como seria:
TELEINFORMATICA : Teoria De Señales


Programa Principal:

// PIC16F877A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include "RPM.h"
#include "LCD_control.h"
#include "LCD_NUMEROSGRANDES.h"


/*========================================================================
  FUNCTION:     main()
  DESCRIPTION:  Devuelve el valor de las rev por minuto(entero sin signo)
  PARAMETERS:   Ninguno
  RETURNS:      Nada
  REQUIREMENTS: Ninguno
========================================================================*/
void main(void)
{
    //Configuracion de puertos
    TRISD = 0x00;
    PORTD = 0x00;
    //Inicializaciones
    LCD_init();
    RPM_init();
    
    LCD_command(CLEAR);
    LCD_array(1,1,"*    PIC16F877A    *");
    LCD_array(2,1,"*  MEDIDOR DE RPM  *");
    LCD_array(4,1,"*       ****       *");
    __delay_ms(2000);
    
    LCD_command(CLEAR);
    LCD_array(2,1,"*  REV POR MINUTO  *");
    LCD_array(1,1,"*       ****       *");
    LCD_array(3,1,"*                  *");
    LCD_array(4,1,"*       ****       *");
    
    while(1)
    {
        char buffer[10];
        
        //Carga el valor de rpm en una cadena de texto
        sprintf(buffer,"%4u",(int)RPM_read());
        LCD_array(3,8,buffer);          //Imprime valor de rpm(entero)
        __delay_ms(1000);
    }
    return;
}


/*******************************************************************************
|  CLASS:         Desarrollo
|  PROGRAM:       LCD_RPM
|  AUTHOR:        Agustin; Lautaro
|  DESCRIPTION:   Lee las revoluciones por minutos de una determ. frecuencia,
|                                mediante las interrupciones por RB0 con flanco ascendente.
|  REQUIREMENTS:  Ingreso de pulsos por entra RB0
|  ADDITIONAL:    Valor flotante "%(cant enteros).(cant decimales)f","sin (int)" 
|
*******************************************************************************/



RPM.H :

#include <xc.h>
#include <stdint.h>
#ifndef _XTAL_FREQ
    #define _XTAL_FREQ 4000000
#endif

/*------------------------------------------------------------------------------
                            FUNCTION PROTOTYPES
 -----------------------------------------------------------------------------*/
void RPM_init(void);
float RPM_read(void);
void interrupt ventana(void);



RPM.C : 

#include "RPM.h"

/*------------------------------------------------------------------------------
                        VARIABLE DECLARATIONS GLOBAL
------------------------------------------------------------------------------*/
bit pulso=0;    //Detecta cuando se produce el primer y segundo pulso por RB0
bit flag=0;
unsigned int T1=0,T2=0;


/*========================================================================
  FUNCTION:     RPM_init()
  DESCRIPTION:  Inicializa los registros y configuraciones necesarios
  PARAMETERS:   Ninguno
  RETURNS:      Nada
  REQUIREMENTS: Ingreso de pulso por RB0
========================================================================*/
void RPM_init(void)
{
    //Configuracion de Puertos
    TRISBbits.TRISB0 = 1;
    
    //Configuracion de timer 1 como contador de oscilador interno
    T1CONbits.T1CKPS1 = 1;              //Preescaler en 1:8
    T1CONbits.T1CKPS0 = 1;              //Preescaler en 1:8
    T1CONbits.TMR1CS = 0;               //Reloj interno/4
    T1CONbits.TMR1ON = 1;               //Hablita timer1
    
    //Configuracion de interrupcion por RB0
    INTCONbits.INTE = 1;                //Habilita interrupcion por RB0
    INTEDG = 1;                         //Por flanco ascendente
    INTF = 0;                           //Bandera en 0
}


/*========================================================================
  FUNCTION:     RPM_read()
  DESCRIPTION:  Genera el valor de frecuencia y rpm 
  PARAMETERS:   Ninguno
  RETURNS:      Flotante --> variable rpm
  REQUIREMENTS: Ninguno
========================================================================*/
float RPM_read(void)
{
    /*-----------------------------------------------------------------------
                            VARIABLE DECLARATIONS
    -----------------------------------------------------------------------*/
    float freq=0,rpm=0;
    TMR1IF = 1;

    //Habilita interrupcion global
    INTCONbits.GIE = 1;

    while(flag == 0);
    
    //Calcula la frecuencia y la transforma en rpm
    freq = 1/((T2-T1) * 0.000008);      //Calcula la frecuencia de los pulsos
    rpm = freq * 60;                    //Calcula los rpm
    
    //Devuelve el valor de rpm
    return rpm;
}


/*========================================================================
  FUNCTION:     ventana()
  DESCRIPTION:  Genera una ventana que depende de la frecuencia que ingresa
  PARAMETERS:   Ninguno
  RETURNS:      Nada
  REQUIREMENTS: Ingreso de pulsos por RB0
========================================================================*/
void interrupt ventana(void)
{
    char band = 0;
    band = 0;
    
    //Inicializa el timer1
    if(TMR1IF == 1)
    {
        TMR1 = 0;                       //Inicia el timer1 en 0
        T1 = TMR1;
        TMR1IF = 0;                     //Inicia el timer1
    }
    
    //Guarda el valor de T1
    if(pulso == 1)
    {
        //Guarda el valor del segundo flanco ascendente
        TMR1ON = 0;                     //Detiene el timer1
        T2 = TMR1;                      //Guarda el valor obtenido
        INTCONbits.GIE = 0;             //Deshabilita las interrupciones 
        TMR1 = 0;
        TMR1IF = 1;
        TMR1ON = 1;
        pulso = 0;
        band = 1;
        flag = 1;
    }
    
    if(band == 0)   pulso = 1;
    INTF = 0;
}


/*******************************************************************************
|  LIBRERIE:      RPM.c
|  DESCRIPTION:   Lee las revoluciones por minutos de una determ. frecuencia,
|                                mediante las interrupciones por RB0 con flanco ascendente.
|  REQUIREMENTS:  Ingreso de pulsos por entra RB0
|
*******************************************************************************/



LIBRERIA LCD.H : 

#include <xc.h>
#define _XTAL_FREQ 4000000


/*------------------------------------------------------------------------------
                            PROGRAM DEFINES
 -----------------------------------------------------------------------------*/
#ifndef LCD_16X2
    #define LCD_16X2 0x01
    
    //Configuraciones de pines
    #define RS_PIN PORTDbits.RD1
    #define RS_TRIS TRISDbits.TRISD1
    #define RW_PIN PORTDbits.RD2
    #define RW_TRIS TRISDbits.TRISD2
    #define E_PIN PORTDbits.RD3
    #define E_TRIS TRISDbits.TRISD3
    #define BITS_PIN PORTD
    #define BITS_TRIS TRISD
    
    //Funciones del lcd
    #define CLEAR 0x01                  //Limpiar el display
    #define CURSOR_OFF 0x0C             //Desactiva el cursor
    #define CURSOR_ON 0x0E              //Actva el cursor solo
    #define CURSOR_BLINK_ON 0x0F        //Activa el cursor y el destello
    #define HOME 0x02                   //Vuelve a la posicion home 0,0
    #define DISPLAY_RIGHT 0x1C          //Corrimiento de pantalla a la derecha
    #define DISPLAY_LEFT 0x18           //Corrimiento de pantalla a la izquierda
    #define CURSOR_RIGHT 0x14           //Movimiento del cursor a la derecha
    #define CURSOR_LEFT 0x10            //Movimiento del cursor a la izquierda
    #define PRIMERA_FILA 0x02
    #define SEGUNDA_FILA 0xC0
    #define TERCERA_FILA 0x94
    #define CUARTA_FILA 0xD4

    //Generacion de caracter
    #define CARACTER_POS0 0x00          //Caracter posicion 0
    #define CARACTER_POS1 0x01          //Caracter posicion 1
    #define CARACTER_POS2 0x02          //Caracter posicion 2  
    #define CARACTER_POS3 0x03          //Caracter posicion 3
    #define CARACTER_POS4 0x04          //Caracter posicion 4
    #define CARACTER_POS5 0x05          //Caracter posicion 5
    #define CARACTER_POS6 0x06          //Caracter posicion 6
    #define CARACTER_POS7 0x07          //Caracter posicion 7 

    //Generacion de numero grandes
    #define LCD_20X4 0x02    //Numero grandes para Lcd 20x4
    #define JUST_RIGHT 0x10  //Numeros con justificacion derecha de la pantalla
    #define JUST_LEFT 0x11   //Numeros con justificacion izquierda de la pantalla
#endif


/*------------------------------------------------------------------------------
                            FUNCTION PROTOTYPES
 -----------------------------------------------------------------------------*/
void LCD_init(void);
void LCD_command(unsigned char cmd);
void LCD_array(int x,int y,const char *date);
void LCD_xy(int x,int y);
void LCD_date(char date);
void LCD_E(void);
void LCD_shift(unsigned char dir,unsigned char cant);
void LCD_character(unsigned char adress,char caracter[]);
void LCD_numerogrande(int valor);



LIBRERIA LCD.C :


#include "LCD_control.h"

//********************************************************************************
//Esta funcion inicializa el lcd con sus configuraciones; Debe utilizarse primero*
//********************************************************************************
void LCD_init(void)
{
    //Tiempo de inicilizacion
    __delay_ms(20);
    
    for(char i=0;i<3;i++)
    {
        LCD_command(0x03);                  //Recomendado para inicializar el controlador
        __delay_ms(5);
    }
    
    //Configuraciones del LCD 16x2
LCD_command(0x33);                  //Inicializa el controlador
    __delay_us(100);                        
    LCD_command(0x32);                      //Modo de 4 bits
    __delay_ms(5);  
LCD_command(0x28);                  //Modo 4 bits,2 lineas y fuente de 5x7
    __delay_us(100);
LCD_command(0x0C);                  
    __delay_us(100);
LCD_command(0x06);
    __delay_us(100);
    LCD_command(CLEAR);                 //Limpia la pantalla
    __delay_ms(3);

    return;
}

//********************************************************************************
//Esta funcion permite ingresar un comando al lcd; LCD_command(CLEAR);************
//********************************************************************************
void LCD_command(unsigned char cmd)
{
    //Salidas en 0
    BITS_TRIS &= 0x00;              //Pone todo el puerto como salida,para poder escribir en el lcd              

    //Escribe los comandos
    BITS_PIN &= 0x00;                    //Limpiar el puerto
    BITS_PIN |= (cmd & 0xF0);       //Envia el MSB del comando
    LCD_E();                                     //Habilita el lcd para poder guardar los datos
    BITS_PIN &= 0x00;                   //Limpia el puerto
    BITS_PIN |= (cmd<<4 & 0xF0);    //Envia el LSB del comando
    LCD_E();                                    //Habilita el lcd para poder guardar los datos

    BITS_TRIS &= 0xF0;                //Vuelve a poner como entrada
    
    __delay_ms(2);
    return;
}

//********************************************************************************
//Esta funcion permite enviar los datos al lcd, para poder visalizar la letra*****
//********************************************************************************
void LCD_date(char date)
{
    //Setea las configuraciones para poder escribir
    BITS_TRIS &= 0x00;              //Modo de salida

    //Envia el dato
    BITS_PIN &= 0x00;               //Limpia el puerto
    BITS_PIN |= (date & 0xF0);      //Envia MSB
    RS_PIN = 1;                     //Modo de escritura
    LCD_E();                        //Habilita los datos
    BITS_PIN &= 0x00;               //Limpiar el puerto
    BITS_PIN |= (date<<4 & 0xF0);   //Enviar LSB
    RS_PIN = 1;                     //Modo de escritura
    LCD_E();                        //Habilita los datos

    BITS_TRIS &= 0xF0;              //Modo de entrada

    __delay_ms(2);
    return;
}

//********************************************************************************
//Esta funcion permite enviar el dato al lcd**************************************
//********************************************************************************
void LCD_E(void)
{
    E_PIN = 1;
    __delay_us(5);
    E_PIN = 0;
    __delay_us(5);
}

//********************************************************************************
//Esta funcion permite enviar una candena de caracteres***************************
//********************************************************************************
void LCD_array(int x,int y,const char *date)
{
    //Ubica el lcd
    switch(x)
    {
        case 1: LCD_command(0x80 | (0x00 + (y - 1)));
        break;
        case 2: LCD_command(0x80 | (0x40 + (y - 1)));
        break;
        case 3: LCD_command(0x80 | (0x14 + (y - 1)));
        break;
        case 4: LCD_command(0x80 | (0x54 + (y - 1)));
        break;
    }
    
    //Envia la cadena
    while(*date)
    {
        LCD_date(*date);
        __delay_us(100);
        date++;
    }
}

//********************************************************************************
//Esta funcion permite ubicar en un lugar el lcd**********************************
//********************************************************************************
void LCD_xy(int x,int y)
{
    switch(x)
    {
        case 1: LCD_command(0x80 | (0x00 + (y - 1)));
        break;
        case 2: LCD_command(0x80 | (0x40 + (y - 1)));
        break;
        case 3: LCD_command(0x80 | (0x14 + (y - 1)));
        break;
        case 4: LCD_command(0x80 | (0x54 + (y - 1)));
        break;
    }
}

//*********************************************************************************
//Esta funcion realiza un corrimiento de pantalla; El 10 representa la cantidad de*
//veces que se va a correr la pantalla*********************************************
void LCD_shift(unsigned char dir,unsigned char cant)
{
    char i=1;
    //Realiza el corrimiento de pantalla
    while(i <= cant)
    {
        LCD_command(dir);
        __delay_ms(250);
        i++;
    }

    LCD_command(HOME);              //Vuelve a la posicion inicial
    i = 1;
}

//********************************************************************************
//Esta funcion genera un caracter que no se encuentra en la lista del lcd*********
//********************************************************************************
void LCD_character(unsigned char adress,char caracter[])
{
    LCD_command(0x40 + (adress * 8));
    for(char i=0;i<8;i++)
    {
        LCD_date(caracter[i]);
    }
}

/*Ejemplo de uso de la funcion de creacion de caracter:
 *char caracter1[8] = 
    {
        0b00000000,
        0b00001010,
        0b00001010,
        0b00001010,
        0b00001010,
        0b00010001,
        0b00001110,
        0b00000000,
    };
    LCD_command(CLEAR);
    LCD_caracter(CARACTER_POS0,caracter1);
    LCD_xy(0,0);
    LCD_date(CARACTER_POS0);
    __delay_ms(1000);
 */



FIN PROGRAMA.





    



No hay comentarios.:

Publicar un comentario