SlideShare uma empresa Scribd logo
1 de 17
Baixar para ler offline
Guía de pickit 3
 
            
           El contador de programa
                                  

        Este tiene 21 bits de anchura y se divide en tres de 8 bits, PCL, PCH, PCU siendo PCH Y 
PCU los registros a los que no se puede escribir directamente ni tampoco son visibles a no ser que 
se realice mediante alguna instrucción de lectura o escritura sobre el registro PCL. De esta forma se 
actualiza los registros superiores del PC. También es modificable si una instrucción de salto o de 
subrutina se ejecuta, permitiéndose la escritura directamente por dichas instrucciones pero el dato 
no será transferido desde el PCH y PCU  al contador de registro.
        Ante un reset, el  PC se carga con el valor 0, por lo que este apunta a la dirección 0 de la 
memoria de programa, y según la instrucción escrita (normalmente un "goto") así actuará.
        Hay que decir que las instrucciones no se pueden ejecutar en bytes impares, ya que el     
                                                                                                  PC
solo va saltando de dos en dos ya que su bit de menos peso, tiene siempre puesto a 0 por lo que solo  
son pares las lineas a las que salta.

 
            
           PROGRAMANDO CON C 

        El compilador C para pic de MPLAB implementa la siguiente regla:
        1. Las instrucciones se almacenan en la sección denominada “code.”
        2. Los datos son almacenados en “romdata” conjuntamente con “ROM”

      MPLAB  C  COMPILER  puede   generar  dos  modelos   de  memoria,   corto    y  largo.  En   el 
modelo corto se usa un puntero de 16 bits, mientras que el modelo largo se usa uno de 24 bits (PC).

 
            
           MEMORIA      
                    DE DATOS 

        La   memoria   de   datos   es   llamada   “file  register”   o   memoria   de   registros.   Una   vez   que 
encendemos el pic, los datos contenidos en dichos registros, son aleatorios. Los registros se agrupan 
en orden de 256 bytes los cuales pueden ser seleccionados en bancos accesibles por los 4 bits de 
mayor peso del registro de direcciones  BSR  (  Bank  Select  Register  ). Las áreas especiales en el 
banco 0 y en el 15 son directamente accesibles y son denominadas ACCESS RAM y es aquí donde 
están los registros especiales (FSR) como son por ejemplo, los registros para programar un puerto 
de I/O, bits de algún registro de estado....

#pragma varlocate le dice al compilador dónde se almacenan las variables.

Las  variables  no inicializadas son almacenadas en memoria mediante “udata”, y el compilador 
realizará   lo   necesario   para   almacenar   y   distribuir   los   datos   correctos,   así   como   su   tipo   para 
optimizar la memoria al máximo, una vez que lo inicialice el compilador pasará los datos de la 
memoria de programa a la de datos para comprobar su correcta ortografía y tipos de datos para 
luego optimizar el programa.

        REGISTROS ESPECIALES SFR
        Estos   registros   especiales  son (  PC, status, pila,  EEDATA,,,,) sirven para  programar   los 
periféricos y los demás registros como STATUS o PC   y el compilador de C puede acceder a ello 
por su nombre y puede modificarlos y leerlos como si fuesen variables. Se localizan el el Banco 15 
de la memoria de datos.
EJERCICIOS PRACTICOS SOBRE C

        EJERCICIO 1

       Conectar el PICKIT3 al puerto usb del pc y después conectarnos la placa al conector ICSP.
       Vamos a crear un proyecto de compilación en C con el  compilador C de MPLAB.
       El proyecto consiste en encender un led indefinidamente conectado a una puerta, y veremos 
como se realizan todos los pasos para su compilación. Para crear un proyecto vamos a realizarlo 
mediante el asistente, por lo que accedemos a Project>Project Wizard... y nos sale una ventana de 
bienvenida, por lo que pulsamos NEXT.
    1. Seleccionamos un componente que en este caso será PIC18F45K20 y pulamos en Next.
    2. Seleccionamos el lenguaje de programación “Microchip C18 Toolsuite”  y pulsamos Next.
    3. Crear   un   nuevo   proyecto.   Busca   C.LessosnPICKIT  3  Debug  Express  Lessons01  Hello 
       LED  y nombra el proyecto  Lessson1  LED  y lo guardamos con  SAVE  entonces le damos a 
       NEXT para continuar.
    4. Podemos añadir archivos y fuentes que tengamos escritos al proyecto ( evidentemente  antes 
       deben estar creados en nuestro disco duro) . A la izquierda seleccionamos el archivo  01 
       HELLO LED.c  y lo añadimos. Pulsamos Next para continuar.
    5. Esta ultima ventana verificaremos todos nuestros datos y pincharemos en Finish.

       Para ver el proyecto que hemos creado, vamos a   View>Project y veremos nuestro área de 
trabajo el archivo llamado  Lesson 1 LED.mcw( en el título de la ventana) y el archivo proyecto 
Lesson 1 LED.mcp .
       Para   completar   el   proyecto   tenemos   que   añadir  Linker   Script  y   el  header  del 
microcontrolador al proyecto. El Linker Script se necesita para construir el proyecto. Es un archivo 
de comandos para el compilador y se definen las opciones que describe el mapa de memoria del 
microcontrolador y existen 4 linkers:
       18f45k20.lkr              Linker básico en modo no extendido
       18f45k20_e.lkr            Linker para compilar en modo extendido.
       18F45k20i.lkr             Linker que se usa con Debbuger ( previene  el código de aplicaciones
                                 ejecutar pequeñas áreas de memoria reservada al debugger.).
        18f45k20i_e.lkr          Linker para el debbuger en modo extendido.
       Para añadir el linker al proyecto hacemos Project>Add files to project... y dentro de la caja 
de selección de “Files of types”   seleccionamos   Linker Scritp (*.lkr) que están en CMCC18h y 
abrimos el  p18f45k20.h. Una nota importante, si modificamos el archivo seleccionado en nuestro 
proyecto, también se modificará el original y por tanto eso no lo deseamos, por lo que haremos lo 
siguiente,  File>Save   AS....   para   salvar   una   copia   en   el   nuevo   proyecto,   es   decir,   el   archivo 
p18f45k20.h    lo   copiaremos   en   el   presente   proyecto   y   así   no   lo   modificaremos.   Por   último 
File>Save Workspace. Debe quedarnos algo así:




                                                                                El programa :
/**  C   O  N   F  I G U  R   A  T  I  O  N      B  I  T  S  ******************************/ 
#pragma config FOSC = INTIO67 
#pragma config WDTEN = OFF, LVP = OFF 

/** I N C L U D E S   **************************************************/ 
#include "p18f45K20.h" 

/**  D   E  C   L  A R A  T   I  O  N  S  *******************************************/ 

void   main   (void) 
{ 
        TRISD = 0b01111111;               //    PORTD bit 7 to output (0); bits 6:0 are inputs  (1) 
        LATDbits.LATD7 = 1;               //    Set LAT register bit 7 to turn on LED 
        while (1) ; 
} 

       Veamos como funciona esto,,,,
#pragma config   Sirve para configurar los registros, que en este caso son FOSC Y WDTEN Y LVP
#include          Para incluir los header de los chips usados

TRISD           Es una variable que accede al sfr con el mismo nombre TRISD que está incluida en 
                el include anterior. En concreto esta pone a 0 o 1 los bits de la puerta D siendo 0 las 
                que se usan como salida y 1 los que se usan como entrada. Así  tenemos el código 
                0b01111111 por lo que pone a RD7 COMO SALIDA Y EL RESTO COMO 
                ENTRADA (RD6­RD0). El “0b” es una notación para el compilador que le indica 
                que el dato expresado es “binario”, si fuese hexadecimal seria 0x.....



LATDBITS.LATD7   LATDBITS  también está definido en el p18f45k20.h y permite el acceso  a los 
           bits individuales del registro LATD el cual en esta instrucción se pone a 1 la salida 
           D7 a través de LATD7 ( latch7).

        CONSTRUYENDO Y PROGRAMANDO EL PROYECTO

       Seleccionamos  Project> Build All. El archivo generado es un hex que se grabará en el pic.
       Cuando   termine   aparece   el   mensaje  Build  sucess,   si   ha   ocurrido   algún   error,   del   tipo 
p18f45k20.h no se a podido encontrar, es debido a que MPLAB C fue instalado sin añadir  Add 
header file path to MCC_INCLUDE enviromnet variable option   durante la instalación por lo que 
habrá que reinstalar  MPLAB C  de nuevo.
       Ahora   vamos   a   elegir   el   pickitt   3   como   programador   yendo   a  Programmer  >   Select 
Programmer > 4pickitt 3. lo que hará que aparezca una nueva pestaña en la parte de la ventana de 
información, mostrando el estado de dicho programador y todos los mensajes que se produzcan. El 
programador será inicializado y éste debe informar de que ha encontrado la placa DEMO a la que 
está enganchado y mostrar el microcontrolador que posee, que en este caso es nuestro pic18f45k20.
Aquí podemos observar que  no se ha detectado  
                                                    la placa con el pic ya que sino se programa al  
                                                    pikit3   para   que   alimente   a   la   placa,   esta   no  
                                                    podrá ser encontrada de ninguna manera.
                                                     Para   ello   debemos   de   configurar   el   pickit   3 
                                                    para ello y por tanto   vamos a Programmer > 
                                                    Settings...
                                                    Para   dicho   pic   debemos   alimentarlo   como  
                                                    máximo a 3,25 volts y por tanto deslizaremos el  
                                                    cursor   hasta   que   esté   en   dicha   tensión.   Lo  
                                                    salvamos   dando   ok   y   debe   aparecer   en   la  
ventana nuestro pic18f45k20.
       Pasamos ahora a meter el programa en el pic18f45k20 yendo a  Programmer > Program  y 
…. listo, ya esta programado. Si se ha cometido algún error en la programación consultar la ayuda 
del pickit 3  Help> Topics...  y bajo  Programmer  seleccionamos  pickit 3  y OK. En la pestaña de 
contenidos seleccionamos Troubleshooting para más información.

       PROYECTO 2 LED PARPADEANTE.

       Aquí se expone un proyecto con la meta de:
       – Abrir un área de trabajo de proyecto seleccionado desde File>open Workspaces
       – Configuración   de   bits   de   propósito   especial,   modos   de   operación   y   habilitar 
          características del microcontrolador.
       – Retardos, librerías.....

        En este punto, ya hemos programado nuestro pic18f45k20 y todavía no se ha cerrado el 
proyecto, pero nosotros vamos a abrir otro área de trabajo para el nuevo proyecto. Para ello debemos 
ira File >Open Workspaces.... y buscamos C:LessonsPICkit 3 Debug Express Lessons02 
Blink LED y abrimos el 02 Blink LED.mcw archivo.
        Antes de abrir una nueva área de trabajo, MPLAB nos pregunta si queremos guardar la 
anterior, por lo que lo recomendable es decir que si.

       CONFIGURANDO BITS 

       En este ejercicio, la configuración de los bits están definidas  en la parte superior del archivo 
de Blink LED. C como se muestra:


/**  C  O N  F I G  U  R  AT   I O   N     B I  T  S  ******************************/ 
#pragma   config FOSC=INTIO67, FCMEN=OFF,  IESO = OFF          // CONFIG1H 
#pragma   config PWRT = OFF,    BOREN= SBORDIS, BORV = 30     // CONFIG2L 
#pragma   config WDTEN     = OFF, WDTPS = 32768                          // CONFIG2H 
#pragma   config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC       
// CONFIG3H 
#pragma   config STVREN= ON, LVP = OFF, XINST = OFF               // CONFIG4L 
#pragma   config CP0 =OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF  // CONFIG5L 
#pragma   config CPB = OFF, CPD = OFF                                         // CONFIG5H 
#pragma   config WRT0 = OFF,    WRT1 = OFF, WRT2 = OFF, WRT3 = OFF        // CONFIG6L 
#pragma   config WRTB = OFF,    WRTC = OFF, WRTD = OFF                             // CONFIG6H 
#pragma   config EBTR0 =OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF    // CONFIG7L 
#pragma   config EBTRB = OFF                                                          // CONFIG7H 

       Como vimos en el ejercicio anterior, los bits se configuran utilizando  #pargma config  y 
separándolos por   comas. Cada microcontrolador tiene sus propias características y las podemos 
encontrar en MPLAB IDE HELP. Por ejemplo vamos a buscar las del pic18f45k20:
       1      Seleccionarnos MPLAB IDE menú Help>Topics... y buscar la categoría Lenguajes 
              Tool.
       2      PIC18 Config Settings” luego OK.
       3      Cuando la ventana de ayuda se abra, seleccionamos la pestaña Contenidos y expandir 
              la sección “ Configuration Settings” .
       4      Seleccionamos nuestro pic18f45k20.

      La configuración de los bits en este ejercicio es diferente a la que trae por defecto, por lo que 
vamos a prestar atención y vemos como funciona.


FOSC = INTIO67                     Esta configuración configura al pic para que trabaje con el oscilador interno
                                   por lo que no necesita ningún oscilador de cristal externo para funcionar.
                                   La frecuencia por defecto es de 1 MHz y así podemos utilizar los pines RA6
                                   (osc1) y RA7 (osc2) como bits de I/O de la puerta A ya que no se van a usar 
                                   como entradas para el oscilador.
WDTEN = OFF                        Esta configuración nos permite apagar el Watchdog Timer ( WDT) ya que en
                                   este ejercicio no lo vamos a usar. Ya se sabe que si usamos el WDT y no lo 
                                   refrescamos, éste reseteará el microcontrolador.
 
LVP = OFF                           
                                   Esto apaga el modo de Low Voltage­Programing  y por tanto libera la patita     
                                    
                                   PGM o RB5 ya que LVP no lo usa PICKIT 3.       

        El resto de los bits son iguales a los que trae por defecto, pero no está mal recordarle al 
compilador de que es ésta y no otra la configuración que nosotros deseamos.
        Y ahora ponemos el programa principal. Observa que la linea # include ha añadido un nuevo 
fichero y también el símbolo “ ~ “ delante del LATDbits.LATD7

/** I N C L U D E S   **************************************************/ 
#include "p18f45k20.h" 
#include "delays.h" 

/**  D    E C   L   A  R  A  T   I   O  N  S   *******************************************/ 

void   main   (void) 
{ 
        TRISD   =   0b01111111;//    PORTD   bit    7   to   output   (0)   ;  bits   6:0  are   inputs (1) 
        while   (1) 
        { 
                  LATDbits.LATD7   =   ~LATDbits.LATD7;       //   toggle   LATD 
                  Delay1KTCYx(50);//    Delay    50   x    1000  =   50,000   cycles;   200ms  @   1MHz 
        } 
} 
                                          
            Observa que se ha incluido la linea #include “delays.h” , este header se localiza al igual que 
p18f45k20.h , osea de C:MCC18h. Y por tanto , tenemos la instrucción de esta librería utilizada en 
el programa con la línea Delay1KTCYx (50) ;
Esta   función   crea  un retardo de  1000  instrucciones  de  ciclo  multiplicado  por  lo  que hay  entre 
paréntesis y nos daría 1000*50= 50.000 ciclos y como en nuestro microcontrolador el ciclo es ¼ de 
la señal de reloj, pues en este caso ( sin oscilador es 1MHzz) será 1mHz/4 = 250KHzz lo que nos da 
unos 200 ms que mas que suficiente lento para que nuestro ojo lo vea parpadear.

        LESSON 3 ROTACION LED

       Este programa realiza el desplazamiento de leds encendiendo uno detrás de otro. El archivo 
03 Rotate LED.c declara una variable como global llamada LED_Number y así se asigna:

/** V A R I A B L E S *************************************************/ 
#pragma udata                            // asigna variables estáticas no inicializadas
unsigned char LED_Number;               // 8­bit variable 

       La directiva #pragma udata sirve para decir al compilador que las variables de datos que a 
continuación siguen, se deben de meter en los registros del PIC( ojo es en el área de registros).
       Hay dos directiva que se pueden usar con #pragma
       – udata : Se almacenan datos (registros) sin inicializar en los registros del pic.
       – idata: Los datos inicializados se almacenan en el espacio de registros del pic y los datos 
           de la inicialización son guardados en la memoria de programa y movidos por el código 
           de inicialización de arranque, antes de que empiece el programa.

       La declaración de datos puede pertenecer a una sección con un nombre. Dicho nombre de 
sección puede asociarse a un script SECTION para colocarlo en un área particular de memoria.
       La directiva #pragma udata se debe de especificar la dirección de comienzo de los datos a 
almacenar en el pic y a partir de estas, serán secuenciales una detrás de otra. Supongamos que 
queremos colocar la variable LED NUMBER al inicio del banco de registros número 3, y por tanto 
se debería de programar así:
       #pragma udata mysection = 0x300 unsigned char 
       LED_Number;                                       // 8­bit variable unsigned int 
       AnotherVariable; 

        Aquí mysection es una sección con dicho nombre y que empieza en la dirección 0x300 y los 
datos que va a recibir serán del tipo unsigned char. LED Number será una variable y separada por ; 
las siguientes variables. Hay que decir que no es lo mismo guardar datos de 8 bits que de 16 como 
por ejemplo el tipo de dato integer que es de 16 bits lo que ocupará dos posiciones  en la sección.

      Hasta ahora hemos visto como se insertan datos en el área de registros, y a continuación 
veremos como metemos datos en el área de programa.

/** D E C L A R A T I O N S *******************************************/ 
// declare constant data in program memory starting at address 0x180 

#pragma romdata Lesson3_Table = 0x180 
const   rom  unsigned   char   LED_LookupTable[8]   =   {0x01,   0x02,   0x04,   0x08,   0x10,   0x20,   0x40,  
0x80}; 
#pragma  code                                                //  declare executable instructions 
void  main  (void) 
{ 
…..

         Podemos ver dos directivas usadas:
         code : Las propias instrucciones del programa. Compilará las instrucciones del programa en 
                la memoria de programa del pic.
     Romdata : Datos almacenados en la memoria de programa. Se suele usar con la directiva 
                “rom” y los datos serán del tipo constante ( no pueden variar) y compilados en 
                espacio de memoria de programa.
         En este ejercicio se va a utilizar un array de datos LED_LookupTable para convertir un 
número representando los leds 0­7 en un patrón de bits para configurar apropiadamente el puerto D 
que   se   denomina   PORTD   para   poder   encender   un   led   tras   otro.   Por   eso   se   utiliza   un   array 
constante , para que los datos de dicho array no cambien por culpa del programa o acción indebida. 
Por lo tanto, esta constante es declarada en romdata sección y usa “rom” para hacerla constante y 
colocarla en la parte de la memoria de programa. 
         La sección romdata ha sido declarada también con un nombre Lesson3_Table y asignada a 
una dirección 0X180.
         Selecciona MPLAB IDE Project> Build All para compilar el ejercicio y después selecciona 
View> Program Memory para visualizar el contenido compilado de la memoria de programa.




Observar como el la dirección 0180 está el array ( está invertido por el sistema de programación) se 
puede observar  0201 ( invertido será 01/02) y el 0804 (04/08).... 

        Si colocamos #pragma code y a continuación colocamos main() , el programa se almacenará 
en la sección indicada en la memoria de programa del pic. Si no se ha especificado ninguna sección 
ni tampoco la dirección de inicio de programa, el compilador colocará el programa en la siguiente 
sección de programa libre que tenga el pic.

        El programa:

/** V A R I A B L E S *************************************************/ 

#pragma udata                                       // declare statically allocated uninitialized variables 
unsigned char LED_Number;                           // 8­bit variable 
/** D E C L A R A T I O N S *******************************************/ 
// declare constant data in program memory starting at address 0x180 

#pragma romdata Lesson3_Table = 0x180 
const   rom   unsigned   char   LED_LookupTable[8]   =   {0x01,   0x02,   0x04,   0x08,   0x10,   0x20,   0x40,  
0x80}; 
#pragma   code                               //   declare   executable   instructions 

void main (void) 
{ 
   LED_Number = 0;                                  //       initialize 
   TRISD   =   0b00000000;                          //   PORTD   bits  7:0    are   all   outputs   (0) 
   while   (1) 
   { 
             // use lookup table to output one LED on based on LED_Number value 
        
        LATD = LED_LookupTable[LED_Number]; 
        LED_Number++;                               //    rotate   display  by   1 
        if (LED_Number == 8) 
        LED_Number = 0;                             //      go   back  to  LED    0. 
        Delay1KTCYx(50);                   //    Delay   50  x  1000    =   50,000   cycles;   200ms @ 1MHz 
   } 
}

Inicialización de variables y I/O puertos.
        Se  configura  trisd  para que todas  las patitas  del  portd  sean salidas y la variable global 
LED_Number es el numero de led a encender.
        Primero se inicializa con el valor 0 en  LED_Number  y después se usa como array   en el 
índice y el array devuelve el valor por la posición que le indica LED_Number. Como el valor inicial 
de LED_Number es cero, el índice del array es cero también, por lo que su valor a devolver es el 
primer dato del array, osea 0x01. Este valor es almacenado en el latch del puerto D quedando en 
primera instancia la formula con el siguiente valor:

        LATD =LED_lookupTable[LED_Number] siendo su valor LATD = 0x01

        Seguimos y vemos que ahora se incrementa  LED_Number  por lo que el próximo valor a 
mostrar será el siguiente (0x02). Se compara el valor del índice( LED_Number) por si su valor es 8, 
que en caso de afirmativo volvería a poner a LED_Number a 0 ( reset) o en caso contrario ejecuta un 
retardo de 200 ms y vuelve de nuevo al array indefinidamente haciendo girar los leds.

        Ejercicio 4 Rota switch

        En este ejercicio se utiliza un switch para hacer rotar los leds del ejercicio anterior.
Se utiliza la directiva #define y se asume que el lector ya sabe o por lo menos está  familiarizado 
con el lenguaje C. 
        #define Pin_Switch  PORTBbits.RB0
Esto hará que cada vez que pongamos Pin_Switch el compilador lo sustituye  por PORTBbits.RB0.
Pero para que el compilador entienda la directiva #define  se debe incluir el archivo cabecera “04 
Switch Input.h”, veamos como:
        #include “04 Switch Input.h”
Existe un programa en aplicaciones que usan los switch que evitan el efecto rebote. Es un 
efecto que al pulsar el switch, rebota los contactos haciendo de una pulsación simple , en un tren de 
pulsos que provocaría efectos indeseados. Supongamos que queremos contar las veces que pulsamos 
en el switch, este al ser pulsado una vez podemos encontrarnos con la sorpresa que nuestro contador 
pueda contar 10 100 o 3 unidades en vez de una , que es la que esperábamos.
        Para evitar este efecto rebote, se añade un retardo de 5 ms , tiempo mas que suficiente para 
que la señal sea estable y eliminaremos dicho efecto. 




       Este es el organigrama para evitar dicho efecto. Observa que espera a que se pulse el switch, 
cuando este es presionado, se incrementa un contador y cuando este llega a 5 entonces da la señal de 
que se ha pulsado dicho switch. En caso de que el contador no haya llegado a 5  se realiza un retardo 
de 1 ms y se vuelve a incrementar el contador haciéndose la misma pregunta una y otra vez hasta 
que se completen los 5 ms que será cuando el circuito realice el organigrama unas 5 veces y cada 
una de ellas de 1 ms.
       El programa:

/** V A R I A B L E S *************************************************/ 

#pragma udata                                   // declare statically allocated uinitialized variables 
unsigned char LED_Display;                       // 8­bit variable 

/** D E C L A R A T I O N S *******************************************/ 
#pragma code                                    //     declare   executable  instructions 
void  main   (void) 
{ 
        unsigned    char   Switch_Count  =  0; 
        LED_Display    =   1;                    //   initializa 
        TRISD   =   0b00000000;                  //   PORTD   bits  7:0   todas salidas    (0) 
        INTCON2bits.RBPU = 0;                    //   habilita PORTB internal pullups resistencias
        WPUBbits.WPUB0 = 1;                     //   enable pull up on RB0 
        ANSELH = 0x00;                           //   AN8­12 are digital inputs (AN12 on RB0) 
        TRISBbits.TRISB0 = 1;                     //   PORTB bit 0 (connected to switch) is input       (1) 
        while (1) 
        { 
            LATD = LED_Display;                 //   enciende el led
            LED_Display <<=      1;                       //   rotate   display by     1 
           if (LED_Display == 0)                          //   rotated   bit  out,   so   set  bit   0 
                LED_Display = 1; 
            while   (Switch_Pin   !=  1);          //   wait  for   switch  to    be  released 
            Switch_Count = 5; 
            do 
            { // monitor switch input for 5 lows in a row to debounce if 
                  (Switch_Pin == 0) 
                  { // pressed state detected 
                       Switch_Count++; 
                  } 
                  else 
                  { 
                     Switch_Count = 0; 
                  } 
                  Delay10TCYx(25);                          // delay 250 cycles or 1ms. } 
             while (Switch_Count < DetectsInARow); 

        Ojo a las variables, ya que la variable global se almacena en un registro del pic mientras que 
las variables locales se destruyen al salir de la función que la crea. Así   LED_Display es global 
mientras que Switch_Count es local y se destruye al finalizar el programa ya que se almacena en la 
pila del programa.
        El interruptor está conectado a RB0 y cuando este es pulsado se tira a masa “0” por lo que 
debe estar con resistencias pull­up habilitadas  ya que puede provocar fallos de lectura si no se 
presiona   dicho   switch   sin   habilitar   pull­up   del   RB0.   Pero   esta   patita   comparte   con   la   entrada 
analógica AN12, es decir, que el mismo pin puede ser digital o analógico. Hay que configurarlo 
como digital y como entrada.Para ello vemos como lo hace en el programa:

INTCON2bits.RBPU   =   0;    aquí   podemos   ver   como   configurar   el   registro   INTCON2   el   bit 
correspondiente al pull­up que en este caso es RBPU y lo ponemos a cero.
WPUBbits.WPUB0 = 1;      Habilitamos aquí, el pull­up del RB0
ANSELH = 0x00;    Forzamos a que las entradas analógicas AN8­12 sean digitales poniéndolas a 0.
 TRISBbits.TRISB0 = 1;     Configuramos RB0 como entrada.




        Observa los registros AN8­12. Aquí se usa un sistema de rotado de leds mas simple que en el 
ejercicio anterior el cual usaba una tabla con un índice para poder mostrar un patrón de bits en la 
salida y aparentar el desplazamiento. En este caso usaremos algo mucho mas sencillo para realizar 
el mismo efecto, en este caso se desplaza el bit de mayor peso de LED_Display y como es mostrado 
en LATD pues se muestra en la salida.
         LED_Display <<=      1;

         Ejercicio 5 Temporizador

      En   este   ejercicio   vamos   a   utilizar   el   temporizador   TMR0   en   vez   de   utilizar   un   bucle 
temporizado, dejando así  libre a la CPU de dicho conteo, encargándose de la cuenta el TMR0.
      Veamos sus registro de configuración:




    •    El bit 7 activa o no el temporizador.
    •    El bit 6 se usa para seleccionar entre 8/16 bits.
    •    El bit 5 selecciona entre entrada externa o ciclos de reloj interno.
    •    El bit 4 se usa para activar la cuenta en el flaco de subida de la señal o la de bajada.
    •    El bit 0­1­2­3 se usan para activar el preescaler (divisor) y su rango de división.

        El TMR0 es el temporizador/contador de la familia 18Fxxxxx que utiliza el reloj interno o 
los impulsos externos a través de la patita TOCK1. Puede realizar cuentas de 0­255 si se configura 
como   8   bits   o,   de   0­65535   si   lo   hace   en   modo   16   bits.   Un   bit   de   flag   se   activa   cuando   el 
temporizador ha llegado a rebasar la cuenta y vuelve de nuevo a cero.
        El   preescaler   se   usa   para   generar   una   cuenta   por   cada   impulso   del   reloj   de   entrada 
( recordemos que la frecuencia interna es ¼ la frecuencia del oscilador ) y si el rango del preescaler 
es de 1/8  significa que dará un pulso por cada 8 pulsos de reloj, si es 1/16 pues cada 16......
        El   preescaler   se   borra   cuando   se   escribe   en   el   temporizador,   por   lo   que   habrá   que 
configurarlo cada vez que se escriba en el temporizador.
        Cuando utilicemos el temporizador en modo 16 bits, hay que prestar especial atención ya que 
se usan el temporizador bajo y el alto TMR0L y TMR0H ubicados en la zona de registros SFR del 
pic y que TMR0L es leíble y se escribe   directamente, mientras que la parte alta del contador 
TMR0H no es directamente accesible. En su lugar se usa TMR0H pero para poder leerlo, primero 
debemos LEER EL TMR0 PRIMERO Y DESPUES SE ACTIVARÁ TMR0H Y PARA ESCRIBIR 
EN EL TEMPORIZADOR PRIMERO SE ESCRIBIRÁ EN TMR0H ANTES QUE TMR0L.
        En el ejercicio vamos a temporizar entre 200 y 300 ms y vamos a ver como hacemos esto a 
través de nuestro preescaler.
        Hay que configurar T0CON para que el resultado sea satisfactorio y por ello en la tabla 
anterior vemos como se configuran los bits de dicho registro.

       – Lo ponemos en modo 16 bits por lo que el bit 6 lo ponemos a 0.
       – Usaremos los ciclos internos de reloj por lo que el bit 5 se queda a 0.
       – Como la temporización coincide con el tiempo que queramos no usaremos el bit PSA o 
         bit   numero   3   ya   que   65536   x   (1   /   250,000)   =   262ms,   es   decir,   si   la   cuenta   del 
         temporizador llega a 65536 y tarda en cada ciclo  1/250,000 pues nos da los 262 ms que 
         está dentro de nuestro rango.
       – El bit 7 se pone a 0 ya que queda desactivado y se activa cada vez que se escribe en el.

        El resto de bits no importa su configuración por lo que el dato a escribir de forma binaria en 
el T0CON será 0b0000100.
        Abrir el archivo 05 Timer.c y 05 Timer.h. En el archivo de cabecera .h podemos encontrar 
las siguientes sentencias:
        typedef enum { LEFT2RIGHT, RIGHT2LEFT}  LEDDirections; 
        typedef enum {FALSE, TRUE} BOOL; 

         El tipo de dato enum, utiliza un nombre LEDDirections para identificarlos y solo admite los 
valores que están entre paréntesis, que en este caso es  LEFT2RIGHT, RIGHT2LEFT, es decir, que 
si utilizamos la variable LEDDirectios, sus valores que puede tomar son estos dos y no otros.
         Quizás le sea más fácil la linea del enum BOOL que le hemos puesto que solo admita como 
valores FALSE Y TRUE.
         Hay que inicializarlas como cualquier variable pero, solo con los valores que admite. Ojo 
son tipos de variables no variables en si ( como lo son integer, char, double....). Veamos como se 
inicializan:

       LEDDirections Direction = LEFT2RIGHT; 
       BOOL SwitchPressed = FALSE; 

        Aquí podemos ver que hemos definido una variable Direction del tipo LEDDirections y con 
el valor inicial LEFT2RIGHT ( que es el valor que definimos en el tipo enum). Así Direction solo 
puede tener dos valores LEFT2RIGHT Y RIGHT2LEFT únicamente.
        Para el tipo BOOL hemos definido otra variable llamada SwitchPressed y se ha inicializado 
con el valor FALSE.
        La variable Direction será utilizada para determinar la dirección de rotación de los leds y la 
variable Switchpressed recuerda al programa que se ha presionado el switch el cual cambiará el 
sentido de la rotación de los leds.

//  Inicializamos el contador 
INTCONbits.TMR0IF   =  0;                 //  line  1 
T0CON = 0b00001000;                       //  line  2 

// T0CON  =  0b00000001;  (se ignora por el momento) 
TMR0H = 0;                         //  line  3 
TMR0L = 0;                         //  line  4 
T0CONbits.TMR0ON  =   1;           //  line  5 

       Esta es la parte del programa que inicializa el temporizador , deshabilita las interrupciones 
generada por el mismo al sobrepasar la cuenta, escribe en el registro T0CON el patrón de bits a 
configurar para la temporización, así como la escritura en el temporizador en el orden preferente 
siendo TMR0H la primera en escribirse y luego TMRL0 la última, y por último habilitamos el 
temporizador.

        El programa:

// ******************************************************************* 
// *    See included documentation for Lesson instructions           * 
// ******************************************************************* 
/** C O N F I G U R A T I O N   B I T S ******************************/ 

#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF                      // CONFIG1H 
#pragma config PWRT = OFF, BOREN = OFF, BORV = 30                           // CONFIG2L 
#pragma config WDTEN = OFF, WDTPS = 32768                                   // CONFIG2H 
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC            //  
CONFIG3H 
#pragma config STVREN = ON, LVP = OFF, XINST = OFF                          // CONFIG4L 
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF                   // CONFIG5L 
#pragma config CPB = OFF, CPD = OFF                                         // CONFIG5H 
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF               // CONFIG6L 
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                           // CONFIG6H 
#pragma   config  EBTR0  = OFF,  EBTR1  =  OFF, EBTR2  =  OFF, EBTR3  = OFF                      //  
CONFIG7L 
#pragma config EBTRB = OFF                                                  // CONFIG7H 

/** I N C L U D E S **************************************************/ 
#include "p18f45k20.h" 
//#include "delays.h"  // no longer being used.
#include "05 Timer.h"  // header file 

/** V A R I A B L E S *************************************************/ 
#pragma udata                     // declare statically allocated uinitialized variables 
unsigned char LED_Display;        // 8­bit variable 

/** D E C L A R A T I O N S *******************************************/ 
#pragma code                              // declare executable instructions 
void main (void) 
{ 
    LEDDirections Direction = LEFT2RIGHT;                 // es del tipo enum en el archivo .h
    BOOL SwitchPressed = FALSE;                           // también del tipo enum en .h
   LED_Display = 1;            // initialize la variable global
    // Init I/O 
    TRISD = 0b00000000;      // PORTD bits 7:0 son todas salidas (0) 
    INTCON2bits.RBPU = 0;                 // enable PORTB internal pullups 
     WPUBbits.WPUB0 = 1;                          // enable pull up on RB0 
    ANSELH = 0x00;              // AN8­12 are digital inputs (AN12 on RB0) para convertir a digitales
    TRISBbits.TRISB0 = 1;       // PORTB bit 0 pone esta como entrada.

    // Init Timer 
    INTCONbits.TMR0IF = 0;          // se borra el flag de cuenta sobrepasada.
    T0CON = 0b00001000;             // Configuración del tocon sin preescaleer.
    //T0CON = 0b00000001;             // prescale 1:4 ­ four times the delay.
            TMR0H = 0;                      // borrado del temporizador parte alta
    TMR0L = 0;                       // parte baja
    T0CONbits.TMR0ON = 1;           // comienza a temporizar
    while (1) 
    { 
        if (Direction == LEFT2RIGHT) // recuerda que si inicializo con LEFT2RIGHT
        { 
            LED_Display <<= 1;          // rotate display by 1 from 0 to 7 
            if (LED_Display == 0) 
                LED_Display = 1;        // rotated bit out, so set bit 0 
        } 
        if (Direction == RIGHT2LEFT) 
        { 
            LED_Display >>= 1;          // rotate display by 1 from 7 to 0 
            if (LED_Display == 0) 
                LED_Display = 0x80;     // rotated bit out, so set bit 7 
        } 
        LATD = LED_Display;         // output LED_Display value to PORTD LEDs 
        do 
        { // comprueba si el pulsador esta pulsado
            if (Switch_Pin == 1) // recuerda el el pulsador se pone a masa cuando se pulsa
            { // el pulsador no esta pulsado
                SwitchPressed = FALSE; 
            } 
            else if (SwitchPressed == FALSE) // && (Switch_Pin == 0) due to if­else 
            { // el pulsador está presionado
                SwitchPressed = TRUE; 
                // cambia entonces la dirección
                if (Direction == LEFT2RIGHT) 
                    Direction = RIGHT2LEFT;  // aquí cambia la dirección escribiendo lo contrario.
                else 
                    Direction = LEFT2RIGHT; 
            } 
        } while (INTCONbits.TMR0IF == 0); // se repita el ciclo do while hasta TMR0 llegue a fin.

        // Timer expired 
        INTCONbits.TMR0IF = 0;          // Reset Timer flag 
    } 
}

         EJERCICIO 6

        EL DEBUGGER
        Tenemos que decir, que el presente ejercicio, presenta por primera vez el uso del debugger 
usando   para   ello   el   programa   anterior.   Evidentemente   su   función   es   ver   en   tiempo   real   si   los 
registros   cambian,   que   valor   tienen   en   un   momento   determinado....   etc.   Esto   es   parecido   al 
simulador pero en este caso se reserva un área de memoria en el microcontrolador para efectuar el 
debugger o depurador de programa de forma que si el compilador hizo bien su trabajo, dejó este 
área vacía y reservada para este cometido.
        El pickit3 se usará como ICD debuggin circuit y utilizará los recursos no accesibles para el 
usuario para dicho cometido en el pic.
        En este caso la patita MCLR ( master control reset) está reservada para el cometido y por 
tanto no se podrá usar ni programar como entrada o salida I/O normal.
        Los pines PGC Y PGD tampoco se usaran como puertos I/O ya que los usaremos en el 
debuggin.
        Un área de la pila de memoria se usará y por tanto no accesible para el usuario.
        Se utilizará un área de memoria de programa y de registros para el depurado y se queda 
marcado en el MPLAB IDE como una R (reservado) y por tanto, el usuario no podrá utilizar.
        El pickit 3 no puede usarse como debugger ICD y programador al mismo tiempo, por tanto 
si se usa el debugger, el programador se desactiva.   Debugger > Select Tool > 2 PICkit 3 es lo que 
debemos de hacer para seleccionar el pikit3 como debugger.

        Comenzamos:

        1­       En la barra de herramientas del MPLAB IDE  seleccionamos Debug en vez de 
                 Release.
        2­       Compilar el proyecto 05 ( esto reservará en el pic el área para su debuggin).
        3­       Lo programamos Debugger> Program.
        4­       Arrancamos el debuggin. Debugger > Run.

               Se observa que el pic18f45k20 funciona con total normalidad, pero esta vez está en 
modo debuggin.
      Operaciones básicas:
  • HALT  El programa del pic18f45k20 se puede parar en cualquier momento, si pulsamos F5 
      o vamos a Debugger > Halt . Se mostrará una flecha verde indicado el punto de parada.
  • STEP Se permite ejecutar el program paso a paso de las siguientes maneras:
      ◦ STEP INTO se ejecuta paso a paso pero al llegar a una función de llamada se para y 
           salta la primera linea de dicha función.
      ◦ STEP OVER se ejecuta paso a paso y al llegar a una función de llamada, esta se ejecuta 
           entera y el salto llega al final de dicha funcion call.
      ◦ STEP OUT se ejecuta paso a paso y ejecuta sin parar las subrutinas.
  • RUN se ejecuta el programa hasta encontrar un punto de break o sea parado por el usuario 
      con HALT.
  • RESET Se ejecuta Debugger > Processor> Reset Se ejecuta un reset del micro, pero solo si 
      el   microcontrolador   estaba   previamente   parado   y   por   tanto   empieza   desde   la   primera 
      instrucción de programa.
  • RESET Se ejecuta con Reset>Processor Reset F6 Al ejecutarse MPLAB IDE abre un nuevo 
      archivo c018i.c inicializa la pila de software C y asigna todos los datos de inicialización de 
      variables permitiendo llevar al pic a un estado de judicialización completa y luego salta a la 
      instrucción main() después de inicializar las variables.

       Usando puntos de Parada.
       La mejor forma de usar un punto de parada para que el programa al ejecutarse, se ejecute 
bien y se pare donde queramos, es ir a la linea que nos interesa y con el botón secundario del ratón 
pulsamos   y   ponemos   el   breakpoint   (   Set   breakpoint   ),   apareciendo   un   rombo   rojo   con   una   B 
indicando que ahí se parará el programa. Realicemos con la línea 111 o SwitchPressed = TRUE; y 
tal y como hemos puesto el punto de parada justo cuando se debe presionar el botón, el programa 
continua y por tanto no se para. Pero si se pulsa el botón, el programa quedará parado por el break 
que hemos colocado.



        El número de breakpoints que se puede utilizar depende mucho del microcontrolador que se 
use, nuestro pic18f45k20 tiene 3 como máximo. Si abrimos  Debugger > Breakpoints podemos ver 
los break que se han usado y los máximos que permite nuestro pic ( HW BP )

        Echando un vistazo a las variables y a los registros SFR.

         Se pueden ver los registros abriendo View > File Registers  y los SFR con View > Special 
Function Registers , sin embargo no se recomienda que dichas ventanas estén abiertas ya que se 
pueden leer dichos registros desde la tarjeta cuando está en modo RUN parado o en modo paso a 
paso.   Leer   todos   estos   datos   sobre   el   ICD   BUS   puede   tomar   un   tiempo   significativo   debido 
principalmente a la memora que contenga el pic18f45k20 así como la velocidad de su reloj interno, 
así que es mejor cerrar las ventanas de los registros.
         La mejor manera de ver los registros que sólo interesan es abriendo una ventana llamada 
Watch y se abre View > Watch

                                                                        Los SFR que nos interese, 
                                                                  lo   añadimos   desde   el   campo 
                                                                  seleccionable que está marcado 
                                                                  en   la   figura   de   arriba   como 
                                                                  ADCON0 y pulsando el botón 
                                                                  ADD   SFR   de   la   misma 
                                                                  ventana.
                                                                        Para   nuestro   ejercicio 
añadiremos PORTB Y LATD  ya que son los que hemos usado tanto para el pulsador como para la 
salida de los leds.
        Las variables que hemos creado nosotros las podemos monitorizar  seleccionado­las desde el 
campo que  nos queda a la derecha ( que en este caso marca  config) y pulsando el botón  Add 
Symbol.
        Añadiremos por tanto para nuestro ejercicio LED_Display, SwitchPressed y Direction. Y nos 
                                                               debe de quedar algo así:




       Recordemos que nuestras variables del tipo “enum” como son  Direction y SwitchPressed se 
mostraran en este caso como valor numérico y no como palabras escritas (let2righ, right2left.... etc).
El formato de muestra de valores en el campo Value, se puede cambiar pinchando con el ratón y en 
Properties en el menú que nos aparece.
Con Watch podemos también cambiar los valores de las variables y por supuesto al cambiar dicho 
valor,   cambiará   en   realidad   en   el   pic18f45k20   y   por   tanto   si   escribimos   AA   en   el   LATD   se 
encenderán los leds correspondientes.
Selecciona ahora PORTB y selecciona sus propiedades y buscando el formato, lo cambiamos a 
binario, pulsamos OK y cerramos el dialogo. Ahora se verá la información de PORTB  en binario 
con el bit de mas peso a la izquierda(7).
Realizamos el paso a paso pulsando F8 ( step over )   que en este modo se ejecuta la subrutina y 
observa que el PORTB debe tener el switch ( PORTB0) a 1 ya que no se ha pulsado, claro que si 
pulsamos el botón y ejecutamos de nuevo con F8 el valor será 0 siempre que se mantenga pulsado 
hasta que sea ejecutada la subrutina. Recuerdas donde pusimos el punto de break....




         Como podemos ver, el pulsador en estado normal es 1 por lo que la sentencia else if no se 
cumple y salta a el retos del programa por debajo de los corchetes.... Pero en caso de que si se 
cumpla, se parará al llegar a la linea 111 y deberemos pulsar o ejecutar paso a paso el programa, ya 
que se ha quedado en estado HALT. Pulsamos F8 para ver el registro PORTB0  como cambia a 0.
         Practica con el código añadiendo los breakpoints donde te apetezca y observa los registro 
como   cambian.   Añade   también   TMR0L   y   TMR0H   a   la   ventana   WATCH   y   observa   su 
comportamiento,   sobre   todo   cuando   estamos   en   modo   paso   a   paso.   Comprobará   que   no   se 
incrementa por cada instrucción ya que cada instrucción compilada en C creará varias instrucciones 
en   lenguaje   ensamblador   y   el   Timer0   es   incrementado   una   vez   por   cada   instrucción   maquina 
ejecutada ( no C ).

Mais conteúdo relacionado

Mais procurados

Bootloader USB Multiplataforma para pic18f4550
Bootloader USB Multiplataforma para pic18f4550Bootloader USB Multiplataforma para pic18f4550
Bootloader USB Multiplataforma para pic18f4550Biblioman Aquihayapuntes
 
Matriz de LEDs + Interfaz Grafica con GTK en Linux
Matriz de LEDs + Interfaz Grafica con GTK en LinuxMatriz de LEDs + Interfaz Grafica con GTK en Linux
Matriz de LEDs + Interfaz Grafica con GTK en LinuxSNPP
 
Arquitectura de computadoras
Arquitectura de computadorasArquitectura de computadoras
Arquitectura de computadorasYessicafragoso
 
El AT mega8 es un microcontrolador excelente
El AT mega8 es un microcontrolador excelenteEl AT mega8 es un microcontrolador excelente
El AT mega8 es un microcontrolador excelenteJose Alva
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...Victor Asanza
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...Victor Asanza
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...Victor Asanza
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...Victor Asanza
 

Mais procurados (18)

Mm card 7
Mm card 7Mm card 7
Mm card 7
 
Timers 2
Timers 2Timers 2
Timers 2
 
Bootloader USB Multiplataforma para pic18f4550
Bootloader USB Multiplataforma para pic18f4550Bootloader USB Multiplataforma para pic18f4550
Bootloader USB Multiplataforma para pic18f4550
 
Matriz de LEDs + Interfaz Grafica con GTK en Linux
Matriz de LEDs + Interfaz Grafica con GTK en LinuxMatriz de LEDs + Interfaz Grafica con GTK en Linux
Matriz de LEDs + Interfaz Grafica con GTK en Linux
 
como programar un pic
como  programar un piccomo  programar un pic
como programar un pic
 
Arquitectura de computadoras
Arquitectura de computadorasArquitectura de computadoras
Arquitectura de computadoras
 
Pic libre
Pic librePic libre
Pic libre
 
Parpadear un LED
Parpadear un LEDParpadear un LED
Parpadear un LED
 
Manual básico Minicom
Manual básico MinicomManual básico Minicom
Manual básico Minicom
 
Taxímetro con Pic16F887
Taxímetro con Pic16F887Taxímetro con Pic16F887
Taxímetro con Pic16F887
 
Curso de-mcu-proteus
Curso de-mcu-proteusCurso de-mcu-proteus
Curso de-mcu-proteus
 
El AT mega8 es un microcontrolador excelente
El AT mega8 es un microcontrolador excelenteEl AT mega8 es un microcontrolador excelente
El AT mega8 es un microcontrolador excelente
 
Manual tp12
Manual tp12Manual tp12
Manual tp12
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN A RESUELTA 1er PARCIAL (2019 2do ...
 
Familia De Los Microcontroladores Pic
Familia De Los Microcontroladores PicFamilia De Los Microcontroladores Pic
Familia De Los Microcontroladores Pic
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, TALLER RESUELTO 1ra EVALUACIÓN (2019 2do ...
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, LECCIÓN B RESUELTA 1er PARCIAL (2019 2do ...
 
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...
⭐⭐⭐⭐⭐ DISEÑO DE SISTEMAS DIGITALES, EXAMEN RESUELTO 3ra EVALUACIÓN (2019 1er ...
 

Destaque

Private and confidential transaction
Private and confidential transactionPrivate and confidential transaction
Private and confidential transactionAmar kavia
 
Atención de Derechos ARCO
Atención de Derechos ARCOAtención de Derechos ARCO
Atención de Derechos ARCOprodato
 
What's it like to work for an App developer [flash talk]
What's it like to work for an App developer [flash talk]What's it like to work for an App developer [flash talk]
What's it like to work for an App developer [flash talk]Scott Alexander-Bown
 
Inauguración nueva escuela de música de sitges en el escaan
Inauguración nueva escuela de música de sitges en el escaanInauguración nueva escuela de música de sitges en el escaan
Inauguración nueva escuela de música de sitges en el escaanVideoPressMedia
 
Presentacion inventario de emisiones Costa Rica
Presentacion inventario de emisiones Costa RicaPresentacion inventario de emisiones Costa Rica
Presentacion inventario de emisiones Costa RicaPlugin Digital
 
Presentacion estructura del computador
Presentacion estructura del computadorPresentacion estructura del computador
Presentacion estructura del computadorcarlosangulo23
 
Bicentenario euge y vale 6c 010
Bicentenario euge y vale 6c 010Bicentenario euge y vale 6c 010
Bicentenario euge y vale 6c 010Miriam Roca
 
Efectos del aborto en el cerebro de la mujer
Efectos del aborto en el cerebro de la mujerEfectos del aborto en el cerebro de la mujer
Efectos del aborto en el cerebro de la mujerManuel Álvarez
 
Electricidad
ElectricidadElectricidad
Electricidadcristeit
 
Clase 2da, intro a comunicación
Clase 2da, intro a comunicaciónClase 2da, intro a comunicación
Clase 2da, intro a comunicaciónLeonardo Antoniassi
 
MPSG_presentation_EN
MPSG_presentation_ENMPSG_presentation_EN
MPSG_presentation_ENAlex Mejevoi
 
Curso basico de ingles 1 atc Ibarra
Curso basico de ingles 1 atc IbarraCurso basico de ingles 1 atc Ibarra
Curso basico de ingles 1 atc Ibarrateacher
 
Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014
Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014
Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014Fernando Saenz-marrero
 

Destaque (20)

Private and confidential transaction
Private and confidential transactionPrivate and confidential transaction
Private and confidential transaction
 
Folleto capadocia
Folleto capadociaFolleto capadocia
Folleto capadocia
 
Atención de Derechos ARCO
Atención de Derechos ARCOAtención de Derechos ARCO
Atención de Derechos ARCO
 
What's it like to work for an App developer [flash talk]
What's it like to work for an App developer [flash talk]What's it like to work for an App developer [flash talk]
What's it like to work for an App developer [flash talk]
 
Inauguración nueva escuela de música de sitges en el escaan
Inauguración nueva escuela de música de sitges en el escaanInauguración nueva escuela de música de sitges en el escaan
Inauguración nueva escuela de música de sitges en el escaan
 
Apps grat comp
Apps grat compApps grat comp
Apps grat comp
 
Álvaro Jover
Álvaro JoverÁlvaro Jover
Álvaro Jover
 
Gaceta 8 2013
Gaceta 8 2013Gaceta 8 2013
Gaceta 8 2013
 
Presentacion inventario de emisiones Costa Rica
Presentacion inventario de emisiones Costa RicaPresentacion inventario de emisiones Costa Rica
Presentacion inventario de emisiones Costa Rica
 
Presentacion estructura del computador
Presentacion estructura del computadorPresentacion estructura del computador
Presentacion estructura del computador
 
Bicentenario euge y vale 6c 010
Bicentenario euge y vale 6c 010Bicentenario euge y vale 6c 010
Bicentenario euge y vale 6c 010
 
Efectos del aborto en el cerebro de la mujer
Efectos del aborto en el cerebro de la mujerEfectos del aborto en el cerebro de la mujer
Efectos del aborto en el cerebro de la mujer
 
Gugu tata powerpoint
Gugu tata powerpointGugu tata powerpoint
Gugu tata powerpoint
 
Electricidad
ElectricidadElectricidad
Electricidad
 
Clase 2da, intro a comunicación
Clase 2da, intro a comunicaciónClase 2da, intro a comunicación
Clase 2da, intro a comunicación
 
Letak pickling agent
Letak pickling agentLetak pickling agent
Letak pickling agent
 
Geografia
GeografiaGeografia
Geografia
 
MPSG_presentation_EN
MPSG_presentation_ENMPSG_presentation_EN
MPSG_presentation_EN
 
Curso basico de ingles 1 atc Ibarra
Curso basico de ingles 1 atc IbarraCurso basico de ingles 1 atc Ibarra
Curso basico de ingles 1 atc Ibarra
 
Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014
Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014
Proyecto 1. MKT&Design : Botella reutilizable Memobottle . GIDIDP-ULPGC 2014
 

Semelhante a Pikit3 parte i-

Semelhante a Pikit3 parte i- (20)

Como programar en Arduino
Como programar en ArduinoComo programar en Arduino
Como programar en Arduino
 
02 programar
02 programar02 programar
02 programar
 
02 programarpic
02 programarpic02 programarpic
02 programarpic
 
Como programar un pic en 4 pasos
Como programar un pic en 4 pasosComo programar un pic en 4 pasos
Como programar un pic en 4 pasos
 
Como programar un PIC
Como programar un PICComo programar un PIC
Como programar un PIC
 
simatic estaciones fms
 simatic estaciones fms simatic estaciones fms
simatic estaciones fms
 
Labview & pic
Labview & picLabview & pic
Labview & pic
 
Construcciondeun pl cconpic
Construcciondeun pl cconpicConstrucciondeun pl cconpic
Construcciondeun pl cconpic
 
Curso de-mcu-proteus
Curso de-mcu-proteusCurso de-mcu-proteus
Curso de-mcu-proteus
 
53592868 curso-de-mcu-proteus
53592868 curso-de-mcu-proteus53592868 curso-de-mcu-proteus
53592868 curso-de-mcu-proteus
 
Microcontroladores ss13
Microcontroladores ss13Microcontroladores ss13
Microcontroladores ss13
 
Microcontroladores ss13
Microcontroladores ss13Microcontroladores ss13
Microcontroladores ss13
 
Curso de microcontroladores capitulo 03
Curso de microcontroladores capitulo 03Curso de microcontroladores capitulo 03
Curso de microcontroladores capitulo 03
 
26176947 tutorial-v-escritura-en-lcd-usando-teclado-matricial
26176947 tutorial-v-escritura-en-lcd-usando-teclado-matricial26176947 tutorial-v-escritura-en-lcd-usando-teclado-matricial
26176947 tutorial-v-escritura-en-lcd-usando-teclado-matricial
 
Tutorial proton part 2
Tutorial proton part 2Tutorial proton part 2
Tutorial proton part 2
 
Proy iker4
Proy iker4Proy iker4
Proy iker4
 
Microcontroladores: Programación del microcontrolador ATMega328P.pdf
Microcontroladores: Programación del microcontrolador ATMega328P.pdfMicrocontroladores: Programación del microcontrolador ATMega328P.pdf
Microcontroladores: Programación del microcontrolador ATMega328P.pdf
 
Uso Mplab
Uso MplabUso Mplab
Uso Mplab
 
Dialnet programando microcontroladorespicenlenguajec-4587553
Dialnet programando microcontroladorespicenlenguajec-4587553Dialnet programando microcontroladorespicenlenguajec-4587553
Dialnet programando microcontroladorespicenlenguajec-4587553
 
Introducpic2
Introducpic2Introducpic2
Introducpic2
 

Pikit3 parte i-

  • 1. Guía de pickit 3                 El contador de programa   Este tiene 21 bits de anchura y se divide en tres de 8 bits, PCL, PCH, PCU siendo PCH Y  PCU los registros a los que no se puede escribir directamente ni tampoco son visibles a no ser que  se realice mediante alguna instrucción de lectura o escritura sobre el registro PCL. De esta forma se  actualiza los registros superiores del PC. También es modificable si una instrucción de salto o de  subrutina se ejecuta, permitiéndose la escritura directamente por dichas instrucciones pero el dato  no será transferido desde el PCH y PCU  al contador de registro. Ante un reset, el  PC se carga con el valor 0, por lo que este apunta a la dirección 0 de la  memoria de programa, y según la instrucción escrita (normalmente un "goto") así actuará. Hay que decir que las instrucciones no se pueden ejecutar en bytes impares, ya que el         PC solo va saltando de dos en dos ya que su bit de menos peso, tiene siempre puesto a 0 por lo que solo   son pares las lineas a las que salta.                 PROGRAMANDO CON C  El compilador C para pic de MPLAB implementa la siguiente regla: 1. Las instrucciones se almacenan en la sección denominada “code.” 2. Los datos son almacenados en “romdata” conjuntamente con “ROM” MPLAB  C  COMPILER  puede   generar  dos  modelos   de  memoria,   corto    y  largo.  En   el  modelo corto se usa un puntero de 16 bits, mientras que el modelo largo se usa uno de 24 bits (PC).                 MEMORIA         DE DATOS  La   memoria   de   datos   es   llamada   “file  register”   o   memoria   de   registros.   Una   vez   que  encendemos el pic, los datos contenidos en dichos registros, son aleatorios. Los registros se agrupan  en orden de 256 bytes los cuales pueden ser seleccionados en bancos accesibles por los 4 bits de  mayor peso del registro de direcciones  BSR  (  Bank  Select  Register  ). Las áreas especiales en el  banco 0 y en el 15 son directamente accesibles y son denominadas ACCESS RAM y es aquí donde  están los registros especiales (FSR) como son por ejemplo, los registros para programar un puerto  de I/O, bits de algún registro de estado.... #pragma varlocate le dice al compilador dónde se almacenan las variables. Las  variables  no inicializadas son almacenadas en memoria mediante “udata”, y el compilador  realizará   lo   necesario   para   almacenar   y   distribuir   los   datos   correctos,   así   como   su   tipo   para  optimizar la memoria al máximo, una vez que lo inicialice el compilador pasará los datos de la  memoria de programa a la de datos para comprobar su correcta ortografía y tipos de datos para  luego optimizar el programa. REGISTROS ESPECIALES SFR Estos   registros   especiales  son (  PC, status, pila,  EEDATA,,,,) sirven para  programar   los  periféricos y los demás registros como STATUS o PC   y el compilador de C puede acceder a ello  por su nombre y puede modificarlos y leerlos como si fuesen variables. Se localizan el el Banco 15  de la memoria de datos.
  • 2. EJERCICIOS PRACTICOS SOBRE C EJERCICIO 1 Conectar el PICKIT3 al puerto usb del pc y después conectarnos la placa al conector ICSP. Vamos a crear un proyecto de compilación en C con el  compilador C de MPLAB. El proyecto consiste en encender un led indefinidamente conectado a una puerta, y veremos  como se realizan todos los pasos para su compilación. Para crear un proyecto vamos a realizarlo  mediante el asistente, por lo que accedemos a Project>Project Wizard... y nos sale una ventana de  bienvenida, por lo que pulsamos NEXT. 1. Seleccionamos un componente que en este caso será PIC18F45K20 y pulamos en Next. 2. Seleccionamos el lenguaje de programación “Microchip C18 Toolsuite”  y pulsamos Next. 3. Crear   un   nuevo   proyecto.   Busca   C.LessosnPICKIT  3  Debug  Express  Lessons01  Hello  LED  y nombra el proyecto  Lessson1  LED  y lo guardamos con  SAVE  entonces le damos a  NEXT para continuar. 4. Podemos añadir archivos y fuentes que tengamos escritos al proyecto ( evidentemente  antes  deben estar creados en nuestro disco duro) . A la izquierda seleccionamos el archivo  01  HELLO LED.c  y lo añadimos. Pulsamos Next para continuar. 5. Esta ultima ventana verificaremos todos nuestros datos y pincharemos en Finish. Para ver el proyecto que hemos creado, vamos a   View>Project y veremos nuestro área de  trabajo el archivo llamado  Lesson 1 LED.mcw( en el título de la ventana) y el archivo proyecto  Lesson 1 LED.mcp . Para   completar   el   proyecto   tenemos   que   añadir  Linker   Script  y   el  header  del  microcontrolador al proyecto. El Linker Script se necesita para construir el proyecto. Es un archivo  de comandos para el compilador y se definen las opciones que describe el mapa de memoria del  microcontrolador y existen 4 linkers: 18f45k20.lkr   Linker básico en modo no extendido 18f45k20_e.lkr Linker para compilar en modo extendido. 18F45k20i.lkr Linker que se usa con Debbuger ( previene  el código de aplicaciones ejecutar pequeñas áreas de memoria reservada al debugger.).  18f45k20i_e.lkr Linker para el debbuger en modo extendido. Para añadir el linker al proyecto hacemos Project>Add files to project... y dentro de la caja  de selección de “Files of types”   seleccionamos   Linker Scritp (*.lkr) que están en CMCC18h y  abrimos el  p18f45k20.h. Una nota importante, si modificamos el archivo seleccionado en nuestro  proyecto, también se modificará el original y por tanto eso no lo deseamos, por lo que haremos lo  siguiente,  File>Save   AS....   para   salvar   una   copia   en   el   nuevo   proyecto,   es   decir,   el   archivo  p18f45k20.h    lo   copiaremos   en   el   presente   proyecto   y   así   no   lo   modificaremos.   Por   último  File>Save Workspace. Debe quedarnos algo así: El programa :
  • 3. /**  C   O  N   F  I G U  R   A  T  I  O  N      B  I  T  S  ******************************/  #pragma config FOSC = INTIO67  #pragma config WDTEN = OFF, LVP = OFF  /** I N C L U D E S   **************************************************/  #include "p18f45K20.h"  /**  D   E  C   L  A R A  T   I  O  N  S  *******************************************/  void   main   (void)  {          TRISD = 0b01111111; //    PORTD bit 7 to output (0); bits 6:0 are inputs  (1)          LATDbits.LATD7 = 1; //    Set LAT register bit 7 to turn on LED          while (1) ;  }  Veamos como funciona esto,,,, #pragma config   Sirve para configurar los registros, que en este caso son FOSC Y WDTEN Y LVP #include      Para incluir los header de los chips usados TRISD Es una variable que accede al sfr con el mismo nombre TRISD que está incluida en  el include anterior. En concreto esta pone a 0 o 1 los bits de la puerta D siendo 0 las  que se usan como salida y 1 los que se usan como entrada. Así  tenemos el código  0b01111111 por lo que pone a RD7 COMO SALIDA Y EL RESTO COMO  ENTRADA (RD6­RD0). El “0b” es una notación para el compilador que le indica  que el dato expresado es “binario”, si fuese hexadecimal seria 0x..... LATDBITS.LATD7   LATDBITS  también está definido en el p18f45k20.h y permite el acceso  a los  bits individuales del registro LATD el cual en esta instrucción se pone a 1 la salida  D7 a través de LATD7 ( latch7). CONSTRUYENDO Y PROGRAMANDO EL PROYECTO Seleccionamos  Project> Build All. El archivo generado es un hex que se grabará en el pic. Cuando   termine   aparece   el   mensaje  Build  sucess,   si   ha   ocurrido   algún   error,   del   tipo  p18f45k20.h no se a podido encontrar, es debido a que MPLAB C fue instalado sin añadir  Add  header file path to MCC_INCLUDE enviromnet variable option   durante la instalación por lo que  habrá que reinstalar  MPLAB C  de nuevo. Ahora   vamos   a   elegir   el   pickitt   3   como   programador   yendo   a  Programmer  >   Select  Programmer > 4pickitt 3. lo que hará que aparezca una nueva pestaña en la parte de la ventana de  información, mostrando el estado de dicho programador y todos los mensajes que se produzcan. El  programador será inicializado y éste debe informar de que ha encontrado la placa DEMO a la que  está enganchado y mostrar el microcontrolador que posee, que en este caso es nuestro pic18f45k20.
  • 4. Aquí podemos observar que  no se ha detectado   la placa con el pic ya que sino se programa al   pikit3   para   que   alimente   a   la   placa,   esta   no   podrá ser encontrada de ninguna manera. Para   ello   debemos   de   configurar   el   pickit   3  para ello y por tanto   vamos a Programmer >  Settings... Para   dicho   pic   debemos   alimentarlo   como   máximo a 3,25 volts y por tanto deslizaremos el   cursor   hasta   que   esté   en   dicha   tensión.   Lo   salvamos   dando   ok   y   debe   aparecer   en   la   ventana nuestro pic18f45k20. Pasamos ahora a meter el programa en el pic18f45k20 yendo a  Programmer > Program  y  …. listo, ya esta programado. Si se ha cometido algún error en la programación consultar la ayuda  del pickit 3  Help> Topics...  y bajo  Programmer  seleccionamos  pickit 3  y OK. En la pestaña de  contenidos seleccionamos Troubleshooting para más información. PROYECTO 2 LED PARPADEANTE. Aquí se expone un proyecto con la meta de: – Abrir un área de trabajo de proyecto seleccionado desde File>open Workspaces – Configuración   de   bits   de   propósito   especial,   modos   de   operación   y   habilitar  características del microcontrolador. – Retardos, librerías..... En este punto, ya hemos programado nuestro pic18f45k20 y todavía no se ha cerrado el  proyecto, pero nosotros vamos a abrir otro área de trabajo para el nuevo proyecto. Para ello debemos  ira File >Open Workspaces.... y buscamos C:LessonsPICkit 3 Debug Express Lessons02  Blink LED y abrimos el 02 Blink LED.mcw archivo. Antes de abrir una nueva área de trabajo, MPLAB nos pregunta si queremos guardar la  anterior, por lo que lo recomendable es decir que si. CONFIGURANDO BITS  En este ejercicio, la configuración de los bits están definidas  en la parte superior del archivo  de Blink LED. C como se muestra: /**  C  O N  F I G  U  R  AT   I O   N     B I  T  S  ******************************/  #pragma   config FOSC=INTIO67, FCMEN=OFF,  IESO = OFF          // CONFIG1H  #pragma   config PWRT = OFF,    BOREN= SBORDIS, BORV = 30     // CONFIG2L  #pragma   config WDTEN     = OFF, WDTPS = 32768                          // CONFIG2H  #pragma   config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC        // CONFIG3H  #pragma   config STVREN= ON, LVP = OFF, XINST = OFF               // CONFIG4L  #pragma   config CP0 =OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF  // CONFIG5L  #pragma   config CPB = OFF, CPD = OFF                                         // CONFIG5H  #pragma   config WRT0 = OFF,    WRT1 = OFF, WRT2 = OFF, WRT3 = OFF        // CONFIG6L  #pragma   config WRTB = OFF,    WRTC = OFF, WRTD = OFF                             // CONFIG6H 
  • 5. #pragma   config EBTR0 =OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF    // CONFIG7L  #pragma   config EBTRB = OFF                                                          // CONFIG7H  Como vimos en el ejercicio anterior, los bits se configuran utilizando  #pargma config  y  separándolos por   comas. Cada microcontrolador tiene sus propias características y las podemos  encontrar en MPLAB IDE HELP. Por ejemplo vamos a buscar las del pic18f45k20: 1 Seleccionarnos MPLAB IDE menú Help>Topics... y buscar la categoría Lenguajes  Tool. 2 PIC18 Config Settings” luego OK. 3 Cuando la ventana de ayuda se abra, seleccionamos la pestaña Contenidos y expandir  la sección “ Configuration Settings” . 4 Seleccionamos nuestro pic18f45k20. La configuración de los bits en este ejercicio es diferente a la que trae por defecto, por lo que  vamos a prestar atención y vemos como funciona. FOSC = INTIO67 Esta configuración configura al pic para que trabaje con el oscilador interno por lo que no necesita ningún oscilador de cristal externo para funcionar. La frecuencia por defecto es de 1 MHz y así podemos utilizar los pines RA6 (osc1) y RA7 (osc2) como bits de I/O de la puerta A ya que no se van a usar  como entradas para el oscilador. WDTEN = OFF Esta configuración nos permite apagar el Watchdog Timer ( WDT) ya que en este ejercicio no lo vamos a usar. Ya se sabe que si usamos el WDT y no lo  refrescamos, éste reseteará el microcontrolador.   LVP = OFF                     Esto apaga el modo de Low Voltage­Programing  y por tanto libera la patita                                             PGM o RB5 ya que LVP no lo usa PICKIT 3.   El resto de los bits son iguales a los que trae por defecto, pero no está mal recordarle al  compilador de que es ésta y no otra la configuración que nosotros deseamos. Y ahora ponemos el programa principal. Observa que la linea # include ha añadido un nuevo  fichero y también el símbolo “ ~ “ delante del LATDbits.LATD7 /** I N C L U D E S   **************************************************/  #include "p18f45k20.h"  #include "delays.h"  /**  D    E C   L   A  R  A  T   I   O  N  S   *******************************************/  void   main   (void)  {          TRISD   =   0b01111111;//    PORTD   bit    7   to   output   (0)   ;  bits   6:0  are   inputs (1)          while   (1)          {                    LATDbits.LATD7   =   ~LATDbits.LATD7;       //   toggle   LATD                    Delay1KTCYx(50);//    Delay    50   x    1000  =   50,000   cycles;   200ms  @   1MHz          }  }                                             Observa que se ha incluido la linea #include “delays.h” , este header se localiza al igual que 
  • 6. p18f45k20.h , osea de C:MCC18h. Y por tanto , tenemos la instrucción de esta librería utilizada en  el programa con la línea Delay1KTCYx (50) ; Esta   función   crea  un retardo de  1000  instrucciones  de  ciclo  multiplicado  por  lo  que hay  entre  paréntesis y nos daría 1000*50= 50.000 ciclos y como en nuestro microcontrolador el ciclo es ¼ de  la señal de reloj, pues en este caso ( sin oscilador es 1MHzz) será 1mHz/4 = 250KHzz lo que nos da  unos 200 ms que mas que suficiente lento para que nuestro ojo lo vea parpadear. LESSON 3 ROTACION LED Este programa realiza el desplazamiento de leds encendiendo uno detrás de otro. El archivo  03 Rotate LED.c declara una variable como global llamada LED_Number y así se asigna: /** V A R I A B L E S *************************************************/  #pragma udata  // asigna variables estáticas no inicializadas unsigned char LED_Number;  // 8­bit variable  La directiva #pragma udata sirve para decir al compilador que las variables de datos que a  continuación siguen, se deben de meter en los registros del PIC( ojo es en el área de registros). Hay dos directiva que se pueden usar con #pragma – udata : Se almacenan datos (registros) sin inicializar en los registros del pic. – idata: Los datos inicializados se almacenan en el espacio de registros del pic y los datos  de la inicialización son guardados en la memoria de programa y movidos por el código  de inicialización de arranque, antes de que empiece el programa. La declaración de datos puede pertenecer a una sección con un nombre. Dicho nombre de  sección puede asociarse a un script SECTION para colocarlo en un área particular de memoria. La directiva #pragma udata se debe de especificar la dirección de comienzo de los datos a  almacenar en el pic y a partir de estas, serán secuenciales una detrás de otra. Supongamos que  queremos colocar la variable LED NUMBER al inicio del banco de registros número 3, y por tanto  se debería de programar así: #pragma udata mysection = 0x300 unsigned char  LED_Number;  // 8­bit variable unsigned int  AnotherVariable;  Aquí mysection es una sección con dicho nombre y que empieza en la dirección 0x300 y los  datos que va a recibir serán del tipo unsigned char. LED Number será una variable y separada por ;  las siguientes variables. Hay que decir que no es lo mismo guardar datos de 8 bits que de 16 como  por ejemplo el tipo de dato integer que es de 16 bits lo que ocupará dos posiciones  en la sección. Hasta ahora hemos visto como se insertan datos en el área de registros, y a continuación  veremos como metemos datos en el área de programa. /** D E C L A R A T I O N S *******************************************/  // declare constant data in program memory starting at address 0x180  #pragma romdata Lesson3_Table = 0x180  const   rom  unsigned   char   LED_LookupTable[8]   =   {0x01,   0x02,   0x04,   0x08,   0x10,   0x20,   0x40,   0x80};  #pragma  code //  declare executable instructions  void  main  (void) 
  • 7. {  ….. Podemos ver dos directivas usadas: code : Las propias instrucciones del programa. Compilará las instrucciones del programa en  la memoria de programa del pic.      Romdata : Datos almacenados en la memoria de programa. Se suele usar con la directiva  “rom” y los datos serán del tipo constante ( no pueden variar) y compilados en  espacio de memoria de programa. En este ejercicio se va a utilizar un array de datos LED_LookupTable para convertir un  número representando los leds 0­7 en un patrón de bits para configurar apropiadamente el puerto D  que   se   denomina   PORTD   para   poder   encender   un   led   tras   otro.   Por   eso   se   utiliza   un   array  constante , para que los datos de dicho array no cambien por culpa del programa o acción indebida.  Por lo tanto, esta constante es declarada en romdata sección y usa “rom” para hacerla constante y  colocarla en la parte de la memoria de programa.  La sección romdata ha sido declarada también con un nombre Lesson3_Table y asignada a  una dirección 0X180. Selecciona MPLAB IDE Project> Build All para compilar el ejercicio y después selecciona  View> Program Memory para visualizar el contenido compilado de la memoria de programa. Observar como el la dirección 0180 está el array ( está invertido por el sistema de programación) se  puede observar  0201 ( invertido será 01/02) y el 0804 (04/08)....  Si colocamos #pragma code y a continuación colocamos main() , el programa se almacenará  en la sección indicada en la memoria de programa del pic. Si no se ha especificado ninguna sección  ni tampoco la dirección de inicio de programa, el compilador colocará el programa en la siguiente  sección de programa libre que tenga el pic. El programa: /** V A R I A B L E S *************************************************/  #pragma udata  // declare statically allocated uninitialized variables  unsigned char LED_Number;  // 8­bit variable 
  • 8. /** D E C L A R A T I O N S *******************************************/  // declare constant data in program memory starting at address 0x180  #pragma romdata Lesson3_Table = 0x180  const   rom   unsigned   char   LED_LookupTable[8]   =   {0x01,   0x02,   0x04,   0x08,   0x10,   0x20,   0x40,   0x80};  #pragma   code //   declare   executable   instructions  void main (void)  {     LED_Number = 0; //       initialize     TRISD   =   0b00000000; //   PORTD   bits  7:0    are   all   outputs   (0)     while   (1)     {               // use lookup table to output one LED on based on LED_Number value                   LATD = LED_LookupTable[LED_Number];          LED_Number++; //    rotate   display  by   1          if (LED_Number == 8)          LED_Number = 0; //      go   back  to  LED    0.          Delay1KTCYx(50); //    Delay   50  x  1000    =   50,000   cycles;   200ms @ 1MHz     }  } Inicialización de variables y I/O puertos. Se  configura  trisd  para que todas  las patitas  del  portd  sean salidas y la variable global  LED_Number es el numero de led a encender. Primero se inicializa con el valor 0 en  LED_Number  y después se usa como array   en el  índice y el array devuelve el valor por la posición que le indica LED_Number. Como el valor inicial  de LED_Number es cero, el índice del array es cero también, por lo que su valor a devolver es el  primer dato del array, osea 0x01. Este valor es almacenado en el latch del puerto D quedando en  primera instancia la formula con el siguiente valor: LATD =LED_lookupTable[LED_Number] siendo su valor LATD = 0x01 Seguimos y vemos que ahora se incrementa  LED_Number  por lo que el próximo valor a  mostrar será el siguiente (0x02). Se compara el valor del índice( LED_Number) por si su valor es 8,  que en caso de afirmativo volvería a poner a LED_Number a 0 ( reset) o en caso contrario ejecuta un  retardo de 200 ms y vuelve de nuevo al array indefinidamente haciendo girar los leds. Ejercicio 4 Rota switch En este ejercicio se utiliza un switch para hacer rotar los leds del ejercicio anterior. Se utiliza la directiva #define y se asume que el lector ya sabe o por lo menos está  familiarizado  con el lenguaje C.  #define Pin_Switch  PORTBbits.RB0 Esto hará que cada vez que pongamos Pin_Switch el compilador lo sustituye  por PORTBbits.RB0. Pero para que el compilador entienda la directiva #define  se debe incluir el archivo cabecera “04  Switch Input.h”, veamos como: #include “04 Switch Input.h”
  • 9. Existe un programa en aplicaciones que usan los switch que evitan el efecto rebote. Es un  efecto que al pulsar el switch, rebota los contactos haciendo de una pulsación simple , en un tren de  pulsos que provocaría efectos indeseados. Supongamos que queremos contar las veces que pulsamos  en el switch, este al ser pulsado una vez podemos encontrarnos con la sorpresa que nuestro contador  pueda contar 10 100 o 3 unidades en vez de una , que es la que esperábamos. Para evitar este efecto rebote, se añade un retardo de 5 ms , tiempo mas que suficiente para  que la señal sea estable y eliminaremos dicho efecto.  Este es el organigrama para evitar dicho efecto. Observa que espera a que se pulse el switch,  cuando este es presionado, se incrementa un contador y cuando este llega a 5 entonces da la señal de  que se ha pulsado dicho switch. En caso de que el contador no haya llegado a 5  se realiza un retardo  de 1 ms y se vuelve a incrementar el contador haciéndose la misma pregunta una y otra vez hasta  que se completen los 5 ms que será cuando el circuito realice el organigrama unas 5 veces y cada  una de ellas de 1 ms. El programa: /** V A R I A B L E S *************************************************/  #pragma udata  // declare statically allocated uinitialized variables  unsigned char LED_Display;  // 8­bit variable  /** D E C L A R A T I O N S *******************************************/  #pragma code //     declare   executable  instructions  void  main   (void)  {          unsigned    char   Switch_Count  =  0;          LED_Display    =   1;               //   initializa          TRISD   =   0b00000000;             //   PORTD   bits  7:0   todas salidas    (0)          INTCON2bits.RBPU = 0;               //   habilita PORTB internal pullups resistencias         WPUBbits.WPUB0 = 1;                 //   enable pull up on RB0          ANSELH = 0x00;                      //   AN8­12 are digital inputs (AN12 on RB0)          TRISBbits.TRISB0 = 1;               //   PORTB bit 0 (connected to switch) is input       (1)          while (1)          {              LATD = LED_Display;             //   enciende el led             LED_Display <<=      1;         //   rotate   display by     1             if (LED_Display == 0)            //   rotated   bit  out,   so   set  bit   0                  LED_Display = 1; 
  • 10.             while   (Switch_Pin   !=  1); //   wait  for   switch  to    be  released              Switch_Count = 5;              do              { // monitor switch input for 5 lows in a row to debounce if                    (Switch_Pin == 0)                    { // pressed state detected                         Switch_Count++;                    }                    else                    {                       Switch_Count = 0;                    }                    Delay10TCYx(25);  // delay 250 cycles or 1ms. }               while (Switch_Count < DetectsInARow);  Ojo a las variables, ya que la variable global se almacena en un registro del pic mientras que  las variables locales se destruyen al salir de la función que la crea. Así   LED_Display es global  mientras que Switch_Count es local y se destruye al finalizar el programa ya que se almacena en la  pila del programa. El interruptor está conectado a RB0 y cuando este es pulsado se tira a masa “0” por lo que  debe estar con resistencias pull­up habilitadas  ya que puede provocar fallos de lectura si no se  presiona   dicho   switch   sin   habilitar   pull­up   del   RB0.   Pero   esta   patita   comparte   con   la   entrada  analógica AN12, es decir, que el mismo pin puede ser digital o analógico. Hay que configurarlo  como digital y como entrada.Para ello vemos como lo hace en el programa: INTCON2bits.RBPU   =   0;    aquí   podemos   ver   como   configurar   el   registro   INTCON2   el   bit  correspondiente al pull­up que en este caso es RBPU y lo ponemos a cero. WPUBbits.WPUB0 = 1;      Habilitamos aquí, el pull­up del RB0 ANSELH = 0x00;    Forzamos a que las entradas analógicas AN8­12 sean digitales poniéndolas a 0.  TRISBbits.TRISB0 = 1;     Configuramos RB0 como entrada. Observa los registros AN8­12. Aquí se usa un sistema de rotado de leds mas simple que en el  ejercicio anterior el cual usaba una tabla con un índice para poder mostrar un patrón de bits en la 
  • 11. salida y aparentar el desplazamiento. En este caso usaremos algo mucho mas sencillo para realizar  el mismo efecto, en este caso se desplaza el bit de mayor peso de LED_Display y como es mostrado  en LATD pues se muestra en la salida.  LED_Display <<=      1; Ejercicio 5 Temporizador En   este   ejercicio   vamos   a   utilizar   el   temporizador   TMR0   en   vez   de   utilizar   un   bucle  temporizado, dejando así  libre a la CPU de dicho conteo, encargándose de la cuenta el TMR0. Veamos sus registro de configuración: • El bit 7 activa o no el temporizador. • El bit 6 se usa para seleccionar entre 8/16 bits. • El bit 5 selecciona entre entrada externa o ciclos de reloj interno. • El bit 4 se usa para activar la cuenta en el flaco de subida de la señal o la de bajada. • El bit 0­1­2­3 se usan para activar el preescaler (divisor) y su rango de división. El TMR0 es el temporizador/contador de la familia 18Fxxxxx que utiliza el reloj interno o  los impulsos externos a través de la patita TOCK1. Puede realizar cuentas de 0­255 si se configura  como   8   bits   o,   de   0­65535   si   lo   hace   en   modo   16   bits.   Un   bit   de   flag   se   activa   cuando   el  temporizador ha llegado a rebasar la cuenta y vuelve de nuevo a cero. El   preescaler   se   usa   para   generar   una   cuenta   por   cada   impulso   del   reloj   de   entrada  ( recordemos que la frecuencia interna es ¼ la frecuencia del oscilador ) y si el rango del preescaler  es de 1/8  significa que dará un pulso por cada 8 pulsos de reloj, si es 1/16 pues cada 16...... El   preescaler   se   borra   cuando   se   escribe   en   el   temporizador,   por   lo   que   habrá   que  configurarlo cada vez que se escriba en el temporizador. Cuando utilicemos el temporizador en modo 16 bits, hay que prestar especial atención ya que  se usan el temporizador bajo y el alto TMR0L y TMR0H ubicados en la zona de registros SFR del  pic y que TMR0L es leíble y se escribe   directamente, mientras que la parte alta del contador  TMR0H no es directamente accesible. En su lugar se usa TMR0H pero para poder leerlo, primero  debemos LEER EL TMR0 PRIMERO Y DESPUES SE ACTIVARÁ TMR0H Y PARA ESCRIBIR  EN EL TEMPORIZADOR PRIMERO SE ESCRIBIRÁ EN TMR0H ANTES QUE TMR0L. En el ejercicio vamos a temporizar entre 200 y 300 ms y vamos a ver como hacemos esto a 
  • 12. través de nuestro preescaler. Hay que configurar T0CON para que el resultado sea satisfactorio y por ello en la tabla  anterior vemos como se configuran los bits de dicho registro. – Lo ponemos en modo 16 bits por lo que el bit 6 lo ponemos a 0. – Usaremos los ciclos internos de reloj por lo que el bit 5 se queda a 0. – Como la temporización coincide con el tiempo que queramos no usaremos el bit PSA o  bit   numero   3   ya   que   65536   x   (1   /   250,000)   =   262ms,   es   decir,   si   la   cuenta   del  temporizador llega a 65536 y tarda en cada ciclo  1/250,000 pues nos da los 262 ms que  está dentro de nuestro rango. – El bit 7 se pone a 0 ya que queda desactivado y se activa cada vez que se escribe en el. El resto de bits no importa su configuración por lo que el dato a escribir de forma binaria en  el T0CON será 0b0000100. Abrir el archivo 05 Timer.c y 05 Timer.h. En el archivo de cabecera .h podemos encontrar  las siguientes sentencias: typedef enum { LEFT2RIGHT, RIGHT2LEFT}  LEDDirections;  typedef enum {FALSE, TRUE} BOOL;  El tipo de dato enum, utiliza un nombre LEDDirections para identificarlos y solo admite los  valores que están entre paréntesis, que en este caso es  LEFT2RIGHT, RIGHT2LEFT, es decir, que  si utilizamos la variable LEDDirectios, sus valores que puede tomar son estos dos y no otros. Quizás le sea más fácil la linea del enum BOOL que le hemos puesto que solo admita como  valores FALSE Y TRUE. Hay que inicializarlas como cualquier variable pero, solo con los valores que admite. Ojo  son tipos de variables no variables en si ( como lo son integer, char, double....). Veamos como se  inicializan: LEDDirections Direction = LEFT2RIGHT;  BOOL SwitchPressed = FALSE;  Aquí podemos ver que hemos definido una variable Direction del tipo LEDDirections y con  el valor inicial LEFT2RIGHT ( que es el valor que definimos en el tipo enum). Así Direction solo  puede tener dos valores LEFT2RIGHT Y RIGHT2LEFT únicamente. Para el tipo BOOL hemos definido otra variable llamada SwitchPressed y se ha inicializado  con el valor FALSE. La variable Direction será utilizada para determinar la dirección de rotación de los leds y la  variable Switchpressed recuerda al programa que se ha presionado el switch el cual cambiará el  sentido de la rotación de los leds. //  Inicializamos el contador  INTCONbits.TMR0IF   =  0;  //  line  1  T0CON = 0b00001000;        //  line  2  // T0CON  =  0b00000001;  (se ignora por el momento)  TMR0H = 0;                 //  line  3  TMR0L = 0;                 //  line  4  T0CONbits.TMR0ON  =   1;   //  line  5  Esta es la parte del programa que inicializa el temporizador , deshabilita las interrupciones 
  • 13. generada por el mismo al sobrepasar la cuenta, escribe en el registro T0CON el patrón de bits a  configurar para la temporización, así como la escritura en el temporizador en el orden preferente  siendo TMR0H la primera en escribirse y luego TMRL0 la última, y por último habilitamos el  temporizador. El programa: // *******************************************************************  // *    See included documentation for Lesson instructions           *  // *******************************************************************  /** C O N F I G U R A T I O N   B I T S ******************************/  #pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF                      // CONFIG1H  #pragma config PWRT = OFF, BOREN = OFF, BORV = 30                           // CONFIG2L  #pragma config WDTEN = OFF, WDTPS = 32768                                   // CONFIG2H  #pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC            //   CONFIG3H  #pragma config STVREN = ON, LVP = OFF, XINST = OFF                          // CONFIG4L  #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF                   // CONFIG5L  #pragma config CPB = OFF, CPD = OFF                                         // CONFIG5H  #pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF               // CONFIG6L  #pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                           // CONFIG6H  #pragma   config  EBTR0  = OFF,  EBTR1  =  OFF, EBTR2  =  OFF, EBTR3  = OFF                      //   CONFIG7L  #pragma config EBTRB = OFF                                                  // CONFIG7H  /** I N C L U D E S **************************************************/  #include "p18f45k20.h"  //#include "delays.h"  // no longer being used. #include "05 Timer.h"  // header file  /** V A R I A B L E S *************************************************/  #pragma udata    // declare statically allocated uinitialized variables  unsigned char LED_Display;   // 8­bit variable  /** D E C L A R A T I O N S *******************************************/  #pragma code     // declare executable instructions  void main (void)  {      LEDDirections Direction = LEFT2RIGHT;  // es del tipo enum en el archivo .h     BOOL SwitchPressed = FALSE;  // también del tipo enum en .h    LED_Display = 1;            // initialize la variable global     // Init I/O      TRISD = 0b00000000;      // PORTD bits 7:0 son todas salidas (0)      INTCON2bits.RBPU = 0; // enable PORTB internal pullups       WPUBbits.WPUB0 = 1; // enable pull up on RB0      ANSELH = 0x00;              // AN8­12 are digital inputs (AN12 on RB0) para convertir a digitales     TRISBbits.TRISB0 = 1;       // PORTB bit 0 pone esta como entrada.     // Init Timer 
  • 14.     INTCONbits.TMR0IF = 0;          // se borra el flag de cuenta sobrepasada.     T0CON = 0b00001000;             // Configuración del tocon sin preescaleer.     //T0CON = 0b00000001;             // prescale 1:4 ­ four times the delay. TMR0H = 0;                      // borrado del temporizador parte alta     TMR0L = 0;  // parte baja     T0CONbits.TMR0ON = 1;           // comienza a temporizar     while (1)      {          if (Direction == LEFT2RIGHT) // recuerda que si inicializo con LEFT2RIGHT         {              LED_Display <<= 1;          // rotate display by 1 from 0 to 7              if (LED_Display == 0)                  LED_Display = 1;        // rotated bit out, so set bit 0          }          if (Direction == RIGHT2LEFT)          {              LED_Display >>= 1;          // rotate display by 1 from 7 to 0              if (LED_Display == 0)                  LED_Display = 0x80;     // rotated bit out, so set bit 7          }          LATD = LED_Display;         // output LED_Display value to PORTD LEDs          do          { // comprueba si el pulsador esta pulsado             if (Switch_Pin == 1) // recuerda el el pulsador se pone a masa cuando se pulsa             { // el pulsador no esta pulsado                 SwitchPressed = FALSE;              }              else if (SwitchPressed == FALSE) // && (Switch_Pin == 0) due to if­else              { // el pulsador está presionado                 SwitchPressed = TRUE;                  // cambia entonces la dirección                 if (Direction == LEFT2RIGHT)                      Direction = RIGHT2LEFT;  // aquí cambia la dirección escribiendo lo contrario.                 else                      Direction = LEFT2RIGHT;              }          } while (INTCONbits.TMR0IF == 0); // se repita el ciclo do while hasta TMR0 llegue a fin.         // Timer expired          INTCONbits.TMR0IF = 0;          // Reset Timer flag      }  } EJERCICIO 6 EL DEBUGGER Tenemos que decir, que el presente ejercicio, presenta por primera vez el uso del debugger  usando   para   ello   el   programa   anterior.   Evidentemente   su   función   es   ver   en   tiempo   real   si   los  registros   cambian,   que   valor   tienen   en   un   momento   determinado....   etc.   Esto   es   parecido   al  simulador pero en este caso se reserva un área de memoria en el microcontrolador para efectuar el 
  • 15. debugger o depurador de programa de forma que si el compilador hizo bien su trabajo, dejó este  área vacía y reservada para este cometido. El pickit3 se usará como ICD debuggin circuit y utilizará los recursos no accesibles para el  usuario para dicho cometido en el pic. En este caso la patita MCLR ( master control reset) está reservada para el cometido y por  tanto no se podrá usar ni programar como entrada o salida I/O normal. Los pines PGC Y PGD tampoco se usaran como puertos I/O ya que los usaremos en el  debuggin. Un área de la pila de memoria se usará y por tanto no accesible para el usuario. Se utilizará un área de memoria de programa y de registros para el depurado y se queda  marcado en el MPLAB IDE como una R (reservado) y por tanto, el usuario no podrá utilizar. El pickit 3 no puede usarse como debugger ICD y programador al mismo tiempo, por tanto  si se usa el debugger, el programador se desactiva.   Debugger > Select Tool > 2 PICkit 3 es lo que  debemos de hacer para seleccionar el pikit3 como debugger. Comenzamos: 1­ En la barra de herramientas del MPLAB IDE  seleccionamos Debug en vez de  Release. 2­ Compilar el proyecto 05 ( esto reservará en el pic el área para su debuggin). 3­ Lo programamos Debugger> Program. 4­ Arrancamos el debuggin. Debugger > Run. Se observa que el pic18f45k20 funciona con total normalidad, pero esta vez está en  modo debuggin. Operaciones básicas: • HALT  El programa del pic18f45k20 se puede parar en cualquier momento, si pulsamos F5  o vamos a Debugger > Halt . Se mostrará una flecha verde indicado el punto de parada. • STEP Se permite ejecutar el program paso a paso de las siguientes maneras: ◦ STEP INTO se ejecuta paso a paso pero al llegar a una función de llamada se para y  salta la primera linea de dicha función. ◦ STEP OVER se ejecuta paso a paso y al llegar a una función de llamada, esta se ejecuta  entera y el salto llega al final de dicha funcion call. ◦ STEP OUT se ejecuta paso a paso y ejecuta sin parar las subrutinas. • RUN se ejecuta el programa hasta encontrar un punto de break o sea parado por el usuario  con HALT. • RESET Se ejecuta Debugger > Processor> Reset Se ejecuta un reset del micro, pero solo si  el   microcontrolador   estaba   previamente   parado   y   por   tanto   empieza   desde   la   primera  instrucción de programa. • RESET Se ejecuta con Reset>Processor Reset F6 Al ejecutarse MPLAB IDE abre un nuevo  archivo c018i.c inicializa la pila de software C y asigna todos los datos de inicialización de  variables permitiendo llevar al pic a un estado de judicialización completa y luego salta a la  instrucción main() después de inicializar las variables. Usando puntos de Parada. La mejor forma de usar un punto de parada para que el programa al ejecutarse, se ejecute  bien y se pare donde queramos, es ir a la linea que nos interesa y con el botón secundario del ratón  pulsamos   y   ponemos   el   breakpoint   (   Set   breakpoint   ),   apareciendo   un   rombo   rojo   con   una   B  indicando que ahí se parará el programa. Realicemos con la línea 111 o SwitchPressed = TRUE; y 
  • 16. tal y como hemos puesto el punto de parada justo cuando se debe presionar el botón, el programa  continua y por tanto no se para. Pero si se pulsa el botón, el programa quedará parado por el break  que hemos colocado. El número de breakpoints que se puede utilizar depende mucho del microcontrolador que se  use, nuestro pic18f45k20 tiene 3 como máximo. Si abrimos  Debugger > Breakpoints podemos ver  los break que se han usado y los máximos que permite nuestro pic ( HW BP ) Echando un vistazo a las variables y a los registros SFR. Se pueden ver los registros abriendo View > File Registers  y los SFR con View > Special  Function Registers , sin embargo no se recomienda que dichas ventanas estén abiertas ya que se  pueden leer dichos registros desde la tarjeta cuando está en modo RUN parado o en modo paso a  paso.   Leer   todos   estos   datos   sobre   el   ICD   BUS   puede   tomar   un   tiempo   significativo   debido  principalmente a la memora que contenga el pic18f45k20 así como la velocidad de su reloj interno,  así que es mejor cerrar las ventanas de los registros. La mejor manera de ver los registros que sólo interesan es abriendo una ventana llamada  Watch y se abre View > Watch Los SFR que nos interese,  lo   añadimos   desde   el   campo  seleccionable que está marcado  en   la   figura   de   arriba   como  ADCON0 y pulsando el botón  ADD   SFR   de   la   misma  ventana. Para   nuestro   ejercicio  añadiremos PORTB Y LATD  ya que son los que hemos usado tanto para el pulsador como para la  salida de los leds. Las variables que hemos creado nosotros las podemos monitorizar  seleccionado­las desde el  campo que  nos queda a la derecha ( que en este caso marca  config) y pulsando el botón  Add  Symbol. Añadiremos por tanto para nuestro ejercicio LED_Display, SwitchPressed y Direction. Y nos  debe de quedar algo así: Recordemos que nuestras variables del tipo “enum” como son  Direction y SwitchPressed se  mostraran en este caso como valor numérico y no como palabras escritas (let2righ, right2left.... etc). El formato de muestra de valores en el campo Value, se puede cambiar pinchando con el ratón y en  Properties en el menú que nos aparece.
  • 17. Con Watch podemos también cambiar los valores de las variables y por supuesto al cambiar dicho  valor,   cambiará   en   realidad   en   el   pic18f45k20   y   por   tanto   si   escribimos   AA   en   el   LATD   se  encenderán los leds correspondientes. Selecciona ahora PORTB y selecciona sus propiedades y buscando el formato, lo cambiamos a  binario, pulsamos OK y cerramos el dialogo. Ahora se verá la información de PORTB  en binario  con el bit de mas peso a la izquierda(7). Realizamos el paso a paso pulsando F8 ( step over )   que en este modo se ejecuta la subrutina y  observa que el PORTB debe tener el switch ( PORTB0) a 1 ya que no se ha pulsado, claro que si  pulsamos el botón y ejecutamos de nuevo con F8 el valor será 0 siempre que se mantenga pulsado  hasta que sea ejecutada la subrutina. Recuerdas donde pusimos el punto de break.... Como podemos ver, el pulsador en estado normal es 1 por lo que la sentencia else if no se  cumple y salta a el retos del programa por debajo de los corchetes.... Pero en caso de que si se  cumpla, se parará al llegar a la linea 111 y deberemos pulsar o ejecutar paso a paso el programa, ya  que se ha quedado en estado HALT. Pulsamos F8 para ver el registro PORTB0  como cambia a 0. Practica con el código añadiendo los breakpoints donde te apetezca y observa los registro  como   cambian.   Añade   también   TMR0L   y   TMR0H   a   la   ventana   WATCH   y   observa   su  comportamiento,   sobre   todo   cuando   estamos   en   modo   paso   a   paso.   Comprobará   que   no   se  incrementa por cada instrucción ya que cada instrucción compilada en C creará varias instrucciones  en   lenguaje   ensamblador   y   el   Timer0   es   incrementado   una   vez   por   cada   instrucción   maquina  ejecutada ( no C ).