Hola gente que tal, quiería preguntarles si hay algo que no estoy viendo que esté haciendo mal.
He realizado un programa en CCS para el PIC16F684, el cual simulo en PROTEUS V7.4 y funciona a la perfección. Pero ahora cuando lo paso al PIC en cuestion y lo monto sobre una protoboard no funciona adecuadamente. Lo que he detectado hasta el momento es que los pines de salida que van a los registros de desplazamiento estan transmitiendo información, no he montado la parte de los display ya que no era lo que queria probar ahora, pero bueno con el osciloscopio veo cambios en esos pines (C0,C1 y C2). Cuando presiono el pulsador para cambiar entre un tipo de secuencia y otra, las salidas antes mencionadas dejan de variar, como si el programa se quedara colgado y no hace mas nada. Tampoco cambia del led rojo al led verde. Y los más importante de todo, en el pin 13 (A0) tengo una salida de una secuencia de pulsos que nunca aparece y no se porque. A ver si estoy cometiendo algun error que no estoy viendo y alguien de afuera quizas lo pueda ver. Adjunto todos los datos que tengo para que puedan ver mejor.
He realizado un programa en CCS para el PIC16F684, el cual simulo en PROTEUS V7.4 y funciona a la perfección. Pero ahora cuando lo paso al PIC en cuestion y lo monto sobre una protoboard no funciona adecuadamente. Lo que he detectado hasta el momento es que los pines de salida que van a los registros de desplazamiento estan transmitiendo información, no he montado la parte de los display ya que no era lo que queria probar ahora, pero bueno con el osciloscopio veo cambios en esos pines (C0,C1 y C2). Cuando presiono el pulsador para cambiar entre un tipo de secuencia y otra, las salidas antes mencionadas dejan de variar, como si el programa se quedara colgado y no hace mas nada. Tampoco cambia del led rojo al led verde. Y los más importante de todo, en el pin 13 (A0) tengo una salida de una secuencia de pulsos que nunca aparece y no se porque. A ver si estoy cometiendo algun error que no estoy viendo y alguien de afuera quizas lo pueda ver. Adjunto todos los datos que tengo para que puedan ver mejor.
Código:
#include <16F684.H> // Directivas del PIC 16F684
// Declaro la palabra de configuración del microcontrolador //
#fuses INTRC_IO,NoWdt,NoBrownout,Protect // INTRC_IO, NoWatchDog, NoBrownOut, Protect
#fuses NoMclr,NoCpd,Put,NoFcmen,NoIeso // NoMasterClear, NoEEProtection, Put, NoFcmen, NoIeso
// Configuro el cristal que voy a utilizar //
#use delay(clock=4000000) // Frecuencia de 4MHz interna
// Modo de configurar los pines de entrada/salida
#use fast_io(A) // Asignación rápida de los pines del puerto A
#use fast_io(C) // Asignación rápida de los pines del puerto C
#locate Puerto_A = 0x05 // Defino el puerto A con una etiqueta
// Registro de PORTA ==> BITS: 5 4 3 2 1 0
// | | | | | |_ RPM : Salida del sensor de RPM
// | | | | |___ Pot_RPM : Entrada para bajar/subir las RPM
// | | | |_____ Led_36_60 : Salida para indicar rueda de 36/60 dientes
// | | |_______ Pulsador : Entrada para cambiar entre rueda de 36 y 60 dientes
// | |_________ Xt : Oscilador a cristal
// |___________ Xt : Oscilador a cristal
#bit RPM = Puerto_A.0 // GP0 como salida
#bit Pot_RPM = Puerto_A.1 // GP1 como entrada
#bit Led_36_60 = Puerto_A.2 // GP2 como salida
#bit Pulsador = Puerto_A.3 // GP3 como entrada
// Configuración de los pines del registro de desplazamiento 74HC595 //
#DEFINE OUTPUT_DATA PIN_C0 // C0 a DS
#DEFINE SHIFT_LOAD PIN_C1 // C1 a STCP
#DEFINE SHIFT_CLOCK PIN_C2 // C2 a SHCP
// Definición de variables
int Valor_timer,Bandera_rueda,contador_36,contador_60,i;
int Unidad_Mil,Centena,Decena,Unidad;
int Numeros[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned int Multiplicador;
long Tiempo,RPMs;
float p1=0.7254;
float p2=0.8784;
// Declaro las funciones utilizadas
void Inicializacion_dispositivo (); // Rutina de inicialicación del dispositivo
void Visualizar_RPM (); // Rutina para visualizar las RPM en display 7 segmentos
void Enviar_Numero (); // Rutina que manda en forma serie el numero
// Interrupcion Timer 0
#int_timer0
void Generador_de_pulsos_de_rueda (void)
{
switch (Bandera_rueda) // Salto al caso que corresponda
{
case 0: // Rueda de 36 dientes
{
if (contador_36 < 70) // Ingreso hasta formar los primeros 35 dientes
{
output_toggle (PIN_A0); // Alterno la salida para formar los 35 dientes
contador_36++; // Incremento el contador para determinar el diente 35
}
else
if (contador_36++ == 72) // Incremento el contador pero solo ingreso cuando completo el diente 36 para resetear el contador
{
contador_36 = 0; // Borro el contador
Tiempo = get_timer1(); // Leo el valor del timer para calcular las RPM
set_timer1(0); // Pongo a cero el timer para calcular las RPM para la próxima
}
}break;
case 1: // Rueda de 60 dientes
{
if (contador_60 < 116) // Ingreso hasta formar los primeros 58 dientes
{
output_toggle (PIN_A0); // Alterno la salida para formar los 58 dientes
contador_60++; // Incremento el contador para determinar el diente 58
}
else
if (contador_60 < 118) // El diente 59 va todo en alto
{
RPM = 1; // Pongo la salida en alto
contador_60++; // Incremento el contador para determinar el diente 59
}
else
{
RPM = 0; // Hago baja la salida para el diente 60
if (contador_60++ == 120) // Incremento el contador pero solo ingreso cuando completo el diente 60 para resetear el contador
{
contador_60 = 0; // Borro el contador
Tiempo = get_timer1(); // Leo el valor del timer para calcular las RPM
set_timer1(0); // Pongo a cero el timer para calcular las RPM para la próxima
}
}
}break;
}
set_timer0(Valor_timer); // Seteo el valor del timer en función del valor del potenciometro
}
// Comienzo del programa principal
void main (void)
{
Inicializacion_dispositivo(); // Inicializo el dispositivo
Enable_interrupts (Int_timer0); // Habilito la interrupción del timer1
Enable_interrupts (global); // Habilito las interrupciones globales
for(;;)
{
if (Pulsador == 1) // Si apreto el pulsador ingreso al menú para cambiar de rueda
{
delay_ms (20); // Espero 20 mseg para evitar rebotes
while(Pulsador == 1); // Me quedo esperando hasta soltar el pulsador
if (Bandera_Rueda == 1) // Si la bandera de rueda es 1 entonces cambio a la rueda de 36 dientes
{
while(Contador_60 != 0); // Espero para cambiar de tipo de rueda hasta que termine la que está en curso para comenzar con la nueva
setup_timer_0 (RTCC_DIV_8); // Seteo el prescaler del timer0 a 8 para la rueda de 36 dientes
Led_36_60 = 0; // Prendo el led de la rueda de 36 dientes
Bandera_Rueda = 0; // Pongo en 0 la bandera de rueda para indicar que estamos en la rueda de 36 dientes
}
else // Si la bandera de rueda es 0 entonces cambio a la rueda de 60 dientes
{
while(Contador_36 != 0); // Espero para cambiar de tipo de rueda hasta que termine la que está en curso para comenzar con la nueva
setup_timer_0 (RTCC_DIV_4); // Seteo el prescaler del timer0 a 4 para la rueda de 60 dientes
Led_36_60 = 1; // Prendo el led de la rueda de 60 dientes
Bandera_Rueda = 1; // Pongo en 1 la bandera de rueda para indicar que estamos en la rueda de 60 dientes
}
}
if (Bandera_Rueda == 1)
Valor_timer = p2*Read_adc()+21; // Ecuación de la rueda de 60 dientes
else
Valor_timer = p1*Read_adc()+57; // Ecuación de la rueda de 36 dientes
Visualizar_RPM(); // Rutina para visualizar las RPM
}
}
void Inicializacion_dispositivo(void) // Rutina de inicialicación del dispositivo
{
set_tris_a (0b00001010); // Pines como entrada: A1,A3 - Pines como salida: A0,A2,A4,A5
output_a (0); // Borro las salidas del puerto A
set_tris_c (0b00000000); // Pines como entrada: - Pines como salida: C0,C1,C2,C3,C4,C5
output_c (0); // Borro las salidas del puerto C
setup_timer_0 (RTCC_Internal | RTCC_DIV_8); // Seteo el prescaler del timer0 a 8 para la rueda de 36 dientes
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2); // Seteo el timer 1 para funcionar a 2 useg
Setup_adc_ports (SAN1 | VSS_VDD); // Indico que la entrada AN1 es analógica y con referencia entre Vss y Vdd
Setup_adc (adc_clock_div_8); // Divido por 8 la frecuencia de reloj para un correcto funcionamiento del ADC
Set_adc_channel(1); // Selecciono el canal 1 para realizar conversiones con el ADC
}
void Enviar_Numero (unsigned int8 Valor)
{
Multiplicador = 128;
for (i=0;i<=7;i++) // inicio el bucle de 8 pasos
{
output_bit(Output_Data,!!(Valor&Multiplicador)); // Envio el bit n al IC
output_low(Shift_Clock); // Pongo el clock interno del Shift Register en low
output_high(Shift_Clock); // Genero la señal de reloj para hacer shift register en el IC
Multiplicador>>=1; // y divido la mascara (128,64,32,16,8,4,2,1)
}
}
void Visualizar_RPM (void)
{
if (Tiempo != 0)
{
RPMs = 30000000/Tiempo;
Unidad_Mil = 0;
Centena = 0;
Decena = 0;
Unidad = 0;
while (RPMs > 1000)
{
RPMs-=1000;
Unidad_Mil++;
}
while (RPMs > 100)
{
RPMs-=100;
Centena++;
}
while (RPMs > 10 )
{
RPMs-=10;
Decena++;
}
while (RPMs > 1)
{
RPMs-=1;
Unidad++;
}
Enviar_Numero(Numeros[Unidad_Mil]);
Enviar_Numero(Numeros[Centena]);
Enviar_Numero(Numeros[Decena]);
Enviar_Numero(Numeros[Unidad]);
output_low(Shift_Load); // Cuando envió el byte completo pongo a low el clock externo del IC
output_high(Shift_Load); // y genero la señal de reloj para pasar el contenido del
output_low(Shift_Load); // registro a las salidas del IC
}
}