Diferencia entre revisiones de «Preguntas Frecuentes Demoqe»

De Wikitronica
Saltar a: navegación, buscar
 
(No se muestran 55 ediciones intermedias de 6 usuarios)
Línea 1: Línea 1:
  
 +
==Rebotes en Pulsadores o Interruptores==
  
===La macro BitCopy del prof. Uribe===
+
¿Qué son los rebotes?
  
===Pregunta 33 o 97 del problemario===
 
  
===Rebotes en Pulsadores o interruptores===
+
[[Image:Rebotes_en_pulsadores.jpg|right|]]
  
===Manejo y programación de timers.===
+
Al pulsar algún botón o interruptor, no se realiza una conexión perfecta e instantánea como nosotros esperamos. Un pulsador se compone de dos partes de metal que entran en contacto (choca una con la otra) al accionarlo. Este choque genera unos rebotes realmente pequeños que suceden tan rápido que son imperceptibles para nosotros (aunque no para el [[Tarjeta_de_Desarrollo_-_DEMOQE128|DEMOQE128]]) hasta que finalmente se consigue un contacto firme.
===Macros en el HC9S08===
+
 
 +
 
 +
Los rebotes pueden ocasionarnos molestos inconvenientes como lo son las falsas interrupciones o las interrupciones no deseadas. Entonces, ¿cómo corregir este problema?
 +
 
 +
 
 +
La solución es sencilla y consta de dos aproximaciones. La primera es por hardware, adaptando a la entrada del interruptor de nuestra tarjeta un circuito simple con resistores y capacitores tal que los rebotes sean absorbidos por el capacitor. No nos centraremos en esta aproximación.
 +
 
 +
 
 +
Ya que no siempre disponemos de los componentes electrónicos, la aproximación más práctica suele ser por software y es la que vamos a implementar. Basta con añadir un pequeño retardo en nuestro programa desde que se detecta el primer pulso hasta que se vuelve a leer la entrada del pulsador. Dicho retardo debe ser suficientemente largo para asegurar que cuando finalice ya se hayan extinguido los rebotes, pero también lo suficientemente corto para que sea imperceptible para nosotros.
 +
 
 +
 
 +
El siguiente es un posible código en ensamblador, usando las interrupciones del módulo KBI y RTC, para llevar esto acabo:
 +
<syntaxhighlight lang="asm">
 +
; Include derivative-specific definitions
 +
 
 +
            INCLUDE 'derivative.inc'
 +
 
 +
 
 +
;
 +
 
 +
; export symbols
 +
 
 +
;
 +
 
 +
            XDEF _Startup
 +
            ABSENTRY _Startup
 +
 
 +
 
 +
;
 +
 
 +
; variable/data section
 +
 
 +
;
 +
 
 +
            ORG    RAMStart        ;; Insert your data definition here
 +
 
 +
contador:    DS.B  1                ;; Variable a usar para incrementar y mostrar en los leds
 +
PermisoLeer: DS.B 1                  ;; Variable a usar para  autorizar el incremento del contador
 +
 
 +
;
 +
 
 +
; code section
 +
 
 +
;
 +
 
 +
            ORG    ROMStart
 +
 
 +
 
 +
_Startup:
 +
 
 +
            LDA    #$43
 +
            STA    SOPT1     
 +
            LDHX    #RAMEnd+1        ;; Inicializamos el Stack Pointer
 +
            TXS
 +
           
 +
            CLRA
 +
            STA  contador            ;; Inicializamos el contador
 +
            LDA  #$1
 +
            STA PermisoLeer          ;; Damos inicialmente autorización para incrementar el contador la
 +
                                      ;; la primera vez que se ejecuta el programa.
 +
 
 +
           
 +
 
 +
            BSR Configurar_GPIO
 +
            BSR Configurar_RTC
 +
            BSR Configurar_KBI
 +
 
 +
 
 +
           
 +
 
 +
            CLI  ;; Habilitamos interrupciones
 +
 
 +
 
 +
 
 +
 
 +
mainLoop:
 +
 
 +
            BRA    mainLoop
 +
 
 +
           
 +
 
 +
;**************************************************************
 +
 
 +
;*              Subrutinas de Configuracion                     
 +
 
 +
;**************************************************************
 +
 
 +
 
 +
Configurar_KBI:
 +
 
 +
 
 +
 
 +
  LDA #$06
 +
  STA KBI1SC    ;; KBACK=1 (1 se borran los pedidos de interrupcion),KBIE=1 (habilita las interrupciones)
 +
   
 +
  LDA #$04
 +
  STA KBI1PE    ;; Habilitando pin PTA2 como KBI
 +
 
 +
  LDA #$00
 +
  STA KBI1ES    ;; Pines detectan una caída de voltaje (PTA2)
 +
 
 +
           
 +
      RTS
 +
 
 +
 
 +
Configurar_RTC:
 +
 
 +
                               
 +
 
 +
            LDA #%00011000      ;; RTIF=0, RTCLKS6=0 RTCLKS5=0, RTIE=1, RTCPS3=1, RTCPS2=0, RTCPS1=0, RTCPS0=0
 +
            STA RTCSC          ;; Fuente reloj interna 1khz. Interrupciones habilitadas. Reloj configurado a 1s.         
 +
 
 +
            LDA #1              ;; Definimos el valor del registro modulo del RTC
 +
            STA RTCMOD
 +
           
 +
 
 +
            LDA SCGC2          ;; Deshabilitamos el Clock Gate para el RTC       
 +
            EOR #%00000100
 +
            STA SCGC2
 +
         
 +
 
 +
            RTS
 +
 
 +
 
 +
 
 +
Configurar_GPIO:                    ;; General Port Input/Output
 +
 
 +
           
 +
 
 +
            LDA #%00111111
 +
            STA PTCDD              ;; 6Bits (LSB) PTC - habilitados como salida colocando 1 (PTC0 a PTC5) 
 +
            LDA #%11000000
 +
            STA PTEDD              ;; 2Bits (MSB) PTE - habilitados como salida colocando 1 (PTE6 Y PTE7)
 +
           
 +
            LDA #%00111111
 +
            STA PTCD                ;; Cero a la salida (logica negada): se apagan los leds
 +
            LDA #%11000000
 +
            STA PTED                ;; Cero a la salida (logica negada): se apagan los leds         
 +
 
 +
 
 +
            LDA #%00000100          ;; Se habilita la resistencia de pull-up para el interruptor
 +
            STA PTAPE              ;; PTA2. Esto significa que si se presiona el botón, el valor lógico es 0,
 +
                                    ;; si no se presiona, el valor lógico es 1.                   
 +
 
 +
            LDA #%11111011          ;; Se habilita PTADD2 como entrada
 +
            STA PTADD         
 +
 
 +
 
 +
            RTS
 +
 
 +
 
 +
 
 +
;**************************************************************
 +
 
 +
;*              Rutinas de interrupcion                    *
 +
 
 +
;**************************************************************
 +
 
 +
 
 +
 
 +
Interrupcion_KBI:
 +
 
 +
 +
 
 +
  LDA  %11111101              ;; Deshabilito interrupciones del KBI
 +
  AND  KBI1SC
 +
  STA  KBI1SC
 +
 
 +
 
 +
  LDA PermisoLeer            ;; Verifico si tengo permiso para incrementar contador
 +
  CMP #$1
 +
  BEQ IncContador           
 +
  BRA FinKBI
 +
 
 +
 
 +
 
 +
IncContador:
 +
 
 +
 
 +
 
 +
      LDA #$0
 +
      STA PermisoLeer
 +
      LDA SCGC2                ;; Habilitamos el Clock Gate para el RTC       
 +
      ORA #%00000100
 +
      STA SCGC2
 +
 
 +
      LDA contador
 +
      INCA
 +
      STA contador            ;; Incremento el contador
 +
         
 +
      LDA #%00111111          ;; Mascara con el contador
 +
      AND contador            ;; para pasar por PTC
 +
      COMA
 +
      STA  PTCD         
 +
 
 +
      LDA #%11000000          ;; Mascara con el contador
 +
      AND contador            ;; para pasar por el PTE
 +
      COMA
 +
      STA PTED
 +
 
 +
 
 +
 
 +
FinKBI:
 +
 
 +
 
 +
 
 +
  LDA  #%00000110            ;; Habilito interrupciones del KBI y limpia la bandera
 +
  STA  KBI1SC
 +
 
 +
 
 +
 
 +
  RTI
 +
 
 +
 
 +
 
 +
Int_RTC:
 +
 
 +
      LDA #$80
 +
      ORA RTCSC
 +
      STA RTCSC
 +
      LDA #$1
 +
      STA PermisoLeer
 +
      LDA SCGC2              ;; Deshabilitamos el Clock Gate para el RTC       
 +
      EOR #%00000100
 +
      STA SCGC2
 +
 
 +
 
 +
 
 +
  RTI
 +
 
 +
 
 +
 
 +
;**************************************************************
 +
 
 +
;* spurious - Spurious Interrupt Service Routine.            *
 +
 
 +
;*            (unwanted interrupt)                          *
 +
 
 +
;**************************************************************
 +
 
 +
 
 +
 
 +
spurious:    ; placed here so that security value
 +
 
 +
  NOP  ; does not change all the time.
 +
 
 +
 
 +
  RTI
 +
 
 +
 
 +
 
 +
;**************************************************************
 +
 
 +
;*                Interrupt Vectors                          *
 +
 
 +
;**************************************************************
 +
 
 +
 
 +
 
 +
            ORG  $FFCE           
 +
 
 +
            DC.W  Int_RTC  ;; RTC
 +
 
 +
           
 +
 
 +
            ORG  $FFDA
 +
 
 +
  DC.W  Interrupcion_KBI  ;; Keyboard
 +
 
 +
 
 +
            ORG $FFFA
 +
 
 +
  DC.W  spurious          ;; IRQ
 +
  DC.W  spurious          ;; SWI
 +
  DC.W  _Startup          ;; Reset
 +
</syntaxhighlight>
 +
====¿Cómo se ve a nivel de hardware el problema de las falsas interrupciones y el BSET IRQSC_IRQACK?====
 +
 
 +
==Manejo y programación de Timers.==
 +
 
 +
 
 +
Un Timer o Temporizador en el DEMOQE es un circuito digital que generalmente contiene las siguientes partes:
 +
 
 +
#Un contador digital de 16 bits
 +
##Este contador es un registro. Este registro se puede leer y también se puede escribir. Por lo que se puede iniciar con un valor diferente de 0.
 +
##El contador puede ir desde 0 hasta 65536
 +
##El contador se puede configurar para que funcione de forma incremental o decremental
 +
##Se incrementa o disminuye el contador en cada pulso de reloj
 +
#Una fuente de reloj que define la frecuencia a la que se va a incrementar el contador.
 +
##Pueden existir diferentes fuentes de reloj
 +
##Esta fuente de reloj se puede '''Preescalar''' lo cual significa que se puede crear un reloj mas lento a partir del reloj fuente. Este nuevo reloj se utiliza para incrementar al contador.
 +
#Un comparador de Módulo
 +
##Es un registro del mismo tamaño que el contador
 +
##Este registro se puede configurar por el usuario
 +
##Si el valor del contador es igual en algún instante al registro de módulo, el contador se reinicia.
 +
#Una interrupción por desbordamiento
 +
##Cuando el Timer llega a su valor máximo se produce una interrupción
 +
##También se puede producir una interrupción si el Timer se reinició debido a que llegó al valor del registro Módulo
 +
 
 +
En el Demoqe se tiene un módulo llamado RTC (real time counter) y varios módulos llamados TPM, los cuales son dispositivos Temporizadores.
 +
 
 +
En líneas generales para programar cada uno de ellos el usuario debe realizar las siguientes configuraciones iniciales de sus registros:
 +
 
 +
*Seleccionar Fuente de Reloj
 +
*Seleccionar preescalador para la frecuencia en la que se quiere incrementar/decrementar el contador
 +
*Seleccionar si el contador va a ser incremental o decremental
 +
*Configurar el registro del contador a su valor inicial
 +
*Configurar el registro de Módulo si es necesario
 +
*Habilitar/deshabilitar las interrupciones por desbordamiento
 +
 
 +
Para la configuración del RTC se puede servir de guía del [[RTC (Real-timer counter) - MC9S08QE128|artículo correspondiente al RTC]]
 +
 
 +
Para la configuración del TPM se puede servir de guía del [[TPM (Timer/Pulse Width Modulator) - MC9S08QE128|artículo correspondiente al TPM]]
 +
 
 +
 
 +
 
 +
 
 +
===¿Cuáles serían los pasos necesarios para configurar y trabajar con varios cloks? Ejm: Cada led que "encienda y apague" a una determinada frecuencia.===
 +
 
 +
==Macros en el HC9S08==
 
Los Macros son una secuencia de líneas de texto que puede incluir Opcodes y Directivas con variables y constantes. Una vez que se define un macro se puede utilizar su nombre para ejecutar esas líneas de texto. Cuando el ensamblador procesa el nombre del macro, lo reemplaza con las líneas de texto asociadas a ese macro y las ejecuta como si estuvieran escritas en el código fuente.
 
Los Macros son una secuencia de líneas de texto que puede incluir Opcodes y Directivas con variables y constantes. Una vez que se define un macro se puede utilizar su nombre para ejecutar esas líneas de texto. Cuando el ensamblador procesa el nombre del macro, lo reemplaza con las líneas de texto asociadas a ese macro y las ejecuta como si estuvieran escritas en el código fuente.
  
 
Los macros permiten que un programa complejo y extenso se vea mas condensado y ordenado, haciendo énfasis principalmente en la funcionalidad y no en el detalle de la ejecución. Esto permite un nivel de abstracción superior y la reutilización de código común. Adicionalmente permiten la inclusión de parámetros.
 
Los macros permiten que un programa complejo y extenso se vea mas condensado y ordenado, haciendo énfasis principalmente en la funcionalidad y no en el detalle de la ejecución. Esto permite un nivel de abstracción superior y la reutilización de código común. Adicionalmente permiten la inclusión de parámetros.
  
 +
====Definición de un Macro====
 
En el HC9S08 la definición de un Macro consiste en 4 partes:
 
En el HC9S08 la definición de un Macro consiste en 4 partes:
  
Línea 37: Línea 357:
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
====Parametros====
 +
 +
Se pueden utilizar hastsa 36 parámetros en los Macros. Estos parámetros son reemplazados por el argumento correspondiente cuando se ejecuta el Macro.
 +
Para designar un parámetro se utiliza el caracter '''\''' seguido de un número (0-9) o una letra en mayúsculas (A-Z).
 +
 +
El parámetro \0 corresponde a un argumento de tamaño que sigue al nombre del macro separado por un punto (.)
 +
 +
Ejemplo, dado el siguiente Macro:
 +
 +
<syntaxhighlight lang="asm">
 +
MyMacro: MACRO
 +
        DC.\0  \1, \2
 +
        ENDM
 +
 +
</syntaxhighlight>
 +
 +
La utilización en un programa podría ser:
 +
 +
<syntaxhighlight lang="asm">
 +
MyMacro.B $10, $56
 +
 +
</syntaxhighlight>
 +
 +
Y el ensamblador lo convierte en:
 +
 +
<syntaxhighlight lang="asm">
 +
DC.B $10, $56
 +
</syntaxhighlight>
 +
 +
Como se puede ver en el ejemplo los argumentos $10 y $56 corresponden al parámetro \1 y \2 respectivamente. A los argumentos se les asigna un número de parámetro según el orden en que se coloquen luego del nombre del Macro, empezando desde \1 hasta \9 y luego \A hasta \Z.
 +
 +
====Etiquetas en los Macros====
 +
 +
Cuando se programa con Macros a cualquier línea se le puede asignar una etiqueta. Si se tienen múltiples definiciones de Macros puede surgir el problema de que dos Macros diferentes utilicen el mismo nombre de etiqueta dando como resultado comportamientos indefinidos.
 +
 +
Para resolver esta situación se definen etiquetas que son únicas para cada Macro. Al utilizar la directiva \@ el ensamblador genera un etiqueta única (una String de 5 dígitos de la forma nnnnn). Cada vez que se utiliza \@ se genera un String de 5 dígitos de manera incremental. Se le pueden agregar caracteres adicionales para entender mejor el código:
 +
 +
Definición de un Macro con etiquetas.
 +
 +
<syntaxhighlight lang="asm">
 +
clear:  MACRO
 +
          LDX  #\1
 +
          LDA  #16
 +
\@LOOP:    CLR  0,X
 +
          INCX
 +
          DECA
 +
          BNE  \@LOOP
 +
        ENDM
 +
 +
</syntaxhighlight>
 +
 +
Si llamamos al Macro Clear dos veces:
 +
 +
<syntaxhighlight lang="asm">
 +
clear temporal
 +
 +
clear data
 +
</syntaxhighlight>
 +
 +
El ensamblador expande este código de la siguiente manera:
 +
 +
<syntaxhighlight lang="asm">
 +
              clear temporal
 +
              LDX  #temporal
 +
              LDA    #16
 +
_00001LOOP:    CLR  0,X
 +
              INCX
 +
              DECA
 +
              BNE  _00001LOOP
 +
            clear data
 +
              LDX  #data
 +
              LDA  #16
 +
_00002LOOP:    CLR  0,X
 +
              INCX
 +
              DECA
 +
              BNE  _00002LOOP
 +
 +
</syntaxhighlight>
 +
 +
==Interrupciones==
 +
 +
 +
 +
Una Interrupción es una señal recibida por el procesador de un ordenador, indicando que debe "interrumpir" el curso de ejecución actual y pasar a ejecutar código específico para tratar esta situación.
 +
 +
Luego de finalizada dicha subrutina, se reanuda la ejecución del programa. En ocasiones se pueden producir una interrupción dentro de una interrupción llamadas interrupciones anidadas. Cuando se producen este tipo de interrupcion, el micro las atiende de acuerdo el orden de prioridad por el cual esta configurado, para luego retornar a la sección del código que se estaba ejecutando en el momento de atender dicha interrupción.
 +
 +
Cuando se atiende una interrupción se realiza una copia de toda la información necesaria, de registros y banderas, guardándose en la pila, para después retornar al final de la misma. Hay que tener en cuenta que en la rutina de interrupción se debe limpiar las banderas de la misma para  permitir próximas interrupciones
 +
                                [[Image:Uso del stack al entrar y salir de una interrupcion.PNG]]
 +
 +
 +
Para mayor información acerca de las diversas interrupciones que se pueden realizar en el  MC9S08QE128 y el orden de prioridad de las interrupciones ver:[[Interrupciones]]
 +
 +
===Generacion de interrupciones en la simulacion===
 +
 +
 +
 +
El programa Codewarrior 6.3 presenta la opción “debug” que permite simular el programa sin necesidad de la conexión de un micro. En dicha aplicación también se puede simular las interrupciones como se presentan con el uso del micro.
 +
 +
Para crear las interrupciones en la simulación, se deben seguir los siguientes pasos:
 +
 +
1.  Correr el programa y detenerlo con la opción Halt
 +
 +
2.  Seleccionar la opción HCS08FCS que se encuentra en la parte superior del programa de simulación
 +
 +
3.  Seleccionar IRQ Module
 +
 +
4.  Seleccionar Set IRQ Inputs Levels (INPUTS)
 +
 +
 +
      [[Image:Opciones para generar interrupciones.PNG]]
 +
 +
 +
 +
Despues de realizar los anteriores pasos se desplegara una ventana que mostrara los diferentes puertos que realizan interrupciones, configurados por defecto con el valor FF, con excepción del IRQ que esta configurado con 1.
 +
 +
                                  [[Image:Configuracion de Puertos de entradas para generar interrupciones.PNG]]
 +
 +
 +
 +
Para realizar una interrupción se debe colocar en 0 el puerto que la debe generar, como ejemplo, se generara una interrupción por el puerto PTA2, por lo cual se le asignara a InputA el valor FB.
 +
 +
 +
[[Image:Configuracion de PTA2 como interrupcion.PNG]]
 +
 +
 +
Y se puede observar que el programa entro en la instrucción Izquierda, dado que es la rutina que se llama al presionar el botón Pta2.
 +
 +
Para generar otras interrupciones, primero se debe colocar todos los registros con sus valores originales, es decir FF, presionar la opción Ok,  y luego modificarlos para que genere la interrupción deseada.
 +
 +
Las interrupciones por Tpm no necesitan se configuradas con los pasos anteriormente mencionadas, dado que ellas interrumpen en el debugger.
 +
 +
===Interrupciones del puerto serial en la simulacion===
 +
 +
 +
Para realizar interrupción por puerto serial, se deben seguir los siguientes pasos:
 +
 +
1.      Seleccionar la opción HCS08FCS que se encuentra en la parte superior del programa de simulación
 +
 +
2.      Seleccionar la opción SCI Module
 +
 +
3.      Seleccionar la opción Queue SCI Input Data (SCDI)
 +
 +
 +
[[Image:Opciones para generar una interrupcion por puerto serial.png]]
 +
 +
 +
Después se va a desplegar una ventana con el título de SCI In vacía, allí deberá colocar los valores que desea que el programa reciba, lo cual es una simulación de lo que se espera recibir por puerto serial.
 +
 +
                              [[Image:Ventana donde se colocara los valores transmitidos por el puerto serial.png]]
 +
 +
 +
Para cargar cada valor debe darle doble click al espacio resaltado en azul, lo cual desplegara una ventana en la cual debe introducir el valor que recibir en el programa.
 +
 +
[[Image:Ejemplo de como colocar valores que se recibiran por el puerto serial.png]]
 +
 +
 +
 +
Después de correr el programa si desea visualizar la salida, o el resultado que se va a transmitir por el puerto serial (solo si código recibe y transmite por puerto serial), puede seguir los siguientes pasos:
 +
 +
1.      Seleccionar la opción HCS08FCS que se encuentra en la parte superior del programa de simulación
 +
 +
2.      Seleccionar la opción SCI Module
 +
 +
3.      Seleccionar la opción View SCI Output Data (SCDO)
 +
 +
Lo cual desplegara una ventana donde aparecerán los valores que se están transmitiendo por puerto serial
  
Macros recursivas que son algo extrañas en lo que respecta a su proceso de ensamblado.
+
[[Image:Opcion para visualizar la recepcion del puerto serial.png]]
  
===Interrupciones anidadas y mi programa se queda pegado en una interrupción ¿Puedo resetear el micro? si es sí ¿Por que?===
+
==Configuración del IRQ==
  
===¿Qué ocurre si en medio de mi programa ocurre una interrupción justo antes de realizar un salto luego de una comparación?, ¿Cuando regrese mis banderas pueden estar modificadas?¿Debo recrearlas?¿Como?===
 
===¿Cómo se ve a nivel de hardware el problema de las falsas interrupciones y el BSET IRQSC_IRQACK?===
 
  
===Yo me pregunto si es posible modelar con el debugger (sin la tarjeta) alguna de las interrupciones con las que hemos trabajado y si es así, ¿cómo?===
 
  
===¿Se puede colocar el generador de funciones como entrada a la tarjeta y escuchar esa onda a través del buzzer?===
+
Ver artículo: [[IRQ (External Interrupt Request) - MC9S08QE128]]
  
===Cuales serian los pasos necesarios para configurar y trabajar con varios cloks? Ejm: Cada led que "encienda y apague" a una determinada frecuencia.===
+
==¿Se puede colocar el generador de funciones como entrada a la tarjeta y escuchar esa onda a través del buzzer?==
  
===¿Como podría conectar en paralelo los micros?===
+
==Comunicación entre microcontroladores==
  
===¿Si quisiera colocar un arduino para que trabaje en conjunto a mc9s08, seria un procedimiento parecido a colocar 2 mc9s08 en conjunto?===
+
# ¿Como podría conectar en paralelo los micros?
 +
# ¿Si quisiera colocar un [[arduino]] para que trabaje en conjunto a mc9s08, seria un procedimiento parecido a colocar 2 mc9s08 en conjunto?
 +
# Puerto Serial
  
===¿Cual seria la base para configurar correctamente el control de una matriz de leds nxn con el micro?===
+
==¿Cual seria la base para configurar correctamente el control de una matriz de leds nxn con el micro?==
  
===Según tengo entendido, el giroscopio de la tarjeta es digital y su activación es diferente a la mostrada en el manual de referencia, pues éste hace mención al modelo analógico. ¿Como puedo trabajar con él?===
+
==Según tengo entendido, el giroscopio de la tarjeta es digital y su activación es diferente a la mostrada en el manual de referencia, pues éste hace mención al modelo analógico. ¿Como puedo trabajar con él?==

Revisión actual del 15:58 20 jun 2014

Rebotes en Pulsadores o Interruptores

¿Qué son los rebotes?


Rebotes en pulsadores.jpg

Al pulsar algún botón o interruptor, no se realiza una conexión perfecta e instantánea como nosotros esperamos. Un pulsador se compone de dos partes de metal que entran en contacto (choca una con la otra) al accionarlo. Este choque genera unos rebotes realmente pequeños que suceden tan rápido que son imperceptibles para nosotros (aunque no para el DEMOQE128) hasta que finalmente se consigue un contacto firme.


Los rebotes pueden ocasionarnos molestos inconvenientes como lo son las falsas interrupciones o las interrupciones no deseadas. Entonces, ¿cómo corregir este problema?


La solución es sencilla y consta de dos aproximaciones. La primera es por hardware, adaptando a la entrada del interruptor de nuestra tarjeta un circuito simple con resistores y capacitores tal que los rebotes sean absorbidos por el capacitor. No nos centraremos en esta aproximación.


Ya que no siempre disponemos de los componentes electrónicos, la aproximación más práctica suele ser por software y es la que vamos a implementar. Basta con añadir un pequeño retardo en nuestro programa desde que se detecta el primer pulso hasta que se vuelve a leer la entrada del pulsador. Dicho retardo debe ser suficientemente largo para asegurar que cuando finalice ya se hayan extinguido los rebotes, pero también lo suficientemente corto para que sea imperceptible para nosotros.


El siguiente es un posible código en ensamblador, usando las interrupciones del módulo KBI y RTC, para llevar esto acabo:

; Include derivative-specific definitions

            INCLUDE 'derivative.inc'


;

; export symbols

;

            XDEF _Startup
            ABSENTRY _Startup


;

; variable/data section

;

             ORG    RAMStart         ;; Insert your data definition here

contador:    DS.B   1                ;; Variable a usar para incrementar y mostrar en los leds
PermisoLeer: DS.B 1                  ;; Variable a usar para  autorizar el incremento del contador

;

; code section

;

            ORG    ROMStart


_Startup:

            LDA    #$43
            STA     SOPT1       
            LDHX    #RAMEnd+1        ;; Inicializamos el Stack Pointer
            TXS
            
            CLRA
            STA   contador            ;; Inicializamos el contador
            LDA   #$1
            STA PermisoLeer           ;; Damos inicialmente autorización para incrementar el contador la 
                                      ;; la primera vez que se ejecuta el programa.

            

            BSR Configurar_GPIO
            BSR Configurar_RTC
            BSR Configurar_KBI


            

            CLI   ;; Habilitamos interrupciones




mainLoop:

            BRA    mainLoop

            

;**************************************************************

;*              Subrutinas de Configuracion                       

;**************************************************************


Configurar_KBI:

   

   LDA #$06
   STA KBI1SC     ;; KBACK=1 (1 se borran los pedidos de interrupcion),KBIE=1 (habilita las interrupciones)
    
   LDA #$04
   STA KBI1PE     ;; Habilitando pin PTA2 como KBI
   
   LDA #$00
   STA KBI1ES     ;; Pines detectan una caída de voltaje (PTA2)

            
      RTS
   

Configurar_RTC:

                                

            LDA #%00011000      ;; RTIF=0, RTCLKS6=0 RTCLKS5=0, RTIE=1, RTCPS3=1, RTCPS2=0, RTCPS1=0, RTCPS0=0
            STA RTCSC           ;; Fuente reloj interna 1khz. Interrupciones habilitadas. Reloj configurado a 1s.          

            LDA #1              ;; Definimos el valor del registro modulo del RTC
            STA RTCMOD
            

            LDA SCGC2           ;; Deshabilitamos el Clock Gate para el RTC         
            EOR #%00000100
            STA SCGC2 
           

            RTS



Configurar_GPIO:                    ;; General Port Input/Output

            

            LDA #%00111111
            STA PTCDD               ;; 6Bits (LSB) PTC - habilitados como salida colocando 1 (PTC0 a PTC5)  
            LDA #%11000000
            STA PTEDD               ;; 2Bits (MSB) PTE - habilitados como salida colocando 1 (PTE6 Y PTE7)
            
            LDA #%00111111
            STA PTCD                ;; Cero a la salida (logica negada): se apagan los leds
            LDA #%11000000
            STA PTED                ;; Cero a la salida (logica negada): se apagan los leds          


            LDA #%00000100          ;; Se habilita la resistencia de pull-up para el interruptor
            STA PTAPE               ;; PTA2. Esto significa que si se presiona el botón, el valor lógico es 0,
                                    ;; si no se presiona, el valor lógico es 1.                    

            LDA #%11111011          ;; Se habilita PTADD2 como entrada
            STA PTADD          


            RTS



;**************************************************************

;*              Rutinas de interrupcion                     *

;**************************************************************



Interrupcion_KBI:

 

   LDA  %11111101              ;; Deshabilito interrupciones del KBI
   AND  KBI1SC
   STA  KBI1SC
  

   LDA PermisoLeer             ;; Verifico si tengo permiso para incrementar contador
   CMP #$1
   BEQ IncContador            
   BRA FinKBI

  

IncContador:



      LDA #$0
      STA PermisoLeer
      LDA SCGC2                ;; Habilitamos el Clock Gate para el RTC         
      ORA #%00000100
      STA SCGC2 

      LDA contador
      INCA
      STA contador             ;; Incremento el contador
           
      LDA #%00111111           ;; Mascara con el contador
      AND contador             ;; para pasar por PTC
      COMA
      STA  PTCD           

      LDA #%11000000          ;; Mascara con el contador
      AND contador            ;; para pasar por el PTE
      COMA
      STA PTED



FinKBI:

  

   LDA  #%00000110            ;; Habilito interrupciones del KBI y limpia la bandera
   STA  KBI1SC



   RTI



Int_RTC:

      LDA #$80
      ORA RTCSC
      STA RTCSC
      LDA #$1
      STA PermisoLeer 
      LDA SCGC2              ;; Deshabilitamos el Clock Gate para el RTC         
      EOR #%00000100
      STA SCGC2 



   RTI



;**************************************************************

;* spurious - Spurious Interrupt Service Routine.             *

;*             (unwanted interrupt)                           *

;**************************************************************



spurious:    ; placed here so that security value

   NOP   ; does not change all the time.


   RTI



;**************************************************************

;*                 Interrupt Vectors                          *

;**************************************************************



            ORG   $FFCE            

            DC.W  Int_RTC   ;; RTC

            

            ORG   $FFDA

   DC.W  Interrupcion_KBI   ;; Keyboard


            ORG $FFFA

   DC.W  spurious           ;; IRQ
   DC.W  spurious           ;; SWI
   DC.W  _Startup           ;; Reset

¿Cómo se ve a nivel de hardware el problema de las falsas interrupciones y el BSET IRQSC_IRQACK?

Manejo y programación de Timers.

Un Timer o Temporizador en el DEMOQE es un circuito digital que generalmente contiene las siguientes partes:

  1. Un contador digital de 16 bits
    1. Este contador es un registro. Este registro se puede leer y también se puede escribir. Por lo que se puede iniciar con un valor diferente de 0.
    2. El contador puede ir desde 0 hasta 65536
    3. El contador se puede configurar para que funcione de forma incremental o decremental
    4. Se incrementa o disminuye el contador en cada pulso de reloj
  2. Una fuente de reloj que define la frecuencia a la que se va a incrementar el contador.
    1. Pueden existir diferentes fuentes de reloj
    2. Esta fuente de reloj se puede Preescalar lo cual significa que se puede crear un reloj mas lento a partir del reloj fuente. Este nuevo reloj se utiliza para incrementar al contador.
  3. Un comparador de Módulo
    1. Es un registro del mismo tamaño que el contador
    2. Este registro se puede configurar por el usuario
    3. Si el valor del contador es igual en algún instante al registro de módulo, el contador se reinicia.
  4. Una interrupción por desbordamiento
    1. Cuando el Timer llega a su valor máximo se produce una interrupción
    2. También se puede producir una interrupción si el Timer se reinició debido a que llegó al valor del registro Módulo

En el Demoqe se tiene un módulo llamado RTC (real time counter) y varios módulos llamados TPM, los cuales son dispositivos Temporizadores.

En líneas generales para programar cada uno de ellos el usuario debe realizar las siguientes configuraciones iniciales de sus registros:

  • Seleccionar Fuente de Reloj
  • Seleccionar preescalador para la frecuencia en la que se quiere incrementar/decrementar el contador
  • Seleccionar si el contador va a ser incremental o decremental
  • Configurar el registro del contador a su valor inicial
  • Configurar el registro de Módulo si es necesario
  • Habilitar/deshabilitar las interrupciones por desbordamiento

Para la configuración del RTC se puede servir de guía del artículo correspondiente al RTC

Para la configuración del TPM se puede servir de guía del artículo correspondiente al TPM



¿Cuáles serían los pasos necesarios para configurar y trabajar con varios cloks? Ejm: Cada led que "encienda y apague" a una determinada frecuencia.

Macros en el HC9S08

Los Macros son una secuencia de líneas de texto que puede incluir Opcodes y Directivas con variables y constantes. Una vez que se define un macro se puede utilizar su nombre para ejecutar esas líneas de texto. Cuando el ensamblador procesa el nombre del macro, lo reemplaza con las líneas de texto asociadas a ese macro y las ejecuta como si estuvieran escritas en el código fuente.

Los macros permiten que un programa complejo y extenso se vea mas condensado y ordenado, haciendo énfasis principalmente en la funcionalidad y no en el detalle de la ejecución. Esto permite un nivel de abstracción superior y la reutilización de código común. Adicionalmente permiten la inclusión de parámetros.

Definición de un Macro

En el HC9S08 la definición de un Macro consiste en 4 partes:

  • El encabezado del Macro (la directiva .MACRO)
  • El cuerpo del Macro. Una lista secuencial de líneas de ensamblador, algunas de ellas pueden usar parámetros.
  • La directiva de finalización (.ENDM)
  • Eventualmente pueden tener una instrucción llamad .MEXIT la cual detiene la expansión del Macro

El cuerpo del macro puede contener:

  • Instrucciones de ensamblador
  • Directivas de ensamblador
  • Llamadas a Macros que se definieron anteriormente

NO se pueden definir Macros dentro de un Macro.

El formato para realizar la llamada a un macro es:

[<label>:] <name>[.<sizearg>] [<argument> [,<argument>]...]

Parametros

Se pueden utilizar hastsa 36 parámetros en los Macros. Estos parámetros son reemplazados por el argumento correspondiente cuando se ejecuta el Macro. Para designar un parámetro se utiliza el caracter \ seguido de un número (0-9) o una letra en mayúsculas (A-Z).

El parámetro \0 corresponde a un argumento de tamaño que sigue al nombre del macro separado por un punto (.)

Ejemplo, dado el siguiente Macro:

MyMacro: MACRO
         DC.\0   \1, \2
         ENDM

La utilización en un programa podría ser:

MyMacro.B $10, $56

Y el ensamblador lo convierte en:

DC.B $10, $56

Como se puede ver en el ejemplo los argumentos $10 y $56 corresponden al parámetro \1 y \2 respectivamente. A los argumentos se les asigna un número de parámetro según el orden en que se coloquen luego del nombre del Macro, empezando desde \1 hasta \9 y luego \A hasta \Z.

Etiquetas en los Macros

Cuando se programa con Macros a cualquier línea se le puede asignar una etiqueta. Si se tienen múltiples definiciones de Macros puede surgir el problema de que dos Macros diferentes utilicen el mismo nombre de etiqueta dando como resultado comportamientos indefinidos.

Para resolver esta situación se definen etiquetas que son únicas para cada Macro. Al utilizar la directiva \@ el ensamblador genera un etiqueta única (una String de 5 dígitos de la forma nnnnn). Cada vez que se utiliza \@ se genera un String de 5 dígitos de manera incremental. Se le pueden agregar caracteres adicionales para entender mejor el código:

Definición de un Macro con etiquetas.

clear:   MACRO
           LDX   #\1
           LDA   #16
\@LOOP:    CLR   0,X
           INCX
           DECA
           BNE   \@LOOP
        ENDM

Si llamamos al Macro Clear dos veces:

clear temporal

clear data

El ensamblador expande este código de la siguiente manera:

               clear temporal
               LDX   #temporal
               LDA    #16
_00001LOOP:    CLR   0,X
               INCX
               DECA
               BNE   _00001LOOP
             clear data
               LDX   #data
               LDA   #16
_00002LOOP:    CLR   0,X
               INCX
               DECA
               BNE   _00002LOOP

Interrupciones

Una Interrupción es una señal recibida por el procesador de un ordenador, indicando que debe "interrumpir" el curso de ejecución actual y pasar a ejecutar código específico para tratar esta situación.

Luego de finalizada dicha subrutina, se reanuda la ejecución del programa. En ocasiones se pueden producir una interrupción dentro de una interrupción llamadas interrupciones anidadas. Cuando se producen este tipo de interrupcion, el micro las atiende de acuerdo el orden de prioridad por el cual esta configurado, para luego retornar a la sección del código que se estaba ejecutando en el momento de atender dicha interrupción.

Cuando se atiende una interrupción se realiza una copia de toda la información necesaria, de registros y banderas, guardándose en la pila, para después retornar al final de la misma. Hay que tener en cuenta que en la rutina de interrupción se debe limpiar las banderas de la misma para permitir próximas interrupciones

                                Uso del stack al entrar y salir de una interrupcion.PNG


Para mayor información acerca de las diversas interrupciones que se pueden realizar en el MC9S08QE128 y el orden de prioridad de las interrupciones ver:Interrupciones

Generacion de interrupciones en la simulacion

El programa Codewarrior 6.3 presenta la opción “debug” que permite simular el programa sin necesidad de la conexión de un micro. En dicha aplicación también se puede simular las interrupciones como se presentan con el uso del micro.

Para crear las interrupciones en la simulación, se deben seguir los siguientes pasos:

1. Correr el programa y detenerlo con la opción Halt

2. Seleccionar la opción HCS08FCS que se encuentra en la parte superior del programa de simulación

3. Seleccionar IRQ Module

4. Seleccionar Set IRQ Inputs Levels (INPUTS)


     Opciones para generar interrupciones.PNG


Despues de realizar los anteriores pasos se desplegara una ventana que mostrara los diferentes puertos que realizan interrupciones, configurados por defecto con el valor FF, con excepción del IRQ que esta configurado con 1.

                                 Configuracion de Puertos de entradas para generar interrupciones.PNG


Para realizar una interrupción se debe colocar en 0 el puerto que la debe generar, como ejemplo, se generara una interrupción por el puerto PTA2, por lo cual se le asignara a InputA el valor FB.


Configuracion de PTA2 como interrupcion.PNG


Y se puede observar que el programa entro en la instrucción Izquierda, dado que es la rutina que se llama al presionar el botón Pta2.

Para generar otras interrupciones, primero se debe colocar todos los registros con sus valores originales, es decir FF, presionar la opción Ok, y luego modificarlos para que genere la interrupción deseada.

Las interrupciones por Tpm no necesitan se configuradas con los pasos anteriormente mencionadas, dado que ellas interrumpen en el debugger.

Interrupciones del puerto serial en la simulacion

Para realizar interrupción por puerto serial, se deben seguir los siguientes pasos:

1. Seleccionar la opción HCS08FCS que se encuentra en la parte superior del programa de simulación

2. Seleccionar la opción SCI Module

3. Seleccionar la opción Queue SCI Input Data (SCDI)


Opciones para generar una interrupcion por puerto serial.png


Después se va a desplegar una ventana con el título de SCI In vacía, allí deberá colocar los valores que desea que el programa reciba, lo cual es una simulación de lo que se espera recibir por puerto serial.

                              Ventana donde se colocara los valores transmitidos por el puerto serial.png


Para cargar cada valor debe darle doble click al espacio resaltado en azul, lo cual desplegara una ventana en la cual debe introducir el valor que recibir en el programa.

Ejemplo de como colocar valores que se recibiran por el puerto serial.png


Después de correr el programa si desea visualizar la salida, o el resultado que se va a transmitir por el puerto serial (solo si código recibe y transmite por puerto serial), puede seguir los siguientes pasos:

1. Seleccionar la opción HCS08FCS que se encuentra en la parte superior del programa de simulación

2. Seleccionar la opción SCI Module

3. Seleccionar la opción View SCI Output Data (SCDO)

Lo cual desplegara una ventana donde aparecerán los valores que se están transmitiendo por puerto serial

Opcion para visualizar la recepcion del puerto serial.png

Configuración del IRQ

Ver artículo: IRQ (External Interrupt Request) - MC9S08QE128

¿Se puede colocar el generador de funciones como entrada a la tarjeta y escuchar esa onda a través del buzzer?

Comunicación entre microcontroladores

  1. ¿Como podría conectar en paralelo los micros?
  2. ¿Si quisiera colocar un arduino para que trabaje en conjunto a mc9s08, seria un procedimiento parecido a colocar 2 mc9s08 en conjunto?
  3. Puerto Serial

¿Cual seria la base para configurar correctamente el control de una matriz de leds nxn con el micro?

Según tengo entendido, el giroscopio de la tarjeta es digital y su activación es diferente a la mostrada en el manual de referencia, pues éste hace mención al modelo analógico. ¿Como puedo trabajar con él?