Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

08/03/2016 #1

Avatar de gustavo

Comunicacion serie entre dos Atmega8 ?
Hola comunidad! Queria hacerles una consulta y espero puedan ayudarme,
Estoy iniciando en la comunicacion serial, utilizo dos Atmega8 y AtmelStudio.
Lo que intento hacer es que el uC que esta programado como TX, maneje dos pulsadores(encendido y apagado) para controlar el parpadeo de los leds conectados al uC que esta programado como RX. El problema en el cual me encuentro es que al hacer parpadear los leds no puedo apagarlos, los mismos no lo hacen debido a que no puede salir del bucle y siguen parpadeando infinitamente. Les dejo el codigo y adjunto la libreria de USART que utilizo para que puedan simularlo y agradezco si puedieran ayudarme u orientarme en el error que estoy cometiendo, desde ya muchas gracias!

Saludos!



Codigo fuente: TX

Código:
/*
	Nombre: TX.c
	
*/ 

/* Configuraciones Generales */
#define  F_CPU 8000000UL 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"

/* Variables a Utilizar */				
unsigned char encender = 'a';			
unsigned char apagar = 'b';			

int main(void)
{	
	// Comunicacion serial a 4800 baudios
	SerialBegin(103);	
								
	// PC0 y PC1 como entrada
	DDRC =  (0<<PC1) | (0<<PC0);

	// Limpiamos PORTC
	PORTC = 0x00;										
	
    while(1)
    {
	// Testeo estado de PC0
	if (bit_is_clear(PINC,PC0) == 0)
	{
		// Retardo para verificar la pulsacion
		_delay_ms(50);
		
                // Testeo nuevamente PC0			
		if (bit_is_clear(PINC,PC0) == 0)
		{
			// Envio el dato "encender"
			SerialWrite(encender);	
		}				
	}
	// Testeo estado de PC1
	if (bit_is_clear(PINC,PC1) == 0)
	{
		// Retardo para verificar la pulsacion
		_delay_ms(50);

		// Testeo nuevamente PC1
		if (bit_is_clear(PINC,PC1) == 0)
	        {
			// Envio el dato "apagar"
			SerialWrite(apagar);
	        }			
	}			
    }
}

Codigo fuente: RX

Código:
/*
	Nombre: RX.c

 */ 

/* Configuraciones Generales */
#define F_CPU 8000000UL 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"

/* Variables a utilizar */
unsigned char dato_serial;
unsigned char encender = 'a';
unsigned char apagar = 'b';

int main(void)
{					
	// Comunicacion serial a 4800 baudios
	SerialBegin(103);	
				
	// Puerto C como salida
	DDRC = 0xFF;

        // Limpio PORTC
	PORTC = 0x00;	

    while(1)
    {
	// Almaceno el dato recibido en "dato_serial" 
	dato_serial = SerialRead();

	// Es igual a "encender"?
	if (dato_serial == encender)
	{
              while(true)
              {
                      // Parpadeo...
		      PORTC = 0b11111111;
		      _delay_ms(500);
		      PORTC = 0b00000000;
		      _delay_ms(500);

                      // Almaceno dato recibido en "dato_serial"
                      dato_serial = SerialRead();
                      // Es igual a "apagar"?
                      if(dato_serial == apagar)
                      {
                            PORTC = 0b00000000;
                            // Salgo...
                            break;
                      }
              }
	}
    }
}
08/03/2016 #2

Avatar de Scooter

Entierra bien hondo los delays del demonio y no los uses mas. Usa timers e interrupciones que están para eso. Lo mismo con el puerto serie.
Si estás haciendo una cosa no puedes hacer otra. Solución no hagas lo que no hace falta hacer, pones un timer y mientras llega la interrupción haces otra cosa, activas las interrupciones del puerto serie y mientras llega o no llega algo haces otra cosa.
08/03/2016 #3

Avatar de locodelafonola

gustavo dijo: Ver Mensaje
Hola comunidad! Queria hacerles una consulta y espero puedan ayudarme,
Estoy iniciando en la comunicacion serial, utilizo dos Atmega8 y AtmelStudio.
Lo que intento hacer es que el uC que esta programado como TX, maneje dos pulsadores(encendido y apagado) para controlar el parpadeo de los leds conectados al uC que esta programado como RX. El problema en el cual me encuentro es que al hacer parpadear los leds no puedo apagarlos, los mismos no lo hacen debido a que no puede salir del bucle y siguen parpadeando infinitamente. Les dejo el codigo y adjunto la libreria de USART que utilizo para que puedan simularlo y agradezco si puedieran ayudarme u orientarme en el error que estoy cometiendo, desde ya muchas gracias!

Saludos!
hola ., bueno por empezar tambien tendrias que publicar el esquema de coneccion de los dos atmega
Scooter dijo: Ver Mensaje
Entierra bien hondo los delays del demonio y no los uses mas. Usa timers e interrupciones que están para eso. Lo mismo con el puerto serie.
Si estás haciendo una cosa no puedes hacer otra. Solución no hagas lo que no hace falta hacer, pones un timer y mientras llega la interrupción haces otra cosa, activas las interrupciones del puerto serie y mientras llega o no llega algo haces otra cosa.
querido amigo ., tenes toda la razon., con los delay
pero me suena a codigo de arduino ., aca subo dos tutoriales con el uso de la USART
y tambien ., por lo general se usa una frecuencia de BUIDOS de 9600 ., y en el codigo no es esa (en el tuto explicaca como)
ACLARACION : los tutos no son de mi autoria ., pero es de un integrante de ATMEL CORPORACION ., yo solo los traduje al castellano ., y tengo permiso del autor a publicarlos libremente
Archivos Adjuntos
Tipo de Archivo: pdf tutorial manejo de interupciones de la USART.pdf (62,7 KB (Kilobytes), 11 visitas)
Tipo de Archivo: pdf tutorial manejo de la USART.pdf (67,4 KB (Kilobytes), 10 visitas)
08/03/2016 #4

Avatar de Scooter

A mi también me ha sonado a arduino más que a C. No estoy muy puesto en C.
08/03/2016 #5

Avatar de John Miller

gustavo dijo: Ver Mensaje
Hola comunidad! Queria hacerles una consulta y espero puedan ayudarme,
Estoy iniciando en la comunicacion serial, utilizo dos Atmega8 y AtmelStudio.
Lo que intento hacer es que el uC que esta programado como TX, maneje dos pulsadores(encendido y apagado) para controlar el parpadeo de los leds conectados al uC que esta programado como RX. El problema en el cual me encuentro es que al hacer parpadear los leds no puedo apagarlos, los mismos no lo hacen debido a que no puede salir del bucle y siguen parpadeando infinitamente. Les dejo el codigo y adjunto la libreria de USART que utilizo para que puedan simularlo y agradezco si puedieran ayudarme u orientarme en el error que estoy cometiendo, desde ya muchas gracias!

Saludos!
Hola buen día. Una leída no está de sobra: http://microcontroladores-mrelberni....-avr-ejemplos/

http://winavr.scienceprog.com/exampl...ntrollers.html

MAKI.
08/03/2016 #6

Avatar de locodelafonola

¡¡¡ BRUJO !!!! con los delay jajajajajajajajajaja
Scooter dijo: Ver Mensaje
A mi también me ha sonado a arduino más que a C. No estoy muy puesto en C.
en efecto amigo Scooter ., me sonaba a arduino ., pero la primer parte me compilo bien (TX)
ahora la segunda parte (RX) ., mmmmmmm ., encontre varios errores
solo repare para poder compilar ., y poder simular (traceo de linea por linea de ejecucion) el error que marcaba era
lo que faltaba era una enumeracion o definicion de funcion en el while y le agregue esta definicion
Código PHP:
enum {FALSE=0TRUE=1}; 
bueno a partir de alli ., me compilo correctamente y sin error
pero aqui viene lo interesante ., el traceo del compilador se detiene en un !!!!! DELAY ¡¡¡¡¡ jajajaja ., es aca
el programa corre perfecto y sin problemas hasta aqui
o sea que los problemas son los delay ., lo curioso es que el compilador se para ., justo donde explica el consultante
pero nunca podria haber complado por el otro error ., y si la libreria no estaba correcta ¿¿¿ como probo en el simulador virtual ???
conclucion : aca falta algo o nunca probo ., y como dijo Scooter ., lo delay no van., osea habria que arreglar esto
Código PHP:
 while(TRUE)
              {
                      
// Parpadeo...
              
PORTC 0b11111111;
              
_delay_ms(500);
              
PORTC 0b00000000;
              
_delay_ms(500); 
hola
Makitronica dijo: Ver Mensaje
Hola buen día. Una leída no está de sobra: http://microcontroladores-mrelberni....-avr-ejemplos/

http://winavr.scienceprog.com/exampl...ntrollers.html

MAKI.
gracias por la info ., nunca esta demas ., mas cuando uno no usa arduino ., sino atmega y AVRstudio
tambien subo los dos proyectos completos ., en AVRStudio 4.13 ., se abren con la extencion .aps (como en todos los AVRstudio de ATMEL) ., no importa su vercion
Imágenes Adjuntas
Tipo de Archivo: jpg error.jpg (145,9 KB (Kilobytes), 63 visitas)
Tipo de Archivo: jpg ERROR DELAY.jpg (131,0 KB (Kilobytes), 63 visitas)
Tipo de Archivo: jpg ERROR DELAY 1.jpg (136,3 KB (Kilobytes), 63 visitas)
Archivos Adjuntos
Tipo de Archivo: rar usart atmega8 tx.rar (14,5 KB (Kilobytes), 1 visitas)
Tipo de Archivo: rar usart atmega8 Rx.rar (14,9 KB (Kilobytes), 1 visitas)
08/03/2016 #7

Avatar de Scooter

Me tendré que empollar el C. Sigo estando verde veinte años después.
08/03/2016 #8

Avatar de locodelafonola

Hola
Scooter dijo: Ver Mensaje
Me tendré que empollar el C. Sigo estando verde veinte años después.
en el enlace que puso el compañero Makitronica ., tenes tutos PIC y AVR en C ., estan buenos y en español http://microcontroladores-mrelberni....-avr-ejemplos/
08/03/2016 #9

Avatar de gustavo

Buenas a todos y muchas gracias por las respuestas, no tuve tiempo de comentar durante el dia por cuestiones laborales.
Como dice el amigo locodelafonola, lo que necesito hacer es el parpadeo de los leds sin utilizar los delay y por eso recurri a ustedes. ya que estos me perjudican al querer realizar otra tarea con el uC, tambien me he dado cuenta de los errores en el RX y ya fueron solucionados.
Creo que veo viable la opcion que me da el amigo Scooter, utilizar los timers y las interrupciones para dicha tarea y quisiera saber si podrian ayudarme a implementarla.
No es Arduino, es el mismo AVR-GCC y la libreria Usart.h la cree hace algun tiempo leyendo tutioriales con la idea de facilitarme la programacion serial! Se las adjunto aqui mismo!

Código:
/* 
------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------

     Nombre: usart.h
Descripción: Librería para el manejo de la USART 

------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------

Se declara la función que configura el USART en modo asincrono normal. En este ejemplo se trabajara 
el microcontrolador a una frecuencia de 8 Mhz y a una velocidad de 9600 baudios. Calculamos entonces el registro UBRR:

		UBRR = (Fosc/16*BAUD) - 1 
		
		UBRR = (8000000/16*9600) - 1
		UBRR = 51.08333

El valor obtenido para 9600 baudios fue de 51.0833 por lo tanto, 
se tomara el valor de 51 redondeando el valor obtenido y con el cual calculamos los baudios reales:
			
		BAUD = Fosc/16*(UBRR + 1)
		
		BAUD = 8000000/16*(51 + 1)
		BAUD = 9615.3846

9615.3846 Sera el valor real de baudios por segundo con los que el microcontrolador trabajara, 
pero para obtener el % de error respecto al valor de 9600 aplicamos la siguiente formula:

		ERROR = (BAUDRATE/BAUD - 1)*100%
		
		ERROR = (9615.3846/9600 - 1)*100
		ERROR = 0.16%
		
Como se puede ver el porcentaje de error es muy pequeño. Procedemos entonces a iniciar la comunicacion serial de la siguiente forma:

		SerialBegin(51);

La sentencia "SerialBegin()" inicia la comunicacion serial y tomamos el valor "51" 
obtenido del calculo que realizamos anteriormente. 

-----------------------------------------------------------------------------------------------------------------------

Estas operaciones previamente realizadas son para conocer un poco más el funcionamiento del registro 
y el cómo calcular el valor respecto a algún baud rate deseado. 
También hay una tabla que facilito con los valores más usados, la cual calcule con la formula del modo asincrono normal.

		BAUDIOS		FOSC	  UBRR		ERROR
		-------------------------------------
		2400		1Mhz	  26		0.2%
		4800		1Mhz	  13		0.2%
		9600		1Mhz	  7			-0.6%	 
		-------------------------------------
		2400		4Mhz	  104		0.2%
		4800		4Mhz	  52		0.2%
		9600		4Mhz	  26		0.2%
		-------------------------------------
		2400		8Mhz	  207		0.2%
		4800		8Mhz	  103		0.2%
		9600		8Mhz	  51		0.2%
		-------------------------------------
		2400		10Mhz	  260		0.2%
		4800		10Mhz	  130		0.2%
		9600		10Mhz	  65		0.2%
		-------------------------------------
		2400		12Mhz	  312		0.2%
		4800		12Mhz	  156		0.2%
		9600		12Mhz	  78		0.2%
		-------------------------------------	
		2400		16Mhz	  416		0.2%
		4800		16Mhz	  208		0.2%
		9600		16Mhz	  104		0.2%
		-------------------------------------
		2400		20Mhz	  520		0.2%
		4800		20Mhz	  260		0.2%
		9600		20Mhz	  130		0.2%
		-------------------------------------
*/

#ifndef USART_H
#define USART_H

void SerialBegin( unsigned int baud);
void SerialWrite( unsigned char data);
unsigned char SerialRead( void );
void SerialString(char cadena[]);

/* Función inicializar USART */
void SerialBegin( unsigned int baud )
{
    /* Se establece la tasa de baudios con el valor ingresado a la funcion */
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    /* Se habilita la recepción y la transmisión de datos */
    UCSRB = (1<<RXEN)|(1<<TXEN);
    /* Se establece el formato de la trama: 8 bits de datos, 2 bits de parada, sin bits de paridad */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

/* Función para transmitir un caracter */
void SerialWrite( unsigned char data )
{
    /* Espera hasta que el buffer esté vacio */
    while ( !( UCSRA & (1<<UDRE)) );
    /* Pone el dato en el buffer de transmisión, envía el dato */
    UDR = data;
}

/* Función para recibir un caracter */
unsigned char SerialRead( void )
{
    /* Espera a recibir datos */
    while ( !(UCSRA & (1<<RXC)) );
    /* Devuelve el dato leido */
    return UDR;
}

/* Funcion para transmitir una cadena de caracteres */
void SerialString(char cadena[])
{
	/* Índice */
    int i;
	/* Recorre la cadena */
    for(i=0;cadena[i]!='\0';i++) 
		/* Transmite el dato */
        SerialWrite(cadena[i]);
}
#endif
---------- Actualizado después de 59 minutos ----------

Compañeros, les adjunto archivos completos. Codigo fuente TX y RX, .HEX de cada uno y archivo de simulacion con ISIS Proteus 7.

Codigo fuente: TX

Código PHP:
/*
    Nombre: TX.c
    
*/ 

/* Configuraciones Generales */
#define  F_CPU 8000000UL 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"

/* Variables a Utilizar */                
unsigned char encender 'a';            
unsigned char apagar 'b';            

int main(void)
{    
    
// Comunicacion serial a 4800 baudios
    
SerialBegin(103);    
                                
    
// PC0 y PC1 como entrada
    
DDRC =  (0<<PC1) | (0<<PC0);

    
// Limpiamos PORTC
    
PORTC 0x00;                                        
    
    while(
1)
    {
        
// Testeo estado de PC0
        
if (bit_is_clear(PINC,PC0) == 0)
        {
            
// Retardo para verificar la pulsacion
            
_delay_ms(50);
        
                    
// Testeo nuevamente PC0            
            
if (bit_is_clear(PINC,PC0) == 0)
            {
                
// Envio el dato "encender"
                
SerialWrite(encender);    
            }                
        }
        
// Testeo estado de PC1
        
if (bit_is_clear(PINC,PC1) == 0)
        {
            
// Retardo para verificar la pulsacion
            
_delay_ms(50);

            
// Testeo nuevamente PC1
            
if (bit_is_clear(PINC,PC1) == 0)
            {
                
// Envio el dato "apagar"
                
SerialWrite(apagar);
            }            
        }            
    }

Codigo fuente RX:

Código PHP:
/*
    Nombre: RX.c

 */ 

/* Configuraciones Generales */
#define F_CPU 8000000UL 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"

/* Variables a utilizar */
unsigned char dato_serial;
unsigned char encender 'a';
unsigned char apagar 'b';

int main(void)
{                    
    
// Comunicacion serial a 4800 baudios
    
SerialBegin(103);    
                
    
// Puerto C como salida
    
DDRC 0xFF;

    
// Limpio PORTC
    
PORTC 0x00;    

    while(
1)
    {
    
// Almaceno el dato recibido en "dato_serial" 
    
dato_serial SerialRead();

    
// Es igual a "encender"?
    
if (dato_serial == encender)
    {
           while(
1)
           {
                
// Parpadeo...
        
PORTC 0b11111111;
        
_delay_ms(500);
        
PORTC 0b00000000;
        
_delay_ms(500);

        
// Almaceno dato recibido en "dato_serial"
        
dato_serial SerialRead();
        
// Es igual a "apagar"?
        
if(dato_serial == apagar)
        {
            
PORTC 0b00000000;
            
// Salgo...
            
break;
        }
            }
    }
    }

Archivos Adjuntos
Tipo de Archivo: rar Prueba.rar (57,3 KB (Kilobytes), 2 visitas)
08/03/2016 #10

Avatar de locodelafonola

Hola
gustavo dijo: Ver Mensaje
Buenas a todos y muchas gracias por las respuestas, no tuve tiempo de comentar durante el dia por cuestiones laborales.
Como dice el amigo locodelafonola, lo que necesito hacer es el parpadeo de los leds sin utilizar los delay y por eso recurri a ustedes. ya que estos me perjudican al querer realizar otra tarea con el uC, tambien me he dado cuenta de los errores en el RX y ya fueron solucionados.
Creo que veo viable la opcion que me da el amigo Scooter, utilizar los timers y las interrupciones para dicha tarea y quisiera saber si podrian ayudarme a implementarla.
No es Arduino, es el mismo AVR-GCC y la libreria Usart.h la cree hace algun tiempo leyendo tutioriales con la idea de facilitarme la programacion serial! Se las adjunto aqui mismo!

Código:
 
/* 
------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------

     Nombre: usart.h
Descripción: Librería para el manejo de la USART 

------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------

Se declara la función que configura el USART en modo asincrono normal. En este ejemplo se trabajara 
el microcontrolador a una frecuencia de 8 Mhz y a una velocidad de 9600 baudios. Calculamos entonces el registro UBRR:

		UBRR = (Fosc/16*BAUD) - 1 
		
		UBRR = (8000000/16*9600) - 1
		UBRR = 51.08333

El valor obtenido para 9600 baudios fue de 51.0833 por lo tanto, 
se tomara el valor de 51 redondeando el valor obtenido y con el cual calculamos los baudios reales:
			
		BAUD = Fosc/16*(UBRR + 1)
		
		BAUD = 8000000/16*(51 + 1)
		BAUD = 9615.3846

9615.3846 Sera el valor real de baudios por segundo con los que el microcontrolador trabajara, 
pero para obtener el % de error respecto al valor de 9600 aplicamos la siguiente formula:

		ERROR = (BAUDRATE/BAUD - 1)*100%
		
		ERROR = (9615.3846/9600 - 1)*100
		ERROR = 0.16%
		
Como se puede ver el porcentaje de error es muy pequeño. Procedemos entonces a iniciar la comunicacion serial de la siguiente forma:

		SerialBegin(51);

La sentencia "SerialBegin()" inicia la comunicacion serial y tomamos el valor "51" 
obtenido del calculo que realizamos anteriormente. 

-----------------------------------------------------------------------------------------------------------------------

Estas operaciones previamente realizadas son para conocer un poco más el funcionamiento del registro 
y el cómo calcular el valor respecto a algún baud rate deseado. 
También hay una tabla que facilito con los valores más usados, la cual calcule con la formula del modo asincrono normal.

		BAUDIOS		FOSC	  UBRR		ERROR
		-------------------------------------
		2400		1Mhz	  26		0.2%
		4800		1Mhz	  13		0.2%
		9600		1Mhz	  7			-0.6%	 
		-------------------------------------
		2400		4Mhz	  104		0.2%
		4800		4Mhz	  52		0.2%
		9600		4Mhz	  26		0.2%
		-------------------------------------
		2400		8Mhz	  207		0.2%
		4800		8Mhz	  103		0.2%
		9600		8Mhz	  51		0.2%
		-------------------------------------
		2400		10Mhz	  260		0.2%
		4800		10Mhz	  130		0.2%
		9600		10Mhz	  65		0.2%
		-------------------------------------
		2400		12Mhz	  312		0.2%
		4800		12Mhz	  156		0.2%
		9600		12Mhz	  78		0.2%
		-------------------------------------	
		2400		16Mhz	  416		0.2%
		4800		16Mhz	  208		0.2%
		9600		16Mhz	  104		0.2%
		-------------------------------------
		2400		20Mhz	  520		0.2%
		4800		20Mhz	  260		0.2%
		9600		20Mhz	  130		0.2%
		-------------------------------------
*/

#ifndef USART_H
#define USART_H

void SerialBegin( unsigned int baud);
void SerialWrite( unsigned char data);
unsigned char SerialRead( void );
void SerialString(char cadena[]);

/* Función inicializar USART */
void SerialBegin( unsigned int baud )
{
    /* Se establece la tasa de baudios con el valor ingresado a la funcion */
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    /* Se habilita la recepción y la transmisión de datos */
    UCSRB = (1<<RXEN)|(1<<TXEN);
    /* Se establece el formato de la trama: 8 bits de datos, 2 bits de parada, sin bits de paridad */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

/* Función para transmitir un caracter */
void SerialWrite( unsigned char data )
{
    /* Espera hasta que el buffer esté vacio */
    while ( !( UCSRA & (1<<UDRE)) );
    /* Pone el dato en el buffer de transmisión, envía el dato */
    UDR = data;
}

/* Función para recibir un caracter */
unsigned char SerialRead( void )
{
    /* Espera a recibir datos */
    while ( !(UCSRA & (1<<RXC)) );
    /* Devuelve el dato leido */
    return UDR;
}

/* Funcion para transmitir una cadena de caracteres */
void SerialString(char cadena[])
{
	/* Índice */
    int i;
	/* Recorre la cadena */
    for(i=0;cadena[i]!='\0';i++) 
		/* Transmite el dato */
        SerialWrite(cadena[i]);
}
#endif
en el primer link ., que publico el compañero Makitronica ., tenes el ejemplo de lo mismo con dos atmega88 (es lo mismo que el atmega 8 ., cambia solo las prestaciones)
proba con esos ejemplos ., (tiene un solo led pero podes poner mas)
leete los tutos que yo subi ., a ver si te sirven para entender., arma la compilacion (que compile y y tracee con F11) y subila como lo hice yo
PD: yo no uso simulador alguno ., en caso de la USART ., se prueba en lo fisico ., el problema esta en la compilacion dentro del compilador ., es inutil la simulacion en ISIS Proteus 7 EDITO PARA NO CREAR NUEVO MENSAJE
bueno ., aca te aporto una idea de como tendria que ser el temporisador (TIMER)
este ejemplo es muy basico ., pero se adapta a todos los atmegas usa el timer0
Código PHP:
*// Demo Programa (AVR GCC)//*
*//LED@0.5 Blink Hz en PORTC [3,2,1,0]//*

 

# Include <avr/io.h> 

# include <avr/interrupt.h>

volátil count uint8_t;

void main ()

{

   
// Pre-escalador = FCPU/1024 

   
TCCR0 | = ( << CS02) | ( << CS00);

   
// Habilitar Overflow Interrupt Enable 

   
TIMSK | = ( << TOIE0);

   
// Inicializar Contador 

   
TCNT0 ;

   
// Inicializar nuestra varriable 

   
count ;

   
// Puerto C [3,2,1,0] como poner un 

   
DDRC | = 0x0F ;

   
// Habilitar interrupciones Global

   
sei ();

   
// Loop  Infinito

    
while( );

}

ISR (TIMER0_OVF_vect)

{

   
// Esta es la rutina de servicio de interrupción de TIMER0 DESBORDAMIENTO Interrupción. 

   // CPU llamará automáticamente cuando este TIMER0 desborda.

   // Incrementar nuestra variable

   
count + +;

   if (
count == 61 )

   {

      
PORTC = ~ PORTC;  // Invertir el valor de PORTC 

      
count ;

   }


bueno aca tenes lo que comunmente se llama BLINKY ., que tambien lo podrias usar
Código PHP:
#include <avr/io.h>

/* Este ejemplo destellar los LED en STK500, que se encarga de tendencia a la basura GCC bucles de retardo vacíos mediante la inserción de asm en línea volátil. */
   
void wait (void
{
    
asm volatile ("nop"::);
}

int main (void
{
    
unsigned char i;
    
unsigned long j;
    
    
DDRB 0xFF;            // PORTB configurar como salida
    
    
for(;;) 
    {
        for (
i=0x01i<0x80i<<=1
        {
            
PORTB = ~i;
            
            
/* Delay */
            
for (j=0j<20000j++) wait();
        }
        
        for (
i=0x80i>0x01i>>=1
        {
            
PORTB = ~i;
            
            
/* Delay o Retardo, los bucles de espera definidos en avr / delay.h, también podría ser utilizado */
            
for (j=0j<20000j++) wait();
        }
    }

Archivos Adjuntos
Tipo de Archivo: rar tutorial manejo del TIMER .rar (116,8 KB (Kilobytes), 0 visitas)
Tipo de Archivo: rar Blinky.rar (4,7 KB (Kilobytes), 0 visitas)
10/03/2016 #11

Avatar de gustavo

¡Excelente aporte! Ayer estuve leyendo los artículos que me dejaron y se los agradezco.
Con este ejemplo espero entender un poco más. Realmente muchas gracias locodelafonola por tomarte el tiempo en ayudarme.
Ni bien pueda terminar, posteo el código completo por si a alguno de ustedes le sirve a futuro para realizar algo.
Estamos en contacto por este medio. Muchas gracias.
11/03/2016 #12

Avatar de gustavo

Buenas noches! Gracias a todos ustedes y a locodelafonola que dedico parte de su tiempo en explicarme y ayudarme, les comento que pude realizar este ejercicio que por asi decirlo no me dejaba dormir jaja
Me tome el tiempo de leer cada uno de los articulos mencionados que me han recomendado y fueron de mucha ayuda los ejemplos de locodelafonola, ahora el programa realiza lo que estaba queriendo.
Les adjunto todos los archivos que incluyen los programas para cada uC y la simulacion por Proteus, se encuentran compilados y probados al 100%. Espero que les sea de gran ayudar u ejemplo para implementar en sus proyectos.
Estoy en deuda y ojala algun dia pueda aportar un poco mas. Por el momento me encuentro aprendiendo! Les mando un saludo grande y vuelvo agradecer a todos por su tiempo!


Codigo fuente: TX

Código PHP:
/*
    Nombre: TX.c
    
*/ 

/* Configuraciones Generales */
#define  F_CPU 8000000UL 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"

/* Variables a Utilizar */                
unsigned char encender 'a';            
unsigned char apagar 'b';            

int main(void)
{    
    
// Comunicacion serial a 4800 baudios
    
SerialBegin(103);    
                                
    
// PC0 y PC1 como entrada
    
DDRC =  (0<<PC1) | (0<<PC0);

    
// Limpiamos PORTC
    
PORTC 0x00;                                        
    
    while(
1)
    {
        
// Testeo estado de PC0
        
if (bit_is_clear(PINC,PC0) == 0)
        {
            
// Retardo para verificar la pulsacion
            
_delay_ms(50);
        
                    
// Testeo nuevamente PC0            
            
if (bit_is_clear(PINC,PC0) == 0)
            {
                
// Envio el dato "encender"
                
SerialWrite(encender);    
            }                
        }
        
// Testeo estado de PC1
        
if (bit_is_clear(PINC,PC1) == 0)
        {
            
// Retardo para verificar la pulsacion
            
_delay_ms(50);

            
// Testeo nuevamente PC1
            
if (bit_is_clear(PINC,PC1) == 0)
            {
                
// Envio el dato "apagar"
                
SerialWrite(apagar);
            }            
        }            
    }


Codigo fuente: RX

Código PHP:
/*
    Nombre: RX.c

 */ 

/* Configuraciones Generales */
#define F_CPU 8000000UL 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"

/* Variables a utilizar */
unsigned char dato_serial;
unsigned char encender 'a';
unsigned char apagar 'b';
int contador;

ISR (TIMER0_OVF_vect)
{
    
// Incrementa variable    
    
contador++;

    
// Pregunto si el contador es igual a 7
    
if (contador == 7)
    {
        
// Invierte el valor de PORTC
        
PORTC = ~ PORTC;  

        
// Pone contador a 0
        
contador ;    
    }
}

ISR(USART_RXC_vect)
{
    
// Almaceno el dato recibido por puerto serial en la variable "dato_serial"
    
dato_serial SerialRead();
    
    
// Pregunto si "dato_serial" es igual a "encender"
    
if (dato_serial == encender)
    {
        
// Habilito interrupcion por Overflow
        
TIMSK = (1<<TOIE0);
                
/* Al activar el bit TOIE0 del registro TIMSK,
                   activo la interrupcion por Overflow y 
                   esto me permite el parpadeo de leds*/                  
    
}
    
    
// Pregunto si "dato_serial" es igual a "apagar"
    
if (dato_serial == apagar)
    {
        
// Deshabilito interrupcion por Overflow
        
TIMSK = (0<<TOIE0);
        
// Apago los leds
        
PORTC 0x00;
    }
}

int main(void)
{                    
    
// Comunicacion serial a 4800 baudios
    
SerialBegin(103);    
                
    
// Puerto C [3,2,1,0] como salida
    
DDRC 0x0F ;

    
// Limpio PORTC
    
PORTC 0x00;    
    
    
// Prescaler = FCPU/1024
    
TCCR0 = (1<<CS02) | (1<<CS00);

    
// Inicio interrupcion por Overflow deshabilitada
    
TIMSK = (0<<TOIE0);
    
    
// Inicializo contador en 0          
    
TCNT0 0;

    
// Habilito interrupciones globales
    
sei();

    while(
1)
    {
    }


Codigo fuente: usart.h

Código PHP:
/* 
------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------

     Nombre: usart.h
Descripción: Librería para el manejo de la USART 

------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------

Se declara la función que configura el USART en modo asincrono normal. En este ejemplo se trabajara 
el microcontrolador a un a frecuencia de 8 Mhz y a una velocidad de 9600 baudios. Calculamos entonces el registro UBRR:

        UBRR = (Fosc/16*BAUD) - 1 
        
        UBRR = (8000000/16*9600) - 1
        UBRR = 51.08333

El valor obtenido para 9600 baudios fue de 51.0833 por lo tanto, 
se tomara el valor de 51 redondeando el valor obtenido y con el cual calculamos los baudios reales:
            
        BAUD = Fosc/16*(UBRR + 1)
        
        BAUD = 8000000/16*(51 + 1)
        BAUD = 9615.3846

9615.3846 Sera el valor real de baudios por segundo con los que el microcontrolador trabajara, 
pero para obtener el % de error respecto al valor de 9600 aplicamos la siguiente formula:

        ERROR = (BAUDRATE/BAUD - 1)*100%
        
        ERROR = (9615.3846/9600 - 1)*100
        ERROR = 0.16%
        
Como se puede ver el porcentaje de error es muy pequeño. Procedemos entonces a iniciar la comunicacion serial de la siguiente forma:

        SerialBegin(51);

La sentencia "SerialBegin()" inicia la comunicacion serial y tomamos el valor "51" 
obtenido del calculo que realizamos anteriormente. 

-----------------------------------------------------------------------------------------------------------------------

Estas operaciones previamente realizadas son para conocer un poco más el funcionamiento del registro 
y el cómo calcular el valor respecto a algún baud rate deseado. 
También hay una tabla que facilito con los valores más usados, la cual calcule con la formula del modo asincrono normal.

        BAUDIOS        FOSC      UBRR        ERROR
        -------------------------------------
        2400        1Mhz      26        0.2%
        4800        1Mhz      13        0.2%
        9600        1Mhz      7            -0.6%     
        -------------------------------------
        2400        4Mhz      104        0.2%
        4800        4Mhz      52        0.2%
        9600        4Mhz      26        0.2%
        -------------------------------------
        2400        8Mhz      207        0.2%
        4800        8Mhz      103        0.2%
        9600        8Mhz      51        0.2%
        -------------------------------------
        2400        10Mhz      260        0.2%
        4800        10Mhz      130        0.2%
        9600        10Mhz      65        0.2%
        -------------------------------------
        2400        12Mhz      312        0.2%
        4800        12Mhz      156        0.2%
        9600        12Mhz      78        0.2%
        -------------------------------------    
        2400        16Mhz      416        0.2%
        4800        16Mhz      208        0.2%
        9600        16Mhz      104        0.2%
        -------------------------------------
        2400        20Mhz      520        0.2%
        4800        20Mhz      260        0.2%
        9600        20Mhz      130        0.2%
        -------------------------------------
*/

#ifndef USART_H
#define USART_H

void SerialBeginunsigned int baud);
void SerialWriteunsigned char data);
unsigned char SerialReadvoid );
void SerialString(char cadena[]);

/* Función inicializar USART */
void SerialBeginunsigned int baud )
{
    
/* Se establece la tasa de baudios con el valor ingresado a la funcion */
    
UBRRH = (unsigned char)(baud>>8);
    
UBRRL = (unsigned char)baud;
    
/* Se habilita la recepción y la transmisión de datos */
    /* Tambien se habilita la interrupcion por USART por transmision y recepcion*/
    
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE);
    
/* Se establece el formato de la trama: 8 bits de datos, 2 bits de parada, sin bits de paridad */
    
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

/* Función para transmitir un caracter */
void SerialWriteunsigned char data )
{
    
/* Espera hasta que el buffer esté vacio */
    
while ( !( UCSRA & (1<<UDRE)) );
    
/* Pone el dato en el buffer de transmisión, envía el dato */
    
UDR data;
}

/* Función para recibir un caracter */
unsigned char SerialReadvoid )
{
    
/* Espera a recibir datos */
    
while ( !(UCSRA & (1<<RXC)) );
    
/* Devuelve el dato leido */
    
return UDR;
}

/* Funcion para transmitir una cadena de caracteres */
void SerialString(char cadena[])
{
    
/* Índice */
    
int i;
    
/* Recorre la cadena */
    
for(i=0;cadena[i]!='\0';i++) 
        
/* Transmite el dato */
        
SerialWrite(cadena[i]);
}
#endif 
Archivos Adjuntos
Tipo de Archivo: rar Prueba.rar (73,2 KB (Kilobytes), 2 visitas)
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.