Vistas de página en total

jueves, 22 de septiembre de 2011

Comparación de microcontroladores:

AVR de Atmel:

Los AVR son una familia de microcontroladores RISC de Atmel. El AVR es una CPU de arquitectura Harvard. Tiene 32 registros de 8 bits.
El AVR fue diseñado desde un comienzo para la ejecución eficiente de código C compilado. Como este lenguaje utiliza profusamente punteros para el manejo de variables en memoria, los tres últimos pares de registros internos del procesador son usados como punteros de 16 bit al espacio de memoria externa, bajo los nombres X, Y y Z.

Distintos tipos de microcontroladores:

-8bits TinyAVR ( es muy pequeño en memoria y cantidad de pines)
-8bits megaAVR (es un microcontrolador grande en memoria y cantidad de pines)
-8/16bits (es un microcontrolador muy grande en memoria y cantidad de pines)
-32bits AVR UC3 ( es un microcontrolador muy potente)
-microcontroladores para manejo de baterias ( para usos especiales)
-microcontroladores para la industria automotriz ( para usos especiales tambien)

Los AVR son microcontroladores rapidos , ya que no dividen la frecuencia del timer , y ademas favorecen al ahorro de energía. Su desventaja es que son muy dificiles de conseguir en argentina.

Tomemos como ejemplo el microcontrolador ATmega8 , ya que es el mas característico , asi como el 16F84 para microchip , o el GP32 para Freescale.

Caracteristicas:

-Arquitectura RISC avanzada
 130 intrucciones ; 1 por cada ciclo de clock.
 32x8 registros de propósito general
 Hasta 16 MIPS(millones de instrucciones por segundo) a 16MHz
-8 Kb de memoria Flash
-0,5 Kb de memoria EEPROM
-1 Kb de memoria RAM
-23 pines de entrada/salida
-18 interrupciones (2 en pines de entrada/salida)
-3 puertos 
-Arquitectura Harvard
-40 mA como máximo por pin , en modo source y sink
-300mA como máximo entre la suma de todos los bancos
-No posee arquitectura completamente ortogonal
-No posee banco
-6V como tensión máxima que puede soportar

Periféricos ATmega8:

-2 temporizadores /contadores de 8 bits con pre-escala y un modo de comparación
-1 temporizador / contador de 16 bits con pre-escala y un modo de comparacion y de captura
-RTC(real time counter)
-3 canales PWM
-ADC de 8 canales (TQFP y QFN/MLF) con los bits de precision
-ADC de 6 canales (PDIP) con los bits de precisión.
-TWI (two - wire interfae) (tambien conocido como I2C)
-Ustart

-Power on Reset y Brown-out
-Oscilador RC interno calibrado
-Interrupciones internas y externas 
-Bits de seguridad /bloqueo
-Modos de ahorro de energía

Herramientas de programación:

-Programadores
            AVRDUDE
PONYPROGE
-Compiladores
GNUToolChain
Siml-ación:
SimulAVR + GDB
Entornos Gráficos
Code::Bocks
Eclipse Plugin AVR


Cuando se genera un archivo con el compilador , en esta marca se llama .elf


Freescale (antiguamente MOTOROLA):
Tomemos como ejemplo el microcontrolador GP32 , que es uno de los mas comunes y mas "fáciles" de conseguir. ( estos microcontroladores son difíciles de conseguir en nuestro país):


-Características:
100 Veces más rápido
Fácil programación
Es de 8/16Bits
Posibilidad de multiplicar y dividir ( en los de otras empresas esto no es posible
Se comunica fácilmente con otros microcontroladores
Funciona entre -40°C  a 85°C
Posee 512Mb de memoria RAM
Posee memoria EEPROM de 32K
Modo Stand-By
Tiene puerto SERIE
Tiene una memoria sin bancos
Arquitectura Von Neumann
Memoria de Datos y Memoria de Programa en el mismo lugar (lo que provoca que el Bus no pueda mandar un código e ir buscando otro al mismo tiempo).
Memoria Flash: 32K
Divide por 4 la frecuencia del oscilador
15mA como corriente máxima en modo sink y source
Cuando se genera un archivo resultante con el compilador este sera .S19

Estas son algunas de las diferencias del código de freescale;

$ = numero hexadecimal
% = numero binario
# = el numero que le sigue se toma como una posición de memoria
#[ = escribir un literal
mov      #{ XXXXXXX} , Y ( lo que esta entre llaves lo pone en 1 . Lo que esta despues de la coma , es de que registro lo extrae
* = a continuación se escribira un comentario
1 = salida
0 = entrada
mov    #$23 , T1MODL ( en este caso primero se marca lo que voy a mover , y luego donde)
Cuando al final del numero hay una T, quiere decir que esta en base decimal

Con estos microcontroladores , no es necesario programar directamente el microcontrolador , si no que podemos programar el butloader , que significa que el micro esta siendo programado , mientras esta siendo utilizado.
Posee un Timer : Cuando el contador que tiene , llega a los ciclos que configuramos , se produce la interrupción que hayamos determinado. Esto es causa del desborde que se produce ( se produce un flag (es un bit dentro de un registro que automáticamente se pone en 1) , y llama a la subrutina). Los pulsos provienen del clock.
La ventaja de los programas de Freescale es que no necesitamos un delay para realizar instrucciones en el programa principal

jueves, 15 de septiembre de 2011

Act 5: Contador - Sistemas secuenciales (Parte B)

Circuito esquemático :

Circuito de contador en PCB:


 Programa en C para el contador en el PIC12F683



#include <main.h>



void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_8MHZ);

   while(!input(PIN_A3));

  

output_a (0b011001);
delay_ms (1000);
output_a (0b011000);
delay_ms (1000);
output_a (0b001111);
delay_ms (1000);
output_a (0b001110);
delay_ms (1000);
output_a (0b001101);
delay_ms (1000);
output_a (0b001100);
delay_ms (1000);
output_a (0b001011);
delay_ms (1000);
output_a (0b001010);
delay_ms (1000);
output_a (0b001001);
delay_ms (1000);
output_a (0b101000);
}


Otra forma de realizar el mismo programa , pero con vectores es :

#include <main.h>


void main()
{
   int secuencia[] = {0b011001, 0b011000, 0b001111, 0b001110,
                   0b001101, 0b001100, 0b001011, 0b001010,
                   0b001001, 0b101000};
   
   int i;

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_8MHZ);


   while(!input(PIN_A3));

   for (i=0; i < 10; i++) {
      output_a (secuencia[i]);
      delay_ms (1000);
   }
}

Foto del circuito en el protoboard:

Video del programa para comprobar que funciona en el Proteus.



miércoles, 14 de septiembre de 2011

Hola Mundo!

;====================================================================
; Programa principal
;====================================================================
Main
call LCD_Inicializa
call Retardo_1ms
movlw 'H'
call LCD_Caracter
movlw 'o'
call LCD_Caracter
movlw 'l'
call LCD_Caracter
movlw 'a'
call LCD_Caracter
movlw ' '
call LCD_Caracter
movlw 'M'
call LCD_Caracter
movlw 'u'
call LCD_Caracter
movlw 'n'
call LCD_Caracter
movlw 'd'
call LCD_Caracter
movlw 'o'
call LCD_Caracter
movlw '!'
call LCD_Caracter
goto $
;==================================================================== 
END ;Directiva que indica la finalización del pgm
Aclaración:
En la libreria LCD_4BIT.INC , modificamos en la parte de Subrutina "LCD_Inicializa" lo siguiente : 
(Esto se realizó para no tener problemas con la frecuencia del LCD y estar modificando la frecuencia del microcontrolador):



; Subrutina "LCD_Inicializa" ------------------------------------------------------------
;
; Inicialización del módulo LCD: Configura funciones del LCD, produce reset por software,
; borra memoria y enciende pantalla. El fabricante especifica que para garantizar la
; configuración inicial hay que hacerla como sigue:
;
LCD_Inicializa
bsf STATUS,RP0 ; Configura las líneas conectadas al pines RS,
bcf LCD_PinRS ; R/W y E.
bcf LCD_PinEnable
bcf LCD_PinRW
bcf STATUS,RP0
bcf LCD_PinRW ; En caso de que esté conectado le indica
; que se va a escribir en el LCD.
bcf LCD_PinEnable ; Impide funcionamiento del LCD poniendo E=0.
bcf LCD_PinRS ; Activa el Modo Comando poniendo RS=0.
call Retardo_20ms
movlw b'00110000'
call LCD_EscribeLCD ; Escribe el dato en el LCD.
call Retardo_5ms
movlw b'00110000'
call LCD_EscribeLCD
call Retardo_200micros
movlw b'00110000'
call LCD_EscribeLCD
call Retardo_20micros ; NUEVO
movlw b'00100000' ; Interface de 4 bits.
call Retardo_20micros ; NUEVO
call LCD_EscribeLCD



La parte señalada en amarillo es la que fue agregada a esta subrutina.

jueves, 25 de agosto de 2011

Proyecto Multímetro inalámbrico


Explicación del proyecto:
El proyecto que tuvimos que realizar es un voltimetro inalambrico. Este proyecto se divide en 2 placas que funcionan de la siguiente manera: una toma el valor de tension en el potenciometro y lo convierte a valores binarios (unos y ceros) para luego trasmitirlos a través de un led infrarrojo( que es el que conmunmente podemos encontrar en un control remoto de un television , dvd , etc). La otra placa debe recibir este codigo binario , transformarlos a valores de tensión (o analñogicos) y mostrarlos en una pantalla de lcd de 16x2.

Protocolo utilizado: Para poder transmitir un valor de tension y poder "traducirlo" del otro lado, es necesario establecer un protocolo , para poner de acuerdo qué va a ser un valor , y qué va a ser otro valor. Un ejemplo sencillo seria el de dos barcos que se ven enfrentados a distancia. El único elemento que poseen es una linterna. Un barco , prende y apaga esa linterna 5 veces , y entre ellos entienden que al prender y apagar esa linterna , significa que un barco va a atacar a otro. En cambio , si prende y apaga la linterna 10 veces , los dos barcos saben que uno se va a retirar. Eso es establecer un protocolo , comunicarse a partir de algo que dos objetos ya tienen definido de antemano.
En nuestro caso , un 1 , en codigo binario , equivaldría a 15 pulsos de una señal cuadrada , para la cual el tiempo de estado en alto es de 13 microsegundos , y el de estado en bajo es de otros 13 microsegundos , lo que genera una frecuencia de aproximadamente 38Mhz , que es a la que el receptor trabaja y reconoce las señales mandadas correctamente. Estos unos y ceros son los conseguidos en la conversión de tensión de potenciómetro , los cuales son mandados de a uno por vez, por ejemplo si medimos 5V y al convertirlo se transforma en 10100101, el transmisor primero mandara un 1 , despues un 0 , despues un 1 , y asi sucesivamente. .



Restricciones a tener en cuenta:
1)La unidad Tx transmite el valor analógico al Rx ; y éste lo muestra en el LCD

2)La transmisión se realiza cuando se pulsa Tx

3)El alcance no debe ser menor a 2 metros(en línea recta)

4)Al conectar el Rx se debe leer : "Sistema Tx Rx por IR" durante 5 segundos , y luego mostrar el úmtimo valor enviado por el Tx

5)Se debe mostrar la tensión medida en la entrada del PIC12F683(Va)

Otras utilidades:
Quizás al no tener muchos conocimientos sobre la electrónica , hablar de tensión en un potenciometro , y poder verlo en una pantalla no posee mucho interés. Pero podríamos en lugar de medir tensión , colocarle un sensor de temperatura. Esto nos serviría por ejemplo para poder colocar este sensor fuera de la casa, en un balcón por ejemplo , y poder medir a través de un vidrio la temperatura que hay fuera de nuestra casa.
Cabe aclarar que el funcionamiento de los controles remotos se basa en este tipo de comunicación por inflarrojo , asique de alguna manera podríamos diseñar un control para poder controlar las velocidades de un ventilador , su pendido o su apagado; o apagar una luz a la distancia
Circuito esquemático de la parte de Transmisión:
Plaqueta de la parte de Transmisión:



Imagen de la cerigrafía espejada

Imagen de las pistas de la placa

Circuito esquemático de la parte de Recepción y LCD 

PCB la parte de Recepción y LCD

Diagrama de pistas


Imágenes para imprimir sobre la plaqueta 







Programa de transmision:


; Configuro Registros

bank0
clrf GPIO ;Borro el puerto y configuro las
movlw 0x07 ;entradas anulando los comparadores
movwf CMCON0
bank1
clrf ANSEL ; I/O digitales
movlw B'00001000' ; GP5=GP4=GP2=GP1=GP0/Salidas
movwf TRISIO ; GP3=Entradas
movlw 0x70 ; Clock Interno a 8 MHz
movwf   OSCCON
clrf OPTION_REG ; Pullup habilitado GPPU (general)
movlw 0x36
movwf WPU ; Pullups individuales habilitados
bank0              ; Hay que pullupear GP3 externamente
bcf     LED_IR_OUT ; Apago el led IR



; Programa principal

Conversion
banksel TRISIO
bsf TRISIO,0
banksel ANSEL
movlw b'01110001'
iorwf ANSEL
banksel ADCON0
movlw b'10000001'
movwf ADCON0
call Retardo_1ms
bsf ADCON0,GO
btfsc ADCON0,GO
goto $-1
banksel ADRESH
movf ADRESH,W
movwf RESULTHI
banksel ADRESL
movf ADRESL,W
movwf valor_ADC





movlw .8
movwf contador                    ;le doy el valor 8 a contador

Aca

bcf STATUS,C                   ;pongo el Carry en cero
movf constante
movwf valor_ADC
rlf valor_ADC,F                  ;roto a la izquierda el resultado de la conversion
btfss STATUS,C                  ;pregunto si el Carry esta en 1 , si lo esta , vaya a TX_uno , sino a TX_cero
goto TX_cero
goto TX_uno
ABC
decfsz contador,F                 ;decremento la variable contador en 1
goto Aca
goto Conversion
TX_uno
movlw .30
movwf constante2 ;le doy el valor 30 a constante 2
M
bsf     LED_IR_OUT            ;pongo en 1 la  GP2
goto $+1
goto $+1                              ;genero retardo
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
bcf LED_IR_OUT         ;pongo en 0 GP2
goto $+1
goto $+1
goto $+1
goto $+1 ;genero retardo
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
decfsz constante2                                ;decremento constante2 en uno, si esta en 1 repito lo de abajo de M
goto M
call Retardo_10ms
goto ABC                                           ;vuelvo a repetir todo

TX_cero
movlw .15
movwf constante1 ;le doy el valor 15 a constante1
A
bsf     LED_IR_OUT         ;pongo en 1 GP2
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1                                              ;genero retardo
 goto $+1
goto $+1
 goto $+1
 goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
bcf LED_IR_OUT         ;pongo en 0 GP2
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1                                             ;genero retardo
 goto $+1
goto $+1
 goto $+1
 goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
decfsz constante1 ;decremento constante1 y si no esta en 0 ,repito lo de abajo de A
goto A
call Retardo_10ms                              ;retardo      
goto ABC ;vuelvo a ABC para hacer el procedimiento de vuelta


        #include <RETARDOS.INC>

END

Hojas de Datos:
Pic 16f84a   http://ww1.microchip.com/downloads/en/devicedoc/35007b.pdf
Pic 12f683  http://ww1.microchip.com/downloads/en/devicedoc/41211d_.pdf
IRM 8501  http://www.alldatasheet.com/datasheet-pdf/pdf/109788/ETC/IRM8602.html


INDEXADO_02

En lenguaje ASSEMBLER

;====================================================================
; Programa principal
;====================================================================
ABC 
movf  PORTA,W 
andlw b'00000111' 
addwf PCL,F 
goto  VACIO 
goto  LLENANDOSE 
goto  ALARMA_A 
goto  LLENO 
goto  ALARMA_B 
goto  ALARMA_C 
goto  ALARMA_D 
goto  REBOSE 


VACIO 
movlw b'1100001' 
goto  XYZ  


LLENANDOSE 
movlw b'1100010' 
goto  XYZ 


ALARMA_A 
movlw b'10000' 
goto  XYZ 


LLENO 
movlw b'100100' 
goto  XYZ 


ALARMA_B 
movlw b'10000' 
goto  XYZ 


ALARMA_C 
movlw b'10000' 
goto  XYZ 


ALARMA_D 
movlw b'10000' 
goto  XYZ 


REBOSE 
movlw b'1000' 


XYZ 
movwf PORTB 
goto  ABC



DE OTRA MANERA:
; Definiciones y Equivalencias
;====================================================================
#DEFINE SV PORTA,0 ;SV es RA0 
#DEFINE SLL PORTA,1 ;SLL es RA1
#DEFINE SR PORTA,2 ;SR es RA2
#DEFINE VACIO PORTB,0 ;VACIO es la pata RB0
#DEFINE LLENANDOSE PORTB,1 ;LLENANDOSE es RB1
#DEFINE REBOSE PORTB,2 ;REBOSE es RB2
#DEFINE LLENO PORTB,3 ;LLENO es RB3
#DEFINE ALARMA PORTB,4 ;ALARMA es RB4
#DEFINE BOMBA1 PORTB,5 ;BOMBA1 es RB5
#DEFINE BOMBA2 PORTB,6 ;BOMBA2 es RB6


;====================================================================
; Programa principal
;====================================================================
ABC 


VACIADO
btfsc SR ;Verifica el estado de SR para ver si esta en 0
goto REBOSE1
btfsc SLL ;Verifica si SLL esta en 0
goto LLENO1
btfsc SV ;Verifica el estado de SV para ver si esta en 0
goto LLENADO
bsf VACIO ;deja en 1 a VACIO
bsf BOMBA1 ;activa la bomba 1
bsf BOMBA2 ;activa la bomba 2


LLENADO
    clrf    PORTB ;Deja todo el PUERTOB en 0
btfsc SV ;Verifica si SV esta en 0
goto    LLENO1
bcf VACIO ;Deja a VACIO en 0
bsf BOMBA1 ;Activa la bomba 1
bsf BOMBA2 ;Activa la bomba 2
bsf LLENANDOSE ;Activa LLENANDOSE


LLENO1
btfsc SLL ;Verifica si SLL esta en 0
goto REBOSE1
bcf LLENANDOSE ;Apaga LLENANDOSE
bsf BOMBA1 ;Prende bomba 1
bcf BOMBA2 ;Apaga bomba 2
bsf LLENO

REBOSE1
btfsc SR ;Verifica si ST esta en 0
goto ALARMA1
bcf BOMBA1 ;Apaga bomba 1
bcf LLENO ;apaga LLENO
bsf REBOSE ;Prende REBOSE
goto ABC


ALARMA1
bsf ALARMA ;Enciende ALARMA
bcf BOMBA1 ;Apaga bomba 1
bcf BOMBA2 ;Apaga bomba 2


;====================================================================
END ;Directiva que indica la finalización del pgm





En lenguaje C




#include "C:\Problema\problema.h"




void main()
{
while(1){


switch (input_a()){
   case 0:
    output_b(0b01100001);
    break
   case 1:
    output_b(0b01100010);
    break
   case 2:
    output_b(0b00010000);
    break
   case 3:
    output_b(0b00100100);
    break
   case 4:
    output_b(0b00010000);
   case 5:
    output_b(0b00010000);
    break
   case 6:
     output_b(0b00010000);
    break
   case 7:
    output_b(0b00001000);
    break


}