Programas para Robots.
  Imagenes
 

Código en CCS:

Código:
#Include <16F876A.h>            // Usamos el PIC 16F876A.

#FUSES NOWDT, XT, PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#Use Delay(clock=4000000)       // Usamos un cristal de 4MHz, por ejemplo. 

#ZERO_RAM                       // Variables a cero.

#byte porta = 0x05              // Asignamos PortA
#byte portb = 0x06              // Asignamos PortB
#byte portc = 0x07              // Asignamos PortC

// ------ Variables Globales ------
int8   x = 0;                   // Declaramos el valor de X como Byte, es decir, 8 bits.
                                // Esta variable ha de ser global porque su valor lo usaremos
                                // en la interrupción y en el programa principal.

// --------- Interrupción ---------
#INT_EXT                        // Interrupción: Decodificación de Encoder.
void IntRB0() 
{
   // CCS se encarga de desactiva automáticamente cualquier interrupción.
   // No hace falta guardar contextos de registros, al menos con el PIC 16F876A.

   if (bit_test(portb, 0))      // Si PortB.0 = 1,
   {  
       ext_int_edge(H_TO_L);    // entonces activar la siguiente interrupción para flanco de bajada. 
       if (bit_test(portb, 1))  // Si PortB.1 = 1,
       {
           x++;                 // entonces incrementar una unidad el valor de X.
       }
   }
   else                         // Si PortB.0 = 0, 
   {  
       ext_int_edge(L_TO_H);    // entonces activar la siguiente interrupción para flanco de subida.
       if (bit_test(portb, 1))  // Si PortB.1 = 1,
       {
           x--;                 // entonces decrementar una unidad el valor de X.
       }
   }
   // Al finalizar la interrupción CCS se encarga de volver a poner automáticamente
   // la badera INTF = 0 ---> borra la interrupción para poder permitir la siguiente;
   // no hemos de hacer nada por nuestra parte, al menos con el PIC 16F876A.
}

void main()                     // Inicio y configuración.
{
   port_b_pullups(FALSE);       // Configuración para el PIC 16F876A.
   setup_adc_ports(NO_ANALOGS); // Sin comparadores ni ADCs, todo digital, etc...
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   enable_interrupts(int_ext);  // Activar Interrupción Externa. 
   ext_int_edge(L_TO_H);        // Inicialmente detectar interrupción por flanco de subida. 
   enable_interrupts(GLOBAL);   // Interrupciones Generales Activadas. 

   set_tris_a(0b111111);        // Puerto A todo entradas (en este caso no usamos el Puerto A).
   set_tris_b(0b11111111);      // Puerto B todo entradas (sólo usamos las entradas RB0 y RB1).
   set_tris_c(0b00000000);      // Puerto C todo salidas  (8 bits que irán a los LEDs).

   // ---------- Programa Principial ----------

   While (True)
   {
          portc = x;            // El valor de X sale por el Puerto C a los 8 LED de salida. 
   }      
   
}
Código en Proton IDE:

Código:
Device=16F876A

REMINDERS = FALSE
     Config XT_OSC, PWRTE_ON, CPD_OFF, WDT_OFF, BODEN_OFF, LVP_OFF
REMINDERS = TRUE

Symbol INTF   = INTCON.1         ' RB0 External Interrupt Flag
Symbol INTE   = INTCON.4         ' RB0 External Interrupt Enable
Symbol GIE    = INTCON.7         ' Global Interrupt Enable
Symbol INTEDG = OPTION_REG.6     ' Flag = 0 int. por flanco bajada. Flag = 1 int. por flanco subida.

On_INTERRUPT GoTo Interrupcion   ' Interrupción por Hardware (es la más rápida).

GIE    = 1                       ' Activa interrupciones generales.
INTE   = 1                       ' Activa la interrupción externa RB0/INT.
INTEDG = 1                       ' Hace que inicialmente la interrupción se habilite
                                 ' para flanco de subida.

ALL_DIGITAL = TRUE               ' Todas las entradas y salidas son digitales.
                                                                              
TRISA  = %111111
TRISB  = %11111111               ' Puerto A y B todo entradas.
TRISC  = %00000000               ' Puerto C como salida para visualizar a través de los LED.
           
Dim x As  Byte                   ' Variable X ---> contador de posición actual con resolución 0..255


x=0                              
 
While 1=1                        ' |------ Programa Principal ------|
     
     PORTC = x                   ' El contenido de X se visualiza en el Puerto C a través de los LED.

Wend                             ' |--------------------------------|
             
End                              

    
Interrupcion:                 '-------- Decodificador de Encoder --------------
       
    Context SAVE              ' Salva en contexto de los registros antes de operar con la interrupción.
    
    If PORTB.0 = 1    Then    ' Si RB0 se ha puesto a 1 (flanco de subida),
       INTEDG  = 0            ' entonces activar la siguiente interrupción para flanco de bajada.
       If PORTB.1 = 1 Then    ' Si RB1 está a 1,
          Inc x               ' entonces incrementar el contador X.
       EndIf
    EndIf
    
    If PORTB.0 = 0    Then    ' Si RB0 se ha puesto a 0 (flanco de bajada),
       INTEDG  = 1            ' entonces activar la siguiente interrupción para flanco de subida.
       If PORTB.1 = 1 Then    ' Si RB1 está 1,
          Dec x               ' entonces decrementar el contador X.
       EndIf
    EndIf
     
    INTF = 0                  ' Borra el "flag" de la interrupción RB0/INT para poder permitir la   
                              ' siguiente interrupción cuando ocurra.
    Context Restore           ' Restablece el contexto de los registros tal como estaban antes de la
                              ' interrupción.
 
 
  19469 visitantes (37172 clics a subpáginas)  
 
Este sitio web fue creado de forma gratuita con PaginaWebGratis.es. ¿Quieres también tu sitio web propio?
Registrarse gratis