Thông báo

Collapse
No announcement yet.

Giao tiếp I2C

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Giao tiếp I2C

    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);
    }
    }

  • #2
    mình cũng đã làm về I2C với cả 8051 và AVR.
    theo mình thì nếu 24Cxx đã nhận địa chỉ thì nó sẽ nhận được dữ liẹu.
    Nếu bạn làm với AVR thì đâu cần phải viết chương trinh phức tạp thế.AVR đã tích hợp sẵn các hàm cho i2c và lcd,bạn chỉ cần khởi tạo và xài thôi.
    mà hình như trong ct của bạn khi truyền dữ liệu thì sau byte địa chỉ của 24cxx chưa có địa chỉ để ghi dữ liệu vào 24cxx(địa chỉ của bộ nhớ 24cxx)
    lúc đầu bạn đừng nên kiểm tra bit ACK vội.
    bạn tham khảo code của tôi viét cho ds1307.
    #include <REGX51.H>
    #include <intrins.h>
    sbit SDA= P1^0;
    sbit SCL= P1^1;
    unsigned char Byte[8];
    //--------------------------------------------------//
    void delay(long n);
    void START(void);
    void STOP(void);
    unsigned char I2C_Read(unsigned char ACK);
    unsigned char I2C_Read2(unsigned char ACK);
    bit I2C_Write(unsigned char Data);
    //--------------------------------------------------//
    void delay(long n)
    {
    long i;
    for(i=1;i<n;i++){;}
    }
    void START()
    {
    SDA=1;
    SCL=1;
    SDA=0;
    delay(4);
    SCL=0;
    SDA=1;
    }
    void STOP()
    {
    SDA=0;
    SCL=1;
    delay(4);
    SDA=1;
    }
    bit I2c_Write(unsigned char Data)
    {
    unsigned char i;
    bit databit;
    for(i=1;i<=8;i++)
    {
    databit = Data&0x08;
    SDA = databit;
    Data = Data<<1;
    SCL =1;
    SCL=0;
    }
    SDA=1;
    SCL=1;
    databit = SDA;
    SCL=1;
    return(databit);
    }
    unsigned char I2C_Read2()
    {
    unsigned char i,Data;
    bit databit;
    Data=0;
    for(i=1;i<=8;i++)
    {
    SCL=1;
    databit =SDA;
    Data =Data<<1;
    Data =Data|databit;
    SCL=0;
    }
    SDA=1;
    SCL=1;
    SCL=0;
    return(Data);
    }
    unsigned char I2C_Read()
    {
    unsigned char Data=0,i;
    bit databit;
    for(i=1;i<=8;i++)
    {
    SCL=1;
    databit =SDA;
    Data =Data<<1;
    Data =Data|databit;
    SCL=0;
    }
    }
    void RtcRead(void)
    {
    unsigned char i;
    I2C_START();
    I2c_Write(0xd0);
    I2c_Write(0x00);
    I2c_STOP();
    delay(4);
    I2C_START();
    I2c_Write(0xd1);
    for(i=0;i<=6;i++)
    {
    Byte[i]=I2C_Read();
    }
    Byte[7] = I2C_Read2();
    I2c_STOP();
    }
    void RtcWrite(void)
    {
    unsigned char i;
    I2C_START();
    I2c_Write(0xd0);
    I2c_Write(0x00);
    for(i=0;i<=7;i++)
    {
    I2c_Write(Byte[i]);
    }
    I2c_STOP();
    }
    void Rtc_Reset(void)
    {
    Byte[0] = Byte[0]& 0x7f;
    Byte[2] = Byte[2]& 0xbf;
    Byte[0] = Byte[7]& 0xfc;
    }
    void main(void)
    {
    RtcRead();
    //Rtc_Reset();
    RtcWrite();
    while(1){;}
    }

    chúc bạn thành công

    Comment


    • #3
      Cái TWI nay khong kho vì Datasheet viết rất rỏ ban ban đọc kỷ lam lam duoc à

      Comment


      • #4
        BẠn có thể tham khảo tai http://www.dks.com.vn/forum_posts.as...38&get=last#67

        Comment

        Về tác giả

        Collapse

        Hunget Tìm hiểu thêm về Hunget

        Bài viết mới nhất

        Collapse

        • bqviet
          Trả lời cho Đấu tắt điện cho máy tính bảng
          bởi bqviet
          Bqv cáo lỗi vì chưa đủ khả năng diễn giải để người đọc hiểu. Người làm kỹ thuật sâu đôi khi như thế đó. Về việc nạp pin không vào dù cell mới, khả năng cái mạch quản lý đó đã hỏng - cũng chính là nguyên nhân đám cell cũ hỏng từ đầu.
          06-12-2025, 17:17
        • nguyendinhvan
          Trả lời cho Xin hỏi về mạch thu FM/AM trong catsette
          bởi nguyendinhvan
          Theo tôi, nó chỉ là cái Tuy- ê - nơ, hoặc là khối Trung Văn Tần, nó một phần trong cái Da đì ô thôi. Vì có thấy một chỗ có ba chân hàn, giiống như chân Cờ rít sờ tăng 455 ki nô hẹc. Còn khối Tuy ê nơ thì không nhìn thây cái Di ốt Va di cáp...
          05-12-2025, 19:59
        • afrendly
          Trả lời cho Đấu tắt điện cho máy tính bảng
          bởi afrendly
          Có vẻ ngoài hiểu biết của mình rồi. Cuối cùng mình quyết định tìm mua 2 pin trên Shopee, giá 200K thay vào. Tuy nhận pin được 1%, sạc mãi không vào nhưng cũng mở được máy lên. Vậy cũng tạm. Cảm ơn bạn đã hỗ trợ nhé....
          04-12-2025, 01:27
        • nick22
          Trả lời cho Máy điện châm ?
          bởi nick22
          Đúng như bạn nói, máy điện châm hiện nay trên thị trường đã khá đa dạng về mẫu mã, chức năng và giá thành.
          01-12-2025, 13:23
        Đang tải...
        X