Bác nào đã từng làm việc với giao tiếp I2C cua chip meag16 rồi cho em hỏi. Tại sao em dùng con mega16 kết nối tới EEPROM 24C64 qua I2C mà không được. Em gửi bit start và địa chỉ EEPROM đi EEPROM có ACK lại, nhưng gửi dữ liệu đi nó nhất định không nhận. Đây là code của em:
(Khi chạy chương trình, LCD hiện "Loi add_wr_H!").
#include <avr\io.h>
#include <D:\Setup\Quan trong\AVR\Header File\hunget_lcd.h>
void start();
void stop();
void diachighi();
void diachidoc();
int main()
{
// Khoi tao LCD de hien thi.
LCD_CUR_MODE(0,0);
LCD_INIT(4);
LCD_DIS_STR("Thu EEPROM:");
// TWI
TWBR = 3; // Khoi tao toc do 100.000Hz
///////////////////
start();
diachighi();
/////////////////////
TWDR = 0x01; // Dia chi cao la 01
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x30)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_wr_H!");
while(1);
}
//////////////////
TWDR = 0x01; // Dia chi thap la 01
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x30)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_wr_L!");
while(1);
}
////////////////////////
TWDR = 0x92; // Du lieu la 92
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x28)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi ghi data!");
while(1);
}
stop();
//////////////////////////////////////////////////
// Doc
//////////////////////////////////////////////////
start();
diachidoc();
///////////////////
TWDR = 0x01; // Dia chi cao la 00
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x28)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_re_H!");
while(1);
}
//////////////
TWDR = 0x01; // Dia chi thap la 09
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x28)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_re_L!");
while(1);
}
////////////////
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x50)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi doc data");
while(1);
}
LCD_CUR_JUMP(2,5);
LCD_PRINT_DIGIT(TWDR,3);
stop();
return(0);
}
void start()
{
TWCR |= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // Truyen bit start.
while(!(TWCR & (1<<TWINT))); // Cho co TWI
if((TWSR & 0xF8) != 0x08) // Neu sai start
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi start!");
while(1);
}
}
void stop()
{
TWCR |= (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); // Truyen stop.
while(!(TWCR & (1<<TWINT))); // Cho co TWI
}
void diachighi()
{
TWDR = 0xA0; // Dia chi slave 000. ghi
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x18)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi address wr!");
while(1);
}
}
void diachidoc()
{
TWDR = 0xA1; // Dia chi slave 000. doc
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x40)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi address re!");
while(1);
}
}
(Khi chạy chương trình, LCD hiện "Loi add_wr_H!").
#include <avr\io.h>
#include <D:\Setup\Quan trong\AVR\Header File\hunget_lcd.h>
void start();
void stop();
void diachighi();
void diachidoc();
int main()
{
// Khoi tao LCD de hien thi.
LCD_CUR_MODE(0,0);
LCD_INIT(4);
LCD_DIS_STR("Thu EEPROM:");
// TWI
TWBR = 3; // Khoi tao toc do 100.000Hz
///////////////////
start();
diachighi();
/////////////////////
TWDR = 0x01; // Dia chi cao la 01
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x30)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_wr_H!");
while(1);
}
//////////////////
TWDR = 0x01; // Dia chi thap la 01
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x30)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_wr_L!");
while(1);
}
////////////////////////
TWDR = 0x92; // Du lieu la 92
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x28)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi ghi data!");
while(1);
}
stop();
//////////////////////////////////////////////////
// Doc
//////////////////////////////////////////////////
start();
diachidoc();
///////////////////
TWDR = 0x01; // Dia chi cao la 00
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x28)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_re_H!");
while(1);
}
//////////////
TWDR = 0x01; // Dia chi thap la 09
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x28)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi add_re_L!");
while(1);
}
////////////////
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x50)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi doc data");
while(1);
}
LCD_CUR_JUMP(2,5);
LCD_PRINT_DIGIT(TWDR,3);
stop();
return(0);
}
void start()
{
TWCR |= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // Truyen bit start.
while(!(TWCR & (1<<TWINT))); // Cho co TWI
if((TWSR & 0xF8) != 0x08) // Neu sai start
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi start!");
while(1);
}
}
void stop()
{
TWCR |= (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); // Truyen stop.
while(!(TWCR & (1<<TWINT))); // Cho co TWI
}
void diachighi()
{
TWDR = 0xA0; // Dia chi slave 000. ghi
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x18)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi address wr!");
while(1);
}
}
void diachidoc()
{
TWDR = 0xA1; // Dia chi slave 000. doc
TWCR |= (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
if((TWSR & 0xF8) != 0x40)
{
LCD_CUR_JUMP(2,0);
LCD_DIS_STR("Loi address re!");
while(1);
}
}
Comment