Thông báo

Collapse
No announcement yet.

TWI master slave giữa hai con atmega

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

  • TWI master slave giữa hai con atmega

    Mình viết bằng codevision nha!

    Cao thủ nào có làm giao tiếp TWI(i2c) giữa 2 vi điều khiển atmega cho mình xin code tham khảo với...

    Mình cần chương trình đơn giản thôi VD nhấn nút con mster con slave sáng led, va ngược lại....

    mình hoc codevision nên chỉ hiểu code viết bằng thằng này thui...

    Mong anh em giúp đỡ nghiên cứu điêu đầu quá, ttrên mạng họ viết toàn bằng winavr đọc không hiểi nổi.....

    Mong ae giúp!!!!

    Thank nhiều

  • #2
    theo ý kiến mình thì vs cái giao tiếp i2c, khi master giao tiếp vs slave thì con slave có địa chỉ quy định cho nó, hơn nữa con slave phải ở chế độ rảnh nghĩa là ko giao tiếp vs 1 con master nào khác chẳng hạn trong trường hợp chung slave. khi con master gọi thì con slave phải trả lời ngay. nếu xét 1 con AVR làm master, 1 con AVR làm slave và con này chỉ ngồi chơi xơi nước chờ lệnh từ master theo ý kiến mình là ko khó, khó cái là con slave đang làm việc mà con master gọi ko trả lời thôi, nên thiết nghĩ phải có 1 cái j đó như ngắt báo chẳng hạn, thế nó thành 3 wire mất ^^
    Website chính thức đổi địa chỉ website thành
    Mời các bạn ghé thăm !!!

    Comment


    • #3
      Hi bạn hohoanganhfu
      Mình đã làm giao tiếp về cái này trên atmega 128. Bạn đang làm trên con nào. 1 Master mình điều khiển giao tiếp với nhiều con Slave. Mình sẽ post từ từ lên cho bạn hiểu. Mình cũng tham khảo trên Cùng học AVR (AVR tutorial) - Tài liệu AVR tiếng Việt. Trên đó họ hướng dẫn tỉ mỉ lắm.
      Khi giao tiếp I2C thì 1 con bạn phải init là master, con này ko cần đánh địa chỉ. các con khác phải init là slave, và đánh địa chỉ cho nó.
      VD mình dùng Atmega 128, thạch anh 11.0592MHz
      B1:Khoi tao 1 con lam master, bit rate là 51.200 kHz
      void I2C_M_INIT()
      {
      // 2 Wire Bus initialization
      // Generate Acknowledge Pulse: Off
      // 2 Wire Bus Slave Address: 00h
      // General Call Recognition: Off
      // Bit Rate: 51.200 kHz
      TWSR=0x00;
      TWBR=0x64; // 51200 Hz
      TWAR=0x00;
      TWCR=0x04;
      }

      B2: Khởi tạo Slave, bit rate 51.200 KHz
      void I2C_S_INIT(unsigned char add)
      {
      // 2 Wire Bus initialization
      // Generate Acknowledge Pulse: On
      // 2 Wire Bus Slave Address: add
      // General Call Recognition: Off
      // Bit Rate: 51.200 kHz
      TWSR=0x00;
      TWBR=0x64; // cap xung 51.200 kHz
      TWAR=(unsigned char)(add<<1)+0; // dia chi add, ko dung general call
      TWCR=0x45; // TWEA=1,TWEN=1 KICH HOAT TWI, TWIEN=1 KICH HOAT NGAT
      //TWCR=0x05; // TWEA=1,TWEN=1 KICH HOAT TWI, TWIEN=1 KICH HOAT NGAT
      }

      Có 3 con Slave thì bạn sẽ khởi tạo 3 con có địa chỉ lần lượt là 1,2,3
      Chúc bạn thành công. Mà bạn đang đi học hay đi làm rồi.
      Sống là để chiến đấu

      Comment


      • #4
        Cảm ơn bạn rất nhiều!!!!
        mình hay sài Atmega8,16,32 nhưng con nào cũng được cấu trúc giống nhau mà!
        mình cũng xem trên hocavr nhưng trình độ hạn hẹp nêng chưa hiểu nổi...nên mới lên đây nhờ giúp đỡ...

        hitechvn mong bạn post tiếp các phần sau...

        Mình dang học năm 3 trường KH Tự Nhiên TPHCM...
        Cũng mới học môn VĐK kỳ này nên còn gà quá.

        Bạn học trường nào vậy...
        Last edited by hohoanganhfu; 22-06-2012, 17:32.

        Comment


        • #5
          Mình đi làm rồi, hồi xưa mình cũng làm về cái này. Như vậy mình sẽ post lên từ từ phần giao tiếp I2C giữa 2 con Atmega128 nhé. Còn bạn tự chuyển thanh ghi cho phù hợp với con Atmega32. 2 dây SCL, SDA bạn treo lên 5V qua trở 4,7K chưa. Bạn đọc trên Cùng học AVR (AVR tutorial) - Tài liệu AVR tiếng Việt thì chỉ đọc về cấu trúc I2C thôi, còn code họ viết bằng winavr mình ko dùng.

          Trong bài toán này của bạn,chú ý bạn nên chỉ đọc 1 chiều truyền nhận dữ liệu như sau: Master truyền dữ liệu, Slave nhận dữ liệu
          ( Chức năng A, C trong hocavr.com)
          Chip Master chủ động truyền nên không cần dùng ngắt. Chíp Slave phải dùng ngắt để nhận dữ liệu từ master. Cả 2 chip bạn sử dụng chung 1 file header I2C như sau. File này mình cũng tự tạo cũng tham khảo trên mạng


          [I]#ifndef _AT128_I2C_H_
          #define _AT128_I2C_H_

          #include <mega128.h>

          /* TWCR definitions --------------------------------------------------------------------- */
          #define TWINT 7
          #define TWEA 6
          #define TWSTA 5
          #define TWSTO 4
          #define TWWC 3
          #define TWEN 2
          #define TWIE 0


          /* Master */
          #define I2C_START 0x08 // Master gui START thanh cong
          #define I2C_REPEATSTART 0x10 // gui REPEAT START thanh cong

          /* Master Transmitter */
          #define I2C_MT_SLA_ACK 0x18 // Master gui SLA+W thanh cong, da nhan ACK
          #define I2C_MT_SLA_NACK 0x20 // Master da gui SLA+W, nhan NOT ACK
          #define I2C_MT_DATA_ACK 0x28 // Master gui DATA thanh cong, nhan ACK
          #define I2C_MT_DATA_NACK 0x30 // Master da gui DATA, nhan NOT ACK
          #define I2C_MT_ARB_LOST 0x38 // Master lost

          /* Master Receiver */
          #define I2C_MR_ARB_LOST 0x38 // Master lost
          #define I2C_MR_SLA_ACK 0x40 // Master gui SLA+R thanh cong, da nhan ACK
          #define I2C_MR_SLA_NACK 0x48 // Master da gui SLA+R, nhan NOT ACK
          #define I2C_MR_DATA_ACK 0x50 // Master nhan DATA thanh cong, gui ACK
          #define I2C_MR_DATA_NACK 0x58 // Master nhan DATA, gui NOT ACK

          /* Slave Transmitter */
          #define I2C_ST_SLA_ACK 0xA8 // Slave nhan SLA+R, gui ACK
          #define I2C_ST_ARB_LOST_SLA_ACK 0xB0 // Slave lost SLA+R, gui ACK
          #define I2C_ST_DATA_ACK 0xB8 // Slave truyen DATA thanh cong, nhan ACK
          #define I2C_ST_DATA_NACK 0xC0 // Slave truyen DATA thanh cong, nhan NOT ACK
          #define I2C_ST_LAST_DATA 0xC8 // Slave gui DATA cuoi

          /* Slave Receiver */
          #define I2C_SR_SLA_ACK 0x60 // Slave nhan SLA+W thanh cong, gui ACK
          #define I2C_SR_ARB_LOST_SLA_ACK 0x68 // Slave lost SLA+W, gui ACK
          #define I2C_SR_GCALL_ACK 0x70 // Slave nhan GCALL, gui ACK
          #define I2C_SR_ARB_LOST_GCALL_ACK 0x78 // Slave lost GCALL, gui ACK
          #define I2C_SR_DATA_ACK 0x80 // Slave nhan DATA, gui ACK
          #define I2C_SR_DATA_NACK 0x88 // Slave nhan DATA, gui NOT ACK
          #define I2C_SR_GCALL_DATA_ACK 0x90 // Slave nhan DATA GCALL, gui ACK
          #define I2C_SR_GCALL_DATA_NACK 0x98 // Slave nhan DATA GCALL, gui NOT ACK
          #define I2C_SR_STOP 0xA0 // Slave nhan STOP

          /* Misc */
          #define I2C_NO_INFO 0xF8
          #define I2C_BUS_ERROR 0x00

          /*
          * R/~W bit in SLA+R/W address field.
          */
          #define I2C_READ 1
          #define I2C_WRITE 0

          #define I2CStart() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //0xA4
          #define I2CStop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //0x94
          //#define I2CWaitAck() {while(!(TWCR&(1<<TWINT)));} // kiem tra va doi cho den khi bit TWINT=1
          #define I2CChkAck() (TWSR&0xF8) //check ack
          #define I2C_STATUS (TWSR&0xF8)
          #define I2CSendAck() (TWCR|=(1<<TWINT)|(1<<TWEA))
          #define I2CSendNoAck() (TWCR&=~((1<<TWINT)|(1<<TWEA))) // su dung
          //#define I2CSendNoAck() (TWCR&=~((0<<TWINT)|(1<<TWEA))) // dang dieu chinh
          #define I2CSendByte(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
          #define I2CRcvNckByte() (TWCR=(1<<TWINT)|(1<<TWEN)) //0x84
          #define I2CRcvAckByte() (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA)) //0xC4

          #define I2C_Stop() I2CStop()
          #define I2C_SendAck() I2CSendAck()
          #define I2C_SendNoAck() I2CSendNoAck()
          #define I2C_WaitAck() I2CWaitAck()

          /* I2C Config */
          #define I2C_ERR 0
          #define I2C_CRR 1

          void I2CWaitAck()
          {
          static unsigned int i;
          //doi cho den khi rx_ack1=1 hoac i = 65535
          //toc do 9600 thi 1 byte =1ms -->250 byte = 0,25s <0,5s
          //timeout
          for(i=0;((TWCR&(1<<TWINT))==0)&&(i<65534);i++) //Wait loop // 0.5s
          {
          // for(ii=0;ii<10;ii++){;} //12s <--> ii=100; => 5s <--> ii=40 // test ko co gi khoang 2,2 s
          }
          // while(!(TWCR&(1<<TWINT)));
          }


          unsigned char I2C_Start()
          {
          cbi(TWCR,TWIE);
          I2CStart(); // xoa TWINT
          I2CWaitAck();
          if( I2CChkAck()!=I2C_START ) return I2C_ERR;
          return I2C_CRR;
          }
          unsigned char I2C_Repeatstart()
          {
          I2CStart();
          I2CWaitAck();
          if(I2CChkAck()!=I2C_REPEATSTART ) return I2C_ERR;
          return I2C_CRR;
          }

          unsigned char I2C_SendWAdr(unsigned char WAdr)
          {
          I2CSendByte((WAdr<<1)+I2C_WRITE);
          I2CWaitAck();
          if( I2CChkAck()!=I2C_MT_SLA_ACK ) return I2C_ERR;
          return I2C_CRR;
          }

          unsigned char I2C_SendRAdr(unsigned char RAdr)
          {
          I2CSendByte((RAdr<<1)+I2C_READ);
          I2CWaitAck();
          if( I2CChkAck()!=I2C_MR_SLA_ACK ) return I2C_ERR;
          return I2C_CRR;
          }
          unsigned char I2C_SendData(unsigned char configDat)
          {
          I2CSendByte(configDat);
          I2CWaitAck();
          if( I2CChkAck()!=I2C_MT_DATA_ACK ) return I2C_ERR;
          return I2C_CRR;
          }
          unsigned char I2C_RcvNAckData(unsigned char *pRdData)
          {
          I2CRcvNckByte(); // xoa TWINT va set NOT ACK
          I2CWaitAck();
          if( I2CChkAck()!=I2C_MR_DATA_NACK ) return I2C_ERR;
          *pRdData=TWDR;
          return I2C_CRR;
          }

          unsigned char I2C_RcvAckData(unsigned char *pRdData)
          {
          // unsigned char *ptr;
          I2CRcvAckByte();
          I2CWaitAck();
          if( I2CChkAck()!=I2C_MR_DATA_ACK ) return I2C_ERR;
          *pRdData=TWDR;
          return I2C_CRR;
          }

          unsigned char I2C_Write_Data(unsigned char WAdr,unsigned char data)
          {
          if( I2C_Start()==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          if( I2C_SendWAdr(WAdr)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          if( I2C_SendData(data)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          I2C_Stop();

          return I2C_CRR;
          }

          unsigned char I2C_Write_MultiData(unsigned char WAdr,unsigned char *pWrData,unsigned char num)
          {
          unsigned char i;
          unsigned char *ptr;

          ptr=pWrData ;

          if( I2C_Start()==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          if( I2C_SendWAdr(WAdr)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}
          for( i = 0; i < num; i++)
          {
          if( I2C_SendData(ptr[i])==I2C_ERR ) {I2C_Stop();return I2C_ERR;}
          }

          I2C_Stop();
          return I2C_CRR;
          }

          unsigned char I2C_Read_Data(unsigned char RAdr, unsigned char *pRdData)
          {
          unsigned char *ptr;

          ptr=pRdData ;

          if( I2C_Start()==I2C_ERR ){I2C_Stop();return I2C_ERR;}

          if( I2C_SendRAdr(RAdr)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          if( I2C_RcvNAckData(ptr)==I2C_ERR ){I2C_Stop();return I2C_ERR;}

          I2C_Stop();

          return I2C_CRR;
          }
          unsigned char I2C_Read_MultiData(unsigned char RAdr,unsigned char *pRdData,unsigned char num)
          {
          unsigned char i;
          unsigned char *ptr;
          ptr=pRdData ;

          if(I2C_Start()==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          if( I2C_SendRAdr(RAdr)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          for(i=0;i<num-1;i++)
          {
          if( I2C_RcvAckData(ptr)==I2C_ERR ){I2C_Stop();return I2C_ERR;}
          ptr++;
          }
          if( I2C_RcvNAckData(ptr)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          I2C_Stop();

          return I2C_CRR;
          }

          unsigned char I2C_WriteRead_MultiData(unsigned char WAdr,unsigned char *pWrData,unsigned char numW,unsigned char RAdr,unsigned char *pRdData,unsigned char numR)
          {
          unsigned char i;
          unsigned char *ptrW,*ptrR;
          ptrR=pRdData ;
          ptrW=pWrData ;


          if( I2C_Start()==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          if( I2C_SendWAdr(WAdr)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}
          for( i = 0; i < numW; i++)
          {
          if( I2C_SendData(ptrW)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}
          }

          if( I2C_Repeatstart()==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          if( I2C_SendRAdr(RAdr)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          for(i=0;i<numR-1;i++)
          {
          if( I2C_RcvAckData(ptrR)==I2C_ERR ){I2C_Stop();return I2C_ERR;}
          ptrR++;
          }
          if( I2C_RcvNAckData(ptrR)==I2C_ERR ) {I2C_Stop();return I2C_ERR;}

          I2C_Stop();

          return I2C_CRR;
          }

          void I2C_M_INIT()
          {
          // 2 Wire Bus initialization
          // Generate Acknowledge Pulse: Off
          // 2 Wire Bus Slave Address: 00h
          // General Call Recognition: Off
          // Bit Rate: 51.200 kHz
          TWSR=0x00;
          TWBR=0x64; // 51200 Hz
          TWAR=0x00;
          TWCR=0x04;
          }

          void I2C_S_INIT(unsigned char add)
          {
          // 2 Wire Bus initialization
          // Generate Acknowledge Pulse: On
          // 2 Wire Bus Slave Address: add
          // General Call Recognition: Off
          // Bit Rate: 51.200 kHz
          TWSR=0x00;
          TWBR=0x64; // cap xung 51.200 kHz
          TWAR=(unsigned char)(add<<1)+0; // dia chi add, ko dung general call
          TWCR=0x45; // TWEA=1,TWEN=1 KICH HOAT TWI, TWIEN=1 KICH HOAT NGAT
          //TWCR=0x05; // TWEA=1,TWEN=1 KICH HOAT TWI, TWIEN=1 KICH HOAT NGAT
          }

          void I2C_STOP()
          {
          TWSR=0x00;
          TWBR=0x00;
          TWAR=0x00;
          TWCR=0x00;
          }

          #endi
          f

          Bạn đọc qua file này. Mỗi lần master gửi địa chỉ, hay data yêu cầu phải có xác nhận. Slave sẽ gửi xác nhận bằng hàm I2CSendAck();
          Sống là để chiến đấu

          Comment


          • #6
            anh hitechvn oi , em đọc đoạn code của anh nhưng em không hiểu phần:
            #define TWINT 7
            #define TWEA 6
            #define TWSTA 5
            #define TWSTO 4
            #define TWWC 3
            #define TWEN 2
            #define TWIE 0

            là để làm gì vậy anh? Mong anh giải thích giùm em.
            Cám ơn anh nhiều.

            Comment


            • #7
              em Catinh cũng làm về phần này à. đó chính là vị trí các bit trong thanh ghi TWCR
              VD TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) //0xA4 tương đuơng TWCR=(1<<7)|(1<<5)|(1<<2) =0b10100100 hay 0xA4
              nói chung là để set giá trị thanh ghi TWCR, viết như trên sẽ rõ là mình on bit nào lên.
              Các phiên bản codevision avr mới sẽ có file tự define cái này rồi nên mình ko phải define nữa.
              Sống là để chiến đấu

              Comment


              • #8
                Mà em build trên codevision thi nó báo warmning, nhưng chạy trên protues thì không ảnh hưởng gì.
                em làm truyền nhận giữa 2 atmega32 ,master lấy dữ liệu từ 8 switch truyền cho slave hiển thị trên 3 led 7 đoạn, e chạy trên protues được rồi nhưng nạp vào mạch thực tế thì không chạy, anh hitechvn làm rồi có kinh nghiệm giúp em với. hix
                Last edited by catinh; 26-06-2012, 18:52.

                Comment


                • #9
                  Nguyên văn bởi catinh Xem bài viết
                  Mà em build trên codevision thi nó báo warmning, nhưng chạy trên protues thì không ảnh hưởng gì.
                  em làm truyền nhận giữa 2 atmega32 ,master lấy dữ liệu từ 8 switch truyền cho slave hiển thị trên 3 led 7 đoạn, e chạy trên protues được rồi nhưng nạp vào mạch thực tế thì không chạy, anh hitechvn làm rồi có kinh nghiệm giúp em với. hix
                  Bạn post sơ đồ nguyên lý cho mình coi xem nào. Trên protues chạy rồi mà thực tế ko chạy thì xem mạch hàn chuẩn chưa. Có bị đứt đường mạch không v...v...
                  Sống là để chiến đấu

                  Comment

                  Về tác giả

                  Collapse

                  hohoanganhfu Trường ĐH khoa Hoc Tự Nhiên Tìm hiểu thêm về hohoanganhfu

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

                  Collapse

                  Đang tải...
                  X