sábado, 11 de marzo de 2017

WINAVR PUERTOS IO parte 1.


WinAvr nos permite acceder a los puertos de entrada y salida mediante los registros DDRx, PORTx y PINx, donde x corresponde al nombre del puerto a utilizar.

DDRx.


Es el registro que se ocupa de hacer que el puerto sea de entrada o salida según el valor que tenga.

Si los bits de DDRx son 0 entonces será de entrada y si los bits son 1 será de salida.

Ejemplo:

DDRA=0b00001111; //los bits 0 a 3 del puerto A son de salida el resto son de entrada.

PORTx.


Es el registro que escribe o lee el puerto.

Si los bits de PORTx son 0 entonces en el puerto se escribirá un nivel bajo y si los bits son 1 en puerto tendrá nivel alto.

Ejemplo:

PORTA=0b11000000; //los bits 0 a 5 tienen nivel bajo, el resto son de nivel alto (esto si el puerto es configurado como salida mediante el registro DDRA=0b11111111).

PINx.


Este registro se utiliza para efectuar la lectura de un puerto configurado como entrada.

Ejemplo:

var=PINA; //Guarda en la variable var el valor de los niveles que existe en el puerto A (esto si se configura al puerto A como entrada mediante el registro DDRA=0b00000000).

En WinAVR para tener acceso a los puertos de entrada y salida se debe incluir la librería io.h del siguiente modo.

#include <avr/io.h>

Para poder hacer uso de retardos en los programas se tiene la librería delay.h y se la llama del siguiente modo.

#include <util/delay.h>

Ejercicio 1.


Hacer un contador ascendente por el puerto D con un tiempo de retardo de 200m[s].

Solución.

Se debe configurar el puerto como salida (0b11111111=255) y luego hacer que el valor del puerto se incremente en 1.

#include <avr/io.h>     //incluye la librería para el acceso a los puertos

#include <util/delay.h>           //incluye la librería para los retardos

int main(void)                        

{

            PORTD=0;                  //borra el puerto D

            DDRD=255;               //configura todo el puerto D como salida

            while(1)

            {

                        PORTD++;                 //el puerto D se incrementa en 1

                        _delay_ms(200);         //retardo de 200ms

            }

            return 0;

}

Ejercicio 2.


Reflejar por el puerto D los valores lógicos que existen el puerto C.

Solución.

Pare este caso el puerto D debe ser configurado como salida y el puerto C como entrada y para no utilizar resistores externos, en el puerto C activaremos los pull-up internos (estos existen en todos los puertos del ATMEGA 32). Hay que tener cuidado de no manipular bit 2 (PUD) del registro SFIOR.

#include <avr/io.h>

#include <avrlib/avrlibdefs.h>

#include <util/delay.h>

int main(void)

{

            PORTD=0;      //borra el puerto D

            PORTC=255;  //habilita el pull up en el puerto C

            DDRD=255;   //puerto D como salida

            DDRC=0;        //puerto C como entrada

            while(1)

            {

                        PORTD=PINC;           //escribe en el puerto D los valores leídos en el puerto C

                        _delay_ms(10);                       //retardo de 10ms

            }

}

El acceso a los bits individuales de los puertos es algo engorroso teniendo que hacer bastante uso de los enmascaramientos pero podemos lidiar con esos problemas con la ayuda de las librerías proporcionadas por Procyon AVRlib (la manera de obtenerlos y situarlos en el lugar adecuado se mencionan en la anterior entrega titulada WINAVR 0).

La nueva librería a utilizar es avrlibdefs.h y la incluiremos del siguiente modo.

#include <avrlib/avrlibdefs.h>

Las funciones disponibles para la manipulación de bits de los puertos son:

bit_is_set(sfr, bit);       //Retorna verdadero si el bit esta a 1

bit_is_clear(sfr, bit);   //Retorna verdadero si el bit es 0

cbi(reg,bit);                 //Pone a 0 el bit

sbi(reg,bit);                 //Pone a 1 el bit

Ejercicio 3.


Hacer que el bit 1 del puerto D muestre el estado invertido del bit 5 del puerto C.





Solución.

Los puertos después del reset siempre inician como entradas así que solo hacen falta definir los puertos de salida y para no usar resistores externos utilizaremos los pull up internos del puerto C.

#include <avr/io.h>

#include <avrlib/avrlibdefs.h>

#include <util/delay.h>

int main(void)

{

            sbi(PORTC,5); //pull up activado en el bit 5 del puerto C

            sbi(DDRD,1);  //bit 1 del puerto D como salida

            while(1)

            {

                        if(bit_is_set(PINC,5))

                        {

                                   cbi(PORTD,1);

                        }

                        else

                        {

                                   sbi(PORTD,1);

                        }

                        _delay_ms(100);

            }

}

Ejercicio 4.


Efectuar un contador ascendente descendente visualizado en un display conectado al puerto B. Cuando el pin 0 del puerto A esta a nivel bajo el contador es ascendente y de otro modo el contador es descendente.

Solución.
Para generar los dígitos en el display se hará uso de un decodificador implementado en forma de vector.
#include <avr/io.h>
#include <avrlib/avrlibdefs.h>
#include <util/delay.h>
int main(void)
{
            //decodificador para el display
unsigned char tabla[]={63,6,91,79,102,109,125,7,127,103};
            unsigned char contador=0;
            PORTD=0;                  //borra el puerto D
            DDRD=255;                //puerto D como salida
            sbi(PORTA,0);            //pullup en el bit 0 del puerto D
            while(1)
            {
                        PORTD=tabla[contador];
                        _delay_ms(500);
                        if(bit_is_clear(PINA,0))
                        {
                                   if(++contador==10)    //primero incrementa contador y luego compara
                                   {
                                               contador=0;
                                   }
                        }
                        else
                        {
                                   if(--contador==255)    //primero decrementa contador y luego compara
                                   {
                                               contador=9;
                                   }
                        }
            }
            return 0;
}



Hasta la siguiente entrega.

lunes, 6 de febrero de 2017

Grabando AVRs


   GRABANDO AVRs


Cuando trabajamos con AVRs podemos encontrar muchas herramientas de software libre (WINAVR por ejemplo). En cuanto al Hardware también podemos encontrar libremente el grabador para AVRs conocido como USBasp del cual se pueden encontrar los esquemas fácilmente. En mi caso compre el grabador ya hecho a un compañero de mi facultad.

Pero con el grabador no es suficiente adicionalmente se necesita un programa que haga funcionar al grabador (USBasp), por fortuna de estos hay varios y el que me parece bastante practico es el conocido Khazama, este programa es libre y se lo puede descargar de la página del autor.


Instalando Kazama.
Instalamos y aceptamos todo lo que os pida. Una vez instalado tenemos.
Al ejecutar el programa es mejor ejecutarlo como administrador.
Luego seleccionamos el microcontrolador ATMEGA32.

Instalando controladores para USBasp.

Una vez conectado el grabador (USBasp) puede que la PC no lo reconozca por falta de los controladores. Buscando en el administrador de dispositivos tenemos.
Ahora procedemos a instalar los controladores.
Seleccionamos “buscar software del controlador en el equipo”.
Seleccionar la ruta donde se instaló khazama para mi caso fue (win10 32 bits)
C:\Program Files\khazama.com\Khazama AVR Programmer\win-driver\libusb_1.2.4.0

Luego aceptar la advertencia de software desconocido. Ahora tenemos el USBasp listo para trabajar con khazama y grabar AVRs.

Conectando USBasp al AVR.

ATMEGA32 vienen de fábrica configurado para trabajar con reloj interno de 1M[Hz] por eso el grabador USBasp tiene un pin de selección de reloj lento (Slow SCK=GND), esto puede ser molesto algún momento ya que el AVR se graba lento. Para cambiar esta situación se puede elegir un oscilador interno más rápido (16M[Hz]) o usa un cristal externo.
Importante. Si se hace uso de un cristal externo la siguiente vez que se grabe el AVR debe hacerse con el mismo cristal conectado.
Pines de conexión de USBasp y AVR.
Trabajando con khazama.

Si se instaló la versión v1.7.0 configuramos la velocidad del reloj ISP a automático.

Si se desea se puede tikear todas las opciones excepto Write Fuses and Lock esto para no tener accidentes.
Cuidado si se deshabilita el bit SPIEN al momento de grabar los fuses tendremos un caos… bueno no, solo perderemos la capacidad de grabar al AVR, para saber el real efecto de esto se puede buscar en internet.
Ahora se configurara el AVR para que trabaje con un cristal externo de 16M[Hz] para obtener la mayor velocidad de trabajo de la cpu.
Primero leemos la configuración de los fuses presionando el icono de candado cerrado presionando Read All.

Desplazándonos a la parte interior tenemos los fuses que configuran la fuente de reloj.



Una vez seleccionado se procede a grabar los fuses con el boton Write All y listo, el AVR ahora trabajara con cristal externo (16M[Hz]) la próxima vez que se desee grabar el AVR el cristal debe estar presente.
A partir de este momento ya podemos cambiar la velocidad del reloj ISP del grabador USBasp cambiando la posición del clock select, para mi caso el grabador queda asi.
Después de esto ya no tendremos la necesidad de manejar los fuses y solo nos dedicaremos a grabar nuestros programas en el AVR.

Código básico de prueba.
 Una vez creado el proyecto en WINAVR editamos el Makefile y cambiamos el valor de la F_CPU a 16M[Hz].

Una vez compilado solo queda grabar el chip.

viernes, 13 de enero de 2017

Programando con winAvr desde 0


Programando con winAvr desde 0.


WinAvr es una herramienta que nos ayuda a desarrollar programas en C para microcontroladores AVR.

Esta herramienta se basa en el compilador GCC que es de código libre y abierto.

Para iniciarnos usaremos las siguientes herramientas.

WinAvr (Compilador en C para AVR).

Parche para win 8, 10 (Reemplazar el archivo msys.dll en la directorio utils\bin de win avr)

ProcyonAVRlib (Librerías para hardware)
Cualquier programador para avr como ser USBasp

Instalando WinAvr.


Una vez que se descarga el instalador de WinAvr lo ejecutamos como administrador.


Luego seguir la instalación sin cambios.

Aplicando el parche.

Descomprimir msys-1.0.dll.

 Reemplazar el archivo msys-1.0.dll en C:\WinAVR-20100110\utils\bin

Agregando las librerías Procyon AVRlib.
Descomprimir AVRlib.
Copiar y pegar en C:\WinAVR-20100110\avr\include.
Ahora ya se tiene todo listo para programar con WinAvr.

Primer proyecto con WinAvr.

Una vez instalado Win Avr se tienen dos herramientas, una es para configurar el reloj, el uC Avr, etc., la otra es para hacer el código del programa.
Con MFile[WinAVR] en la pestaña Makefile seleccionamos el AVR (para este caso y los de mas será el atmega32).
Luego de seleccionar el uC a usar en la pestaña File guardamos sin cambiar de nombre y sin extensión en la ruta de la carpeta donde estemos haciendo el proyecto.


Con Programmers Notepad creamos el proyecto.
Ahora se puede introducir en pequeño código de prueba.
Luego guardamos el código que se hiso de preferencia con el nombre main.c


Finalmente adicionamos el archivo main.c y el Makefile.






Ahora si se desea se puede cambiar la velocidad de la cpu editando el makefile, para este lo cambiaremos a 1MHz.
Para compilar vamos a la pestaña Tools y [WinAVR]Make All y si todo está bien se tiene la siguiente respuesta.
Bien hasta aquí la primera parte sobre WinAVR, un saludo y hasta la próxima.