domingo, 17 de noviembre de 2013

UART0 Y ENSAMBLADOR

    A continuación el siguiente programa tiene como fin hacer uso de la transmisión de datos con  ayuda del microcontrolador, este tipo de actividad es de gran ayuda dentro de la ingeniería debido a su extenso uso dentro de las diversas aplicaciones en las que se puede utilizar este tipo de comunicaciones.

DESCRIPCION
   El programa realizado realiza el envió de datos únicamente, lo cual realiza cada 10ms aproximadamente haciendo uso del timer0 en modo CTC y de la interrupción por coincidencia donde además de realizar el envió de datos también cambia el estado de PD6 para observar la velocidad de funcionamiento de la interrupción.

Dejare el link de la simulacion y el programa al final  para que puedan descargarlo
Alguna pregunta o sigerencia ingresela en los comentarios

 PROGRAMA

/*
 * usart0.asm
 *
 *  Created: 17/11/2013 12:04:29
 *   Author: NEBURESS.KYLL
 */

 .include "m48def.inc"

 .def var1 = r16
 .def var0 = r17
 .def temp = r18
 .def retraso = r19

 .org 0x000
 rjmp init
 .org OC0Aaddr
 rjmp TIM0_COMPA ; Timer0 CTC



init: 
        sbi   DDRD,6   ;DECLARA A PD6 COMO SALIDA
        ;INICIALIZA LA PILA
        ldi   r20,0xFF
        ldi   temp,high(RAMEND)
        out   SPH,temp
        ldi   temp,low(RAMEND)
        out   SPL,temp
        ;INICIALIZA EL TIMER
        call  init_timer    
        ;HABILITA LA INTERRUPCION GLOBAL 
        sei
        ;INICIALIZA EL USART
        call ini_usart

main:
        ;BUCLE INFINITO
rjmp main

;INICIALIZA EL TIMER EN MODO CTC
init_timer:
        ldi retraso,(5<<CS00)
        sts 0x45,retraso                               ;PREESCALER 1024.....0x45=TCCR0B
        ldi retraso,0x4E
        sts 0x47,retraso                               ;0x47=OCR0A.......CARGA A OCR0A=4E
        ldi retraso,(1<<COM0A0)|(1<<WGM01)
        sts 0x44,retraso                               ;ESTABLECE A COM0A0 EN CAMBIO DE ESTADO EN COINCIDENCIA Y ESTABLECE A TIMER0 EN
                                                       ;MODO CTC
        clr retraso
        ldi retraso,(1<<OCIE0A)                        ;SETEA LA MASCARA DE COINCIDENCIA OCIE0A
        sts TIMSK0,retraso
        ret                                            ;RETORNA



ini_usart:
;ESTABLECER BAUD RATE A 9600 PARA F_CPU=8MHz SIN PREESCALAMIENTO
        ldi var1,0x00
        sts UBRR0H,var1
        ldi var0,0x33
        sts UBRR0L,var0

;HABILITAR RECEPCION Y TRANSMISION

        ldi temp,(1<<RXEN0)|(1<<TXEN0)
        sts UCSR0B,temp

;ESTABLECER EL FORMATO: 8 BITS DE DATOS, 2 BITS DE STOP

        ldi temp,(1<<USBS0)|(3<<UCSZ00)
        sts UCSR0C,temp
        ret

transmit:
        ;ESPERA A QUE EL BUFFER DE TRASNMISION SE ENCUENTRE VACIO
        lds var1,UCSR0A
        sbrs var1,5
        rjmp transmit                
        ;COLOCA EL DATO DE temp Y LO ENVIA
        sts UDR0,r20
        ret       
        ;RETORNA

TIM0_COMPA:
        push temp                    ;COLOCA A temp EN LA PILA
        in temp,SREG                 ;GUARDA EL VALOR DE SREG en temp

        call  transmit               ;TRANSMITE EL VALOR DEL REGISTRO r20
        dec   r20                    ;DECREMENTA EL VALOR DEL REGISTRO r20
        lds   var0,SREG              ;CARGA EL VALOR DE SREG EN var0
        sbrc  var0,1                 ;SI r20==0 ENTONCES
        ldi r20,0xFF                 ;r20=0XFF

        out SREG,temp                ;RETORNA EL VALOR DE SREG ANTES DE INGRESAR A LA INTERRUPCION
        pop temp                     ;RETIRA LA INTERRUPCION DE LA PILA
        reti



   A continuacion se mostraran los registros que se usaron para este programa ademas de que se indicara la direccion nde aquellos donde su direccion en el .include "m48def.inc" no son las indicadas
por lo cual se cambiaron, dependiendo del microcontrolador que utilicen esto podria no ser verdad por lo que si usan un microcontrolador diferente revisen las direcciones de los registros para que el programa funcione como se espera.



 REGISTRO TCCR0A (0x44)


REGISTRO TCCR0B (0x45)




GENERADOR DE FUNCIONAMIENTO DEL TIMER0















 PREESCALADOR DEL TIMER0



















 REGISTRO OCR0A (0x47)





 
 TIMSK0
  

BAUD RATE PARA DIFERENTES FRECUENCIAS DE PROCESAMIENTO  Y SU VALOR EN UBRRn CORRESPONDIENTE


 

 PRUEBA DE FUNCIONAMIENTO DEL PROGRAMA

SIMULACION EN ATMEL STUDIO 6



 SIMULACION EN PROTEUS




LINK
https://mega.co.nz/#!MtsX1Q7J!QUB9JDmIRdW_N-I6UBTXQymfb3k2hnWcloA50m-Afc8

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







miércoles, 13 de noviembre de 2013

ADC Y ENSAMBLADOR

A continuación se realizara un ejemplo de la configuración del ADC de un microcontrolador en ensamblador específicamente para el ATMEGA48 en modo corrida libre.

DESCRIPCIÓN
las variables ACUMULADOR y TEMP tiene como objetivo guardar el resultado de la conversión así como de permitir el control de los registros respectivamente, el resultado de la conversión se cargara en la variable ACUMULADOR y se presentara por medio del puerto D.

dejare al final el link con el código del programa y su simulación en proteus

PROGRAMA
/*
 * ADC.asm
 *
 *  Created: 13/11/2013 19:30:41
 *   Author: NEBURESS.KYLL
 */ 

 .def ACUMULADOR=r16
 .def TEMP=r17

 .org 0x00
 rjmp init

 init: 
LDI TEMP,0x60
STS ADMUX,TEMP ;configura el voltaje de referencia así como el canal a utilizar VREF=VCC 
                                                          ;canal ADC0 y la justificación a la izquierda
LDI TEMP,0xFF        
OUT DDRD,TEMP                  ;configura el puerto D como salida
LDI TEMP,0x86
STS ADCSRA,TEMP              ;inicializa el ADC así como fijar el preescalamiento y                                                                                    

START:                                         
LDI TEMP,0xC6
STS ADCSRA,TEMP           ;inicializa conversión 
 CAPTURA:                                          ;espera a que termine la conversión
        LDS TEMP,ADCSRA
SBRS TEMP,4
RJMP CAPTURA       
;TERMINA CONVERSION
LDS ACUMULADOR,ADCH                    
OUT PORTD,ACUMULADOR            ;presenta el resultado de la conversión en el puerto D
RJMP START                                        ;comienza una nueva conversión

                                   ADCSRA REGISTER



 ADMUX REGISTER
PREESCALER


NETWORK







LINK
https://mega.co.nz/#!QttjUCoa!EvKuTXnUWqpT-mJw_ZNfkitw_FVxcfB-Qq3h1ZTnHnw

TIMER0 CON ENSAMBLADOR

El siguiente programa tiene como fin mostrar una forma sencilla de utilizar el timer0 para que realiza una actividad en determinado tiempo.

DESCRIPCIÓN
el programa cambia el estado de PD4 cada vez que el registro OCR0A coincide con TCNT0, lo cual sucede cada 8 ms.

Dejo al final el link del código del programa y la simulación en proteus

Alguna duda puede ingresarla en los comentarios

PROGRAMA

/*
 * timer.asm
 *
 *  Created: 13/11/2013 11:08:11
 *   Author: NEBURESS.KYLL
 */ 

 .def temp=r17

 .org 0x00
rjmp init

 rjmp init

 init:
ldi temp,0x42;
out TCCR0A,temp ;configurar timer
ldi temp,0x04;
out TCCR0B,temp
ldi temp,0xF9;
out OCR0A,temp
;salidas
ldi temp,0xFF
out DDRD,temp
start:
rjmp start




LINK
https://mega.co.nz/#!Uk9UlZoT!UdsQImKsP3BjNjp_m0f-nGPuDqU0C6tsTDAiU52GSXA

martes, 5 de noviembre de 2013

MUESTREO DE SEÑALES CON SCILAB

  A continuación se mostrara el uso del software scilab para la adquisición de datos de señales analógicas utilizando el microcontrolador ATMEGA48, para poder hacer uso del código que se presentara procure observar la entrada MUESTREO DE SEÑALES  que se encuentra en el blog.

DESCRIPCIÓN:

  El código realiza la adquisición de 200 datos enviados por el puerto serial, el cual esta configurado con en este caso con el puerto serial COM6, este valor tendrá que modificarse dependiendo del puerto que este usando su convertidor serial-usb o su puerto serial; el baud rate utilizado es de 19200 el cual debe de ser el mismo que el que esta utilizando el el dispositivo que envía los datos, en nuestro caso es el dispositivo AVR; no hay paridad; se enviaran 8 bits de datos y 2 bits de stop.

  Se mostraran 2 programas uno donde se podrá observar el muestreo de la señal en tiempo real con el inconveniente de que el tiempo de muestreo en PC no puede ser muy bajo ya que sobrecargaría el programa, el segundo realiza un muestreo mucho mas rápido y se encuentra configurado para poder hacer un muestreo de 800 microsegundos el numero de muestras esta determinado por la variable n la cual se puede ajustar dependiendo de sus necesidades.

Alguna duda pueden ingresarla en los comentarios

muestreo lento

clf;                                                  //limpia la pantalla
n=200;                                           //numero de muestreos
y=ones(1,200);                              //vector de unos donde se almacenaran los datos adquiridos
h=openserial(6,"19200,n,8,2");      //abre el puerto serial
i=1;                                               //declara un contador
while i<=n                                     //ciclo para la adquisición de los datos
    pot=ascii(readserial(h));            //guarda el dato obtenido en la variable pot
        y(i)=(pot(1))*5/256;            //asigna el elemento 1 de pot al i-esimo elemento del vector y                                                                      //preescalando los valores de [0:255] a [0:5]
        xpause(5000);                     //realiza una espera de 5 milisegundos
        plot(i,y(i),'X-r');                   //gráfica el valor adquirido
        drawnow();
        i=i+1;                                  //incrementa el contador
end
closeserial(h)                               //cierra el puerto


muestreo en tiempo real

clf;                                               //limpia la pantalla
n=7000;                                      //numero de muestreos
y=ones(1,n-1);                            //vector de unos donde se almacenaran los datos adquiridos
h=openserial(5,"19200,n,8,2");    //abre el puerto serial
i=1;                                             //declara un contador
x=[0:1:n];                                    //vector para realizar la graficación de los datos                     
while i<=n                                   //ciclo para la adquisición de los datos
    pot=ascii(readserial(h));           //guarda el dato obtenido en la variable pot
        y(i)=pot(1);                         //asigna el elemento 1 de pot al i-esimo elemento del vector y
        xpause(800);                       //realiza una pausa de 800 microsegundos
        i=i+1;                                  //incrementa el contador
end                                             //termina la adquisición
k=(5/256).*y;                             //guarda la conversión del vector y en k para observar el valor de 0 a 5V
plot2d2(x,k)                               //gráfica los datos adquiridos
closeserial(h)                              //cierra el puerto serial


LINK DE CÓDIGO EN SCILAB PARA MUESTREO RÁPIDO
https://mega.co.nz/#!E48zGC4D!EuD1rmsbZkEmAtI23CZHayqUtn1T9MMAOAqcmfxmioQ

muestreo lento

muestreo rápido 



domingo, 3 de noviembre de 2013

PRUEBA DE ENTRADAS


El siguiente es un programa sencillo en ensamblador el cual hace el uso de algunas instrucciones sencillas para cambiar de estado dos salidas, dependiendo del estado de las entradas.

DESCRIPCIÓN:

Se hará el uso de los siguientes mnemonicos:

SBIS   Saltar si el bit en el registro de E / S se encuentra
Prueba el estado de las entradas y descarta la siguiente instrucción si hay un uno en el bit del registro
SBIC   Saltar si el bit en el registro de E / S no se encuentra
Prueba el estado de las entradas y descarta la siguiente instrucción si hay un cero en el bit del registro
CBI     limpia el bit del registro de E / S
Envía un cero a la salida indicada
SBI     setea el bit del registro de E / S
Envía un uno a la salida indicada

PROGRAMA
/*
 * ejemplo2.asm
 *
 *  Created: 02/11/2013 18:20:21
 *   Author: NEBURESS.KYLL
 */ 

 .device ATMEGA48
 .include "C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRAssembler\2.1.51.64\avrassembler\include\m48def.inc"

 .def var = r16

 rjmp INIT

 INIT:
 ldi var,0xf0   ;salida nibble alto - entradas nibble bajo
 out DDRD,var   
 sbi PORTD,0
 ldi var,0x0f   ;entradas nibble alto - salidas nibble bajo
 out DDRB,var
 sbi PORTD,2

 start:
 ;apaga o prende la salida PB2
sbis PIND,0            ;prueba si esta presionada la entrada de no ser así realiza la sentencia siguiente
sbi    PORTB,2
sbic PIND,0           ;prueba si esta presionada la entrada de ser así realiza la sentencia siguiente
cbi PORTB,2
 ;apaga o prende la salida PD4
sbic PIND,2           ;prueba si esta presionada la entrada de ser así realiza la sentencia siguiente
sbi    PORTD,4
sbis PIND,2           ;prueba si esta presionada la entrada de no ser así realiza la sentencia siguiente
cbi PORTD,4
rjmp start 

       

sábado, 2 de noviembre de 2013

APRENDIENDO ENSAMBLADOR

En esta ocasión se realizara una pequeño ejemplo de como programar un microcontrolador AVR en lenguaje ensamblador, el propósito de este es conocer el funcionamiento de este tipo de programación así como de observar sus ventajas en comparación con los lenguajes de alto nivel tales como C.

El programa que se les mostrara es muy sencillo únicamente cambia de estado las salidas de los puertos B y D pero, el aprendizaje este tipo de programación es muy importante en la ingeniería sobretodo a la hora de disminuir el tamaño de un programa y reducir la carga en el microcontrolador.

DESCRIPCIÓN:

  El programa comienza de forma similar a como programamos en C, declaramos el dispositivo que estamos utilizando y la directiva .include donde agregamos el contenido del archivo a nuestro programa, en este caso incluimos el correspondiente a nuestro microcontrolador, en nuestro caso el ATMEGA48.
  Una vez realizado todo esto definimos una variable a uno de nuestros registros de propósito general
el cual nos permitirá definir salidas y cambiar el estado de nuestros puertos.
  A continuación se ingresa al label Init donde definiremos nuestras salidas, en este caso definimos como salidas todo el puerto B y D, ademas de que determinamos el valor inicial que presentaran. 
Para finalizar en la ingresamos al label start que es el equivalente a nuestro main en C, donde indicamos que el puerto B presente el numero hexadecimal 0xDD.

Alguna duda pueden ingresarla en los comentarios.

/*
 * por1.asm
 *
 *  Created: 02/11/2013 13:49:46
 *   Author: NEBURESS.KYLL
 */ 

 .device ATMEGA48
.include "C:\Program Files (x86)\Atmel\Atmel Studio6.0\extensions\Atmel\AVRAssembler\2.1.51.64\avrassembler\include\m48def.inc"

 .def temp =r16



 RJMP Init

 Init: ldi temp,0xFF
out DDRB,temp
ldi temp,0xFF
out DDRD,temp

ldi temp,0xAA
out PORTB,temp
ldi temp,0xF4
out PORTD,temp

start:
ldi    temp,0xDD
out   PORTB,temp
rjmp start

SIMULACIÓN EN PROTEUS


SIMULACIÓN EN ATMEL STUDIO IDE