Autor Tema: Visualización dinámica con PIC18F4550  (Leído 2945 veces)

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

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Visualización dinámica con PIC18F4550
« en: 19 de Octubre de 2017, 17:39:06 »
Hola comunidad

Tengo un problema de implementación para la visualización dinámica en MPLAB y simulado en proteus.
Obviamente necesito que los displays cambien todo el tiempo pero al momento de querer aumentar o decrementar un dígito tal como se evidencia en el código, el display se apaga no entiendo porque..
Además necesito que solo aumente cada vez que se oprime y no se donde colocar las banderas

Agradezco quien pueda ayudarme.

Añado el código



// PIC18F4550 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1L
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

// CONFIG1H
#pragma config FOSC = INTOSC_XT // Oscillator Selection bits (Internal oscillator, XT used by USB (INTXT))
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON         // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config ICPRT = OFF      // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)

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


#include <xc.h>
#define _XTAL_FREQ 4000000

void main(void) {
    OSCCONbits.SCS = 11;
    OSCCONbits.IRCF = 110;
   
    ADCON1bits.PCFG0 = 1;
    ADCON1bits.PCFG1 = 1;
    ADCON1bits.PCFG2 = 1;
    ADCON1bits.PCFG3 = 1;
   
    TRISAbits.RA0 = 1;
    TRISAbits.RA1 = 1;
    TRISAbits.RA2 = 0;
    TRISAbits.RA3 = 0;
   
    TRISBbits.RB0  = 0;
    TRISBbits.RB1  = 0;
    TRISBbits.RB2  = 0;
    TRISBbits.RB3  = 0;
    TRISBbits.RB4  = 0;
    TRISBbits.RB5  = 0;
    TRISBbits.RB6  = 0;

   
    //int leds_unidad [10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};
    int leds_unidad [10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x18};
    int uni,dec,contador = 0;
   
    while(1){
       
       RA2 = 1;
       RA3 = 0;
       PORTB = leds_unidad[uni];
       __delay_ms(15);
       
       RA2 = 0;
       RA3 = 1;
       PORTB = leds_unidad[dec];
       __delay_ms(15);
       
       
       if((RA0 == 0) && (RA1 == 1)){
     __delay_ms(20);
     if((RA0 == 0) && (RA1 == 1)){
        __delay_ms(1000);
        if((RA0 == 0) && (RA1 == 1)){
          if(contador<99){
        contador++;
          }
          else{
      contador = 0;
          }
          }
       }
    }
       
       if((RA0 == 1) && (RA1 == 0)){
     __delay_ms(20);
     if((RA0 == 1) && (RA1 == 0)){
        __delay_ms(1000);
        if((RA0 == 1) && (RA1 == 0)){
        if(contador>0){
           contador--;
        }
        else{
           contador = 99;
        }
          }   
        }
     }
     
       dec = contador/10;
       uni = contador%10;
       
    }
    return;
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Visualización dinámica con PIC18F4550
« Respuesta #1 en: 19 de Octubre de 2017, 17:56:18 »
Son los delays (Esos de 1000ms Especialmente). utiliza un Timer para dar la "frecuencia de resfresco", es decir, usar un Timer por ejemplo en 20ms , cuando entra que pregunte que digito esta encendido, lo apague , cargue el valor y encienda el otro.

De esta forma el Timer siempre va a estar trabajando y multiplexando el display, mostrando los valores rapidamente. Y en tu loop infinito ( while ) pones poner los delays que quieras para leer tus botones de entrada.

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Visualización dinámica con PIC18F4550
« Respuesta #2 en: 19 de Octubre de 2017, 18:03:48 »
Puedo abusar... Pero es que no me han enseñado timer y pues no lo entiendo. O existe una forma con solo delay?

Si puedes ayudarme te agradezco
« Última modificación: 19 de Octubre de 2017, 18:11:46 por gioalex07 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Visualización dinámica con PIC18F4550
« Respuesta #3 en: 19 de Octubre de 2017, 23:53:26 »
Si existe forma de hacerlo.

Lo que te comente era lo ideal.

Entonces tenemos que en el loop principal debemos:

- Multiplexar los digitos
- leer los botones ( para aumentar y decrementar el contador )
- generar un delay para que no todo suceda rapido

Y aca nos enfrentamos al problema de siempre...

Si el delay es muy grande, el multiplexado de los digitos en el display se va a notar. Pero los botones va a ser simple su control.
Si el delay es pequeño los botones se van a leer demasiado rapido. pero el display se va a ver bien.

Lo bueno es que es posible buscar formas de leer los botones mas lento... Hasta ahora el programa queda asi:

Código: C
  1. void main(void)
  2. {
  3.   // Aca configuracion de pines
  4.  
  5.   while(1)
  6.   {
  7.     // Multiplexado
  8.  
  9.    
  10.     if(PORTAbits.RA2)
  11.     {
  12.       // Aca entra si estaban activas las unidades en el anterior paso
  13.       PORTAbits.RA2 = 0;    // Comun unidades las apago
  14.       PORTAbits.RA3 = 1;    // Comun decenas las activo
  15.       PORTB = leds_unidad[dec];
  16.     }
  17.     else
  18.     {
  19.       // Aca entra si estaban activas las decenas en el anterior paso
  20.       PORTAbits.RA2 = 1;    // Comun unidades las apago
  21.       PORTAbits.RA3 = 0;    // Comun decenas las activo
  22.       PORTB = leds_unidad[uni];
  23.     }
  24.  
  25.     // Botones
  26.     // Aca hay que agregar el codigo de los botones
  27.  
  28.     // Delay de cada vuelta del loop
  29.     __delay_ms(20);
  30.   }
  31.  
  32. }

A partir de aca lo unico que hay que hacer es el codigo de los botones. En el codigo de los botones NO SE USA DELAYS

¿ Como no usar delays ? En realidad el unico delay que tenemos es el de los 20ms que esta fuera.
Y te propongo 2 formas de leer los botones.

- 1era opcion
Usar un contador extra que cuente las veces que pasa por el codigo de los botones. Y por ejemplo si quisiera que entre a cada segundo a ver si hay algo presionado, entonces voy a poner a aumentar una variable y cuando pase 50 veces ( 20ms * 50 = 1s ) entro a leer los botones. Otra forma de verlo, cada vuelta del while tarda 20ms gracias al delay, si esperamos que pasen 50 vueltas, estariamos leyendo los botones cada 1s.

Esta opcion esta buena en el sentido de que es simple de implementar.

Código: C
  1. botones++;
  2. if (botones >= 50)
  3. {
  4.     botones = 0;
  5.     if(RA0 == 1 y RA1 == 0)
  6.     {
  7.          //sumo contador
  8.     } else if (RA0 == 0 y RA1 == 1)
  9.     {
  10.          //resto contador
  11.     }
  12. }

La ventaja es que es facil de implementar. La desventaja es que tenes que presionar el boton justo cuando se cumple el segundo, en el peor caso el maximo tiempo que debes tenerlo presionado es 1s, ya que si por ejemplo justo persionamos cuando nuestro contador de vueltas esta en 1 y lo soltamos cuando esta en 49, no va a reconocer esa accion, un simple persion del boton son 200/300ms. reducir la cantidad de vueltas implica que si lo tenes presionado, se incremente o decremente mas rapido, hasta que si lo persionas un poco de mas termines aumentando de a 2. Entonces ganas "responsividad" pero perdes control.

-2da opcion

Esta es la ideal.
En esta opcion vamos a guardar el valor de los botones, asi cuando pase una vuelta volvemos a revisarlo y comparamos con la proxima vuelta.
De aca se desprende 2 posibilidades, que sean iguales o que no, si son iguales quiere decir que se mantuvo presionado el boton y no hacemos nada, si no lo son entonces significa que algo cambio..

Código: C
  1. botonesactual = PORTA & 0x3;  // Solo RA0  yRA1
  2. if ( botonesanteriores != botonesactual)
  3. {
  4.   //Algo cambio, entonces reviso
  5.   if(botonesactual == 0x01) // Solo RA0 presionado
  6.   {
  7.     contador++;  
  8.     if(contador > 99) contador = 99;
  9.   }
  10.   if(botonesactual == 0x02) // Solo RA1 presionado
  11.   {
  12.     if(contador != 0) contador--;
  13.     contador--;  
  14.   }
  15.  
  16. // Actualizo botones anteriores para la proxima vuelta
  17. botonesanteriores = botonesactual;
  18. }


Este ultimo codigo posee una ventaja, y es que responde al minimo tiempo que se puede ejecutar esto, que son los 20ms del delay principal, desventajas asi como esta puede llegar a ser cuando se presionen varios botones, pero que modificando el programa tranquilamente podrias arreglar ese problema. Tambien esos 20ms del loop while nos sirven de una especie de antirebote.

Ahora juntamos todo y....

Código: C
  1. int leds_unidad [10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x18};
  2. int uni = 0,dec = 0;
  3. int botonesanteriores = 0;  // Variable usada para mantener el estado de los botones de la vuelta del while anterior
  4. int botonesactual;             // Variable usada para guardar el valor de los botones presionados en ese ciclo.
  5.  
  6. void main(void)
  7. {
  8.   // Aca configuracion de pines/oscilador/etc
  9.     OSCCONbits.SCS = 11;
  10.     OSCCONbits.IRCF = 110;
  11.  
  12.     ADCON1 = 0xF;
  13.     TRISA = 0x3;
  14.     TRISB = 0;
  15.  
  16.   while(1)
  17.   {
  18.     // Multiplexado
  19.    
  20.     if(PORTAbits.RA2)
  21.     {
  22.       // Aca entra si estaban activas las unidades en el anterior paso
  23.       PORTAbits.RA2 = 0;    // Comun unidades las apago
  24.       PORTAbits.RA3 = 1;    // Comun decenas las activo
  25.       PORTB = leds_unidad[dec];
  26.     }
  27.     else
  28.     {
  29.       // Aca entra si estaban activas las decenas en el anterior paso
  30.       PORTAbits.RA2 = 1;    // Comun unidades las apago
  31.       PORTAbits.RA3 = 0;    // Comun decenas las activo
  32.       PORTB = leds_unidad[uni];
  33.     }
  34.  
  35.     // Botones
  36.     botonesactual = PORTA & 0x3;  // Solo RA0  yRA1
  37.     if ( botonesanteriores != botonesactual)
  38.     {
  39.       //Algo cambio, entonces reviso
  40.       if(botonesactual == 0x01) // Solo RA0 presionado
  41.       {
  42.         uni++;
  43.         if(uni > 9)
  44.         {
  45.           if(dec != 9)
  46.           {
  47.             dec++;
  48.             uni = 0;
  49.           }
  50.           else
  51.           {
  52.             uni = 9;
  53.           }
  54.         }
  55.        
  56.       }
  57.       if(botonesactual == 0x02) // Solo RA1 presionado
  58.       {
  59.         if(uni != 0)
  60.         {
  61.           uni--;
  62.         }
  63.         else
  64.         {
  65.           if(dec != 0)
  66.           {
  67.             dec--;
  68.             uni = 9;
  69.           }
  70.         }
  71.       }
  72.  
  73.     // Actualizo botones anteriores para la proxima vuelta
  74.     botonesanteriores = botonesactual;
  75.     }
  76.  
  77.     // Delay de cada vuelta del loop
  78.     __delay_ms(20);
  79.   }
  80. }

O si queres usar el contador como venias haciendo:

Código: C
  1. int leds_unidad [10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x18};
  2. int uni = 0,dec = 0, contador = 0;
  3. int botonesanteriores = 0;  // Variable usada para mantener el estado de los botones de la vuelta del while anterior
  4. int botonesactual;             // Variable usada para guardar el valor de los botones presionados en ese ciclo.
  5.  
  6. void main(void)
  7. {
  8.   // Aca configuracion de pines/oscilador/etc
  9.     OSCCONbits.SCS = 11;
  10.     OSCCONbits.IRCF = 110;
  11.  
  12.     ADCON1 = 0xF;
  13.     TRISA = 0x3;
  14.     TRISB = 0;
  15.  
  16.   while(1)
  17.   {
  18.     // Multiplexado
  19.    
  20.     if(PORTAbits.RA2)
  21.     {
  22.       // Aca entra si estaban activas las unidades en el anterior paso
  23.       PORTAbits.RA2 = 0;    // Comun unidades las apago
  24.       PORTAbits.RA3 = 1;    // Comun decenas las activo
  25.       PORTB = leds_unidad[dec];
  26.     }
  27.     else
  28.     {
  29.       // Aca entra si estaban activas las decenas en el anterior paso
  30.       PORTAbits.RA2 = 1;    // Comun unidades las apago
  31.       PORTAbits.RA3 = 0;    // Comun decenas las activo
  32.       PORTB = leds_unidad[uni];
  33.     }
  34.  
  35.     // Botones
  36.     botonesactual = PORTA & 0x3;  // Solo RA0  yRA1
  37.     if ( botonesanteriores != botonesactual)
  38.     {
  39.       //Algo cambio, entonces reviso
  40.       if(botonesactual == 0x01) // Solo RA0 presionado
  41.       {
  42.         contador++;  
  43.         if(contador > 99) contador = 99;
  44.       }
  45.       if(botonesactual == 0x02) // Solo RA1 presionado
  46.       {
  47.         if(contador != 0) contador--;
  48.         contador--;  
  49.       }
  50.  
  51.     // Actualizo botones anteriores para la proxima vuelta
  52.     botonesanteriores = botonesactual;
  53.  
  54.     // Actualizo uni y dec
  55.     dec = contador/10;
  56.     uni = contador%10;
  57.  
  58.     }
  59.  
  60.     // Delay de cada vuelta del loop
  61.     __delay_ms(20);
  62.   }
  63. }
« Última modificación: 20 de Octubre de 2017, 00:05:21 por KILLERJC »

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Visualización dinámica con PIC18F4550
« Respuesta #4 en: 20 de Octubre de 2017, 04:06:15 »
Wow muchas gracias
Entonces empezare a detallar más el código a partir de tu ayuda

Dios te guarde por este apoyo que me brindaste

Cualquier duda que tenga comentare el foro pero con tu explicación lo dudo.


Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Visualización dinámica con PIC18F4550
« Respuesta #5 en: 21 de Octubre de 2017, 22:37:47 »
Hola de nuevo

Encontre una manera de solucionar el problema que tenía pero ahora tengo inconvenientes solo al esperar 1 segundo de pulso.
No entiendo porque si estoy indicando que debe esperarse un delay de 1 s pasa derecho el pulso y cuenta el avance en el display

Si puedes ayudarme gracias.


// PIC18F4550 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1L
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

// CONFIG1H
#pragma config FOSC = INTOSC_XT // Oscillator Selection bits (Internal oscillator, XT used by USB (INTXT))
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON         // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config ICPRT = OFF      // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)

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

#include <xc.h>
#define _XTAL_FREQ 4000000
void visualizacion_dinamica();
//int leds_unidad[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
int leds_unidad[10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x18};
int uni, dec, i,j, contador,bandera,bandera2,tiempo = 0;
void main(void) {
   
    OSCCONbits.SCS = 11;
    OSCCONbits.IRCF = 110;
   
    ADCON1bits.PCFG0=1;
    ADCON1bits.PCFG1=1;
    ADCON1bits.PCFG2=1;
    ADCON1bits.PCFG3=1;
   
    TRISAbits.RA0=1; //Pulsador suma
    TRISAbits.RA1=1; //Pulsador resta
    TRISAbits.RA2=0; //Activador display1
    TRISAbits.RA3=0; //Activador display2
   
    TRISBbits.RB0=0; //Puertos de salida display
    TRISBbits.RB1=0;
    TRISBbits.RB2=0;
    TRISBbits.RB3=0;
    TRISBbits.RB4=0;
    TRISBbits.RB5=0;
    TRISBbits.RB6=0;
    TRISBbits.RB7=0;

   
    while(1){
       
        visualizacion_dinamica();
       
        while((PORTAbits.RA0 == 0)&&(PORTAbits.RA1 == 0)){
            visualizacion_dinamica();
            bandera = 1; 
        }
       
        while((PORTAbits.RA0 == 1)&&(PORTAbits.RA1 == 0)){
       visualizacion_dinamica();
       i = 1;
        }
       
        while((PORTAbits.RA0 == 0)&&(PORTAbits.RA1 == 1)){
       visualizacion_dinamica();
       i = 0;
        }
       
        if(bandera == 0){
      
        }
        else{
            if(i == 0){
          while(j<10){
                visualizacion_dinamica();
      __delay_ms(100);
                j++;
               }
                if(contador>0){
                    contador--;
                }
                else{
                    contador = 99;
                }
            }
           
            else if(i == 1){
          while(j<10){
                visualizacion_dinamica();
      __delay_ms(100);
                j++;
               }
                if(contador<99){
                    contador++;
                }
                else{
                    contador = 0;
                }
            }
            bandera = 0;
        }
        visualizacion_dinamica();
        dec = contador/10;
        uni = contador%10;
    }
    return;
}

void visualizacion_dinamica(){
    LATAbits.LATA3=0;
    LATB = leds_unidad[uni];
    LATAbits.LATA2=1;
    __delay_ms(8 );
    LATAbits.LATA2=0;
    LATB = leds_unidad[dec];
    LATAbits.LATA3=1;
    __delay_ms(8 );
}
« Última modificación: 22 de Octubre de 2017, 02:38:33 por gioalex07 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Visualización dinámica con PIC18F4550
« Respuesta #6 en: 22 de Octubre de 2017, 10:46:19 »
Es porque nunca pones j = 0 , La primera ves que entra alli (cualquier boton sea), j era igual a 0, pero luego de ese loop queda en 10.

Código: C
  1. while(j<10){
  2.                 visualizacion_dinamica();
  3.                 __delay_ms(100);
  4.                 j++;
  5.       }

Cuando volves a presionar, sigue estando en 10, entonces el la condicion del while no se cumple y nunca entra. La solucion es que cada ves que vas a hacer el while, pongas j = 0;

Código: C
  1. j = 0;
  2.       while(j<10){
  3.                 visualizacion_dinamica();
  4.                 __delay_ms(100);
  5.                 j++;
  6.       }

PD: A pesar que no comparto la forma en que esta realizado, te sigo en tu implementacion, y te felicito por querer buscar vos tu propia forma de solucionarlo sin copiar el codigo que pase.
PD2: Recorda que el codigo anterior esta en 2 partes de tu codigo. Asi que vas a tener que agregarle la linea a ambas
PD3: Como regla de buena programacion, si tenes que repetir demasiado, entonces existe siempre alguna forma de no hacerlo. Por ejemplo fijate cuantas llamadas a la funcion visualizacion_dinamica tenes. En cambio el codigo que te pase antes se podria reemplazar en 3 llamadas unicas a funciones:

Código: C
  1. void main(void)
  2. {
  3.  
  4.   Configuracion();
  5.  
  6.   while(1){
  7.     Multiplexado();
  8.     LecturaBotones();
  9.     Delay();
  10.   }
  11. }

Eso me deja que cada "funcion" es independiente de la otra, asi que un cambio en una no deberia modificar la otra.

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Visualización dinámica con PIC18F4550
« Respuesta #7 en: 22 de Octubre de 2017, 19:16:11 »
Pues coloque la variable a 0 pero no se detiene el segundo y la visualización falla durante ese tiempo. No se que sucede si le indico que debe esperar 1 s antes de aumentar o decrementar contador

Gracias por tu ayuda

Actualización: Pregunte al docente de la materia y llega y me dice que eso no era necesario.. perdida de tiempo.. Pero ahora descubrí un bucle extraño cuando mantengo pulsado los dos botones. Coloque en la condición de que si los dos son iguales haga la visualización y i = 2 para que no haga ninguna operación pero deberia aumentarme o decrementarme por el primer pulsador que oprimí y no sucede.

while(ra0 == 1 && ra1 == 1){
visualizacion_dinamica();
i = 2;
}
« Última modificación: 24 de Octubre de 2017, 00:08:01 por gioalex07 »


 

anything