viernes, 22 de mayo de 2015

usando printf y scanf en avrgcc con ATmega48

El siguiente codigo hace uso de la libreria usart.h y usart.c que estaban disponibles en el sitio de programacion de microcontroladores AVR de Shawn Johnson Lo interesante de este ejemplo, es el uso de las funciones estandar de C printf y scanf para el envio de cadenas preformateadas a través del puerto serie de este microcontrolador.
A continuación se muestran las fuentes utilizadas para este tipo de comunicacion
/*
 * En las opciones de compilación del linker
 * se deben agregar las siguientes lineas en eclipse
 *
 * -Wl, -u, vfprintf -lprintf_min, -u, vfscanf -lscanf_min -lm
 *
 * En la siguiente ruta
 * Propiedades del proyecto
 *  C/C++ Build
 *   Valores
 *    Toolsettings
 *     AVR C Linker
 *      General

  En codebloacks
Para agregarlas solo da clic derecho en el nombre del proyecto
elige la opcion que dice Properties....
En la ventana que se abre, da clic en el boton Project's Build options...
Te abre una nueva ventana
Da clic en el Tab Linker Setting
y del lado izquierdo encuentras las opciones del linker
quedan de la siguiente manera
-mmcu=atmega48
-Wl,-Map=$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).map,--cref
-u
vfprintf -lprintf_min
-u
vfscanf -lscanf_min -lm
 * */


#include <avr/io.h>
#define F_OSC 1000000UL
#include <util/delay.h>

#include "usart.h"

int main(void)
{
 char name[30];

 usart_init();

 puts("\n\r Enviando datos");
 puts("\n\r Mecatronica\n\r ITST\n\r");

 puts("Como te llamas?:\n\r");
 scanf("%s\n\r", name);

 printf(" Hola %s",name);

 while(1);
}

Librerias

/******************************************************************************
 * FileName:   usart.h
 * Overview:   Macros y prototipos de funciones para el USART0 en modo Asíncrono
 * Processor:  ATmel AVR con USART0
 * Compiler:   AVR IAR C y AVR GCC (WinAVR)
 * Author:     Shawn Johnson. http://www.cursomicros.com.
 *
 * Copyright (C) 2008 - 2013 Shawn Johnson. All rights reserved.
 *
 * License:    Se permiten el uso y la redistribución de este código con 
 *             modificaciones o sin ellas, siempre que se mantengan esta 
 *             licencia y las notas de autor y copyright de arriba.
 *****************************************************************************/

#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>
#include <stdio.h>
/* Define la velocidad de transmisión del USART (en bits/segundo), si aún no 
 * ha sido definida.
 */
#ifndef USART_BAUD
#define USART_BAUD  9600UL
#endif

/* Usar kbhit para ver si hay algún dato en el buffer de recepción antes de
 * llamar directamente a la función getchar para evitar esperas innecesarias.
 */
#define  kbhit()     (UCSR0A & (1<,<RXC0))

/* Descomentar el siguiente #define para que la funcion 'getchar' haga eco de
 * los caracteres recibidos.
 */
//#define __GETCHAR_ECHO__

/* Macros para AVR GCC */
#if defined( __GNUC__ )
#ifdef putchar
#undef putchar
#endif
#ifdef getchar
#undef getchar
#endif
#endif

/* Definiciones de funciones */
void usart_init(void);
int putchar(int);
int getchar(void);

/******************************************************************************
 * FileName:   usart.c
 * Overview:   Implementa funciones para el USART0 en modo Asíncrono
 * Processor:  ATmel AVR con USART0
 * Compiler:   AVR IAR C y AVR GCC (WinAVR)
 * Author:     Shawn Johnson. http://www.cursomicros.com.
 *
 * Copyright (C) 2008 - 2013 Shawn Johnson. All rights reserved.
 *
 * License:    Se permiten el uso y la redistribución de este código con 
 *             modificaciones o sin ellas, siempre que se mantengan esta 
 *             licencia y las notas de autor y copyright de arriba.
 *****************************************************************************/

#include "usart.h"

//****************************************************************************
// Inicializa el USART0.
//****************************************************************************
void usart_init(void)
{
    /* Configurar baud rate   */
    UCSR0A |= (1<<U2X0); //modo2
    UBRR0 = F_CPU/(8*USART_BAUD)-1;
    
    /* Configurar modo de operación Asíncrono y formato de frame a
     * 8 bits de datos, 1 bit de stop y sin bit de paridad.  */
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
    
    /* Habilitar módulos Receptor y Transmisor  */
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);

#if defined( __GNUC__ )
    /* Asociar las funciones 'putchar' y 'getchar' con las funciones de entrada
    * y salida (como printf, scanf, etc.) de la librería 'stdio' de AVR-GCC */
    fdevopen((int (*)(char, FILE*))putchar, (int (*)(FILE*))getchar);
#endif
}

//****************************************************************************
// Transmite el byte bajo de 'dato' por el USART
//****************************************************************************
int putchar(int dato)
{
    /* Esperar a que haya espacio en el buffer de transmisión */
    while ((UCSR0A & (1<<,UDRE0)) == 0 );

    /* Colocar dato en el buffer de transmisión */
    UDR0 = dato;
    return dato;
}

//****************************************************************************
// Recibe un byte de dato del USART
//****************************************************************************
int getchar(void)
{
    /* Esperar a que haya al menos un dato en el buffer de recepción */
    while ((UCSR0A & (1<<RXC0)) == 0 );   
    
    /* Leer y retornar el dato menos reciente del buffer de recepción */   
#if defined ( __GETCHAR_ECHO__ )
    return (putchar(UDR0));
#else
    return UDR0;
#endif
}

Paginas de referencia: http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdio_1ga67bae1ad3af79809fd770be392f90e21.html
http://www.atmel.com/webdoc/AVRLibcReferenceManual/using_tools_1using_sel_gcc_opts.html#using_tools_1gcc_minusW