sábado, 16 de noviembre de 2013

INTERRUPCIONES Y ENSAMBLADOR

El siguiente programa tiene como objetivo mostrar el uso de las interrupciones externas haciendo uso del lenguaje de bajo nivel de los microcontroladores AVR en particular el microcontrolador ATMEGA48.
El programa que se presentara tiene como función el de cambiar el estado de un puerto dependiendo de la interrupción generada así como de poder hacer esto de forma indefinida este programa no tiene aplicación dentro de la ingeniería pero sirve para desarrollar habilidades en programación y de este modo poder resolver problemas prácticos donde el uso de este tipo de funciones son de utilidad.



DESCRIPCIÓN
El código hace uso de las interrupciones INT0 e INT1 las cuales reaccionan a los flancos de bajada,
al realizarse la interrupción de alguno de ellos se realiza lo siguiente
  • Asignar al puerto de salida el valor de la variable correspondiente desplazarX 
  • Mueve el valor de desplazarX a la derecha o izquierda dependiendo de la interrupción generada.
  • Se comprueba que la variable ha llegado al final del byte de ser asi se reinicia su valor para que realize su función otra vez. 
DESCRIPCIÓN DE MNEMÓNICOS UTILIZADOS

SBRC (Skip if bit in register cleared)
Descarta la instrucción siguiente si el bit indicado no se encuentra seteado

SBRS (Skip if bit in register set)
Descarta la instrucción siguiente si el bit indicado se encuentra seteado

 RJMP (Relative jump)
Realiza un salto al lugar indicado con el label


LDI (Load immediate)
Carga un valor de forma inmediata a un registro

OUT (Out port)
Carga el valor de un registro en un puerto

CLR (Clear register)
Limpia el registro indicado

STS (Store direct to SRAM)
Se asigna el valor de un registro a una direccion de la SRAM, este mnemonico reemplaza a out en los registros 0x60 - 0xFF en SRAM, en los cuales solo pueden utilizarse las instrucciones ST/STS/STD y LD/LDS/LDD.

SEI (Global interrupt enable)
Habilita la interrupción global

IN (In port)
Asigna el valor de un puerto a un registro

LSL (Logical shift left)
Realiza un desplazamiento lógico a la izquierda de un registro

LSR (Logical shift right)
Realiza un desplazamiento lógico a la derecha de un registro

RETI (Interrupt return)
Retorna una interrupción

Dejo el link de la simulación y del programa al final
Alguna pregunta del funcionamiento del programa indique enlos comentarios

PROGRAMA

/*
 * pila_int0.asm
 *
 *  Created: 16/11/2013 19:03:23
 *   Author: NEBURESS.KYLL
 */

 .include "m48def.inc"

 .def temp=r16
 .def desplazar0=r17
 .def desplazar1=r18
 .def temp2=r19
 .def temp3=r20

 ;AQUI SE INDICA LA POSICION DONDE COMENZARA EL PROGRAMA
 ;ADEMAS DE LA DIRECCION DE LAS INTERRUPCIONES PARA REALIZAR LAS RUTINAS INDICADAS

 .org 0x00
 rjmp START ; Reset Handler
 .org 0x001
 rjmp EXT_INT0 ; IRQ0 Handler
 .org 0x002
 rjmp EXT_INT1 ; IRQ1 Handler

 ;INICIA EL PROGRAMA
START: ldi temp, high(RAMEND); Main program start
       out SPH,temp ; Set Stack Pointer to top of RAM
       ldi temp, low(RAMEND)
       out SPL,temp

      
       ldi temp,0x00
       out DDRD,temp                            ;SE DECLARA AL PUERTO D COMO ENTRADA
       ldi temp,0xFF                           
       out PORTD,temp                           ;SE HABILITAN LAS RESISTENCIAS DE PULL UP

       ldi temp,0xFF
       out DDRB,temp                            ;SE DECLARA EL PUERTO B COMO SALIDA

       ldi temp,0x3F
       out DDRC,temp                            ;SE DECLARA AL PUERTO C COMO SALIDA

       clr temp                                 ;SE LIMPIA LA VARIABLE temp
       ldi temp,(1<<INT1)|(1<<INT0)             ;SE ASIGNA A temp EL VALOR DE 0x03
       sts 0x3d,temp                            ;SE ASIGNA EL VALOR DE temp AL REGISTRO EIMSK
                                                ;HABILITANDOSE LAS INTERRUPCIONES INT0 E INT1
       clr temp                                 ;SE LIMPIA LA VARIABLE temp
       ldi temp,(1<<ISC01)|(1<<ISC11)           ;SE ASIGNA A temp EL VALOR DE 0x0A PARA QUE LAS INTERRUPCIONES
                                                ;REACCIONEN EN FLANCOS DE BAJADA
       sts EICRA,temp                           ;SE ASIGNA EL VALOR DE temp AL REGISTRO EICRA
      

       sei                                      ;SE HABILITA LA INTERRUPCION GLOBAL

       ldi desplazar0,0x01                      ;SE ASIGNAN VALORES A LAS VARIABLES DE CONTROL
       ldi desplazar1,0x20

main:    rjmp main                               ;BUCLE INFINITO

EXT_INT0:
        push temp                               ;SE GUARDA EL VALOR DE POSICION EN LA PILA
        in   temp, SREG                         ;SE GUARDA EL REGISTRO DE ESTADOS EN LA VARIABLE TEMP
                               
        out PORTB,desplazar0                    ;SE CAMBIA EL ESTADO DEL PUERTO B
        lsl desplazar0                          ;SE DESPLAZA EL VALOR DE LA VARIABLE desplazar0 A LA IZQUIERDA
        sbrc temp2,0                            ;PRUEBA SI SE HA ASIGNADO A LA VARIABLE temp2 UN VALOR EN EL BIT 0 DE SER ASI LE ASIGNA
        ldi desplazar0,0x01                     ;EL VALOR DE 0x01 A LA VARIABLE despazar0
                        
        sbrc desplazar0,7                       ;PRUEBA SI EL BIT 7 DE LA VARIABLE despalzar0 SE ENCUENTRA SETEADO DE SER ASI
        ldi temp2,0x01                          ;ASIGNA EL VALOR DE 0x01 A LA VARIABLE temp2

        sbrs desplazar0,7                       ;COMPRUEBA SI EL BIT 7 DE LA VARIABLE desplazar0 SE ENCUENTRA SETEADO
        ldi temp2,0x00                          ;DE LO CONTRARIO ASIGNA EL VALOR 0x00 A LA VARIABLE temp2

        out SREG, temp                          ;RETORNA EL VALOR DEL REGISTRO SREG
        pop temp                                ;RETIRA EL REGISTRO DE LA PILA
        reti                                    ;RETORNA A LA POSICION DONDE SE ENCONTRABA ANTES DE REALIZARSE LA INTERRUPCION

EXT_INT1:
        push temp                                ;SE GUARDA EL VALOR DE POSICION EN LA PILA
        in   temp, SREG                          ;SE GUARDA EL REGISTRO DE ESTADOS EN LA VARIABLE TEMP

        out PORTC,desplazar1                     ;SE CAMBIA EL ESTADO DEL PUERTO C
        lsr desplazar1                           ;SE DESPLAZA EL VALOR DE LA VARIABLE desplazar1 A LA DERECHA
        sbrc temp3,0                             ;PRUEBA SI SE HA ASIGNADO A LA VARIABLE temp3 UN VALOR EN EL BIT 0 DE SER ASI LE ASIGNA
        ldi desplazar1,0x20                      ;EL VALOR DE 0x20 A LA VARIABLE despazar1

        sbrc desplazar1,0                        ;PRUEBA SI EL BIT 7 DE LA VARIABLE despalzar1 SE ENCUENTRA SETEADO DE SER ASI
        ldi temp3,0x01                           ;ASIGNA EL VALOR DE 0x01 A LA VARIABLE temp3

        sbrs desplazar1,0                        ;COMPRUEBA SI EL BIT 7 DE LA VARIABLE desplazar1 SE ENCUENTRA SETEADO
        ldi temp3,0x00                           ;DE LO CONTRARIO ASIGNA EL VALOR 0x00 A LA VARIABLE temp3
       
        out SREG, temp                          ;RETORNA EL VALOR DEL REGISTRO SREG
        pop temp                                     ;RETIRA EL REGISTRO DE LA PILA
        reti                                               ;RETORNA A LA POSICION DONDE SE ENCONTRABA   ANTES DE REALIZARSE LA INTERRUPCION

       
NOTA:
En la instrucción    sts 0x3d,temp lo correcto seria colocar    sts EIMSK,temp, pero en el microcontrolador ATMEGA48 la dirección del registro se encontraba por defecto en el archivo  .include "m48def.inc" en la posición 0x1d, mas sin embargo la posición real era 0x3d con lo cual si el programa no funciona como debería analicen la localización de su registro en el datasheet de su microcontrolador.

DIRECCIÓN INDICADA DE I EN EL INCLUDE
DIRECCIÓN REAL DE EIMSK

REGISTRO DE CONTROL DE INTERRUPCIONES
SENTIDO DE FUNCIONAMIENTO DE INT0 E INT1
REGISTRO DE ENMASCARAMIENTO DE LAS INTERRUPCIONES EXTERNAS 

  SIMULACIÓN EN PROTEUS



COGIGO EN ATMEL STUDIO 6


 LINK

https://mega.co.nz/#!JkcUVS5J!fxbvQiswMIDkJIStUYkjN2IA5pMawDHF3NgGb1hOwkY







No hay comentarios:

Publicar un comentario