• No results found

3. Life Cycle Software Reliability and Safety Activities

3.3. Design Activities

3.3.2. Software Design Specification

A continuación se realizará de forma metódica la solución a un pequeño problema de programación, comenzando con la definición de los requerimientos de la aplicación, seguido de la correspondiente documentación mediante un diagrama de flujo, hecho esto, se escribirá el programa empleando un editor de texto estándar escribiendo los nemónicos correspondientes para cada bloque del diagrama de flujo.

La función del programa a realizar consiste en hacer que el microcontrolador revise un pin de alguno de sus puertos configurado como entrada, este pin estará conectado a un pulsador que pondrá el pin a tierra cuando se encuentre presionado. Cuando el microcontrolador detecte que el pulsador ha sido presionado debe poner en alto otro pin configurado como salida para encender un LED por 1 segundo, el tiempo que se mantenga presionado el pulsador no debe afectar el tiempo en que el LED es encendido por lo tanto éste solo se volverá a encender una vez el pulsador ha sido soltado y presionado de nuevo.

El montaje del circuito de prueba se realiza haciendo las conexiones necesarias para que funcione el MCU (revisar sección de montaje); además se conecta el pulsador en configuración pull down al pin menos significativo (LSB) del puerto A mientras el Led es conectado al pin más significativo (MSB) empleando una configuración pull up.

1. Diagrama de flujo Programa principal.

En la figura 29 se presenta el diagrama de flujo correspondiente a la aplicación que se desea programar. Como se puede apreciar el diagrama de flujo contiene la mayoría de los bloques descritos anteriormente y cumple con las reglas necesarias para evitar ambigüedades.

El flujo del programa es simple pero no es algo trivial, ya que no se puede lograr la misma funcionalidad de manera sencilla con componentes discretos, se requeriría una serie de integrados externos para realizar la temporización, en ello radica la conveniencia de utilizar un microcontrolador gobernado por un programa ya que éste entra a reemplazar el empleo de diferentes integrados para realizar la misma funcionalidad.

Para escribir un programa en lenguaje ensamblador a partir del diagrama de flujo, el programador debe desarrollar una serie de instrucciones que desempeñarán las

funcionalidades especificadas en cada bloque del diagrama. El paso a seguir con este ejemplo es tomar cada uno de los bloques presentando una opción para la programación con la correspondiente explicación de las instrucciones empleadas. Se recomienda al estudiante hacer uso de los manuales de referencia para consultar los nemónicos de los diferentes comandos.

Para empezar se debe inicializar el microcontrolador configurando los puertos del mismo de acuerdo a las necesidades de la aplicación, en este caso se configuran los pines del puerto A del MCU como entradas a excepción del pin 7 que se empleará como salida para encender el led. La primera precaución que hay que tener en cuenta es la de poner el pin configurado como salida (Bit 7, puerto A (MSB)) en „1‟ para mantener el LED apagado hasta que se detecte la condición de encendido.

Los nemónicos correspondientes a esta parte del diagrama de flujo se presentan a continuación:

PORTA EQU $00 ;Asignación Directa Dirección del puerto A DDRA EQU $04 ;Asigna Dirección control de dato, puerto A TEMP1 EQU $C0 ;Asigna Posición de memoria temporal(1 byte)

ORG $0300 ;El Programa empezará en Dir $0300 INIT LDA #$80 ;Empieza la inicialización

STA PORTA ;El LED se apagará

STA DDRA ;Pone el bit 7 del puerto como salida * El resto de pines del puerto se configura como entrada

El puerto A del HC08 es configurado desde dos registros; el registro de datos y el registro de configuración o control de dato, $0000 y $0004 respectivamente, el primero contiene los datos que se cargarán en cada uno de los pines del puerto y el segundo contiene los bits de configuración del puerto, es decir determina si cada pin es una entrada („0‟) o una salida („1‟). Para una información más detallada sobre los puertos se recomienda al estudiante revisar la sección de puertos I/O en las hojas de datos de la familia HC08 o del dispositivo en particular con que se encuentre trabajando.

En la programación se emplean etiquetas (PORTA DDRA TEMP1) para obtener acceso directo a estas direcciones la siguiente instrucción (ORG) indica al compilador únicamente la dirección de memoria desde donde se comenzará a almacenar el programa.

La instrucción LDA #$80, de acuerdo con las convenciones aprendidas y el set de instrucciones del MCU, lo que realiza es cargar el acumulador empleando direccionamiento inmediato (#) con el dato $80 (%10000000), este dato se carga en el acumulador con la intención de cargarlo posteriormente en el registro de datos y en el registro de configuraciones del puerto A.

De acuerdo con el diagrama de flujo, a continuación se realiza la operación de revisión del pin que se encuentra conectado al pulsador para conocer su estado, para tal efecto se carga el puerto A en su totalidad en el acumulador y luego se realiza la operación lógica AND para comparar el bit de interés (LSB) con un valor alto („1‟ lógico).

TOP LDA PORTA ; Carga el puerto A en el acumulador AND #$01 ; Prueba el bit-0

La acción representada por el primer rombo del diagrama de flujo se realiza con el comando BEQ (bifurcación si es igual), si el resultado de la operación AND es „0‟ lógico es decir que al comparar el puerto A con $01 resulta que los números son iguales se realiza la bifurcación devolviéndose hacia la etiqueta TOP creándose un lazo de espera hasta que el pulsador sea presionado. En caso de que se detecte que se ha presionado el pulsador, se continúa normalmente con la siguiente instrucción.

BEQ TOP ; Lazo hasta que bit0 = 1.

La siguiente instrucción en caso de detectarse que el pulsador ha sido presionado es un salto a la subrutina de espera para evitar rebotes.

JSR DLY50 ; Retardo de 50 ms para los rebotes

La subrutina de retardo se emplea en dos ocasiones para esta aplicación, como retardo anti-rebote y para determinar el tiempo de 1 seg que será encendido el led en caso de ser presionado el pulsador. El correspondiente diagrama de flujo y detalle de programación de esta subrutina se presenta posteriormente.

A continuación del retardo anti-rebote se enciende el Led empleando el siguiente comando:

BCLR 7, PORTA ; Enciende el LED (bit-7 del Puerto A)

Es de tener en cuenta que debido a la forma de conexión del Led (Pull Up) se requiere que en el pin al que se encuentra conectado sea puesto en un estado bajo o „0‟ lógico para hacer que la corriente circule por éste, encendiéndolo así. Una vez el Led es encendido, el flujo del programa indica que debe existir un retardo de un (1) segundo en el cual el Led debe permanecer encendido, para tal efecto es emplea nuevamente la subrutina de retardo pero esta vez puesto que se requiere que el retardo sea aun mayor y teniendo en cuenta que la subrutina creada genera un retardo de 50 ms, se debe realizar un lazo que se repita 20 veces para completar 1 segundo. Los comandos empleados se presentan a continuación:

LDA #20 ;El Decimal 20 se carga en el acumulador DLYLP JSR DLY50 ;Retardo de 50 ms

DECA ;se decrementa el acumulador en una unidad BNE DLYLP ;Si el acumulador no es cero ir a DLYLP. BSET 7,PORTA ;Apaga el LED

El programa finaliza de acuerdo con los requerimientos establecidos con una rutina de espera hasta que el pulsador sea soltado para evitar que se detecte otra orden de encendido del Led antes de haberse soltado y vuelto a presionar, los comandos son los siguientes:

OFFLP BRSET 0,PORTA,OFFLP ; Lazo hasta interruptor abierto JSR DLY50 ; Retardo antirebote.

BRA TOP ; Ir a espera para el siguiente cierre del ; interruptor.

2. Diagrama de Flujo Subrutina de Espera 50 ms.

Como es sabido, una subrutina se trata de un programa generalmente corto que es ejecutado varias veces a lo largo de un programa mayor la intención es escribir este programa una sola vez y llamarlo desde el programa principal cada vez que sea requerido empleando los comandos bifurcación a subrutina (BSR) o salto a subrutina (JSR).

Las instrucciones de salto y bifurcación a subrutina lo primero que hacen es guardar automáticamente en las posiciones de memoria RAM temporales de la pila la dirección de la instrucción inmediatamente siguiente con la intención de retornar con el comando RTS a esta dirección una vez se ha ejecutado la subrutina. La función RTS hace que la CPU recupere de la dirección de retorno previamente guardada.

Por otro lado como se observa en el diagrama de flujo de la subrutina la primera acción es guardar el acumulador para volver a cargarlo una vez se ha terminado la subrutina, esto se realiza ya que éste puede cambiar durante la ejecución de la subrutina y generar resultados no esperados una vez se vuelve al programa principal.

Como se observa en la figura 30, la subrutina de retardo involucra un lazo interno (INNRLP) dentro de otro lazo (OUTRLP). El lazo interno consiste en dos instrucciones que se ejecutan 256 veces antes que X alcance el valor de $00 nuevamente, terminando con la bifurcación BNE, esto suma 6 ciclos a 500 ns por 256 ciclos, lo que es igual a 0.768 ms para el lazo interno. Realizando los cálculos del caso se deduce que el lazo externo debe realizarse 65 veces; el tiempo total para de ejecución para el lazo externo resulta 65*(1536 + 9) o 65*(1545) = 100.425 ciclos de 500 ns es decir 50.212 ms. Sumando las demás instrucciones del lazo externo, se añaden un total de 21 ciclos así que el tiempo total de ejecución de la subrutina DYL50 es 50.223 ms incluyendo el tiempo que requiere la instrucción JSR para llamar a la subrutina.

Otra opción más eficiente sería utilizar el temporizador interno con que cuenta el MCU en este caso no se requeriría realizar todos estos cálculos para cuadrar el tiempo basados en los ciclos de instrucción y además la CPU estaría libre para ejecutar otras acciones durante un retardo de este tipo.