PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Giao tiếp USB, CAN, I2C, SPI, USART... (http://www.picvietnam.com/forum/forumdisplay.php?f=45)
-   -   Giao tiếp I2C (http://www.picvietnam.com/forum/showthread.php?t=611)

falleaf 07-09-2006 11:54 PM

Giao tiếp I2C
 
1 Attachment(s)
Bài báo cáo này do Nguyễn Chí Linh thực hiện trong thời gian làm mod của picvietnam, nhưng không hiểu sao vẫn chưa được đăng. Hôm nay thấy bên dientuvietnam thảo luận về vấn đề này, cho nên mới tìm lại bài báo cáo này và gửi lên.

Chúc vui

bien_van_khat 08-09-2006 06:19 PM

Em post 1 bài ngoài vấn để kỹ thuật nhé. Chữ I2C đọc là gì nhỉ? Nguyên gốc của nó là IIC hoặc viết I2C nhưng số 2 viết nhỏ phía trên giống số mũ. Có người đọc là "Ai chu xi" (I 2 C đánh vần tiếng Anh :D), em nghĩ đúng phải đọc là "Double I C", tương tự như IEEE đọc là (I triple E).

Nhưng em thích đọc là I 2 C (đánh vần tiếng Việt :D). Không biết mọi người đọc như thế nào nhỉ?

namqn 08-09-2006 07:14 PM

Trích:

Nguyên văn bởi bien_van_khat (Post 4838)
Em post 1 bài ngoài vấn để kỹ thuật nhé. Chữ I2C đọc là gì nhỉ? Nguyên gốc của nó là IIC hoặc viết I2C nhưng số 2 viết nhỏ phía trên giống số mũ. Có người đọc là "Ai chu xi" (I 2 C đánh vần tiếng Anh :D), em nghĩ đúng phải đọc là "Double I C", tương tự như IEEE đọc là (I triple E).

Nhưng em thích đọc là I 2 C (đánh vần tiếng Việt :D). Không biết mọi người đọc như thế nào nhỉ?

Dân Anh đọc là "ai tu xi", tiếng của họ thì mình cứ đọc theo họ thôi. Đọc "double I C" thì dài hơn "ai tu xi" nên họ không đọc (dân Anh lười lắm), còn tại sao đọc "triple E" thì thử so sánh "I E E E" với "I triple E" xem cái nào dễ đọc hơn (cùng số âm tiết).

Thân,

falleaf 09-09-2006 01:22 PM

Trích:

Nguyên văn bởi bien_van_khat (Post 4838)
Em post 1 bài ngoài vấn để kỹ thuật nhé. Chữ I2C đọc là gì nhỉ? Nguyên gốc của nó là IIC hoặc viết I2C nhưng số 2 viết nhỏ phía trên giống số mũ. Có người đọc là "Ai chu xi" (I 2 C đánh vần tiếng Anh :D), em nghĩ đúng phải đọc là "Double I C", tương tự như IEEE đọc là (I triple E).

Nhưng em thích đọc là I 2 C (đánh vần tiếng Việt :D). Không biết mọi người đọc như thế nào nhỉ?

Thực ra, mọi người vẫn đọc là "Eye two See". Đây là cách đọc chính xác, không sai. Một cách đọc khác là "Eye square See", đây cũng là một cách đọc đúng. Còn "Double Eye See" thì anh chưa nghe đọc bao giờ. Những cách nói này là anh nói chuyện trực tiếp với bọn nước ngoài, và bọn nó dùng như vậy.

Còn "Eye Triple E" là cách đọc được ghi chú trực tiếp trên trang ieee.org. Ở Pháp thì nó lại đọc (anh viết tiếng Việt) "Y troa dsơ" Cũng đồng nghĩa với I và 3 chữ E.

Do vậy, từ nay về sau, thống nhất trên PICVietnam, chúng ta đọc I2C là "Eye two See", chứ không đọc "Eye Square See" (đề phòng trường hợp cần voice chat, sẽ có một ngày đại hội picvietnam online), còn khi viết thì viết I2C cho nhanh, chứ không nên viết rất mất công viết công thức Latex.

Chúc vui.

thanhha 11-09-2006 10:51 AM

Mình dùng lệnh I2C trong CCS có hiệu quả ko ?!
 
Vì mình đang viết thử I2C. Thấy chương trình mẫu(EX_Slave) trong CCS C mô phỏng bộ nhớ ngoài 24xx chuẩn, nên nạp chạy thử thấy: viết từ Master (Ctr Mater lấy ví dụ: EX_EXTEE) ít nhất là 4 lần mới được, còn đọc thì lại ko được. Xem tài liệu thì thấy có rất nhiều bit bẫy tình huống I2C, nhưng các lệnh về I2C trong CCS thì đơn giản và ít. Vậy, có vấn đề gì không.

Code:

#include <16F876A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12


#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)

typedef enum {NOTHING, CONTROL_READ,
              ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;

I2C_STATE fState;
BYTE address, buffer[0x10];


#INT_SSP
void ssp_interupt ()
{
  BYTE incoming;

  if (i2c_poll() == FALSE) {
      if (fState == ADDRESS_READ) {  //i2c_poll() returns false on the
        i2c_write (buffer[address]);//interupt receiving the second
        fState = NOTHING;          //command byte for random read operation
      }
  }
  else {
      incoming = i2c_read();

      if (fState == NOTHING){
        fState = CONTROL_READ;
      }
      else if (fState == CONTROL_READ) {
        address = incoming;
        fState = ADDRESS_READ;
      }
      else if (fState == ADDRESS_READ) {
        buffer[address] = incoming;
        fState = NOTHING;
      }
  }
}


void main ()
{
  int i;

  fState = NOTHING;
  address = 0x00;
  for (i=0;i<0x10;i++)
      buffer[i] = 0x00;

  enable_interrupts(GLOBAL);
  enable_interrupts(INT_SSP);

  while (TRUE) {}
}


thanhha 12-09-2006 11:25 AM

Có ai quan tâm vấn đề I2C trong CCS, cho Hà hỏi 1 chút:
i2c_isr_state() hình như không có trong V 3.227. Version này chỉ có các lệnh I2C cho 16F877A là: i2c_start(), i2c_stop(), i2c_read(),i2c_write(), i2c_poll().
Có phải vậy không. Nếu vậy, mình phải tự tạo i2c_irs_state(). Có phải vậy ko?!.

Vì trong Help V4.0,có nói đến i2c_isr_state(), còn Help V3.227 Hà đang dùng thì ko thấy nói đến.
Có ai rành I2C, chỉ giáo giùm chút ít kinh nghiệm.Xin rất cảm ơn!!

hoanf 12-09-2006 12:52 PM

Chào Hà.
Tui cũng đang mò làm I2C trên CCS đây.
Hà nói là phiên bản 3.227 kô có i2c_irs_state(). Vậy sao Hà kô tải V3.249 về làm.
Mình hi vọng tui cả Hà sẽ cùng nghiên cúu vấn đề này.
Chào
hoanf

thanhha 12-09-2006 01:00 PM

Hà đang tìm đường link để tải Version khác cao hơn: V3.242 thì sáng tới giờ ko thấy gì. Vậy, mình tìm thử V3.249 xem sao.

Bạn biết link V3.249 thì hướng dẫn Hà với !!
Rất cảm ơn !!!

Thanhha

hoanf 12-09-2006 02:52 PM

Chào bạn.
Bạn có thể tải bản V3.249 ở đây
http://rapidshare.de/files/32817261/CCSC_3.249.rar

hoanf

thanhha 13-09-2006 01:59 PM

1 Attachment(s)
Hà vừa thử chtr I2c: Master 16F877A, Slave 16F876A, cùng giao tiếp PC để kiểm tra dữ liệu đọc và viết của Master và Slave> Thấy rất tốt ! I2C hay thiệt! Nhiêm vụ bây giờ mình chỉ tạo giao thức dữ liệu, còn chtr service plug&play slave thì thấy hơi khó! Nhưng mònh cố gắn viết thử. Cảm ơn Hoanf, mọi người rất nhiều !!
Code:

**********************************************
Chtr Master, mình thay đổi chút ít từ chtr mẫu EX_EXTEE.
          1.chỉ liên kết 2401.c (thay vì địa chỉ mặc đinh là 0xa0,
mình thay là 0x10).
          2. Vẫn truyền lệnh từ PC
**********************************************
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include <input.c>
#include <2401.c>


void main() {

  BYTE value, cmd;
  EEPROM_ADDRESS address;

  init_ext_eeprom();

  do {
      do {
        printf("\r\nRead or Write: ");
        cmd=getc();
        cmd=toupper(cmd);
        putc(cmd);
      } while ( (cmd!='R') && (cmd!='W') );

      printf("\n\rLocation: ");

      address = gethex1();

      if(cmd=='R')
        printf("\r\nValue: %X\r\n",READ_EXT_EEPROM( address ) );

      if(cmd=='W') {
        printf("\r\nNew value: ");
        value = gethex();
        printf("\n\r");
        WRITE_EXT_EEPROM( address, value );
      }
  } while (TRUE);
}

Code:

**********************************************
Chtr Slave, thì có thay đổi chút ít từ chtr mẫu EX_Slave:
                  1. giám sát 3 ô nhớ trên PC
                  2. khai báo địa chỉ la 0x10.
**********************************************
#include <16F876A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt ()
{
  BYTE incoming, state;

        state = i2c_isr_state();

        if(state < 0x80)                                          //Master is sending data
        {
                incoming = i2c_read();
                if(state == 1)                                                        //First received byte is address
                        address = incoming;
                if(state == 2)                                                        //Second received byte is data
                        buffer[address] = incoming;
        }
        if(state == 0x80)                                        //Master is requesting data
        {
                i2c_write(buffer[address]);
        }
}

void main ()
{
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_SSP);

  while (TRUE) {
          printf("\r\nValue0: %X\r\n",buffer[0]);
          delay_ms(1000);
          printf("\r\nValue1: %X\r\n",buffer[1]);
          delay_ms(1000);
          printf("\r\nValue2: %X\r\n",buffer[2]);
          delay_ms(1000);
          printf("\r\nValue3: %X\r\n",buffer[3]);
          delay_ms(1000);
}
}

******************************************
Phần mạch điện có File đính kèm :

falleaf 13-09-2006 04:48 PM

Anh đề nghị em post thêm sơ đồ mạch nguyên lý đi kèm. Thực ra không có gì phức tạp cả, chỉ vì bài viết mà chỉ có code không thôi thì nó không sinh động. Hơn nữa, người sau đọc vào không có hình ảnh đi kèm, nhiều khi người ta không hiểu nổi và ngại đọc. Chỉ cần có một cái hình vào, thì bài viết sẽ sinh động hơn nhiều.

Chúc vui.

hoanf 13-09-2006 05:24 PM

:d
 
Chào các bạn và Hà.
Mình mới viết được chương trình giao tiếp I2C đơn giản dùng các hàm của CCS.
Mời các bạn xem và cho nhận xét

Master: truyền dữ liệu cho Slave. Mỗi lần truyền 1 byte.

Code:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#define SLAVE_ADDRESS 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

void write_I2C(int8 a)
{
  i2c_start();
  i2c_write(SLAVE_ADDRESS);
  i2c_write(a);
  i2c_stop();
}

void main()
{
  int8 value;
 
  value = 0;
  while(1){
      write_I2C(value);
      value++;
      delay_ms(100);
  }
}


Slave thì chỉ tiến hành kiểm tra có phải Master truyền hay kô. Nếu truyền thì nhận byte dữ liệu và hiển thị lên port_B:
Code:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

int8 value;

#INT_SSP
void i2c_isr()
{
  int8 state;
  int8 address;
  state = i2c_isr_state();
  if(state == 0)
      address = i2c_read();
  else if(state < 0x80)
        value = i2c_read();
}

void main()
{
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_SSP);

  set_tris_b(0x00);
  while(1){
      output_b(value);
  }
}

Thân
hoanf

hoanf 14-09-2006 12:34 PM

Alo
 
Chào các bạn!!
Mình gặp trục trặc khi đọc dữ liệu từ Slave về.
Đây là đoạn code sử dụng cho 2 con PIC 18F877A.

Master: Yêu cầu Slave nhận dữ liệu liên tục (cách nhau 500ms) và nó sẽ hiển thị giá trị nhận được lên Port_b. Dùng leds để quan sát.

Code:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#define SLAVE_ADDRESS 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

int8 read_I2C()
{
  int8 value;

  i2c_start();
  i2c_write(SLAVE_ADDRESS + 1);
  value = i2c_read();
  i2c_stop();
  return value;
}

void main()
{
  int8 value;

  set_tris_b(0x00);
 
  while(1){
      value = read_I2C();
      output_b(value);
      delay_ms(500);
  }
}

Slave: Truyền dữ liệu cho master và mỗi lần truyền thì giá trị cần truyền tăng lên 1 đơn vị.
Code:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
  int8 state;
  int8 address;
  state = i2c_isr_state();
  if(state >= 0x80){
      i2c_write(value);
      value++;
  }
}

void main()
{
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_SSP);

  set_tris_b(0x00);
  while(1){
      output_b(value);     
  }
}


thanhha 14-09-2006 04:24 PM

Theo Hà nghĩ, ở Master, khi mình đọc cũng phải chờ xung ACK từ Slave thì chtr ko bị rối.
Bạn thử thêm một chtr con chờ Bus trong <2401.c>:

Code:

//**************code thêm vào*********************
BOOLEAN ext_eeprom_ready()
{
  int1 ack;
  i2c_start();           
  ack = i2c_write(SLAVE_ADDRESS); 
  i2c_stop();
  return !ack;
}
//**********************************************
int8 read_I2C()
{
    int8 value;
    while(!ext_eeprom_ready());                        // code thêm vào
    i2c_start();
    i2c_write(SLAVE_ADDRESS + 1);
    value = i2c_read();
    i2c_stop();
    return (value);
}

void main()
{
    int8 value;

    value = 0x00;
    set_tris_b(0x00);

    while(1){
    value = read_I2C();
    output_b(value);
    delay_ms(500);
    }
}

**********************************************
Thân mến !!

falleaf 14-09-2006 04:49 PM

Các em nhớ đặt chương trình trong thẻ [code]...[/code ] (nhớ viết liền lại)

Như vậy thì mọi người sẽ đọc dễ hơn, và nếu code dài quá thì nó cũng thu gọn lại trong một khung cố định.

Ngoài ra, code cũng có thụt ra thụt vào rõ ràng như trong đoạn code mà tụi em copy. Chú ý điều này khi viết bài.

Chúc vui.

Hoanf, và ThanhHa, như anh nói, giúp anh post một cái hình mạch nguyên lý giao tiếp đúng như trong cái đề tài mà tụi em đang thảo luận, để mọi người dễ theo dõi.

Thanks muchie.

hoanf 15-09-2006 11:02 AM

Chào mọi người và Hà.
Mình làm cho nó chạy được rồi.
Mình có một thắc mắc mong Hà và mọi người giải thích dùm. Đó là thông số "FORCE_HW" mà trong phần #use i2c sử dụng
Mình cho rằng thông số này chỉ được áp dụng khi ta quy định chân của I2C đúng theo chân của PIC quy đinh (đối với Pic hỗ trợ I2C). khi mình áp thông số này thì CCS sẽ biên dịch chương trình sao cho phù hơp với cấu hình phần cứng mà PIC hỗ trợ. Còn nếu kô áp thông số này lên thì nó sẽ thực hiện giao thức I2C hoàn toàn bằng phần mềm.

Và còn một lệnh mình chưa rõ đó là : I2C_POLL()

Mong Hà và các bạn góp ý.
Thân
hoanf

falleaf 15-09-2006 12:04 PM

Trích:

Nguyên văn bởi hoanf (Post 4950)
Mình có một thắc mắc mong Hà và mọi người giải thích dùm. Đó là thông số "FORCE_HW" mà trong phần #use i2c sử dụng
Mình cho rằng thông số này chỉ được áp dụng khi ta quy định chân của I2C đúng theo chân của PIC quy đinh (đối với Pic hỗ trợ I2C). khi mình áp thông số này thì CCS sẽ biên dịch chương trình sao cho phù hơp với cấu hình phần cứng mà PIC hỗ trợ. Còn nếu kô áp thông số này lên thì nó sẽ thực hiện giao thức I2C hoàn toàn bằng phần mềm.

Và còn một lệnh mình chưa rõ đó là : I2C_POLL()

Mong Hà và các bạn góp ý.
Thân
hoanf

HW = hardware. Có nghĩa là sử dụng giao tiếp phần cứng. Em hình dung như thế này. Một chuẩn giao tiếp, thực ra chỉ là một quy định và dùng chung, gọi là chuẩn. Thế thì một chuẩn, bao gồm những thứ gì?

Anh chỉ nói đơn giản thế này, nó bao gồm chuẩn về kết nối, có nghĩa là các header em dùng để cắm vào, nôm na là chuẩn cơ khí, chuẩn về đường dây (các loại dây để đảm bảo tín hiệu truyền)..chuẩn cáp, chuẩn thứ ba nôm na là chuẩn về điện là các chuẩn về điện áp, dòng điện, và chuẩn thứ tư là chuẩn logic, chuẩn này ảnh hưởng đến số lượng dây truyền, phương thức truyền nhận, tín hiệu trên các dây... Nói chung, một chuẩn truyền bao gồm các chuẩn như vậy. Anh dùng từ ngữ không chính xác lắm, tụi em có thể tra cứu lại các từ ngữ tiếng Anh, anh chỉ cố gắng giải thích theo nghĩa đơn giản nhất thôi.

Như vậy, bây giờ khi em kết nối về mặt cơ khí (với I2C là hàn vào board, hoặc hai dây cắm vào), chuẩn cable là đường mạch in hoặc dây 3000 đồng/sợi... hehehe... vân vân...

Vậy cái cuối cùng, là chuẩn về logic và điện tử. Em thấy rằng, nếu như bây giờ, mình lấy 2 dây nối bất kỳ, nối vào nhau, dùng con PIC, lập trình một chân tạo xung clk, một chân truyền tín hiệu, đưa vào MAX232, thì lập tức em sẽ có được giao tiếp RS232. Cái này em hoàn toàn lập trình được, đối với bất kỳ chân nào, chỉ cần phỏng theo chuẩn logic của RS232 là em có thể lập trình được. Như vậy, người ta gọi cách làm đó là giao tiếp theo chuẩn RS232 bằng phần mềm. Và thực tế là người ta đã làm như vậy. Còn với giao tiếp I2C, thì em thấy nó có khác gì RS232 đâu, nó cũng có thể làm được như vậy bằng phần mềm, chỉ cần lập trình về mặt logic đảm bảo chuẩn truyền của nó.

Với con PIC bất kỳ, không hỗ trợ I2C, em hoàn toàn có thể thực hiện giao tiếp I2C bằng phần mềm theo cách trên. Với các con PIC hỗ trợ I2C, em có 2 cách để thực hiện giao tiếp I2C là phần cứng và phần mềm. Thế thì phần cứng, thực ra là người ta thêm vào đó một khối module phần cứng, thay cho cái việc mình viết một đoạn chương trình để chạy, thì cái module đó nó làm thay mình, và nó được đóng gói theo đúng chuẩn.

CCS C hỗ trợ hai dạng lập trình. Một dạng là lập trình vài dòng để kích hoạt cái module phần cứng của PIC và chạy giao tiếp bằng phần cứng. Một dạng khác, là nó sẽ tạo ra code để thực hiện cái chuẩn giao tiép đó, gọi là phần mềm.

Như vậy, nếu em dùng module phần cứng, bắt buộc, em phải dùng đúng cái chân của nó, vì cái chân đó nó gắn vào module phần cứng I2C của PIC, còn nếu em dùng phần mềm, thì như anh nói, em có thể dùng bất kỳ chân I/O nào, và em chỉ cần định nghĩa nó là chân I/O là xong, em hoàn toàn có thể tự làm chuyện này.

Hôm nào rảnh, anh sẽ tìm lại code I2C viết bằng phần mềm để tụi em tham khảo. Anh viết lâu rồi, nên phải tìm lại, không hứa trước sẽ nhanh.

Trong khi chờ đợi, cho anh cái hình mạch nguyên lý lên đây đi, coi như là đánh đổi nhé :)

Chúc vui

hoanf 15-09-2006 12:35 PM

Cám ơn anh Falleaf!!
Thực ra mô hình của bạn Hà mới phức tạp nên cần sơ đồ.
Chứ mô hình của em chỉ có 2 con PIC 16F877A nối với nhau qua các chân I2C chứ chả có gì nên em kô post lên.
Nay thấy anh nói vậy thì để em ngồi vẽ post sơ đồ lên.
Còn về chương trình em chưa gửi lên được vì đang tiến hành Optimize. Sẽ post cùng sơ đồ luôn :D.

Thân
hoanf

hoanf 15-09-2006 02:47 PM

1 Attachment(s)
Chào các bạn!!
Cho mình post sơ đồ và code của minh lên đây cho các bạn coi và có gì góp ý cho mình nha.

Đây là đoạn code Master: Master truyền một mảng cho Slave và nhận về mảng mà đã chuyển cho Slave để hiển thị lên port_b(kiểm tra hihi...) giống echo.

Code:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)

void write_I2C(int8 value, int8 slave_addr)
{
  i2c_start();
  i2c_write(slave_addr);
  i2c_write(value);
  i2c_stop();
}

int8 read_I2C(int8 slave_addr)
{
  int8 value_re;
  i2c_start();
  i2c_write(slave_addr + 1);
  value_re = i2c_read(0);
  i2c_stop();
  return value_re;
}

void main()
{
  int8 value_re;
  int8 i;
  const int8 N = 8;
  const int8 DIGITS[N] ={ 0b11111111,
                          0b11111110,
                          0b11111100,
                          0b11111000,
                          0b11110000,
                          0b11100000,
                          0b11000000,
                          0b10000000,
                          };
  const int8 slave_addr = 0x10;

  set_tris_b(0x00);
  while(1){
      for(i = 0; i<8; i++){
        write_I2C(DIGITS[i], slave_addr);
        delay_ms(500);
        value_re = read_I2C(slave_addr);
        output_b(value_re);
      }
  }
}

Còn đây là đoạn code Slave:

Code:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
  int8 state;

  state = i2c_isr_state();
  if(state < 0x80)
      value = i2c_read();
  if(state == 0x80){
      i2c_write(value);
  }
}

void main()
{
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_SSP);

  set_tris_b(0x00);
  while(1){
      output_b(value);
  }
}


falleaf 15-09-2006 03:35 PM

Đơn giản vậy thôi, các em vừa làm xong một bài hướng dẫn I2C khá đầy đủ rồi :)

Thanks muchie

hoanf 15-09-2006 05:04 PM

Trích:

Nguyên văn bởi falleaf (Post 4956)
Đơn giản vậy thôi, các em vừa làm xong một bài hướng dẫn I2C khá đầy đủ rồi :)

Thanks muchie

Hay quá ha. Nhưng nếu mà có chương trình nào tự viết bằng C mà kô lấy các hàm của CCS hỗ trợ sãn cho I2c thì hay biết mấy :D.
Vậy chắc phải đợi bài hướng dẫn I2C nâng cao của anh Falleaf qua'.
Tui em đang đợi chương trình của anh đây.
Thân
hoanf

thanhha 15-09-2006 05:23 PM

Hi các bạn!
Hôm nay I2C không chay, mình dò 1 buổi, phát hiện điện áp cấp 2 Board Master va Slave không đủ 5V và bị lệch(đã nối mass chung 2 board): Master ->4.9V, Slave -> 4.2V. Các bạn nên kiểm tra dòng, áp mạch khi I2C không chạy với chtr đã chuẩn.

Chúc mừng hoanf, bạn đã thành công!!

hoanf 15-09-2006 05:53 PM

Trích:

Nguyên văn bởi thanhha (Post 4958)
Hi các bạn!
Hôm nay I2C không chay, mình dò 1 buổi, phát hiện điện áp cấp 2 Board Master va Slave không đủ 5V và bị lệch(đã nối mass chung 2 board): Master ->4.9V, Slave -> 4.2V. Các bạn nên kiểm tra dòng, áp mạch khi I2C không chạy với chtr đã chuẩn.

Chúc mừng hoanf, bạn đã thành công!!

Hihi! Cám ơn bạn nha.
Ah còn cái vụ nối mass chung là chuối nhất luôn đo'. Làm cho chuẩn I2C từ 2 dây trở thành 3 dây :(.
Giờ chỉ còn 1 cách đó là nối đất cả 2 board là thành chuẩn 2 dây. Hix.

Ah còn cái zu áp thấp này tui mới thấy đó nha. Đúng là gặp mấy lỗi này thì trời biết. Ông Hà này hay lắm mới tìm ra lỗi này đó.

Thân. Cuối tuần vui vẻ nha.
hoanf

falleaf 15-09-2006 10:17 PM

Trích:

Nguyên văn bởi hoanf (Post 4957)
Hay quá ha. Nhưng nếu mà có chương trình nào tự viết bằng C mà kô lấy các hàm của CCS hỗ trợ sãn cho I2c thì hay biết mấy :D.
Vậy chắc phải đợi bài hướng dẫn I2C nâng cao của anh Falleaf qua'.
Tui em đang đợi chương trình của anh đây.
Thân
hoanf

Anh không cho chương trình trực tiếp, nhưng anh cho một gợi ý, không biết như vậy có được không nhỉ?

Con PIC16F84A hình như không có tích hợp chức năng I2C? Nếu như anh không nhớ lầm?!

Bắc thang lên hỏi ông trời, ông mà không biết tui mời ông ggô

Chúc vui

falleaf 15-09-2006 10:42 PM

À, nếu đang nghiên cứu I2C thì anh nghĩ nhân tiện nên đi cho nó tới nơi tới chốn. Tụi em thử làm cái I2C bằng phần mềm xem, tất nhiên source code thì coi như anh cung cấp rồi :), bằng gợi ý.

Ngoài ra, để động viên tinh thần học tập của tụi em, anh xin tặng mỗi em 1 con PIC (nếu tụi em ở SG, thì ghé cửa hàng STH để chọn bất kỳ con nào có ở cửa hàng mà em muốn). Gửi thông tin cá nhân cho anh, để anh nhắn cho anh Lợi.

Hiện tại anh đi rồi nên không thể chuyển phát nhanh cho tụi em được (mỗi lần chuyển tốn tiền, và nếu nhờ Chính chuyển thì tốn tiền của Chính). Anh không biết Hà ở đâu, nhưng hình như Hoàn thì ở HCM và có gặp anh rồi thì phải. Nếu Hà ở nơi khác, Hoàn có thể nhận giúp và chuyển lại cho Hà sau có được không?

Tuỳ tụi em quyết định

Chúc vui.

namqn 15-09-2006 11:56 PM

Trích:

Nguyên văn bởi hoanf (Post 4957)
Hay quá ha. Nhưng nếu mà có chương trình nào tự viết bằng C mà kô lấy các hàm của CCS hỗ trợ sãn cho I2c thì hay biết mấy :D.
Vậy chắc phải đợi bài hướng dẫn I2C nâng cao của anh Falleaf qua'.
Tui em đang đợi chương trình của anh đây.
Thân
hoanf

Tôi đang viết tutorial cho module I2C của dsPIC, tự viết các chương trình con, nhưng còn viết hướng dẫn nữa nên chưa post lên được. Các bạn có thể tham khảo ở đó sau vài ngày nữa.

Ngoài ra còn có chương trình cho PIC18 viết trong C18, dùng kỹ thuật bit-banging, đã thử nghiệm rồi.

Các bạn có thể tìm được nhiều ví dụ tương tự trên net.

Thân,

ntc 16-09-2006 11:45 AM

Trích:

À, nếu đang nghiên cứu I2C thì anh nghĩ nhân tiện nên đi cho nó tới nơi tới chốn. Tụi em thử làm cái I2C bằng phần mềm xem, tất nhiên source code thì coi như anh cung cấp rồi , bằng gợi ý.

Ngoài ra, để động viên tinh thần học tập của tụi em, anh xin tặng mỗi em 1 con PIC (nếu tụi em ở SG, thì ghé cửa hàng STH để chọn bất kỳ con nào có ở cửa hàng mà em muốn). Gửi thông tin cá nhân cho anh, để anh nhắn cho anh Lợi.

Hiện tại anh đi rồi nên không thể chuyển phát nhanh cho tụi em được (mỗi lần chuyển tốn tiền, và nếu nhờ Chính chuyển thì tốn tiền của Chính). Anh không biết Hà ở đâu, nhưng hình như Hoàn thì ở HCM và có gặp anh rồi thì phải. Nếu Hà ở nơi khác, Hoàn có thể nhận giúp và chuyển lại cho Hà sau có được không?

Tuỳ tụi em quyết định

Chúc vui.
Ồ, không sao, không sao, một vài triệu thì thiếu, chứ một vài ngàn thì thu xếp được, thu xếp được.

Hoanf có tham gia dự án PID thì phải. Tha hồ mà nhận chip nhẩy. :D.

Mấy bạn cứ gửi địa chỉ lên đây, mình sẽ chuyển chip cho.

Bạn nào muốn viết code I2C bằng phần mềm, ngôn ngữ ASM, có thể ghé mình, cho mượn tài liệu mà nghiên cứu luôn.

Hiểu được cách viết bằng ASM, chuyển code sang C chắc cũng không có vấn đề gì lớn nhẩy.

;)

chumeodihia 17-09-2006 01:50 AM

Trời ui sao các cụ lão làng nhà ta lai viết giao tiếp bằng ccs không vậy.Tôi thì viết truyền thông I2C bằng cả hai ngôn ngữ luôn ==masterviết bằng CCS và claver viết bằng ASM chạy cực tốt==.MASTER DÙNG 18F452 VÀ CLAVER DUNG 18F4431.HÔM NÀO TUI POST LÊN CHO ANH EM NGHIÊN CỨU CHƠI,hom nay do không đem theo chương trình.
Bác FALLEAF ơi Tôi là thành viên mới vào diễn đàn ghé qua forum này thấy hay nên nhảy vào không biết sau khi post chương trình này lên thì tui được đệ tử mấy túi nhỉ..8-x hehehe.Hỏi thử cho biết thôi chứ không có gì đau

Phong độ chỉ là thoáng qua
Trình độ mới là vĩnh cửu
Chú mèo đihia tái bút
thanks

falleaf 17-09-2006 02:43 AM

HI, mấy túi không quan trọng, vì có thể spam thật nhiều sẽ có nhiều túi :). Nhưng điều đó không được khuyến khích trong picvietnam. Ở picvietnam có một cách nhìn hơi lạ một chút với các diễn đàn khác, đó là sự tập trung và làm việc.

Hãy cho những gì bạn muốn lấy. Đó là nguyên tắc vô cùng quan trọng.

Chúc vui.

rmitoday 18-09-2006 11:42 AM

Bẩm báo PIC bang chủ và các trưởng lão? Như bang chủ đã nói là lên học viết ASM trước rùi chuyển qua các ngôn ngữ khác sẽ dễ. Em thấy cần một tutorial cho I2C bằng ASM vì em mới học nên chỉ biết ASM thui. Các cao thủ ra chiêu bằng C ào ào chẳng hiểu mô tê chi hết á.
Xin cảm ơn.

falleaf 18-09-2006 04:27 PM

Có 2 application notes về master và slave được M cung cấp khá chi tiết, 734, 735 thì phải, không nhớ chính xác là cái nào, bạn có thể tìm hiểu thêm về nó.

Tutorial về I2C bằng MPASM thì Phạm Đức Mạnh đã cung cấp rồi thì phải, bạn tìm lại bài viết của mafd47a.

Chúc vui.

thanhha 18-09-2006 05:12 PM

Vâng! Đúng như Bác F nói !! Hà đã load tài liệu ASM về I2C này ở đây:
http://www.microchip.com/stellent/id...t6_NextRow=101

+Tài liệu AN735 nói về Master.
+Tài liệu AN734 nói về Slave.

Theo Hà nghĩ, mình có thể dùng tài liệu này
để tham khảo tự viết lệnh I2C mới trong CCS C thì rất tốt.
Chương trình viết hay lắm!!

Bạn tham khảo đi !

namqn 21-09-2006 06:26 PM

Các bạn tham khảo thêm ở đây về I2C:

http://namqn.byethost7.com/Commu.php
Thân,

hoangminh1234 03-10-2006 02:23 PM

Anh oi, em chua hieu ve I2C lam va tren dien dan lai chang thay ai noi ve chuyen nay. Trong giao thuc I2C trong CCS co ham i2c_read(), nhung ham do chi la ham doc tu master truyen xuong slave dung ko a? Cai ma tui em dang can la nhu vay: master truyen xuong 10byte (10byte nay chua gia tri la vi tri muon dieu khien dong co rc), sau do slave se doc 10 byte do va xuat gia tri dieu khien cho tung dong co ung voi tung byte da duoc truyen tu master. Nhung em ko thay ai noi ve chuyen nay va co thac mac nhu sau, anh chi dum em nhe
- Du lieu tu master truyen xuong se vao dau trong slave(eeprom?),neu trong eeprom thi lam sao de con slave co the lay ra va su dung cac gia tri do?

falleaf 03-10-2006 02:41 PM

Trích:

Nguyên văn bởi hoangminh1234 (Post 5230)
Anh oi, em chua hieu ve I2C lam va tren dien dan lai chang thay ai noi ve chuyen nay. Trong giao thuc I2C trong CCS co ham i2c_read(), nhung ham do chi la ham doc tu master truyen xuong slave dung ko a? Cai ma tui em dang can la nhu vay: master truyen xuong 10byte (10byte nay chua gia tri la vi tri muon dieu khien dong co rc), sau do slave se doc 10 byte do va xuat gia tri dieu khien cho tung dong co ung voi tung byte da duoc truyen tu master. Nhung em ko thay ai noi ve chuyen nay va co thac mac nhu sau, anh chi dum em nhe
- Du lieu tu master truyen xuong se vao dau trong slave(eeprom?),neu trong eeprom thi lam sao de con slave co the lay ra va su dung cac gia tri do?

Bạn đọc thật kỹ tutorial của picvietnam do Linh viết ở ngay bài đầu tiên của luồng này (falleaf gửi thay cho Linh).

Linh viết bài này có một số vấn đề truyền tải chưa được rõ lắm do cách dùng câu chữ mà thôi. F viết lại đôi chút như sau:

trong giao tiếp I2C, có thể có (1 master và 1 slave) hoặc (1master và nhiều slave). Đây là giao thức chuẩn. Tuy nhiên, cải tiến giao thức này một chút, chúng ta sẽ có mạng I2C (nhiều master, mỗi con thay phiên làm master)..

Chúng ta chỉ đề cập giao tiếp I2C ở dạng chuẩn, tức là có duy nhất 1 master trong mạng.

Khi muốn dữ liệu truyền từ A tới B. Có nhiều trường hợp xảy ra như sau:
A là master, B là slave: khi đó A sẽ gửi một loạt dữ liệu có định dạng sẵn (các bạn xem lại định dạng I2C), thì trong định dạng đó có bao gồm mấy thông tin như sau (master muốn đọc hay muốn ghi? địa chỉ của slave là bao nhiêu? master có muốn kiểm tra bằng xung ACK, tức là xung báo đã truyền nhận đầy đủ hay không? và nội dung dữ liệu (nếu master muốn ghi), và địa chỉ thanh ghi của slave (nếu master muốn đọc một thanh ghi nào đó trong slave).

Nếu A là slave, thì slave không được quyền muốn. Khi nào master kêu nhận thì phải nhận, khi nào master kêu gửi, thì phải gửi. Slave thì không được quyền muốn. Nếu muốn thì làm nô tì I-Sau-ra :D.

Còn nếu cả A và B đều là slave, khi master cần truyền dữ liệu từ A sang B, thì Master phải yêu cầu A gửi cho master, nhận xong, master gửi lại cho B.

Như vậy vấn đề học giao tiếp I2C, chỉ đơn giản là học cách định dạng dữ liệu trong frame truyền của I2C (mô tả sơ bộ ở trên), và học cách nối mạng giữa mạng điện áp thấp và điện áp cao (vd: một thiết bị I2C 3.3V, kết nối với thiết bị 5V thì làm thế nào?).. kiểu như vậy thôi là các bạn đã có thể thiết kể rất nhiều ứng dụng với I2C, và làm việc với rất nhiều thiết bị rồi.

Chúc vui.

hoangminh1234 03-10-2006 04:01 PM

tức là con tớ hoàn toàn bị động trong trường hợp này sao? Nó không thể nào lấy tí thông tin nào đem bán cho các điệp viên để kiếm chút cháo sao? Buồn vậy! Vậy theo anh làm sao giải quyết bài toán mà tụi em đang gặp phải nhỉ:

Một con chủ truyền 10 byte cho con tớ và con tớ có toàn quyền sử dụng 10 byte này??
anh cho em xin ý kiến nhé

Encoder 03-10-2006 06:05 PM

Trích:

Nguyên văn bởi falleaf (Post 4956)
Đơn giản vậy thôi, các em vừa làm xong một bài hướng dẫn I2C khá đầy đủ rồi :)

Chưa đâu bác. Còn viết I2C trên HTPIC thì sao. Bác đã viết chương trình nào chưa, cho em xin tí code.

hoangminh1234 03-10-2006 06:17 PM

Trích:

Nguyên văn bởi falleaf (Post 5232)
và địa chỉ thanh ghi của slave (nếu master muốn đọc một thanh ghi nào đó trong slave).

cai nay sao em ko thay trong CCS noi nang gi toivay anh? Nếu ta biết được địa chỉ thanh ghi bên slave thì hoàn toàn có thể lấy ra xài rồi.
Em vừa đọc cái SPI, thấy con tớ đọc dữ liệu trong thanh ghi SSPBUF ( được master truyền xuống) sau đó xuất ra port B.
file: http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf
Nó làm em nghĩ rằng ko biết mình có thể làm tương tự với i2c ko?? cao huynh nào rành i2c cho ý kiến nhé

falleaf 03-10-2006 09:46 PM

Trích:

Nguyên văn bởi hoangminh1234 (Post 5234)
Một con chủ truyền 10 byte cho con tớ và con tớ có toàn quyền sử dụng 10 byte này??
anh cho em xin ý kiến nhé

Khi con Slave nhận được dữ liệu, thì nó nằm trong thanh ghi đệm, thanh ghi nào thì F quên rồi, và khi đã nằm trong bộ đệm của nó, thì nó có toàn quyền sử dụng. Nó thích làm gì thì làm.

Các bạn lưu ý rằng, F nói trường hợp nâng cao, thì chúng ta hoàn toàn có quyền sử dụng mạng Multi Master. Khi bạn setup chip ở chế độ Slave, thì nó thụ động. Nhưng hãy thử nghĩ, tôi làm slave cho mạng này, và làm master của một mạng khác, vậy thì có được không? Vì tôi có tới 40 chân chứ không phải 2 chân.

Vậy nếu tôi làm master cho một mạng khác, mà trong đó slave của tôi lại là master của cái mạng mà tôi làm slave :). Hoàn toàn được.

Nhưng vấn đề nâng cao ở chỗ nữa, nếu làm như vậy, tôi phải tốn 4 dây để làm 2 mạng. Vấn đề trước đây hình như F đặt ra cho Linh, nhưng Linh chưa giải quyết xong, đó là Multi Master trong một mạng dùng 2 dây thôi.

Vấn đề này F tiếp tục treo ở đây chờ người giải quyết.

Chúc vui.

falleaf 03-10-2006 09:47 PM

Trích:

Nguyên văn bởi hoangminh1234 (Post 5237)
cai nay sao em ko thay trong CCS noi nang gi toivay anh? Nếu ta biết được địa chỉ thanh ghi bên slave thì hoàn toàn có thể lấy ra xài rồi.
Em vừa đọc cái SPI, thấy con tớ đọc dữ liệu trong thanh ghi SSPBUF ( được master truyền xuống) sau đó xuất ra port B.
file: http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf
Nó làm em nghĩ rằng ko biết mình có thể làm tương tự với i2c ko?? cao huynh nào rành i2c cho ý kiến nhé

Bạn đọc lại frame truyền từ Master đến Slave ở hai chế độ ghi và đọc

Chúc vui.


Múi giờ GMT. Hiện tại là 02:00 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam