PIC Vietnam

Go Back   PIC Vietnam > Truyền thông > Giao tiếp USB, CAN, I2C, SPI, USART...

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Giao tiếp USB, CAN, I2C, SPI, USART... Những giao tiếp được tích hợp trên PIC

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 07-09-2006, 11:54 PM   #1
falleaf
PIC Bang chủ
 
falleaf's Avatar
 
Tham gia ngày: May 2005
Bài gửi: 2,631
:
Send a message via Yahoo to falleaf
Giao tiếp I2C

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
File Kèm Theo
File Type: pdf TUT02.01.PVN.LINH.010306.pdf (399.3 KB, 37255 lần tải)
falleaf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 08-09-2006, 06:19 PM   #2
bien_van_khat
...Damned...
 
bien_van_khat's Avatar
 
Tham gia ngày: Apr 2006
Nơi Cư Ngụ: Hồ Chí Minh
Bài gửi: 522
:
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 ), 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 ). Không biết mọi người đọc như thế nào nhỉ?
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 08-09-2006, 07:14 PM   #3
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi bien_van_khat View Post
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 ), 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 ). 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,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 09-09-2006, 01:22 PM   #4
falleaf
PIC Bang chủ
 
falleaf's Avatar
 
Tham gia ngày: May 2005
Bài gửi: 2,631
:
Send a message via Yahoo to falleaf
Trích:
Nguyên văn bởi bien_van_khat View Post
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 ), 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 ). 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.
falleaf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 11-09-2006, 10:51 AM   #5
thanhha
Nhập môn đệ tử
 
Tham gia ngày: Sep 2006
Nơi Cư Ngụ: Ho Chi Minh City
Bài gửi: 9
:
Send a message via Yahoo to thanhha
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) {}
}

thay đổi nội dung bởi: falleaf, 13-09-2006 lúc 04:49 PM.
thanhha vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-09-2006, 11:25 AM   #6
thanhha
Nhập môn đệ tử
 
Tham gia ngày: Sep 2006
Nơi Cư Ngụ: Ho Chi Minh City
Bài gửi: 9
:
Send a message via Yahoo to thanhha
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!!
thanhha vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-09-2006, 12:52 PM   #7
hoanf
Đệ tử 3 túi
 
Tham gia ngày: Jun 2006
Bài gửi: 51
:
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
hoanf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-09-2006, 01:00 PM   #8
thanhha
Nhập môn đệ tử
 
Tham gia ngày: Sep 2006
Nơi Cư Ngụ: Ho Chi Minh City
Bài gửi: 9
:
Send a message via Yahoo to thanhha
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
thanhha vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 12-09-2006, 02:52 PM   #9
hoanf
Đệ tử 3 túi
 
Tham gia ngày: Jun 2006
Bài gửi: 51
:
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
hoanf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 13-09-2006, 01:59 PM   #10
thanhha
Nhập môn đệ tử
 
Tham gia ngày: Sep 2006
Nơi Cư Ngụ: Ho Chi Minh City
Bài gửi: 9
:
Send a message via Yahoo to thanhha
Smile

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 :
Hình Kèm Theo
File Type: gif mach I2C.GIF (35.8 KB, 1499 lần tải)

thay đổi nội dung bởi: thanhha, 14-09-2006 lúc 05:53 PM. Lý do: thêm mạch
thanhha vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 13-09-2006, 04:48 PM   #11
falleaf
PIC Bang chủ
 
falleaf's Avatar
 
Tham gia ngày: May 2005
Bài gửi: 2,631
:
Send a message via Yahoo to falleaf
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.
falleaf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 13-09-2006, 05:24 PM   #12
hoanf
Đệ tử 3 túi
 
Tham gia ngày: Jun 2006
Bài gửi: 51
:
: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

thay đổi nội dung bởi: hoanf, 15-09-2006 lúc 10:00 AM.
hoanf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-09-2006, 12:34 PM   #13
hoanf
Đệ tử 3 túi
 
Tham gia ngày: Jun 2006
Bài gửi: 51
:
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);      
   }
}

thay đổi nội dung bởi: hoanf, 15-09-2006 lúc 12:40 PM.
hoanf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-09-2006, 04:24 PM   #14
thanhha
Nhập môn đệ tử
 
Tham gia ngày: Sep 2006
Nơi Cư Ngụ: Ho Chi Minh City
Bài gửi: 9
:
Send a message via Yahoo to thanhha
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 !!

thay đổi nội dung bởi: thanhha, 14-09-2006 lúc 06:11 PM. Lý do: Canh lề
thanhha vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-09-2006, 04:49 PM   #15
falleaf
PIC Bang chủ
 
falleaf's Avatar
 
Tham gia ngày: May 2005
Bài gửi: 2,631
:
Send a message via Yahoo to falleaf
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.
falleaf vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 05:28 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam