Traduccion o creacion de manual para microcontroladores AVR

"Los de 8 bits son los reconocidos mejores, en 16 bits no. Me refiero la arquitectura de los µC."

si pasa que gracias a la arquitectura de estos se los podría tratar como bien dice en su pagina avr 8/16 bit pero para nosotros la cpu es de 8 bit, y casi nadie ya recomienda los uC de 16 en gral, el salto es de 8 bit a 32 bit, y los avr de 32 bit estaaan imprecionantes.

espero que me lleguen prontos los ATXmega128A3 que pedí, mi jefe también medio a elegir el atmega mas poderos para que hagamos un desarrollo y ando viendo cual es el que mejor se adapta.

saludos Meta
 
Mira Ajna, quien te dijo que no los domino a los avr? trabajo con ellos hace mas de 3 años y creo que son los mejores uC (es mi opinion), y si plantee una duda no quiere decir nada mas.....y fue problema del complilador una opcion que tenia mal tildada....em no entiendo tu preocupación de que yo sepa o no usar los AVR..... (?)

cuando hablo del ejemplo 3 en mi manual es por que me quede en ese ejemplo en mi manual....ahora....en ves de cuestionar si se o no programar los AVR por que no esperas a que suba el manual y sacas tu conclusiones? y tomar o no los conocimientos de ese manual si no te sirve a vos a otro seguro que si.

Calmate y respira, nadien te dijo que no los dominaras, creo que estas inteerpretando mal las cosas, por un lado dices estar haciendo un manual y por otro dices tener problemas en terminar el ejemplo 3, cosa que me confundio y mas aun porque no pusiste cual era el problema con el ejemplo 3.
 
Hola:

En mi caso no do ino ninguno, intento dominar un PIC con ASM y C, no lo dominaré al 100% nunca, por ahora sólo lo básico, un 4% y mucho me parece, configurar puertos como entrada y salida, lo mismo en Analógico, manejar las instrucciones, LCD, motores, PWM, entre algunas cosillas, aún así me cuesta, hablo del PIC, en cuanto al AVR, probé el Teensy 2++, muy fácil de programar.

Para mi, no se si en el futuro reinarán los 32 bits y los de 8 desaparecerán algún día, sobre todo cuando decidan sacar los 64 bits. (Cuando apareció los 32 bits de PIC32, se dijo que tienen los de 64 bits hechos pero no los venden, nadie lohace por ahora).

Lo bueno de los PIC32 que son fáciles de programar, he seguido hace un tiempo un libro en Inglés sobre ellos. Lo bueno que tiene 32 bits que controla pantallas a color como los Galaxy III con soltura, son para este tipo de cosas.

PIC32.jpg


Aquí hay datos para curiosear:

Migración de 8 bits a 32 bits.
http://www.electronicosonline.com/2010/01/07/Definen-como-esencial-migracion-de-8-a-32-bits/

¿8 bits o 32 bits?
http://telecontrolgsm.blogspot.com.es/2009/05/8-bits-x-32-bits.html

Por ahora para hacer cosas sencillas los 8 bits es suficiente, sobre controlas entradas y salidas, en temas más avanzados ya los 32 bits, para eso están, no de adornos.

Salu2.
 
Hola parece haber poca actividad por aqui :confused:, Bueno comparto la traducción que hice de la Nota de aplicación AVR4027... que encontré en la página de Atmel.

Este documento brinda importantes trucos para todos aquellos que programan microcontroladores AVR de 8 bits en lenguaje C. Si utilizan AVR-GCC este documento les puede ser de gran utilidad, si lo que quieren es optimizar su código para reducir tamaño o aumentar velocidad de ejecución, si quieren ir al grano le puse el índice de contenido al final del documento.

Seguramente tendrá algunos errores de traducción pero espero los detecten y los corrijan en todo caso pido disculpas si existen :oops: no me vendría mal alguna realimentación del documento pera mejorar la técnica de traducción...

Espero les sirva...
 

Adjuntos

  • Traduccion AVR04027.pdf
    1.1 MB · Visitas: 131
Hola moyano el link de unos de tus post anteriores ya no anda : (

"Te paso el link: http://www.mil.ufl.edu/~chrisarnold/...tml/index.html "

sabes si esta en otro lado?


Otra cosita mas, estuve haciendo el soft para manejar la memoria 24lc256, como no andaba bien me fije aquí en el foro y me tope con esto. Hay algunas cosas que no entiendo como ser:

el QDEL, este retardo de 5 ciclos maquina que haces con nop a 8MHz serian 625nS cierto?

En el datasheet de esa memoria observe que el bit menos significativo se manda primero, y tu lo haces al revés, por que?

Ahora para mandar un dato yo hago esto:
Código:
void Write_memoria(unsigned char HighDir, unsigned char LowDir, unsigned char Dato)
{
    unsigned char i;
    unsigned char ControlByte=0b10100010;    
    //                               ||||||||__R=1, /W=0
    //                            |||||||___A0=1
    //                            ||||||____A1=0
    //                            |||||_____A2=0
    //                            ||||______0
    //                            |||_______1
    //                            ||________0
    //                            |_________1
    //****************************************************
    StartCondition();
    SCLK_CLR();
    
    for (i=0;i<8;i++)
    {
        if ((ControlByte & 0X01))
        {SDA_SET();}
        else
        {SDA_CLR();}
            
            Delay_i2c();
            SCLK_SET();
            ControlByte = ControlByte>>1;    //DESPLAZO EL DATO
            Delay_i2c();
            SCLK_CLR();
    }
    
    //Noveno clock para el acknowledge    
    Delay_i2c();
    SCLK_SET();
    Delay_i2c();
    SCLK_CLR();
    
    for(i=0;i<8;i++)
    {
        if ((HighDir & 0x01))
        {SDA_SET();}
        else
        {SDA_CLR();}
            
                Delay_i2c();
                SCLK_SET();    
                HighDir=HighDir>>1;
                Delay_i2c();
                SCLK_CLR();
    }
    
    //Noveno clock para el acknowledge    
    Delay_i2c();
    SCLK_SET();
    Delay_i2c();
    SCLK_CLR();
    //Delay_i2c();
    for(i=0;i<8;i++)
    {
        if ((LowDir & 0x01))
        {SDA_SET();}
        else
        {SDA_CLR();}
            
                Delay_i2c();
                SCLK_SET();    
                LowDir=LowDir>>1;
                Delay_i2c();
                SCLK_CLR();
    }
    
    //Noveno clock para el acknowledge    
    Delay_i2c();
    SCLK_SET();
    Delay_i2c();
    SCLK_CLR();
    //Delay_i2c();
    for(i=0;i<8;i++)
    {
        if ((Dato & 0x01))
        {SDA_SET();}
        else
        {SDA_CLR();}
                
                Delay_i2c();
                SCLK_SET();    
                Dato=Dato>>1;
                Delay_i2c();
                SCLK_CLR();
    }
    
    //Noveno clock para el acknowledge
    Delay_i2c();
    SCLK_SET();
    Delay_i2c();
    SCLK_CLR();
    
    StopCondition();
}
void StartCondition()
{
    A0_Enable;    //Habilito el chip
    SDA_SET();    //Aseguro sda en alto 
    SCLK_SET();    //clock en alto 
    SDA_CLR();  //bajo la linea de sda
    Delay_1uS();
}
void StopCondition()
{
    SCLK_SET();
    SCLK_SET();
    SDA_SET();
    Delay_1uS();
}
void Init_I2C()
{
    SDA_DDR|=(1<<SDA_PIN);
    SCLK_DDR|=(1<<SCLK_PIN);
    SDA_SET();
    SCLK_SET();
}
void Delay_i2c()
{
    _delay_us(10);
}

estoy haciendo bien? o que estoy haciendo mal? jeje

espero me puedan dar un amano es para un proyecto de la facultad y queria usar una memoria
saludos y muchas gracias.

PD: dejo el programa modificado hace un rato asi alguien lo pruebe y pueda decirme que ocurre :(
solo leo FF, me fije en el osciloscopio las lineas sclk y sda y parece estar bien a unos 114kHz da el clock por favor si alguien meayuda a sacar andando este soft se los agradeceria.
 

Adjuntos

  • memoria 24lc256.txt
    7.6 KB · Visitas: 15
Última edición por un moderador:
Hola seguí modificando mi soft logre que corra en Proteus pero no en la vida real jaja, alguien puede compilarlo y sacar el problemita o comentármelo? ya no se que hacerle al código : (

use un tutorial de como usar el modulo i2c de este avr y funciona de 10 osea mi circuito esta bien hecho así que es el soft.

lo adjunto aquí por favor si alguien me diera una mano se los agradecería
 

Adjuntos

  • i2c por soft avr.txt
    5.9 KB · Visitas: 24
Hola gonpa,

Sin revisar el código, puesto que dices que te funciona en Proteus, has verificado los fusebits del microcontrolador? Recuerda que al ser una comunicación por I2C, es susceptible a la frecuencia de reloj del microcontrolador. Entonces, verifica que estés trabajando a la frecuencia que tienes programada en F_CPU que según veo es de 11.059 MHz, verifica que el cristal conectado coincida con ese valor, y además que no tengas activado algún fusebit que divida la frecuencia (comúnmente en 8), o que esté trabajando con el oscilador interno (usualmente a 8MHz)... es solamente una posibilidad, no digo que justamente ese sea tu problema, verifica a ver y nos comentas....
 
Hola alepusto,

Gracias por contestar, ya revisé todos esos detalles posibles y está todo en orden funcionando bien. Necesito que estas rutias sean hechas por soft y no por el modulo, ya que es facil migrarlas a otro lado. con el modulo i2c que presentan en "cursomicros.com" funciona muy bien pero bueno mi fin es otro.
Si alguien descubre el error que estoy cometiendo me ayudaría? por favor.

yo sigo intentando.

saludos!
 
Hay una pagina en internet que se llama comunidad atmel:
www.comunidadatmel.com
Se encuentra algo de informacion sobre los micros AVR con el compilador codevision.

Les dejo un par de archivos.

Saludos.
 

Adjuntos

  • Curso AVR con CodeVision v8.0.pdf
    706.6 KB · Visitas: 58
  • Curso Avanzado 8.0.pdf
    887.6 KB · Visitas: 57
Por el problema de comunicaciones i2c por software:

Los tiempos como se marcan más arriba son muy específicos. Por lo tanto los delay no pueden realizarse con las rutinas normales de temporización.
Yo les dejo una rutina que utilizo para comunicar memorias y otros dispositivos i2c, cuando no está la posibilidad de comunicarse via TWI.

Código:
;*************************************************************************
; Title	:    I2C (Single) Master Implementation
; Author:    Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
;            based on Atmel Appl. Note AVR300
; File:      $Id: i2cmaster.S,v 1.12 2008/03/02 08:51:27 peter Exp $
; Software:  AVR-GCC 3.3 or higher
; Target:    any AVR device
;
; DESCRIPTION
; 	Basic routines for communicating with I2C slave devices. This
;	"single" master implementation is limited to one bus master on the
;	I2C bus. 
;  
;       Based on the Atmel Application Note AVR300, corrected and adapted 
;       to GNU assembler and AVR-GCC C call interface
;       Replaced the incorrect quarter period delays found in AVR300 with 
;       half period delays. 
;
; USAGE
;	These routines can be called from C, refere to file i2cmaster.h.
;       See example test_i2cmaster.c 
; 	Adapt the SCL and SDA port and pin definitions and eventually 
;	the delay routine to your target !
; 	Use 4.7k pull-up resistor on the SDA and SCL pin.
;
; NOTES
;	The I2C routines can be called either from non-interrupt or
;	interrupt routines, not both.
;
;*************************************************************************

#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !"
#endif


#include <avr/io.h>



;***** Adapt these SCA and SCL port and pin definition to your target !!
;
#define SDA     	3		// SDA Port B, Pin 3  
#define SCL		4		// SCL Port B, Pin 4
#define SDA_PORT        PORTB           // SDA Port B
#define SCL_PORT        PORTB           // SCL Port B         

;******

;-- map the IO register back into the IO address space
#define SDA_DDR		(_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR		(_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT		_SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT		_SFR_IO_ADDR(SCL_PORT)
#define SDA_IN		(_SFR_IO_ADDR(SDA_PORT) - 2)
#define SCL_IN		(_SFR_IO_ADDR(SCL_PORT) - 2)


#ifndef __tmp_reg__
#define __tmp_reg__ 0
#endif

.section .text
	

;*************************************************************************
; delay half period
; For I2C in normal mode (100kHz), use T/2 > 5us
; For I2C in fast mode (400kHz),   use T/2 > 1.3us
;*************************************************************************
	
.func i2c_delay_T2	        ; delay 5.0 microsec with 12 Mhz crystal.	

i2c_delay_T2:                

          ldi  R17, 0x0E
WGLOOP0:  dec  R17
          brne WGLOOP0
	  ret         
.endfunc                        ; total 60 cyles = 5.0 microsec with 12 Mhz crystal. 


;*************************************************************************
; Initialization of the I2C bus interface. Need to be called only once
; 
; extern void i2c_init(void)
;*************************************************************************
	.global i2c_init
	.func i2c_init
i2c_init:
	cbi SDA_DDR,SDA		;release SDA
	cbi SCL_DDR,SCL		;release SCL
	cbi SDA_OUT,SDA
	cbi SCL_OUT,SCL
	ret
	.endfunc


;*************************************************************************	
; Issues a start condition and sends address and transfer direction.
; return 0 = device accessible, 1= failed to access device
;
; extern unsigned char i2c_start(unsigned char addr);
;	addr = r24, return = r25(=0):r24
;*************************************************************************

	.global i2c_start
	.func   i2c_start
i2c_start:
	sbi 	SDA_DDR,SDA	;force SDA low
	rcall 	i2c_delay_T2	;delay T/2
	
	rcall 	i2c_write	;write address
	ret
	.endfunc		


;*************************************************************************
; Issues a repeated start condition and sends address and transfer direction.
; return 0 = device accessible, 1= failed to access device
;
; extern unsigned char i2c_rep_start(unsigned char addr);
;	addr = r24,  return = r25(=0):r24
;*************************************************************************

	.global i2c_rep_start
	.func	i2c_rep_start
i2c_rep_start:
	sbi	SCL_DDR,SCL	;force SCL low
	rcall 	i2c_delay_T2	;delay  T/2
	cbi	SDA_DDR,SDA	;release SDA
	rcall	i2c_delay_T2	;delay T/2
	cbi	SCL_DDR,SCL	;release SCL
	rcall 	i2c_delay_T2	;delay  T/2
	sbi 	SDA_DDR,SDA	;force SDA low
	rcall 	i2c_delay_T2	;delay	T/2
	
	rcall	i2c_write	;write address
	ret
	.endfunc


;*************************************************************************	
; Issues a start condition and sends address and transfer direction.
; If device is busy, use ack polling to wait until device is ready
;
; extern void i2c_start_wait(unsigned char addr);
;	addr = r24
;*************************************************************************

	.global i2c_start_wait
	.func   i2c_start_wait
i2c_start_wait:
	mov	__tmp_reg__,r24
i2c_start_wait1:
	sbi 	SDA_DDR,SDA	;force SDA low
	rcall 	i2c_delay_T2	;delay T/2
	mov	r24,__tmp_reg__
	rcall 	i2c_write	;write address
	tst	r24		;if device not busy -> done
	breq	i2c_start_wait_done
	rcall	i2c_stop	;terminate write operation
	rjmp	i2c_start_wait1	;device busy, poll ack again
i2c_start_wait_done:
	ret
	.endfunc	


;*************************************************************************
; Terminates the data transfer and releases the I2C bus
;
; extern void i2c_stop(void)
;*************************************************************************

	.global	i2c_stop
	.func	i2c_stop
i2c_stop:
	sbi	SCL_DDR,SCL	;force SCL low
	sbi	SDA_DDR,SDA	;force SDA low
	rcall	i2c_delay_T2	;delay T/2
	cbi	SCL_DDR,SCL	;release SCL
	rcall	i2c_delay_T2	;delay T/2
	cbi	SDA_DDR,SDA	;release SDA
	rcall	i2c_delay_T2	;delay T/2
	ret
	.endfunc


;*************************************************************************
; Send one byte to I2C device
; return 0 = write successful, 1 = write failed
;
; extern unsigned char i2c_write( unsigned char data );
;	data = r24,  return = r25(=0):r24
;*************************************************************************
	.global i2c_write
	.func	i2c_write
i2c_write:
	sec			;set carry flag
	rol 	r24		;shift in carry and out bit one
	rjmp	i2c_write_first
i2c_write_bit:
	lsl	r24		;if transmit register empty
i2c_write_first:
	breq	i2c_get_ack
	sbi	SCL_DDR,SCL	;force SCL low
	brcc	i2c_write_low
	nop
	cbi	SDA_DDR,SDA	;release SDA
	rjmp	i2c_write_high
i2c_write_low:
	sbi	SDA_DDR,SDA	;force SDA low
	rjmp	i2c_write_high
i2c_write_high:
	rcall 	i2c_delay_T2	;delay T/2
	cbi	SCL_DDR,SCL	;release SCL
	rcall	i2c_delay_T2	;delay T/2
	rjmp	i2c_write_bit
	
i2c_get_ack:
	sbi	SCL_DDR,SCL	;force SCL low
	cbi	SDA_DDR,SDA	;release SDA
	rcall	i2c_delay_T2	;delay T/2
	cbi	SCL_DDR,SCL	;release SCL
i2c_ack_wait:
	sbis	SCL_IN,SCL	;wait SCL high (in case wait states are inserted)
	rjmp	i2c_ack_wait
	
	clr	r24		;return 0
	sbic	SDA_IN,SDA	;if SDA high -> return 1
	ldi	r24,1
	rcall	i2c_delay_T2	;delay T/2
	clr	r25
	ret
	.endfunc



;*************************************************************************
; read one byte from the I2C device, send ack or nak to device
; (ack=1, send ack, request more data from device 
;  ack=0, send nak, read is followed by a stop condition)
;
; extern unsigned char i2c_read(unsigned char ack);
;	ack = r24, return = r25(=0):r24
; extern unsigned char i2c_readAck(void);
; extern unsigned char i2c_readNak(void);
; 	return = r25(=0):r24
;*************************************************************************
	.global i2c_readAck
	.global i2c_readNak
	.global i2c_read		
	.func	i2c_read
i2c_readNak:
	clr	r24
	rjmp	i2c_read
i2c_readAck:
	ldi	r24,0x01
i2c_read:
	ldi	r23,0x01	;data = 0x01
i2c_read_bit:
	sbi	SCL_DDR,SCL	;force SCL low
	cbi	SDA_DDR,SDA	;release SDA (from previous ACK)
	rcall	i2c_delay_T2	;delay T/2
	
	cbi	SCL_DDR,SCL	;release SCL
	rcall	i2c_delay_T2	;delay T/2
	
i2c_read_stretch:
    sbis SCL_IN, SCL        ;loop until SCL is high (allow slave to stretch SCL)
    rjmp	i2c_read_stretch
    	
	clc			;clear carry flag
	sbic	SDA_IN,SDA	;if SDA is high
	sec			;  set carry flag
	
	rol	r23		;store bit
	brcc	i2c_read_bit	;while receive register not full
	
i2c_put_ack:
	sbi	SCL_DDR,SCL	;force SCL low	
	cpi	r24,1
	breq	i2c_put_ack_low	;if (ack=0)
	cbi	SDA_DDR,SDA	;      release SDA
	rjmp	i2c_put_ack_high
i2c_put_ack_low:                ;else
	sbi	SDA_DDR,SDA	;      force SDA low
i2c_put_ack_high:
	rcall	i2c_delay_T2	;delay T/2
	cbi	SCL_DDR,SCL	;release SCL
i2c_put_ack_wait:
	sbis	SCL_IN,SCL	;wait SCL high
	rjmp	i2c_put_ack_wait
	rcall	i2c_delay_T2	;delay T/2
	mov	r24,r23
	clr	r25
	ret
	.endfunc

Está en ASM y hay que calcular una subrutina, según el clock del oscilador externo/interno.

*************************************************************************
; delay half period
; For I2C in normal mode (100kHz), use T/2 > 5us
; For I2C in fast mode (400kHz), use T/2 > 1.3us
;*************************************************************************

.func i2c_delay_T2 ; delay 5.0 microsec with 12 Mhz crystal.

i2c_delay_T2:

ldi R17, 0x0E
WGLOOP0: dec R17
brne WGLOOP0
ret
.endfunc ; total 60 cyles = 5.0 microsec with 12 Mhz crystal.

Ahí está calculado para 12Mhz, que es el cristal que utilizo. Ahora si se necesita cambiar de cristal pueden generar una rutina de temporización de 5 microsegundos utilizando un software como el siguiente: http://www.electronics-lab.com/downloads/mcu/003/index.html

También hay que configurar los pines SDA/SCL.

Código:
;***** Adapt these SCA and SCL port and pin definition to your target !!
;
#define SDA     	3		// SDA Port B, Pin 3  
#define SCL		4		// SCL Port B, Pin 4
#define SDA_PORT        PORTB           // SDA Port B
#define SCL_PORT        PORTB           // SCL Port B

Como es complejo de implementar en un programa excrito en C, el autor nos deja la librería con las funciones declaradas en c, que llaman a las funciones hechas en ASM, esto lo realiza luego el linker, por eso hay que declarar el uso del archivo ASM con las funciones en nuestro Makefile.

Código:
#ifndef _I2CMASTER_H
#define _I2CMASTER_H   1
/************************************************************************* 
* Title:    C include file for the I2C master interface 
*           (i2cmaster.S or twimaster.c)
* Author:   Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
* File:     $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target:   any AVR device
* Usage:    see Doxygen manual
**************************************************************************/

#ifdef DOXYGEN
/**
 @defgroup pfleury_ic2master I2C Master library
 @code #include <i2cmaster.h> @endcode
  
 @brief I2C (TWI) Master Software Library

 Basic routines for communicating with I2C slave devices. This single master 
 implementation is limited to one bus master on the I2C bus. 

 This I2c library is implemented as a compact assembler software implementation of the I2C protocol 
 which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c).
 Since the API for these two implementations is exactly the same, an application can be linked either against the
 software I2C implementation or the hardware I2C implementation.

 Use 4.7k pull-up resistor on the SDA and SCL pin.
 
 Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module 
 i2cmaster.S to your target when using the software I2C implementation ! 
 
 Adjust the  CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.

 @note 
    The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted 
    to GNU assembler and AVR-GCC C call interface.
    Replaced the incorrect quarter period delays found in AVR300 with 
    half period delays. 
    
 @author Peter Fleury pfleury@gmx.ch  http://jump.to/fleury

 @par API Usage Example
  The following code shows typical usage of this library, see example test_i2cmaster.c

 @code

 #include <i2cmaster.h>


 #define Dev24C02  0xA2      // device address of EEPROM 24C02, see datasheet

 int main(void)
 {
     unsigned char ret;

     i2c_init();                             // initialize I2C library

     // write 0x75 to EEPROM address 5 (Byte Write) 
     i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode
     i2c_write(0x05);                        // write address = 5
     i2c_write(0x75);                        // write value 0x75 to EEPROM
     i2c_stop();                             // set stop conditon = release bus


     // read previously written value back from EEPROM address 5 
     i2c_start_wait(Dev24C02+I2C_WRITE);     // set device address and write mode

     i2c_write(0x05);                        // write address = 5
     i2c_rep_start(Dev24C02+I2C_READ);       // set device address and read mode

     ret = i2c_readNak();                    // read one byte from EEPROM
     i2c_stop();

     for(;;);
 }
 @endcode

*/
#endif /* DOXYGEN */

/**@{*/

#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
#endif

#include <avr/io.h>

/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_READ    1

/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_WRITE   0


/**
 @brief initialize the I2C master interace. Need to be called only once 
 @param  void
 @return none
 */
extern void i2c_init(void);


/** 
 @brief Terminates the data transfer and releases the I2C bus 
 @param void
 @return none
 */
extern void i2c_stop(void);


/** 
 @brief Issues a start condition and sends address and transfer direction 
  
 @param    addr address and transfer direction of I2C device
 @retval   0   device accessible 
 @retval   1   failed to access device 
 */
extern unsigned char i2c_start(unsigned char addr);


/**
 @brief Issues a repeated start condition and sends address and transfer direction 

 @param   addr address and transfer direction of I2C device
 @retval  0 device accessible
 @retval  1 failed to access device
 */
extern unsigned char i2c_rep_start(unsigned char addr);


/**
 @brief Issues a start condition and sends address and transfer direction 
   
 If device is busy, use ack polling to wait until device ready 
 @param    addr address and transfer direction of I2C device
 @return   none
 */
extern void i2c_start_wait(unsigned char addr);

 
/**
 @brief Send one byte to I2C device
 @param    data  byte to be transfered
 @retval   0 write successful
 @retval   1 write failed
 */
extern unsigned char i2c_write(unsigned char data);


/**
 @brief    read one byte from the I2C device, request more data from device 
 @return   byte read from I2C device
 */
extern unsigned char i2c_readAck(void);

/**
 @brief    read one byte from the I2C device, read is followed by a stop condition 
 @return   byte read from I2C device
 */
extern unsigned char i2c_readNak(void);

/** 
 @brief    read one byte from the I2C device
 
 Implemented as a macro, which calls either i2c_readAck or i2c_readNak
 
 @param    ack 1 send ack, request more data from device<br>
               0 send nak, read is followed by a stop condition 
 @return   byte read from I2C device
 */
extern unsigned char i2c_read(unsigned char ack);
#define i2c_read(ack)  (ack) ? i2c_readAck() : i2c_readNak(); 


/**@}*/
#endif

Yo realice la librería para usar con una memoria 24C256, adaptable a cualquier memoria I2C.

Código:
/*************************************************
 Driver para la memoria EEPROM 24C256.
 Lenguaje: C - Compilador: AVRGCC.
 programador: Moyano Jonathan.
 ************************************************/
#include <avr/io.h>
#include "i2cmaster.h"
#include <util/delay.h>

// Variables usadas:
uint8_t status,datos;


void external_eeprom_init(void) {

    i2c_init(); // Iniciamos I2C.
 }

void write_external_eeprom(uint8_t dato, uint16_t direccion) {

	i2c_start_wait(0xA0); // Enviamos comando de escritura de la memoria EEPROM.

	i2c_write(direccion>>8); // Enviamos parte alta de la dirección.
        i2c_write(direccion);    // Enviamos parte baja de la dirección.
        i2c_write(dato);

	i2c_stop(); 
	
   }

uint8_t read_external_eeprom(uint16_t direccion){

	i2c_start_wait(0xA0);
	i2c_write(direccion>>8); // Enviamos parte alta de la dirección.
        i2c_write(direccion);    // Enviamos parte baja de la dirección.
	
	status = i2c_rep_start(0XA1); // Enviamos comando para leer la memoria EEPROM.

	if(status != 0) { // Si el proceso de lectura falló...cerramos el bus I2C.

	  i2c_stop();

		   }
             else
  
	datos = i2c_readNak(); // caso contrario leemos dato.

  return(datos);

}

Y el programa ejemplo:

Código:
/*************************************************
 PROGRAMAS DE EJEMPLO PARA EL ATTINY2313 - 20PU..
 EJERCICIO Nº14: Usos de comunicación I2C por software (master - esclavo).
 Fecha: 2011.
 Programa: Control de la memoria 24C256.
 Cristal:  12Mhz.
 Programador: USBtinyISP
 ************************************************/

#include <avr/io.h>
#include "i2cmaster.h"  // Librería I2C por software.
#include <util/delay.h>
#include "UARTlbr.c"    // Librería para manejar la UART.
#include <stdlib.h>     // Funciones de conversión de tipos de datos.
#include "24C256.c"     // Funciones de control de la memoria 24C256.


uint8_t lectura; // Variable donde guardamos el dato leido desde la memoria EEPROM.
char Buffer[7];  // Buffer auxiliar.


int main(void)

{
	DDRB = 0x07;   // PB0-PB2 salidas.
	PORTB = 0x00;  // Ponemos todas las salidas a 0. 
	Init_UART(77); // Inicializamos la UART a 9.6Kbps 8N1.

   for(uint16_t i=0; i<=250; i++) {    // Hacemos 250 iteraciones , grabamos 250 datos en las
                                       // primeras 250 posiciones.

	void external_eeprom_init(void);
         
        write_external_eeprom(i,i);

        _delay_ms(5);
		
		lectura = read_external_eeprom(i); // Luego leemos las 250 posiciones de manera 
                                                   // consecutiva...
		
		  itoa(lectura,Buffer,10);         // convertimos el valor leido en ascci.

	      put_str(Buffer);                     // lo mostramos por el puerto serie.
		  
		  _delay_ms(5);
    }
        
}

Y la librería para manejar la USI, con el ATtiny2313 - 20PU.

Código:
// Librería UARTlbr.c
// Esta librería contiene las funciones de control de la UART del ATtiny2313.
// Programador: Moyano Jonathan.
// Lenguaje: AVR - GCC.
// Año: 2011.

/* A través de esta función iniciamos la UART configurando los siguientes parámetros:

- BAUDRATE: Velocidad de comunicación.
- Modo de comunicación: Seteamos Asincrono por defecto.
- Paridad de datos: Sin bit de paridad.
- Bits de datos: 8 bits de datos.

*/

void Init_UART (uint16_t ubrr_value)
{
   // Seteamos la velocidad de comunicación.
   UBRRL = ubrr_value;
   UBRRH = (ubrr_value>>8);
   /* 
   Parametros de la comunicación.
   >> Modo asincrono.
   >> NO paridad de datos.
   >> 1 Bit de stop.
   >> 8 bits de datos.
   */

   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
   // Habilitamos el envío/recepción de datos.
   UCSRB=(1<<RXEN)|(1<<TXEN);

}

// Función que recibe un byte desde la UART.

unsigned char get_byte(void)
{
  // En espera de datos entrantes.
  while (!(UCSRA & (1 << RXC)));

  // En cuanto recibimos un datos retornamos con el.
  return UDR;
}


// Función que transmite un byte por la UART.

void put_byte (unsigned char data)
{
  // Espera a que el buffer de transmisión este libre.
  while (!(UCSRA & (1 << UDRE)));

  // Comienza con la transmisión.
  UDR = data;
}

// Función que transmite una cadena por la UART.

void put_str(char *s)
{
	while(*s)			
	{
		put_byte(*s);	// Envía los datos de la cadena uno a uno.
		s++;		// Aumenta el contador de caracteres.
		_delay_us(50);  // Espera 50us.
	}
}

Espero les sirva, les dejo adjunto el proyecto también, hecho en WINAVR.



PD: Lo mejor para comenzar a programar con ATMEL es una pequeña placa de desarrollo, programador USB como por ejemplo el USBtinyISP y el WINAVR. Como microcontrolador, recomiendo el ATmega644 o en caso de andar corto de dinero el ATtiny2313 O ATmega8 (el PIC16F84 de los AVR..muy conocido y con mil ejemplos)
 

Adjuntos

  • i2c_software_24C256.rar
    40.8 KB · Visitas: 15
Última edición:
Hola a todos.
Hace poco he vuelto a usar los microcontroladores de Atmel motivado más por el entorno de programación “Atmel Studio” que ellos ofrecen, con soporte GCC.

atmst.png

Algunas características:
Es un entorno basado en el IDE de Visual Studio (en mi opinión, es más amigable).
Soporta a microcontroladores AVR y ARM de Atmel; incluye soporte para Arduino.
Incluye plantillas con soporte para todos los módulos AVR.
Soporte para lenguajes C/C++ y ASM (GCC).
Etc.
http://www.atmel.com/microsite/atmel_studio6/

¿Lo han usado?, ¿Cuál es su opinión?

PD: Esto aníma a crear un hilo en el foro dedicado a los AVR como los hay para los PIC "Curso/Tutorial de ....".
 

Adjuntos

  • atmst2.jpg
    atmst2.jpg
    156.6 KB · Visitas: 5
Es excelente, claro necesitas una pc medianamente potente de lo contrario tardaras horas esperando a que cargue, yo lo uso y me encanta, otro aspecto es el terrible tamaño que usa cuando lo instalas completo, pero si solo vas usar micros de 8 bits entonces reduce bastanten que eso ultimamente no importa con tremendos discos duros de Teras.
 
Hola:

¿Visual studio?

No sabía que Atmel puede programarse bajo Visual Studio .net, si te refieres al IDE de Microsoft. Ojalá hagan en el futuro y muy seriamente el C#, al menos le C++ que es más potente que solo el C.

Saludo.
 
Atrás
Arriba