Autor Tema: Problema con I2C de Atmega32 y DS1307  (Leído 12574 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado The_Chosen

  • PIC12
  • **
  • Mensajes: 51
Problema con I2C de Atmega32 y DS1307
« en: 17 de Julio de 2008, 23:02:26 »
Hola amigos, tengo un gran problema con el protocolo de comunicación I2C de un Atmega 16, sencillamente... NO FUNCIONA :brickwall: Prácticamente me he estado dando contra una pared durante todo el día. No he querido usar Librerías ya hechas porque he tenido problemas al usarlas y además al revisar como se programa el I2C, me di cuenta que no era difícil.
Les doy el código que escribí para que puedan verlo bien y así ayudarme :ouch: (estoy programando en lenguaje C, en el Avrstudio4 y usando un Jtag, además lo he simulado en proteus con idénticos resultados :( ):

Código: [Seleccionar]
#define F_CPU 8000000UL
#define SCL_CLOCK 100000L
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


#define I2C_WRITE   0
#define I2C_READ    1       
#define START 0x08
#define MT_SLA_ACK 0x18
#define MT_DATA_ACK 0x28

#define esclavo 0xD0



void i2c_inicio(void);
unsigned char i2c_start(unsigned char address);
unsigned char rep_i2c_start(unsigned char address);
unsigned char i2c_escr(unsigned char dato);
unsigned char i2c_leerAck(void);
unsigned char i2c_leerNack(void);


void i2c_inicio(void)
{

/*inicializar TWPS = 0 => prescaler =1 */

TWSR = 0;
TWBR = ((F_CPU/SCL_CLOCK)-16)/2 ;

}

unsigned char i2c_start (unsigned char address)
{

/*ENVIAR CONDICIÓN START*/

TWCR = /**/ (1<<TWSTA) | (1<<TWEN)| (1<<TWINT);

PORTC = 0x03;


/*ESPERAR SETEO POR WARDWARE DEL FLAG TWINT*/
while (!(TWCR & (1<<TWINT)));

if ((TWSR&0xF8) != START) return 1;


/*mandar dirección de esclavo*/

TWDR = address;
TWCR = (1<<TWINT)|(1<<TWEN);

/*ESPERAR SETEO POR WARDWARE DEL FLAG TWINT*/
while (!(TWCR & (1<<TWINT)));

if ((TWSR&0xF8) != MT_SLA_ACK) return 1;

return 0;


}

/*repetición START*/

unsigned char rep_i2c_start (unsigned char address)
{
return i2c_start(address);
}


unsigned char i2c_escr (unsigned char dato)
{

/*escribir dato después de haber mandado la dirección del esclavo*/

TWDR = dato;
TWCR = (1<<TWINT)|(1<<TWEN);

/*asegurarse del seteo de TWINT*/

while (!(TWCR & (1<<TWINT)));

/* enmascarar y comparar TWSR */

if ((TWSR&0xF8) != MT_DATA_ACK) return 1;

return 0;

}


unsigned char i2c_leerAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));   

    return TWDR;

}

unsigned char i2c_leerNack(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) ;
while(!(TWCR & (1<<TWINT)));   

    return TWDR;

}




void i2c_stop(void)

{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<TWSTO);
}

void main (void)
{

i2c_inicio();
i2c_start(esclavo+I2C_WRITE);
i2c_escr(0x00);/*envío dirección o puntero*/
i2c_escr(0x59); /*segundo*/
i2c_escr(0x35);/*minutos*/
i2c_escr(0x22);/*horas*/
i2c_escr(0x05);/*dia*/
i2c_escr(0x19);/*fecha*/
i2c_escr(0x11);/*mes*/
i2c_escr(0x09);/*año*/
i2c_escr(0x10);/*confuguracion*/
i2c_stop();
}

éste código es para configurar el DS1307, aún no he escrito la parte que me lea los datos de fecha, hora, etc.

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #1 en: 18 de Julio de 2008, 03:12:34 »
Hola amigo yo veo que tu codigo falta varias cosas aqui te pongo un ejemplo mas definido http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=59061&start=20
Suerte
Saludo

Desconectado The_Chosen

  • PIC12
  • **
  • Mensajes: 51
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #2 en: 19 de Julio de 2008, 11:56:43 »
Hola STK500, gracias por responder. El objetivo principal del código es activar el módulo I2C. Es evidente que faltan cosas por ejemplo, más rutinas de error que se corresponden con los códigos de estado del registro TWSR. En la página que has linkeado muestra un ejemplo, que está más completo porque toma mayor cantidad de códigos de error:
Código: [Seleccionar]
#define ISC_START       0x08
#define ISC_REP_START   0x10
#define ISC_SLA_ACK     0x18
#define ISC_SLA_NAK     0x20
#define ISC_DAT_ACK     0x28
#define ISC_DAT_NAK     0x30
#define ISC_ARB_LOST    0x38
#define ISC_MASK        0xF8

Además de ordenar mucho mejor los datos de hora, fecha, etc, para ser mostrados posteriormente a través de una tarjeta  desarrollo:

Código: [Seleccionar]
unsigned char ucSecond, ucMinute, ucHour, ucWeekday, ucDay, ucMonth, ucYear;
Sin embargo, no deja de llamarme poderosamente la atención que mi código es lo mínimo requerido para hacer funcionar el módulo I2C del Atmega16, tomando como referencia el código que aparece en la hoja de datos del ésta. Además, hay librerías ya hechas por otros programadores, igual de simples que han sido probados por otras personas y que no les ha dado problema alguno.

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #3 en: 19 de Julio de 2008, 14:22:49 »
pues debo decirte que lo he probado y me tira solo un error, en la primera linea , que version de AVRstudio tiene?
deberia arreglar tu codigo y ordenarlo mas mejor,los incuide van primero y luegos los define.
Saludo

Desconectado The_Chosen

  • PIC12
  • **
  • Mensajes: 51
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #4 en: 20 de Julio de 2008, 12:16:32 »
pues debo decirte que lo he probado y me tira solo un error, en la primera linea , que versión de AVRstudio tiene?
deberia arreglar tu codigo y ordenarlo mas mejor,los incuide van primero y luegos los define.
Saludo

Cuando generé el código tenia la versión 4.14 build 584, ahora la cambié a la versión  4.14 build 589. En esta última versión no he probado el código  :mrgreen:
Así que los include van primero.. en realidad no me había percatado de ese detalle, de hecho me daba lo mismo :P jujujuju
¿Qué error te lanza? ¿Puedes escribirlo aquí en el foro ?
¿Puedes darme más sugerencias respecto a mi programación?

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #5 en: 20 de Julio de 2008, 12:56:06 »
pues te sugiero que trabaje con la libreria e GGC y actualice el programa, aparte tu codigo no esta completo y mal redactado.
asi es imposible de ayudarte
Saludo

Desconectado The_Chosen

  • PIC12
  • **
  • Mensajes: 51
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #6 en: 20 de Julio de 2008, 16:43:11 »
pues te sugiero que trabaje con la libreria e GGC y actualice el programa, aparte tu codigo no esta completo y mal redactado.
asi es imposible de ayudarte
Saludo

¿Qué error obtuviste cuando compilabas el programa? ¿o sólo era una advertencia?

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #7 en: 20 de Julio de 2008, 19:02:29 »
pues te sugiero que trabaje con la libreria e GGC y actualice el programa, aparte tu codigo no esta completo y mal redactado.
asi es imposible de ayudarte
Saludo

¿Qué error obtuviste cuando compilabas el programa? ¿o sólo era una advertencia?
el error que me daba  es de Mcu que no va con esa configuracion y te falta libreria
y solo un Warning!
no segui probando porque tu codigo no tiene ningun sentido incompleto
asi que si quiere probarlo ponlo completo y te lo pruebo, pero ponle comentario para comprenderlo mejor ya que yo no uso ese lenguaje, sino Bascom con el AvrStudio4
Saludo


Desconectado The_Chosen

  • PIC12
  • **
  • Mensajes: 51
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #8 en: 21 de Julio de 2008, 19:15:00 »
Ya, probé el ATMEGA16 con la librería del señor Peter Fleury (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip) de la cual extraje algunas líneas de programación para mi código, y además lo probé también con el mio usando mi JTAG por supuesto. Mis resultados son los siguientes:

1) Cuando envío la dirección del esclavo, en el registro Status TWSR aparece el código $20, lo cual me indica que se envió el SLA+W y no le llegó el bit de reconocimiento (NOT ACK).

2) Cuando envío un byte de datos, en el registro Status TWSR aparece el código $30, lo cual me indica que se envió el dato pero el maestro no recibió el bit de reconocimiento (NOT ACK).

Por lo tanto el problema no es en el maestro, sino en el esclavo  :D (pensé que podía ser por la direccion del esclavo pero ya lo revisé), ya he cambiado el integrado DS1307 4 veces y no hay respuesta alguna  :?
¿Alguna sugerencia ?

Desconectado sir_alex

  • PIC10
  • *
  • Mensajes: 5
Problema con I2C de Atmega32 y DS1307 libreria DS1307
« Respuesta #9 en: 28 de Abril de 2010, 15:03:40 »
Hola que tal alguien tiene la libreria "ds1307.inc"
estoy trabajando en hacer el reloj en C, trabajo en codevisionavr pero no tiene esa libreria, agradeceria si alguien la tiene o me puede decir donde bajarla gracias!

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #10 en: 28 de Abril de 2010, 15:12:43 »
codeVision es un programa de pago y limitado.

« Última modificación: 28 de Abril de 2010, 15:14:52 por stk500 »

Desconectado The_Chosen

  • PIC12
  • **
  • Mensajes: 51
Re: Problema con I2C de Atmega32 y DS1307 libreria DS1307
« Respuesta #11 en: 28 de Abril de 2010, 22:31:01 »
Hola que tal alguien tiene la libreria "ds1307.inc"
estoy trabajando en hacer el reloj en C, trabajo en codevisionavr pero no tiene esa libreria, agradeceria si alguien la tiene o me puede decir donde bajarla gracias!


Hola, también puedes usar la librería de Peter Fleury para I2C que funciona excelente para este integrado y para cualquier integrado que utilice I2C.
http://homepage.hispeed.ch/peterfleury/i2cmaster.zip

Claro, es para Avr studio :P

Desconectado sir_alex

  • PIC10
  • *
  • Mensajes: 5
DS1307 libreria
« Respuesta #12 en: 29 de Abril de 2010, 13:32:45 »
Hola de nuevo, pues estoy intentando con la libreria que encontre para DS1307, aunq ahora tengo otro detalle, parecia que ya habia quedado pero no; encontre la siguiente libreria (abajo) y la guarde con ".h" y ".inc" y la meti en las carpetas de Codevisionavr, cuando compilo me marca un error de sintaxis de esta libreria, y no estoy seguro si es porq no es para codevision o que pasa  :(.... y si la quito del programa, me marca 3 errores en el codigo, donde ya se supone uso instrucciones de la libreria.. :S.... bueno ojala me pueda orientar gracias, saludos!

LIBRERIA:
Código: [Seleccionar]
;******************************** Librería DS1307.INC ***********************************
;
;
; Estas subrutinas permiten realizar las tareas de manejo del reloj-calendario DS1307
; Este dispositivo transmite la información vía serie a través de un bus I2C.
;
; ZONA DE DATOS **********************************************************************

CBLOCK
Anho ; Guarda el año.
Mes ; Guarda el mes.
Dia ; Guarda el día.
DiaSemana ; Guarda el día de la semana: lunes, etc.
Hora ; Guarda las horas.
Minuto ; Guarda los minutos.
Segundo ; Guarda los segundos.
ENDC

DS1307_DireccionEscritura EQU 0xD0 ; Dirección del DS1307.
DS1307_DireccionLectura EQU 0xD1

; Subrutina "DS1307_Inicializa" ---------------------------------------------------------
;
; Configura la señal cuadrada que genera el DS1307 en su pin SQW/OUT a 1 Hz.

DS1307_Inicializa
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el byte a escribir,
call I2C_EnviaByte ; está en la posición 07h, que corresponde
movlw 0x07 ; al control de la señal cuadrada.
call I2C_EnviaByte
movlw b'00010000' ; Escribe en el registro de control para
call I2C_EnviaByte ; deshabilitar la onda cuadrada del DS1307.
call I2C_EnviaStop ; Termina de enviar datos.

call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el byte a escribir,
call I2C_EnviaByte ; está en la posición 07h, que corresponde
movlw 0x00 ; al control de la señal cuadrada.
call I2C_EnviaByte
movlw b'00000000' ; Escribe en el registro de control para
call I2C_EnviaByte ; deshabilitar la onda cuadrada del DS1307.
call I2C_EnviaStop ; Termina de enviar datos.

return

; Subrutina "DS1307_Lee" ----------------------------------------------------------------
;
; Se leen las variables de tiempo del DS1307 y se guardan en los registros correspondientes.
;
DS1307_Lee
bcf I2C_UltimoByteLeer
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el primer byte
call I2C_EnviaByte ; a leer está en la posición 00H, que corresponde
movlw 0x00 ; a los segundos.
call I2C_EnviaByte
call I2C_EnviaStop ; Envía condición de Stop.
; Ahora va a leer el DS1307.
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionLectura
call I2C_EnviaByte
call I2C_LeeByte ; Lee los segundos.
movwf Segundo ; Lo carga en el registro correspondiente.
call I2C_LeeByte ; Lee el resto de los registros utilizando
movwf Minuto ; el mismo procedimiento.
call I2C_LeeByte
movwf Hora
call I2C_LeeByte
movwf DiaSemana
call I2C_LeeByte
movwf Dia
call I2C_LeeByte
movwf Mes
bsf I2C_UltimoByteLeer ; Para terminar.
call I2C_LeeByte
movwf Anho
call I2C_EnviaStop ; Acaba de leer.
return


; Subrutina "DS1307_Escribe" ----------------------------------------------------------------
;
; Carga los datos de los registros Anho, Mes, etc., dentro del DS1307.

DS1307_Escribe
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el primer byte a escribir
call I2C_EnviaByte ; está en la posición 00h que corresponde
movlw 0x00 ; a los segundos.
call I2C_EnviaByte
movf Segundo,W ; Pasa los segundos de la memoria del PIC16F84A al
call I2C_EnviaByte ; DS1307.
movf Minuto,W ; Y se repite el proceso para el resto.
call I2C_EnviaByte
movf Hora,W
call I2C_EnviaByte
movf DiaSemana,W
call I2C_EnviaByte
movf Dia,W
call I2C_EnviaByte
movf Mes,W
call I2C_EnviaByte
movf Anho,W
call I2C_EnviaByte
call I2C_EnviaStop ; Termina de enviar datos.
return

Desconectado FuYiVape

  • PIC12
  • **
  • Mensajes: 69
    • Electronica y Sistemas
Re: Problema con I2C de Atmega32 y DS1307
« Respuesta #13 en: 29 de Abril de 2010, 13:58:17 »
Hola!

Aca les dejo los archivos para implementar TWI y acceder al DS1307
Yo los estoy usando y funcionan perfecto!

Espero les sirvan!
Saludos.

Desconectado The_Chosen

  • PIC12
  • **
  • Mensajes: 51
Re: DS1307 libreria
« Respuesta #14 en: 29 de Abril de 2010, 16:40:11 »
Hola de nuevo, pues estoy intentando con la libreria que encontre para DS1307, aunq ahora tengo otro detalle, parecia que ya habia quedado pero no; encontre la siguiente libreria (abajo) y la guarde con ".h" y ".inc" y la meti en las carpetas de Codevisionavr, cuando compilo me marca un error de sintaxis de esta libreria, y no estoy seguro si es porq no es para codevision o que pasa  :(.... y si la quito del programa, me marca 3 errores en el codigo, donde ya se supone uso instrucciones de la libreria.. :S.... bueno ojala me pueda orientar gracias, saludos!

LIBRERIA:
Código: [Seleccionar]
;******************************** Librería DS1307.INC ***********************************
;
;
; Estas subrutinas permiten realizar las tareas de manejo del reloj-calendario DS1307
; Este dispositivo transmite la información vía serie a través de un bus I2C.
;
; ZONA DE DATOS **********************************************************************

CBLOCK
Anho ; Guarda el año.
Mes ; Guarda el mes.
Dia ; Guarda el día.
DiaSemana ; Guarda el día de la semana: lunes, etc.
Hora ; Guarda las horas.
Minuto ; Guarda los minutos.
Segundo ; Guarda los segundos.
ENDC

DS1307_DireccionEscritura EQU 0xD0 ; Dirección del DS1307.
DS1307_DireccionLectura EQU 0xD1

; Subrutina "DS1307_Inicializa" ---------------------------------------------------------
;
; Configura la señal cuadrada que genera el DS1307 en su pin SQW/OUT a 1 Hz.

DS1307_Inicializa
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el byte a escribir,
call I2C_EnviaByte ; está en la posición 07h, que corresponde
movlw 0x07 ; al control de la señal cuadrada.
call I2C_EnviaByte
movlw b'00010000' ; Escribe en el registro de control para
call I2C_EnviaByte ; deshabilitar la onda cuadrada del DS1307.
call I2C_EnviaStop ; Termina de enviar datos.

call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el byte a escribir,
call I2C_EnviaByte ; está en la posición 07h, que corresponde
movlw 0x00 ; al control de la señal cuadrada.
call I2C_EnviaByte
movlw b'00000000' ; Escribe en el registro de control para
call I2C_EnviaByte ; deshabilitar la onda cuadrada del DS1307.
call I2C_EnviaStop ; Termina de enviar datos.

return

; Subrutina "DS1307_Lee" ----------------------------------------------------------------
;
; Se leen las variables de tiempo del DS1307 y se guardan en los registros correspondientes.
;
DS1307_Lee
bcf I2C_UltimoByteLeer
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el primer byte
call I2C_EnviaByte ; a leer está en la posición 00H, que corresponde
movlw 0x00 ; a los segundos.
call I2C_EnviaByte
call I2C_EnviaStop ; Envía condición de Stop.
; Ahora va a leer el DS1307.
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionLectura
call I2C_EnviaByte
call I2C_LeeByte ; Lee los segundos.
movwf Segundo ; Lo carga en el registro correspondiente.
call I2C_LeeByte ; Lee el resto de los registros utilizando
movwf Minuto ; el mismo procedimiento.
call I2C_LeeByte
movwf Hora
call I2C_LeeByte
movwf DiaSemana
call I2C_LeeByte
movwf Dia
call I2C_LeeByte
movwf Mes
bsf I2C_UltimoByteLeer ; Para terminar.
call I2C_LeeByte
movwf Anho
call I2C_EnviaStop ; Acaba de leer.
return


; Subrutina "DS1307_Escribe" ----------------------------------------------------------------
;
; Carga los datos de los registros Anho, Mes, etc., dentro del DS1307.

DS1307_Escribe
call I2C_EnviaStart ; Envía condición de Start.
movlw DS1307_DireccionEscritura ; Indica al DS1307 que el primer byte a escribir
call I2C_EnviaByte ; está en la posición 00h que corresponde
movlw 0x00 ; a los segundos.
call I2C_EnviaByte
movf Segundo,W ; Pasa los segundos de la memoria del PIC16F84A al
call I2C_EnviaByte ; DS1307.
movf Minuto,W ; Y se repite el proceso para el resto.
call I2C_EnviaByte
movf Hora,W
call I2C_EnviaByte
movf DiaSemana,W
call I2C_EnviaByte
movf Dia,W
call I2C_EnviaByte
movf Mes,W
call I2C_EnviaByte
movf Anho,W
call I2C_EnviaByte
call I2C_EnviaStop ; Termina de enviar datos.
return

¿Podrías decir cuáles son los errores?