Autor Tema: [Problema CCS] Timer0 y Multiplexion Display 7 Segmentos  (Leído 2494 veces)

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

Desconectado robo_z

  • PIC10
  • *
  • Mensajes: 16
[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« en: 23 de Enero de 2017, 20:15:44 »
Hola Amigos hace poco me anime a hacer una rutina de Multiplexion para un Display Catodo Comun de 4 Digitos con ayuda del Timer0, pero he tenido un inconveniente, Segun Mi Codigo Deberia Mostrar el Numero 9782 pero No enciende el Primer Digito(Numero 9).

No entiendo a causa de que sucede este error, aqui les dejo mi Codigo para que puedan darle una Ojeada:
Código: [Seleccionar]
#include <16F628A.h>

#FUSES PUT                      //Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES CPD                      //Data EEPROM Code Protected
#FUSES PROTECT                  //Code protected from reads
//#FUSES NOWDT

#use delay(internal=4MHz)
#use FIXED_IO( A_outputs=PIN_A3,PIN_A2,PIN_A1,PIN_A0 )
#use FIXED_IO( B_outputs=PIN_B3,PIN_B2,PIN_B1,PIN_B0 )
#define Pin_DispUnidad   PIN_A0
#define Pin_DispDecena   PIN_A1
#define Pin_DispCentena   PIN_A2
#define Pin_DispMillar   PIN_A3
#define Pin_DecoA   PIN_B0
#define Pin_DecoB   PIN_B1
#define Pin_DecoC   PIN_B2
#define Pin_DecoD   PIN_B3

int CorreCaso=0;
//Creamos Un Arreglo que Contiene los Numeros del CERO al NUEVE
const int Numeros[10]={0b00000000, 0b00000001, 0b00000010, 0b00000011, 0b00000100, 0b00000101, 0b00000110, 0b00000111, 0b00001000, 0b00001001};

void Setup()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_BIT);      //8.1 ms overflow
   set_timer0(100); //Cargamos 100 para un Retardo de 5 MiliSegundos
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
}

void main()
{
   Setup();

   while(TRUE)
   {
   
   }
}

#INT_RTCC
void  RTCC_isr(void)
{
   switch (CorreCaso)
   {
      case 0:
      output_bit(Pin_DispUnidad,0);
      output_bit(Pin_DispDecena,1);
      output_bit(Pin_DispCentena,1);
      output_bit(Pin_DispMillar,1);
      output_b(Numeros[2]);
      CorreCaso=1;
      break;
     
      case 1:
      output_bit(Pin_DispUnidad,1);
      output_bit(Pin_DispDecena,0);
      output_bit(Pin_DispCentena,1);
      output_bit(Pin_DispMillar,1);
      output_b(Numeros[8]);
      CorreCaso=2;
      break;
     
      case 2:
      output_bit(Pin_DispUnidad,1);
      output_bit(Pin_DispDecena,1);
      output_bit(Pin_DispCentena,0);
      output_bit(Pin_DispMillar,1);
      output_b(Numeros[7]);
      CorreCaso=3;
      break;
     
      case 3:
      output_bit(Pin_DispUnidad,1);
      output_bit(Pin_DispDecena,1);
      output_bit(Pin_DispCentena,1);
      output_bit(Pin_DispMillar,0);
      output_b(Numeros[9]);
      CorreCaso=0;
      break;
   }
   set_timer0(100);
}

De Antemano se Agradece su tiempo y la Ayuda que Puedan Brindar  8)
« Última modificación: 23 de Enero de 2017, 20:28:01 por robo_z »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« Respuesta #1 en: 23 de Enero de 2017, 23:35:32 »
Código: C
  1. const int Numeros[10]={0b00000000, 0b00000001, 0b00000010, 0b00000011, 0b00000100, 0b00000101, 0b00000110, 0b00000111, 0b00001000, 0b00001001};

Eso que hiciste ahi no tiene sentido ( al menos como tenes el circuito!!! OJO ), por que si lo pasas a decimal es 0,1,2,3,4,5,6,7,8,9 , tendria sentido si es cada bit maneja un segmento o en que tengas bits separados, pero como tenes un conversor binario-7segmento y comenzas desde el bit0 no hace falta, simplemente usas el numero.

output_b( 9 );
output_b( 7 );
output_b( 8 );
output_b( 2 );

O lo dejas como lo tenes en el caso que necesites cambiar los pines.

Código: C
  1. set_timer0(100);

Procura poner el set_timer en la interrupcion al comienzo, asi de esa forma apenas entra ya le asigna un valor y el tiempo es mas constante y no depende de lo que tengas de codigo en la interrupcion.

-------------------------------------------------------------------

Ahora si con la resolucion de problemas....

Las salidas del puerto B esta bien, ya que muestra correctamente los demas.
Las salidas del puerto A parecen correcta, o por lo que parece el unico que no cambia es el pin RA3, todos los demas lo hacen y por eso estan mostrando valor.
El programa esta correcto, es el mismo metodo que usas con las otras salidas y funciona.

¿Por que la ultima no funciona?
Mirando el datasheet me encuentro que RA3 tiene una funcion del modulo de comparador analogico ¿puede ser esta la causa?

proba poner un:

Código: C
  1. setup_comparator (NC_NC_NC_NC);

en tu setup() y ver si funciona. Otra cosa no parece ser. Ya que todo lo demas parece correcto.

Desconectado robo_z

  • PIC10
  • *
  • Mensajes: 16
Re:[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« Respuesta #2 en: 24 de Enero de 2017, 02:09:08 »
Código: C
  1. const int Numeros[10]={0b00000000, 0b00000001, 0b00000010, 0b00000011, 0b00000100, 0b00000101, 0b00000110, 0b00000111, 0b00001000, 0b00001001};

Eso que hiciste ahi no tiene sentido ...

Gracias por los Consejos KILLERJC

Estuve Probando y Probando, Al Final Agrege Un Case (Case 4), que Basicamente Apaga el Digito 1; Este es el Codigo Que Me Funciono:
Código: [Seleccionar]
#include <16F628A.h>

#FUSES PUT                      //Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES CPD                      //Data EEPROM Code Protected
#FUSES PROTECT                  //Code protected from reads

#use delay(internal=4MHz)
#use FIXED_IO( A_outputs=PIN_A3,PIN_A2,PIN_A1,PIN_A0 )
#use FIXED_IO( B_outputs=PIN_B3,PIN_B2,PIN_B1,PIN_B0 )
#define Pin_DispUnidad   PIN_A0
#define Pin_DispDecena   PIN_A1
#define Pin_DispCentena   PIN_A2
#define Pin_DispMillar   PIN_A3

int CorreCaso=0;

void Setup()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_BIT);      //8.1 ms overflow
   set_timer0(100); //Cargamos 100 para un Retardo de 5 MiliSegundos
   setup_comparator(NC_NC_NC_NC);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
}

void main()
{
   Setup();

   while(TRUE)
   {
   
   }
}

#INT_RTCC
void  RTCC_isr(void)
{
   set_timer0(100);
   switch (CorreCaso)
   {
      case 0:
      output_bit(Pin_DispUnidad,0);
      output_bit(Pin_DispDecena,1);
      output_bit(Pin_DispCentena,1);
      output_bit(Pin_DispMillar,1);
      output_b(2);
      CorreCaso=1;
      break;
     
      case 1:
      output_bit(Pin_DispUnidad,1);
      output_bit(Pin_DispDecena,0);
      output_bit(Pin_DispCentena,1);
      output_bit(Pin_DispMillar,1);
      output_b(8);
      CorreCaso=2;
      break;
     
      case 2:
      output_bit(Pin_DispUnidad,1);
      output_bit(Pin_DispDecena,1);
      output_bit(Pin_DispCentena,0);
      output_bit(Pin_DispMillar,1);
      output_b(7);
      CorreCaso=3;
      break;
     
      case 3:
      output_bit(Pin_DispUnidad,1);
      output_bit(Pin_DispDecena,1);
      output_bit(Pin_DispCentena,1);
      output_bit(Pin_DispMillar,0);
      output_b(9);
      CorreCaso=4;
      break;
     
      case 4:     
      output_bit(Pin_DispMillar,1);
      CorreCaso=0;
      break;
   }   
}

Pero Aun No Entiendo por que no Funciono con los 4 Cases Originales (0-3), Pues Deberia Apagar el Primer Digito al Iniciar el Case 0  :?

Gracias Nuevamente  8)




Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« Respuesta #3 en: 24 de Enero de 2017, 02:22:58 »
Debe ser algun problema del simulador tal ves... Como bien decis, deberia haber funcionado.

Tambien podes resumir tu programa, como todos los pines de los comunes estan seguidos y ademas en orden, podes hacer algo asi:

Código: C
  1. int8 NumerosMostrar[4] = {9,8,7,2};
  2.  
  3. #INT_RTCC
  4. void  RTCC_isr(void)
  5. {
  6.    set_timer0(100);
  7.    output_a(~0);         // Apago todo
  8.    output_b(NumerosMostrar[CorreCaso]);    // Pongo el numero
  9.    output_a(~(1<<CorreCaso));           // Procedo a activar el correspondiente
  10.    CorreCaso++;                                 // Incremento digito y de paso me aseguro que no sobrepase los limites
  11.    if( CorreCaso >= 4) {
  12.        CorreCaso = 0;
  13.    }
  14. }

Recorda que tenes que tener cuidado ya que ouput_A cambia TODO el puerto. Pero lo que vas a tener ahi es esta secuencia:

Código: [Seleccionar]
1111 1110
1111 1101
1111 1011
1111 0111
Se repite.

Es solo para que veas algunas otras posibilidades, Aunque con el error que te daba antes sin siquiera realmente existir un error.... no se si funcionara o no.


« Última modificación: 24 de Enero de 2017, 02:26:42 por KILLERJC »

Desconectado robo_z

  • PIC10
  • *
  • Mensajes: 16
Re:[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« Respuesta #4 en: 24 de Enero de 2017, 17:14:13 »
Gracias por el Codigo, Toda Ayuda es Bienvenida :)

La Idea es Hacer Una Rutina de Multiplexion Para Un Contador Ascendente y Descentente que active un Mando o Palanca Basado en Un Joystick, Bueno ya Ire Viendo Como Me las Arreglo.

Como Mencionas es Raro el error, pero bueno Talves sea problema del Isis; Me Recuerda a unos Problemas Que Tuve Cuando Hice Un Programa Para el LCD en Asembler y No Funcionaba a Causa de los Tiempos  :lol:.

Bueno Entonces Doy Como Solucionado Este Problema  :mrgreen:

Desconectado Somag!

  • PIC10
  • *
  • Mensajes: 12
Re:[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« Respuesta #5 en: 03 de Febrero de 2017, 15:35:00 »
No confíes de todo en el simulador, también hice lo que tú, y en la simulación aparecía que no funcionaba, pero me valio chori y se que si estaba bien mi código, lo cargue al pic, lo arme y si funcionó al cien.
No necesitas otro integrado para mostrar los datos, solo necesitas hacer una función que la salida te de el valor para mostrar los dígitos y el encendido de cada display los haces con un transistor

char DtD(char x)
{
   if(x==0){m=63;}
   if(x==1){m=6;}
   if(x==2){m=91;}
        .
        .
        .
        .
        .
        .
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« Respuesta #6 en: 04 de Febrero de 2017, 06:53:52 »
Esto se puede hacer mas simple:
char DtD(char x)
{
   if(x==0){m=63;}
   if(x==1){m=6;}
   if(x==2){m=91;}
        .
        .
        .
        .
        .
        .
}

De esta forma:

Código: C
  1. char valores[10] = {63,6,91,.......etc};
  2.  
  3. //Y luego en ves de una funcion obtenes el valor con:
  4.  
  5. valores[x]; //Siendo x 0,1,2,3,4,etc.

Desconectado Somag!

  • PIC10
  • *
  • Mensajes: 12
Re:[Problema CCS] Timer0 y Multiplexion Display 7 Segmentos
« Respuesta #7 en: 11 de Febrero de 2017, 13:55:21 »
también :-)