En primer lugar, permítame decir que soy un principiante en programación integrada. Estoy intentando escribir / leer usando el protocolo I2C de 24LC256 EEPROM usando Atmega16A.
Al depurar en Atmel Studio 7, veo que puedo enviar una condición de Inicio y escribir datos, pero cuando llamo Detener, el microcontrolador simplemente se bloquea.
He comprobado todas mis conexiones y parecen correctas. A continuación está todo mi código.
#include<avr/io.h>
#include<util/delay.h>
#include<inttypes.h>
void TWI_start(void);
void TWI_repeated_start(void);
void TWI_init_master(void);
void TWI_write_address(unsigned char);
void TWI_read_address(unsigned char);
void TWI_write_data(unsigned char);
void TWI_read_data(void);
void TWI_stop(void);
unsigned char address=0xA0, read=1, write=0;
unsigned char write_data=0x01, recv_data;
unsigned int dataMemAddress=0x08;
int main(void)
{
_delay_ms(2000);
DDRB=0xff;
TWI_init_master(); // Function to initialize TWI
while(1)
{
if(write_data==0x00)
{
write_data=1;
}
TWI_start(); // Function to send start condition
TWI_write_address(address+write); // Function to write address and data direction bit(write) on SDA
TWI_write_data(dataMemAddress);
TWI_write_data(dataMemAddress);
TWI_write_data(write_data); // Function to write data in slave
TWI_stop(); // Function to send stop condition
_delay_ms(10); // Delay of 10 mili second
TWI_start();
TWI_write_address(address+write); // Function to write address and data direction bit(write) on SDA
TWI_write_data(dataMemAddress);
TWI_write_data(dataMemAddress);
TWI_start();
//TWI_repeated_start();
TWI_read_address(address+read); // Function to write address and data direction bit(read) on SDA
TWI_read_data(); // Function to read data from slave
TWI_stop();
_delay_ms(2000);
write_data = write_data * 2;
}
}
void TWI_init_master(void) // Function to initialize master
{
TWSR = 0;
TWBR = 0x0C;//(1<<TWPS1);
TWCR = (1<<TWEN);
//TWBR=0x01; // Bit rate
//TWSR=(0<<TWPS1)|(0<<TWPS0); // Setting prescalar bits
// SCL freq= F_CPU/(16+2(TWBR).4^TWPS)
}
void TWI_start(void)
{
// Clear TWI interrupt flag, Put start condition on SDA, Enable TWI
TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR & (1<<TWINT))); // Wait till start condition is transmitted
while((TWSR & 0xF8)!= 0x08); // Check for the acknowledgement
}
void TWI_repeated_start(void)
{
// Clear TWI interrupt flag, Put start condition on SDA, Enable TWI
TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR & (1<<TWINT))); // wait till restart condition is transmitted
while((TWSR & 0xF8)!= 0x10); // Check for the acknoledgement
}
void TWI_write_address(unsigned char data)
{
TWDR=data; // Address and write instruction
TWCR=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8)!= 0x18); // Check for the acknoledgement
}
void TWI_read_address(unsigned char data)
{
TWDR=data; // Address and read instruction
TWCR=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte received
while((TWSR & 0xF8)!= 0x40); // Check for the acknoledgement
}
void TWI_write_data(unsigned char data)
{
TWDR=data; // put data in TWDR
TWCR=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8) != 0x28); // Check for the acknoledgement
}
void TWI_read_data(void)
{
TWCR=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8) != 0x50); // Check for the acknoledgement
recv_data=TWDR;
PORTB=recv_data;
}
void TWI_stop(void)
{
// Clear TWI interrupt flag, Put stop condition on SDA, Enable TWI
TWCR= (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
//_delay_ms(100);
//while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while(!(TWCR & (1<<TWSTO))); // Wait till stop condition is transmitted
}