Autor Tema: Contador y displays 7 segmentos  (Leído 4880 veces)

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

Desconectado nicola

  • PIC10
  • *
  • Mensajes: 19
Contador y displays 7 segmentos
« en: 24 de Agosto de 2009, 16:38:56 »
Hola que tal? Antes que nada queria agradecerle al foro por haber despertado mi apetito por los PIC  :)
Les cuento sobre mi problema a ver si me pueden ayudar, ya que estuve usando el buscador (alabado sea) pero en este caso no creo haber dado con lo que busco...

En este proyecto necesito que un contador cuente de 0 hasta 1000, y que muestre la cuenta en 4 displays de 7 segmentos. El tiempo que toma en llegar hasta 1000 pueden ser aproximadamente 10 segundos (no es critico el tiempo exacto). Tambien mientras se lleva la cuenta y se muestra en el display (hacer todo en simultaneo es lo que no me sale :(), tengo que prender y apagar 6 led a una frecuencia de 1hz.
La cuenta se frena al presionar un boton y dependiendo el numero en que se haya frenado, se habilitan o se deshabilitan ciertos puertos.
Otra complicacion que no puedo superar es que la cuenta no es lineal. Desde 0 a 500 toma un tiempo, 6 segundos supongamos, y de 500 a mil los 4 segundos restantes. Necesito poder jugar con esos valores porque son a prueba-error...

El bosquejo del programa lo hice con un bucle for que llega hasta 1000, aunque creo que no es el mejor metodo.
Probe usando delay_ms(x) e ir variando x en funcion del numero del contador, cosa que funciona pero me complica q se vean los displays normalmente.

Espero que puedan ayudarme...un saludo!

Les dejo mi humilde codigo, no se rian  :oops:


Citar
#include <16f877a.h>                 //pic a utilizar       
#fuses XT,NOWDT,NOPROTECT,NOPUT      //ordenes para el programador

#use delay(clock=20000000)           //Fosc=2Mhz
#use standard_io(a)
#use standard_io(b)


void main()
{

int16 cont, time;
int digito1, digito2, digito3, digito4;

             //    0     1     2     3     4     5     6     7    8     9
int display[10]={0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b};

set_tris_a(0b00001);
set_tris_b(0);

while(input(PIN_A0)==0);  //inicio...


for(cont=1; cont<=1000; cont++)
{
digito1=cont%10;
digito2=cont/10;
digito3=cont/100;
digito4=cont/1000;

output_high(PIN_A1);
output_b(display[digito1]);
delay_ms(5);
output_low(PIN_A1);

output_high(PIN_A2);
output_b(display[digito2]);
delay_ms(5);
output_low(PIN_A2);

output_high(PIN_A3);
output_b(display[digito3]);
delay_ms(5);
output_low(PIN_A3);

output_high(PIN_A4);
output_b(display[digito4]);
delay_ms(5);
output_low(PIN_A4);

 if((cont>=0)&&(cont<=100))
 time=200;
 if((cont>100)&&(cont<=200))
 time=180;
 if((cont>200)&&(cont<=300))
 time=160;
 if((cont>300)&&(cont<=400))
 time=140;
 if((cont>400)&&(cont<=500))
 time=120;
 if((cont>500)&&(cont<=600))
 time=100;
 if((cont>600)&&(cont<=700))
 time=80;
 if((cont>700)&&(cont<=800))
 time=60;
 if((cont>800)&&(cont<=900))
 time=40;
 if((cont>900)&&(cont<=1000))
 time=20;
delay_ms(time);
}




}

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Contador y displays 7 segmentos
« Respuesta #1 en: 24 de Agosto de 2009, 19:13:33 »
wenassss.... primero que nada miraria la sentencia while(input(PIN_A0)==0);
no se escribe asi....
solo escribe while(!input(PIN_A0))
de esa forma el buqcle se petetira mientras PIN_A0 de como valor logico un 0...

y while(input(PIN_A0)) significa que se repetira el bucle while mientras PIN_A0 sea =1
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Contador y displays 7 segmentos
« Respuesta #2 en: 24 de Agosto de 2009, 20:14:03 »
wenassss.... primero que nada miraria la sentencia while(input(PIN_A0)==0);
no se escribe asi....
solo escribe while(!input(PIN_A0))
de esa forma el buqcle se petetira mientras PIN_A0 de como valor logico un 0...

y while(input(PIN_A0)) significa que se repetira el bucle while mientras PIN_A0 sea =1
Es exactamente lo mismo.

Yo haría el refresco de cada display por interrupción. La interrupción se ejecutaría cada 5ms por ejemplo y refrescaría el display que correspondiera en el momento. Para refrescar los 4 display entonces llevaría 20ms, así que llevaría una cuenta de la cantidad de refrescos como para aumentar el conteo del display cada 300ms.

Por ejemplo:
Código: C
  1. /* Interrupcion cada 5 ms*/
  2. #int_TIMER1
  3. void TIMER1_isr(void){
  4.    set_timer1();
  5.    NumberDisplay++;     // Numero de display a refrescar.-
  6.    switch(NumberDisplay){
  7.       case 1:
  8.          output_low(PIN_A4);  // Ten en cuenta que este pin es colector abierto!!!
  9.          output_high(PIN_A1);
  10.          output_b(display[digito1]);
  11.       break;
  12.       case 2:
  13.          output_low(PIN_A1);
  14.          output_high(PIN_A2);
  15.          output_b(display[digito2]);
  16.       break;
  17.       case 3:
  18.          output_low(PIN_A2);
  19.          output_high(PIN_A3);
  20.          output_b(display[digito3]);
  21.       break;
  22.       case 4:
  23.          output_low(PIN_A3);
  24.          output_high(PIN_A4);
  25.          output_b(display[digito4]);
  26.          NumberDisplay=0;
  27.          // Ya se refrescaron los 4 display, se puede modificar el valor...
  28.          // si ya se repitio por ejemplo 15 veces (300ms).
  29.          NumberRepet++;
  30.          if(NumberRepet==15){
  31.             NumberRepet=0;
  32.             cont++;
  33.             if(cont==1000){
  34.                disable_interrupts(INT_TIMER1); // Terminó el conteo.
  35.                Contando=0;
  36.             }
  37.             digito1=cont%10;
  38.             digito2=cont/10;
  39.             digito3=cont/100;
  40.             digito4=cont/1000;
  41.          }
  42.       break;  
  43.    }
  44.  
  45. }


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado nicola

  • PIC10
  • *
  • Mensajes: 19
Re: Contador y displays 7 segmentos
« Respuesta #3 en: 25 de Agosto de 2009, 17:34:35 »
Muchas gracias por la ayuda Suky!  :)
Ya me estoy metiendo en el mundo de las interrupciones y los timer...empece con programitas muy basicos para ver como se comportan y como se habilitan/deshabilitan los flags, y te digo que estoy aprendiendo!!!

Tengo pensado usar dos timers en el programa: el TIMER0 para contabilizar los 10 segundos y el TIMER1 para refrescar los displays y las luces q tengo que manejar, que te parece?
No bien avance con el codigo lo pego!

Un abrazo, gracias por la explicacion.
 :lol:

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Contador y displays 7 segmentos
« Respuesta #4 en: 25 de Agosto de 2009, 19:22:44 »
Muchas gracias por la ayuda Suky!  :)
Ya me estoy metiendo en el mundo de las interrupciones y los timer...empece con programitas muy basicos para ver como se comportan y como se habilitan/deshabilitan los flags, y te digo que estoy aprendiendo!!!

Tengo pensado usar dos timers en el programa: el TIMER0 para contabilizar los 10 segundos y el TIMER1 para refrescar los displays y las luces q tengo que manejar, que te parece?
No bien avance con el codigo lo pego!

Un abrazo, gracias por la explicacion.
 :lol:

Con el Timer0 se podría controlar los 10 segundos y las luces de 1Hz, y el timer1 para el refresco de los display.

Algunas sentencias que te serán útiles:

Código: C
  1. setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128); // Configura timer con oscilador interno, y prescaler 128.-
  2. setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); // Configura timer con oscilador interno y prescaler 4.-
  3.  
  4.  
  5. set_timer0(100); // escribe en el timer0 100. Registro TMR0
  6. set_timer1(1200);// Escribe en el timer1 1200, Registros TMR1L y TMR1H
  7.  
  8. clear_interrupt(INT_TIMER0); // borra flag de interrupción.-
  9. clear_interrupt(INT_TIMER1);
  10.  
  11. enable_interrupts(INT_TIMER0); // habilita la interrupción.-
  12. enable_interrupts(INT_TIMER1);
  13.  
  14. enable_interrupts(GLOBAL); // habilitador de interrupciones globales.-
  15.  
  16. disable_interrupts(INT_TIMER0); // Deshabilita interrupción.-
  17. disable_interrupts(INT_TIMER1);



Saludos!
No contesto mensajes privados, las consultas en el foro


 

anything