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


jueves, 31 de octubre de 2013

MUESTREO DE SEÑALES

El siguiente programa tiene como objetivo mostrar una forma de realizar el muestreo de señales analógicas para sistemas de control digital, haciendo uso del timer0, interrupción por desbordamiento, el uso del ADC en modo free running, ademas de utilizar el UART para capturar los datos por medio de un programa externos como SCILAB, MATLAB o mediante hiperterminal.

DESCRIPCIÓN:

El timer realiza una interrupción por desbordamiento cada 800 microsegundos, una vez realizada entrado a la interrupción se lee el canal ADC0  y se guarda en una variable char sin signo, posteriormente se envia a través de la UART la cual esta configurada con un baud rate de 19200, sin paridad, enviando 8 bits de datos, con dos bits de stop.

El programa se compone del programa principal ademas de dos librerías para el control de la UART y el ADC los cuales agregare al final para que puedan descargarlos junto con su simulación en proteus.

Alguna duda pueden preguntar en los comentarios

Aquí les muestro el programa principal

/*
 * COMUNICATION2MEGA.c
 *
 * Created: 27/10/2013 12:31:42
 *  Author: NEBURESS.KYLL
 */
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <avr/io.h>
#include "InitADC.h"
#include "UARTAiNit.h"
#include <avr/interrupt.h>
#define bitclear(sfr,bit)(_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bitset(sfr, bit)(_SFR_BYTE(sfr) |= (_BV(bit)))
#define togglebit(sfr,bit)(_SFR_BYTE(sfr)^=(_BV(bit)))

ISR(TIMER0_COMPA_vect){
//ADC y RS232
unsigned char n;
n=convADC();
TransmiteUART0(n);

/*LA ULTIMA PARTE ES PARA OBSERVAR EL FUNCIONAMIENTO DEL ADC SI DESEA PUEDE QUITAR ESTA PARTE*/
if (n>140) bitset(PORTB,PORTB0);
else bitclear(PORTB,PORTB0);
}

void TEMPORIZADOR(){
//PREESCALER DEL TIMER0 A 64
bitclear(TCCR0B,CS02);
bitset(TCCR0B,CS01);
bitset(TCCR0B,CS00);
//DESCONECTAR OC0A
bitclear(TCCR0A,COM0A1);
bitclear(TCCR0A,COM0A0);
//MODO CTC
bitclear(TCCR0B,WGM02);
bitset(TCCR0A,WGM01);
bitclear(TCCR0A,WGM00);
OCR0A=99;
}

void INTERRUPCION(){

bitset(TIMSK0,OCIE0A);
sei();
}

int main(void)
{

bitset(DDRB,DDB0);
TEMPORIZADOR();
INTERRUPCION();
initializeUART0(19200,0,8,2,2);
canalADC(0);
initADC(2,1,5);

    while(1)
    {
        //TODO:: Please write your application code



    }
}


Posteriormente publicare el programa donde podrán observar los datos obtenidos mediante el software scilab.

Les agrego el link de un archivo que hace mención sobre consideraciones que se deben tomar a la hora de seleccionar un capacitor bypass, considero que es de gran ayuda que lo lean debido a su importancia en el desarrollo de practicas donde se deben de compensar ruido y descompensaciones  dentro de los circuitos que son fallos frecuentes dentro de la ingeniería.

LINK CAPACITORES BYPASS

http://www.intersil.com/content/dam/Intersil/documents/an13/an1325.pdf

LINK PROGRAMA

https://mega.co.nz/#!41MHnKzT!EfPiuwr67CZeioVq5VBgMXbYJXA4aOQSJeHCbORGwcg





miércoles, 30 de octubre de 2013

CONTROL DE SERVOMOTOR CON TIMER1


A continuación el siguiente programa mostrara una manera sencilla de controlar un servomotor con ayuda de un potenciometro y el uso de los timers 0 y 1.

DESCRIPCIÓN:

El timer0 realizara una interrupción cada 32,7 ms aproximadamente para lo cual se utilizo el timer en modo normal con lo cual realizara la lectura del canal 0 del ADC y el resultado de la conversión la almacenara en OCR1A con lo que el servo motor cambiara de posición así como su velocidad. El timer1 esta configurado para que el pin PB1 controle al servomotor proporcionando una frecuencia de 50Hz y un ancho de pulso variable determinado por el potenciometro.

Al final agregare el link para que puedan descargar el programa y su simulación.

/*
 * servo_timer1.c
 *
 * Created: 30/10/2013 14:23:13
 *  Author: NEBURESS.KYLL
 */


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <avr/interrupt.h>
#define bitclear(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bitset(sfr,bit) (_SFR_BYTE(sfr) |= (_BV(bit)))
#define togglebit(sfr,bit) (_SFR_BYTE(sfr)^=(_BV(bit)))

unsigned char SERVO_VEL(){

//LEER
bitset(ADCSRA,ADSC);
while(!(ADCSRA&&(1<<ADIF))){}
return ADCH;
}
//interrupción cada 32.7ms
ISR(TIMER0_OVF_vect)
{
//MUEVE MOTOR
    OCR1A=SERVO_VEL();
}
//inicializacion del timer0
void initimer0(){
//PREESCALAMIENTO 1024
bitset(TCCR0B,CS02);
bitclear(TCCR0B,CS01);
bitset(TCCR0B,CS00);
//MODO NORMAL
bitclear(TCCR0B,WGM02);
bitclear(TCCR0A,WGM01);
bitclear(TCCR0A,WGM00);

TCNT0=0;
}
//habilitación de la interrupción del timer0 en modo normal
void interrupcion(){

bitset(TIMSK0,TOIE0);
sei();
}


//habilitación de fast pwm para control de servomotor
void PWM(){
//SALIDA NO INVERTIDA FAST PWM
bitset(TCCR1A,COM1A1);
//FAST PWM
bitset(TCCR1B,WGM13);
bitset(TCCR1B,WGM12);
bitset(TCCR1A,WGM11);
//PREESCALER 64
bitset(TCCR1B,CS11);
bitset(TCCR1B,CS10);
ICR1=2499;
}
//habilitación de canal 0 del ADC
void INITADC(){
//FUENTE DE VOLTAJE
bitclear(ADMUX,REFS1);
bitset(ADMUX,REFS0);
//CANAL 0
bitclear(ADMUX,MUX3);
bitclear(ADMUX,MUX2);
bitclear(ADMUX,MUX1);
bitclear(ADMUX,MUX0);
//JUSTIFICADO A LA DERECHA
bitset(ADMUX,ADLAR);
//PREESCALER DE 64
bitset(ADCSRA,ADPS2);
bitset(ADCSRA,ADPS1);
//HABILITAR ADC
bitset(ADCSRA,ADEN);
}

int main(void)
{
bitset(DDRB,DDB1);
interrupcion();
initimer0();
INITADC();
PWM();

    while(1)
    {
   
    }
}

LINK

https://mega.co.nz/#!818nmTRC!dfNNvToziWGWHdZaeFjG4AhruecWmCZxs2PDdyVcDDQ