Electrónica•Ingenia

Electrónica•Ingenia
sábado, 14 de abril de 2012

Tema 2.- Gestión de los puertos (III)


Tercera parte del tema 2 (Gestión de los puertos), ahora que ya sabemos hacer lo más básico con un PIC vamos a complicar un poco la cosa viendo otras sentencias y como utilizarlas. Una cosa buena que tiene la programación, en general, es la versatilidad a la hora de escribir el código, ya que una cosa se puede hacer de varias maneras con el mismo resultado. Pero todo no es igual aún teniendo el mismo fin ya que siempre hay una manera más optima para hacer lo mismo.

2.6 Gestión de puertos a través de la RAM.
En la entrada anterior vimos como manejar el puerto B como salida mediante directivas, (Output_High (PIN_x); Output_Low (PIN_x);,...) y en esta ocasión lo realizaremos mediante la modificación de la RAM.
Lo primero que tendremos que definir en nuestro programa es el PORTx y TRISx mediante la directiva #BYTE y definiendo su posición correspondiente en la memoria RAM.
#BYTE TRISB = 0x86         // El TRISB se encuentra en la 
   // posición 86h de la RAM.
#BYTE PORTB = 0x06        // Y el PORTB en la 06h.
Una vez las tenemos definidas las podemos utilizar para configurar los puertos asignándoles un valor, de la misma manera que hacíamos con la directiva Set_tris_x (valor);.
 TRISA = 0x00;        // PORTA entero como salida.                
 TRISB = 0xFF;        // Todo el PORTB como entradas.
Y como no escribir directamente en los puertos.
PORTB = 0b00000001;  // Todo el PORTB a nivel bajo menos RB0.
Pero lo que nos permite en C mayor control es trabajar bit a bit con cada registros:

  • Bit_Set (variable, bit);     // Pone a 1 el bit específico de la variable. Siendo el bit de 0 a 7.
  • Bit_Clear (variable, bit);  // Pone a 0 el bit específico de la variable. Siendo el bit de 0 a 7.

//////////////////////////////////////////////////////////////////////
//   _____               _   _     _ ____          _                //
//  |   __|___ _____ ___| |_|_|___| |    \ ___ ___|_|___ ___ ___    //
//  |__   | .'|     |_ -|   | | -_| |  |  | -_|_ -| | . |   |_ -|   //
//  |_____|__,|_|_|_|___|_|_|_|___|_|____/|___|___|_|_  |_|_|___|   //
//                                                  |___|           //
//                                                                  //
//  FIRMWARE:    Ejemplo 4            MICROCONTROLADOR: PIC16F88    //
//                                                                  //
//  WEB:  www.samshieldesigns.blogspot.com                          //
//  COMPILADOR:  CCS C Compiler v.4124                              //
//  IDE:   MPLAB IDE v.8.84                                         //
//  DESCRIPCION: Animaci n de coche fantastico en PORTB             //
//                                                                  //
//////////////////////////////////////////////////////////////////////
#include <16f88.h>
//////////////////////////////////////////////////////////////////////
//                       CONFIGURACION DEL PIC                      //
//////////////////////////////////////////////////////////////////////
#FUSES HS              // High speed Osc (> 4mhz for PCM/PCH) (>10mhz
                       // for PCD)
#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 NOCPD           // No EE protection
#FUSES NOPUT           // No Power Up Timer
#FUSES NOPROTECT       // Code not protected from reading
#FUSES NOWDT           // No Watch Dog Timer
#USE delay(clock=20000000)     // Frecuencia de 20Mhz
#BYTE TRISB = 0x86    // Configuramos el TRISB
#BYTE PORTB = 0x06    // Configuramos el PORTB

#DEFINE Retardo  80           // Definimos 80 como "Retardo"
//////////////////////////////////////////////////////////////////////
//                     CUERPO PRINCIAPAL FIRMWARE                   //
//////////////////////////////////////////////////////////////////////
void main()
  {
  int x=0;                          // Variable entera de (0-255)
  disable_interrupts(GLOBAL);       // Desactivamos las interrupciones
  for(x=0;x<8;x++){                 // Bucle for, se repetir  mientas 
    bit_clear(TRISB,x);             // que x sea menor de 8.
    }                               // configuramos todo el PORTB 
                                    // como salidas.  
    
  while(true)                       // Bucle infinito. True = 1
    {
    for(x=0;x<7;x++){       // Bucle for
        bit_set(PORTB,x);   // Pone a 1 el pin correspondiente a "x"
        delay_ms(Retardo);  // Retardo 80ms    
        bit_clear(PORTB,x); // pone a 0 el pin correspondiente a "x"
        }
    for(x=7;x>0;x--){
        bit_set(PORTB,x);
        delay_ms(Retardo);
        bit_clear(PORTB,x);
        }       
    } // End while(TRUE)
  } //Fin void main

Descargar código y .hex:
En el ejemplo 4 vemos por primera vez un bucle For. Esta declaración no tiene otro fin que repetir las sentencias que hay dentro del bucle hasta que no se cumpla la condición de finalización. Cada vez que se ejecuta todo el bucle se realiza un incremento o decremento sumando o restando la variable de iniciación. Si la variable ya no coincide con el valor de finalización entonces se sale del bucle. 
FOR ( variable de iniciación ; condición de finalización ; incremento/decremento de variable iniciación)
 {
 sentencias
 } // Fin del buble for
Otra manera que existe para realizar un bucle infinito es utilizar un For (;;), sin definir ningún parámetro de inicio ni finalización, en vez del While(TRUE).

En el ejercicio 5 vamos a encontrarnos con la siguiente sentencia:

  • Bit_test ( variable, bit);      // Muestra el bit, de 0 a 7, de la variable.

También encontramos una declaración If-Else. Esta declaración sirve para verificar si se cumple una condición. 
If (expresión){
      sentencia x;
      }
else {
      sentencia y;
      }
Si la expresión es 1 el programa seguirá entrando en el bucle y ejecutando la "sentencia x", saltándose el Else y por ende la "sentencia y". Pero en el caso de que la expresión devuelva un 0 no entrara en el bucle if y saltará directamente a ejecutar el Else y la "sentencia y". Si la expresion se cumple pues se ejecuta el If, pero si no se llega a cumplir se ejecuta el Else.
//////////////////////////////////////////////////////////////////////
//   _____               _   _     _ ____          _                //
//  |   __|___ _____ ___| |_|_|___| |    \ ___ ___|_|___ ___ ___    //
//  |__   | .'|     |_ -|   | | -_| |  |  | -_|_ -| | . |   |_ -|   //
//  |_____|__,|_|_|_|___|_|_|_|___|_|____/|___|___|_|_  |_|_|___|   //
//                                                  |___|           //
//                                                                  //
//  FIRMWARE:    Ejemplo 5            MICROCONTROLADOR: PIC16F88    //
//                                                                  //
//  WEB:  www.samshieldesigns.blogspot.com                          //
//  COMPILADOR:  CCS C Compiler v.4124                              //
//  IDE:   MPLAB IDE v.8.84                                         //
//  DESCRIPCION: Pulsador conectado a RA1 y salida por RB0.         //
//                                                                  //
//////////////////////////////////////////////////////////////////////
#include <16f88.h>
//////////////////////////////////////////////////////////////////////
//                       CONFIGURACION DEL PIC                      //
//////////////////////////////////////////////////////////////////////
#FUSES HS              // High speed Osc (> 4mhz for PCM/PCH) (>10mhz
                       // for PCD)
#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 NOCPD           // No EE protection
#FUSES NOPUT           // No Power Up Timer
#FUSES NOPROTECT       // Code not protected from reading
#FUSES NOWDT           // No Watch Dog Timer
#USE delay(clock=20000000)     // Frecuencia de 20Mhz
#BYTE TRISA = 0x85    // Configuramos el TRISA  
#BYTE TRISB = 0x86    // Configuramos el TRISB
#BYTE PORTA = 0x05    // Configuramos el PORTA
#BYTE PORTB = 0x06    // Configuramos el PORTB

//////////////////////////////////////////////////////////////////////
//                     CUERPO PRINCIAPAL FIRMWARE                   //
//////////////////////////////////////////////////////////////////////
void main()
  {
  setup_port_a(NO_ANALOGS);
  disable_interrupts(GLOBAL);       // Desactivamos las interrupciones
  TRISA = 0xFF;                     // PORTA como entradas
  TRISB = 0x00;                     // PORTB como salidas
  bit_clear(PORTB,1);               // Apagamos el PORTB
  while(true)                       // Bucle infinito. True = 1
    {
    if(bit_test(PORTA,0) == 1){     // Es RA0 es igual a "1"????
        bit_set(PORTB,1);           // SI: Enciendo RB0
        } 
    else                            // NO: Apago RB0
        bit_clear(PORTB,1);         
    } // End while(TRUE)
  } //Fin void main
Descargar código y .hex:
En la siguiente entrada empezaremos a utilizar displays de 7 segmentos, utilizando todo lo aprendido hasta ahora.

Share this post
  • Share to Facebook
  • Share to Twitter
  • Share to Google+
  • Share to Stumble Upon
  • Share to Evernote
  • Share to Blogger
  • Share to Email
  • Share to Yahoo Messenger
  • More...

0 comentarios:

Publicar un comentario