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)

hoangminh1234 04-10-2006 12:41 AM

Trích:

Nguyên văn bởi falleaf (Post 5241)
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.

bác Falleaf nghĩ cao siêu quá, cái em hỏi chỉ ở mức cơ sở, chưa nâng cao dữ vậy đâu anh. Theo em nghĩ với yêu cầu truyền một số lượng byte ( 10 byte chẳng hạn) từ một con pic này sang một con pic khác là yêu cầu rất hay gặp . Anh Falleaf nghĩ cao quá nên vẫn chưa trả lời em câu hỏi này nhỉ?
Em nghĩ rằng dữ liệu truyền từ master sang slave sẽ được lưu tạm trong thanh ghi SSPBUF. Nếu mình lấy ra xài đúng lúc thì sẽ giải quyết được câu hỏi mà em đang đặt ra, được ko anh?

falleaf 04-10-2006 02:15 AM

Anh nói là em đọc lại bài tutorial và frame truyền!

Em chưa đọc kỹ cái bài bạn Thanh Hà gửi về hai cái app mà anh giới thiệu sao?

Chúc vui.

hoangminh1234 04-10-2006 10:22 PM

2 Attachment(s)
hình như mình vẫn chưa hiểu nhau (:)) anh Falleaf nhi?
Như anh đã nói việc truyền và đọc là do con chủ ra lệnh
Cũng như anh đã nói là dữ liệu sẽ được nằm trong thanh ghi SSPBUF của con tớ ( 1thanh ghi ! ?????)
Quan sát hai khung truyền ta thấy rằng việc truyền hay nhận nhiều byte từ master là chuyện nhỏ. Nhưng chuyện không nhỏ ( hay quá nhỏ không ai để ý ) là dữ liệu chạy đi đâu trong con tớ. Khi thằng chủ đưa 10 cô em sang nhà thằng tớ chơi, nhưng thằng tớ nhà nghèo chật hẹp chỉ chứa được một cô thôi, vậy 9 cô kia ở đâu? Không hiểu sao mà khi chủ gọi về thì vẫn đủ 10 cô ?? ( chắc có di động gọi nhau )
Chắc là mấy cô dẫn nhau ra quán Sinh Viên trên đường Bửu Long ngồi đây. Nếu ta biết địa chỉ đường Bửu Long thì hay quá nhỉ :D . Anh Falleaf có biết đường BL nằm đâu ko ?


//sau khi đọc application

À, thì ra nó nằm trong RXbuff, vậy mà sao anh ko nói sớm

namqn 04-10-2006 10:39 PM

Khi slave nhận ra địa chỉ của mình thì nó cần đảm bảo xử lý ở mức nhanh nhất để không bị mất dữ liệu, nghĩa là nhận được byte nào thì nó chuyển ngay byte đó ra khỏi bộ đệm. Ngoài ra, nó còn được phép kéo dài xung clock (clock stretching), và gửi NACK để báo hiệu là nó chưa sẵn sàng. Với PIC thì các phần này được xử lý bằng phần cứng. Bạn chịu khó đọc thêm tài liệu đi.

Thân,

hoangminh1234 08-10-2006 02:49 AM

cám ơn trưởng lão

falleaf 08-10-2006 04:48 AM

Hình như em vẫn chưa đọc cái app note mà Thanh Hà gửi thì phải :D

Em đọc kỹ lại đi xem cách nó xử lý 32 byte được truyền tới như thế nào? Nếu không cần nACK mà xử lý luôn liệu có được không?

Câu trả lời cho câu hỏi của em nằm trong đó :), chỉ vì em không chịu đọc thôi

Chúc vui.

falleaf 03-01-2007 12:57 PM

Hòa, em viết phần giao tiếp I2C giữa thiết bị 5V và 3.3V vào chỗ này.

Vấn đề đặt ra, lúc trước đáng lẽ có trong báo cáo của Linh, nhưng lâu quá F không để ý, vì Linh ngưng đề tài giữa chừng.

Đó là làm thế nào để giao tiếp I2C giữa thiết bị chuẩn 5V và thiết bị chuẩn 3.3V, 2.5V...

Nguyên tắc I2C đến đây coi như là xong, nhưng trong một mạng I2C, thì làm thế nào để kết nối được giữa các thiết bị có chuẩn điện áp khác nhau. Đây là câu hỏi mở rộng tiếp theo ở phần i2c này.

Phạm Thái Hòa sẽ chủ trì phần này, các bạn tiếp tục nghiên cứu và thảo luận về I2C nhé.

Chúc vui.

vagabond 06-01-2007 07:25 AM

Hi mọi người,

Thấy câu hỏi này hay nên vagabond cung tham gia trả lời phát.

Đúng là ngày nay, việc kết nối các khối linh kiện có các mức điện áp khác nhau ngày càng nhiều. Đặc biệt là giữa mức 3.3V và 5V. Trở lại câu hỏi trên, do mình quen sử dụng các IC chuyên dụng nên tạm thời không xét đến các giải pháp khác. Các bạn có thể sử dụng IC 74LVXC4245 để chuyển đổi mức điện áp 3.3-5V. IC này cũng cho phép xác định chiều vào/ra của tín hiệu. IC này sẽ được cấp 2 nguồn áp tham chiếu là 5V và 3.3V. Chú ý: theo sơ đồ dưới đây, ta cần phải có thêm 2 tín hiệu để điều khiển chiều ra/vào của tín hiệu ở các ngõ A và B.

http://i132.photobucket.com/albums/q...74LVXC4245.jpg

Các ngõ A tương ứng với mức điện áp logic 1 là 4.5-5.5V
Các ngõ B tương ứng với mức điện áp logic 1 là 2.7-5.5V
Hai chân ~OE và T/~R cho phép điều khiển tín hiệu đi theo chiều A->B hay B->A hay ở trạng thái HighZ. Mức điện áp điều khiển hai chân này chấp nhận mức logic 1 là 3.3 hay 5V đều được.

Xét trường hợp mạng I2C sẽ có mức logic chuẩn là 5V (hoặc 3.3V) cho toàn mạng và các khối linh kiện có mức logic khác 5V sẽ dùng IC tương thích mức logic. Ta có thể kết nối nhiều khối linh kiện có các mức logic khác nhau trên cùng một mạng I2C.

Bây giờ, ta xét hoạt động của mạng I2C 5V bao gồm một khối linh kiện 3.3V và khối linh kiện 5V.

http://i132.photobucket.com/albums/q...ondmec/I2C.jpg

Khi Master muốn liên lạc với Slave: Slave phải điều khiển IC tương thích điện áp sao cho chiều tín hiệu đi từ A->B (tức là tín hiệu có mức logic 1 từ 5V sẽ chuyển thành 3.3V).

Khi Slave muốn liên lạc với Master, hai chân của IC tương thích điện áp phải được điều khiển để chiều tín hiệu đi từ B->A (tức là tín hiệu có mức logic 1 từ 3.3V sẽ chuyển thành 5V).

Tóm lại việc điều khiển 2 chân ~OE và T/~R của IC tương thích điện áp sẽ do Slave chịu trách nhiệm. Trong ví dụ này, ta đưa thẳng chân ~OE xuống đất và chỉ điều khiển chân T/~R (các bạn coi lại bảng sự thật).

Mạng I2C 3.3V hoàn toàn tương tự như trên. Master và Slave có thể đổi vị trí cho nhau.

Túm lại lần nữa:
- Các bạn có thể kiểm các IC tương thích điện áp có số ngõ ra vào tương ứng với số lượng tín hiệu cần chuyển đổi mức logic. Riêng IC tương thích điện áp chỉ có 2 ngõ ra vào thì mình chưa tìm thấy.
- Đây là một giải pháp an toàn và nhanh, nhất là khi phải làm việc với các mức điện áp khác nhau.
- Tuy nhiên, bù lại bạn phải tốn thêm chỗ cho IC, làm tăng diện tích boar (linh kiện dán CMS vẫn tốn chỗ), phải sử dụng thêm 2 nguồn điện áp, và phải thêm ít nhất là 1 đường tín hiệu để điều khiển chiều A<->B.
- Và một điểm lợi nữa khi cần thiết, bạn có thể cách li hoàn toàn các khối linh kiện với trạng thái HighZ ra khỏi bus I2C (nhưng lại phải tốn thêm tín hiệu điều khiển ~OE).

Có thể có còn các cách khác nữa (diod Zener để ghim điện áp…) nhưng mình … hehehe nhường cho các bạn. Mình chỉ khoái làm việc với các IC chuyên dụng sẵn thôi.

zero_OR_one 12-01-2007 12:51 AM

Trích:

Nguyên văn bởi hoanf (Post 4955)
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);
  }
}


Bác Hoàn cho em hỏi tý,em thử mô phỏng chương trình của bác(có sửa một tý) với proteus thì thấy kết quả slave hiện đúng,master sai(ví dụ value cho là 0x7f thì master là 0x87,sửa value khác thì master vẫn thế---ở đây value của em có vai trò như 1 thành phần của mảng của bác thôi) .Cũng ko hiểu sao ở slave bác lại cho int8 value = 0x01;,đã thay lại mỗi khai báo int8 value thôi,mô phỏng vẫn thế.Không hiểu do phần mềm hay sao???Thông cảm vì em chưa có điều kiện làm vì ko có đủ 2 con chip.

tact 19-01-2007 06:02 PM

chắc bác sửa thế nào ý chứ, em copy về, mô phỏng thấy chạy ngon re. nhưng em làm 1 con master, 4 con slaver thì thôi rồi, tịt ngỏm luôn. bận quá, chẳng co thời gian nghiên cứu nữa. Vậy nên em làm theo cách khác. vẫn chủ đề là 1 M giao tiếp với vài S. hôm qua làm xong rồi. CCS có cái hay là làm giao tiếp cực mạnh.
em lấy ví dụ: 1 Master có thể có nhiều Slaver giao tiếp qua RS232 ( thậm chí giao lưu văn nghệ với nhau chỉ có 1 "đường tơ" cả GND là 2. em chỉ thử dc có 150m thôi vì ko có dây(ko khuếch đại, đệm chốt gì. PIN-2-PIN))
em sẽ về nghiên cứu thêm cái thằng I2C và SPI. công nhận hay thật

huybkdn 31-03-2007 11:20 PM

Hỏi về I2C
 
Chào các bạn, mình mới lần đầu giao tiếp I2C dùng C để giao tiếp giữa 2 pic 16f877a, nên gặp nhiều vấn đề, hôm trước mình có tải chương trình của Hoàn về chạy thử nhưng không được, hi vọng Hoàn, các anh và các bạn cho mình một chương trình mẫu đơn giản có cả chạy mô phỏng bằng Proteus chính xác,rất cám ơn. Email của mình: quanghuy12c4@yahoo.com. Chúc tât cả vui!

hoanf 02-04-2007 10:09 AM

Trích:

Nguyên văn bởi huybkdn (Post 8060)
Chào các bạn, mình mới lần đầu giao tiếp I2C dùng C để giao tiếp giữa 2 pic 16f877a, nên gặp nhiều vấn đề, hôm trước mình có tải chương trình của Hoàn về chạy thử nhưng không được, hi vọng Hoàn, các anh và các bạn cho mình một chương trình mẫu đơn giản có cả chạy mô phỏng bằng Proteus chính xác,rất cám ơn. Email của mình: quanghuy12c4@yahoo.com. Chúc tât cả vui!

Chào bạn,

Mình đã kiểm tra lại chương trình và test trên Protues 6.9 SP5 thấy nó chạy vẫn OK kô có vấn đề gì (Mạch chỉ dùng 1 con Master và 1 con Slave)
Ngoài mình cũng sử dụng chương trình này để test trực tiếp lên phần cứng và cũng OK

Bạn thử kiểm tra lại mạch coi có nối 2 con điện trở 2.2k ở 2 chân SCL và SDA chưa; tần số dao động dùng đúng chưa ...

Chúc vui
hoanf

linhnc308 04-04-2007 03:23 PM

- Trong giao tiếp I2C thì các bạn nên chú ý trong việc sử dụng mạng giao tiếp giữa các IC này với nhau. Trước tôi đã làm giao tiếp với MS là 877A, 6 slave là 18F4331 để điều khiển rồi, chạy khá tốt. Nếu bạn nào làm mà không giao tiếp được thì cần kiểm tra lại khai báo về I2C (cho soft viết bằng CCS thôi nhé), đảm bảo phải giống nhau ở cả Master và Slave, tất nhiên với Slave có thêm phần khai báo địa chỉ.
- Hàm i2c_isr_state() này chỉ có với phiên bản CCS mới (từ 249), nên nếu bạn nào dùng bản cũ sẽ thấy báo lỗi.
- Trường hợp khai báo đúng mà vẫn không giao tiếp được thì cần kiểm tra lại đường giao tiếp I2C (chân SDA và SCL của PIC có thể bị hỏng, cái này tôi đã gặp mấy lần, và khi thử cho giao tiếp với DS1307 hay 24Cxx thì thấy ko đc, thay IC khác hay lái chân SDA, SCL sang chân khác thì lại OK) , vì vậy khi bạ n đã làm đúng các thủ tục mà đọc vẫn thấy 0xFF thì xem lại.
- Vì giao tiếp I2C là onboard nên tôi cũng chưa thử kéo dài đường bus. Để giao tiếp với các thiết bị 3V3, tôi thấy có thể dùng mach phân áp trở cũng tạm đc, nếu bạn nào đã làm AVR giao tiếp với thẻ MMC sẽ thấy sơ đồ mạch đó( http://www.captain.at/electronic-atmega-mmc.php )
- Cái hay của CCS là sẽ tự sinh mã I2C nếu HW ko hỗ trợ, do đó ta có thể tùy biến lái các chân tín hiệu này đến một chân bất kỳ, cả SPI cũng vậy.

Chúc thành công.

huybkdn 08-04-2007 11:44 PM

Mình cảm ơn các bạn rất nhiều, mình đã làm được rồi, mình viết chương trình đơn giản thôi, chỉ dùng Master điều khiển 1 Slave hiển thị LCD và chạy tốt. Cho mình hỏi ngoài luồng một tí, mình đang làm đề tài điều khiển từ xa qua mạng điện thoại, cũng đã tham khảo datasheet và một số tài liệu nhưng chưa thành công, bạn nào có tài liệu cho mình xin, đặc biệt là cái khoản điều khiển con MT8880, đề tài mình gần hết hạn rồi, đang lo lắm, hi vọng được sự giúp đở. Bye,chúc tất cả vui !

minhpupil 11-05-2007 06:43 PM

I2C multi master
 
1 Attachment(s)
Chào các cao thủ , em có bài tập lớn về mạng I2C , trong đó có
2 master( 2 con Pic) , vậy có huynh nào biết rõ về phần này chỉ đệ với.

Đệ thắc mắc như sau:
Trong I2C có 7 bit địa chỉ , vậy có 128 thiết bị.
Vậy địa chỉ cho 2 con master này mình chọn thế nào?
và viết khai báo trong CCSC như thế nào?
Code:

#use i2c(master, sda=PIN_C4, scl=PIN_C3)
đệ thấy trong các phần khai báo của các master ko có ghi địa chỉ
của master trong mạng ?
Theo như bài tập của đệ thì tại 1 thời điểm chỉ có 1 con Pic
là master , con còn lại là slave , vậy đệ phải làm sao để con
kia biết nó là slave tại thời điểm đó ? Có phải nó dùng
i2c_isr_state () để đọc ko ạ?


Đệ mới học về I2C , còn ngu dại , mong các huynh chỉ giáo ạ.

nkh 12-05-2007 01:52 PM

Xin cho đóng góp chút công sức nhé.

namqn: bạn nên đưa link đến post đã chứa file được upload, thay vì upload thêm lần nữa.
http://www.picvietnam.com/forum//sho...=8624#post8624

zero 24-05-2007 11:22 PM

oa giao tiếp I2C hay thiệt đó.
Từ sưa đến j mình chỉ làm nội bộ trong 1 con Chíp chưa thử giao tiếp với bên ngoài theo các chuẩn có sẵn.
Ok mình sẽ nghiên cứu về cái này rồi post ý kiến lên sau. :D Rất cám ơn về các bài viết trên.

hieuhic 26-05-2007 05:26 PM

Thế giới số hay thật

xzero 27-05-2007 04:27 PM

CCS C viet nhu vay sao mo phong protues khong thay duoc....
 
1 Attachment(s)
Mình đang viết I2C kết nối PIC 16F877A voi DS1307 bằng CCS C. bien dich thi khog thay bao loi nhung vao mo phong thi khong thay duoc j het. Các Bác giúp mình với. Code minh co dinh kem...thanhks!!!

tda 27-05-2007 05:47 PM

đệ thấy trong các phần khai báo của các master ko có ghi địa chỉ
của master trong mạng ?
Theo như bài tập của đệ thì tại 1 thời điểm chỉ có 1 con Pic
là master , con còn lại là slave , vậy đệ phải làm sao để con
kia biết nó là slave tại thời điểm đó ? Có phải nó dùng
i2c_isr_state () để đọc ko ạ?

Master thì cần địa chỉ làm gì? Vua thì ai mà chả biết là vua, trừ khi có vua 1, vua 2 cùng 1 vương quốc, lúc đó thì đánh nhau là cái chắc rồi.

Bạn thử dùng cách này thử xem.
Khi cần Pic làm master thì khai báo dòng
#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)
ngay trước cau lệnh master

còn khi cần là slave thì khai bao:
#use i2c(slave, sda=PIN_C4, scl=PIN_C3, address=..., force_hw)
ngay trước cau lệnh slave

Mình thấy trong CSS có sử dụng cách này để thay đổi chân truyền RS232 tại thời điểm cần thiết nhưng chưa thử với I2C

loveall 27-05-2007 10:34 PM

hình bạn post mờ quá!!

huybo02 06-06-2007 06:22 PM

Giúp mình tí nha. Đang tìm hiểu về I2C nên mới viết vài lệnh đơn giản để hiểu nó làm gì. Đã truyền được data từ master sang slave tuy nhiên có rắc rối nhỏ khi slave nhận được thì nó không thực hiện chương trình chính trong main() nữa. Mọi người giúp cách khắc phục.

master: Nhấn button ở RB0 => truyền data2
Code:

#include<16F877A.h>
#use delay(clock=1000000)
#include<def_877a.h>
#use i2c (master,SCL=PIN_C3,SDA=PIN_C4)
#use fast_io(d)
int data,data2;
#int_EXT
void ngat_RB0()
{
  i2c_start();
  i2c_write(0x10);    // slave address
  i2c_write(data2);  // Data to slave
  delay_ms(100);
  i2c_stop();
  portd =data2;
  data2++;
}
void main()
{
  ENABLE_INTERRUPTS(INT_EXT);
  ENABLE_INTERRUPTS(GLOBAL);
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  trisd=0;
  portd=0xF0;
  data2 = 0x5;
  if (data2==255)  data2 = 0;
  while (true)
  {
  }
}

slave: Nhận data2 hiển thị portD, port B thực hiện dịch bit. Nhưng khi nhận thì portB không dịch bit nữa

Code:

#include<def_877a.h>
#use i2c (slave,SCL=PIN_C3,SDA=PIN_C4,address =0x10)
#use fast_io(d)
#use fast_io(b)
int a,value,b;
#INT_SSP
void i2c_isr()
{
  int8 state;
  state = i2c_isr_state();
  if(state < 0x80)
  {
      value = i2c_read(0);
  }
  if(state == 0x80)
  {
      i2c_write(b);
  }
      portb = value;
}

main()
{
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_SSP);
  trisd=0;
  a=1;
  b=0b10101010;
  trisb=0;
  portb=0;
  while (true)
  {
      portd =a;
      delay_ms(500);
      if (a==128)
      {
        a=1;
      }
      else
      {
        a=a<<1;
      }
  }
}

Sẵn đây hỏi luôn làm sao để master đọc từ slave về. Và khi slave truyền bằng i2c_write() thì nó truyền dữ liệu nào?? i2c_write(b) thì nó truyền giá trị của "b" ???

ngohaibac 06-06-2007 09:17 PM

Master đọc dữ liệu từ Slave theo cơ chế : đầu tiên Master chiếm quyền làm chủ (start hay restart) rùi truyền 1 byte hoặc 2 byte đầu chứa địa chỉ của slave và chế độ đọc hoặc ghi (R/W) tương ứng. R/W = 1 tức chế độ Read.

Slave sẽ luôn luôn nghe ngóng đường truyền, nếu tương thích với địa chỉ Master truyền thì nó sẽ gửi ACK xác nhận. Và khi đó, master bắt đầu đọc dữ liệu.

Chúc bạn thành công.

minhpupil 09-06-2007 02:32 AM

Anh Falleaf có viết:
Code:

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.

Để hiểu thêm về Multi master này em phải đọc thêm ở tài liệu nào vậy anh?

Em nghĩ như thế này được không anh?
Giả sử trên mạng có 2 con Master 1 và 2 , tại 1 thời điểm chỉ có 1 con là Mater , con còn lại là Slave . Em lấy chân A0 đọc tín hiệu kích về , khi nào nó là 0 thì Master1 là master , khi nào A0=1 thì Master 2 là master.

Rồi em thay đoạn code viết trong CCS của 2 con master như sau:
Giả sử mặc định ban đầu A0=0 , tức Master1 là master:

Code:

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

 

void main()
{

set_tris_a(0x01); // A0 là chân nhập
Do
{
  if (input(pin_A0))
      {
        #use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)
              // cho master 1 là Slave , nhưng phần này em nghĩ là chỉ đặt đầu 
              //chương trình không thể đưa ra dây.Nên ở đây em định chèn đoạn
              // code assembly để kích thanh ghi như sau:
          #asm
              em đưa đoạn code assembly để kích thanh ghi SSPSTAT,SSPCON1
              và SSPCON2 để đưa master 1 về slave?
          #endasm
      }
  else
      {
          // em đưa đoạn code assembly để đưa Master 1 thành master 
      }

    ............
}While (1)

}

Đối với Master 2 em làm ngược lại. Như vậy đúng không anh?
Em đọc datasheet của Pic 16f877A trang 105 có nói về multi master , nhưng em chưa hiể rõ lắm, mong anh chủ giúp

tda 09-06-2007 07:46 PM

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)
// cho master 1 là Slave , nhưng phần này em nghĩ là chỉ đặt đầu
//chương trình không thể đưa ra dây.Nên ở đây em định chèn đoạn
// code assembly để kích thanh ghi như sau:

cai' nay` cung nhu 1 ham` trong C thoi, no' se set cac thanh ghi tuong ung, nen minh` nghi ko can che`n code ASM nua. Noi' the thoi, chu' minh chua thu.

falleaf 09-06-2007 08:56 PM

Vấn đề khó khăn ở chỗ, hai con PIC hoạt động độc lập với nhau, nó không thể nào biết con nào hiện đang làm master hay slave. Vấn đề xảy ra khi hai con đều "cho rằng mình là master" và gửi một thông tin lên cùng một mạng. Vậy thì sẽ có sự tranh chấp. Lưu ý mạng I2C là mạng 2 dây, khi gửi lên như vậy mọi con đều nhận được và đều sử lý. Hơn nữa, nên nhớ là xung clock của master để giữ nhịp cho toàn bộ mạng, thế thì nếu 2 con cùng lúc tạo ra xung nhịp thì sẽ thế nào? Giá sử như hai con tạo ra xung nhịp khác nhau?

Những vấn đề này xử lý khá loằng ngoằng, nhưng nó được miêu tả rõ trong application note của Microchip, cái này thì F quên mất là AN số bao nhiêu, các bạn tự tìm lại.

Tuy nhiên, lúc F giao cho Linh làm cái bài này, thì vì Linh sử dụng CCS C, cho nên gặp một số khó khăn vì chưa quen sử dụng. Vậy bạn nào có thể làm lại cái AN của Microchip chăng và phân tích rõ vấn đề hơn.

Chúc vui.

namqn 09-06-2007 09:19 PM

Trong datasheet của các chip thường có nói về chế độ multi-master trong giao tiếp I2C (PIC16F877A chẳng hạn) và trong AN735 có ví dụ về cách hiện thực I2C multi-master.

Trong AN736 đề cập đến mạng sử dụng giao thức I2C, trong này cũng có hiện thực I2C multi-master.

Tinh thần chính là sử dụng ngắt báo hiệu xung đột bus khi một chip thử trở thành master (thực sự) trên bus, dùng cờ ngắt BCLIF. Khi phục vụ ngắt này, chip sẽ chờ một khoảng thời gian ngẫu nhiên nào đó và thử thực hiện lại việc chiếm quyền chỉ huy bus.

Thân,

minhpupil 21-06-2007 12:36 AM

1 Attachment(s)
em có nghiên cứu sơ về I2C multimaster , có một số tài liệu post lên cho mọi người tham khảo (tài liệu tham khảo thôi không chắc đúng , he he nhất là
tham khao i2c multimaster.doc đó).

Sau đây là trang web viết lập trình I2C multi master của CCSC

http://www.ccsinfo.com/forum/viewtop...535d38622cb8a4

vandungevn 12-10-2007 12:42 PM

Ai đã làm trên MCC18 giao tiếp I2C chạy chưa, Dũng chỉ ghi được nhưng chưa đọc được, đang làm các mô đun tổng thể đưa ra giáo trình MCC18, anh em giúp với nhé, thanks.

Beginner 18-10-2007 12:25 PM

Các bác cho em hỏi tý:
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;
}

Khi nào thì dùng i2c_read(0),khi nào thì dùng i2c_read(1).
Có phải là(???):i2c_read(1):ra dấu ACK,tiếp tục nhận dữ liệu
i2c_read(0):ra dấu NACK,báo quá trình nhận dữ liệu kết thúc.
Như vậy là code trên nhận đúng 1byte phải không ạ?Em nghĩ thế ko biết đúng hay sai?

vandungevn 24-10-2007 06:40 PM

1 Attachment(s)
i2c_read(0); // No ACK - Stop read i2c
i2c_read(1); // ACK - Reply after read i2c

theo mình thì: đọc 1 byte dùng lệnh i2c_read(1); là ok .
bạn muốn rõ hơn thì đọc về i2c trong datasheet của DS1307, trong đó giới thiệu về cách truyền và nhận i2c.

Chúc thành công....!

tiendungkct 27-10-2007 10:47 AM

tai liau i2c
 
mình có tài liệu viết i2c bấng phần mền khá hay mong sẽ giúp dc các bạn
bạn xem từ trang 340

tiendungkct 27-10-2007 10:55 AM

sao em khong thể úp lên dc vậy

namqn: bạn kiểm tra dung lượng tập tin của bạn xem có vượt quá giới hạn cho phép khi upload hay không. Nếu vượt quá dung lượng cho phép thì bạn có thể gửi email cho F (địa chỉ email nằm ở phần chữ ký của F).

tungtot_vl 14-12-2007 09:52 AM

1 Attachment(s)
các anh giúp em với. em copy bài các bài trên xuống dùng và chạy bình thường. nhưng khi dùng cho 2 con slever thì gặp vấn đề. nếu con 1 chạy thì con 2 không chạy. nếu bỏ đoạn con 1 trong master thì con 2 chạy. nếu dùng cả 2 con thì chỉ có con 1 chạy xong rồi đứng yên. không rỏ nguyên nhân vì sao. mong chỉ giáo

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();
  }
//==============================================
/*void write_I2C2(int8 value, int8 slave_addr1)
  {
      i2c_start();
      i2c_write(slave_addr1);
      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,a;
      const int8 N = 8;
      const int8 DIGITS[N] ={ 0b11111111,
                              0b11111110,
                              0b11111100,
                              0b11111000,
                              0b11110000,
                              0b11100000,
                              0b11000000,
                              0b10000000,
                            };
   
      set_tris_b(0x00);
      while(1)
        {
        // con 1
          for(i = 0; i<8; i++)
              {
                  write_I2C(DIGITS[i], 0x10);
                  delay_ms(500);
                  value_re = read_I2C(0x10);
                  output_b(value_re);
              }
          // con 2
            for(a = 0; a<8; a++)
              {
                  write_I2C(DIGITS[a],0x20);
                  delay_ms(500);
                  value_re = read_I2C(0x20);
                  output_b(value_re);
              }
          }
  }
con slever1
#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);
    }
  }
con slever 2
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x20, force_hw)
int8 value1 = 0x01;
#INT_SSP
void i2c_isr()
  {
    int8 state;
    state = i2c_isr_state();
    if(state < 0x80)
        value1 = i2c_read();
    if(state == 0x80)
      {
        i2c_write(value1);
      }
  }
void main()
  {
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_SSP);
    set_tris_b(0x00);
    while(1)
    {
        output_b(value1);
    }
  }


Beginner 15-12-2007 06:35 PM

Em cũng đang gặp vấn đề tương tự với 1 master và nhiều slave.Mong các bác có kinh nghiệm hướng dẫn.

Khi chỉ có 1 slave thì chạy tốt nhưng có nhiều slave thì có triệu chứng như của bạn tungtot_vl ở trên.

picthanh 16-01-2008 11:50 AM

kbd và I2C
 
xin lỗi các huynnh cho đệ hỏi 1 câu ngu ngóc .em muốn tìm mua một con pic loại rẻ tiền nhất mà có đáp ứng nhu cầu sau: kết nối với bàn phím 4x3 và truyền thông tin phím nhấn ra bus I2C .em chỉ cần hai tinh năng đó thôi.chú ý là loại nào có giá thấp nhất mà có bán trên thị trường Việt Nam.mong các huynh quan tâm giúp đỡ ,tiểu đệ xin cảm ơn trước.

tiendungkct 18-01-2008 07:07 PM

bạn có thể tìm con 16f887 giá hình như 48.000vnd bạn có thể liên hệ anh F

picthanh 18-01-2008 07:43 PM

bạn tiendungkct oi ! mình vừa xem datasheet of con 16f887 xong thấy nó có nhiều ký hiệu lạ trên các chân quá (trước giờ mình mới làm việc việc với con 16f877a thôi)mình thấy con 16f876/873 chỉ có 28 chân nhưng ko biết giá nó bao nhiêu nhỉ.mình o nha trang nếu mua trên picvietnam thì ko biết nhận thế nào nhỉ,và trả tiền ra sao? a nhân tiện bạn cho mình hỏi mình có thể mua bàn phím 4x3 (loại chế tạo sẵn có vỏ bọc bảo vệ ,chống nước ,vì mình muốn đặt nó ngoài trời để điều khiển mà) ở đâu và bao nhiêu?

quoc_nguyen 29-02-2008 12:49 AM

Nack
 
Bạn nào cho mình hỏi muốn gửi xung NACK từ Master --> slave thì làm thế nào.
Thanks

namqn 29-02-2008 01:29 AM

Trích:

Nguyên văn bởi quoc_nguyen (Post 14552)
Bạn nào cho mình hỏi muốn gửi xung NACK từ Master --> slave thì làm thế nào.
Thanks

Bạn đọc phần I2C ở trang web sau vậy, vì bạn không cho biết là PIC 8-bit hay 16-bit.
http://namqn.byethost7.com/Commu.php

Master gửi ACK/NACK khi nó đọc từ slave, muốn làm việc này thì ở thao tác đọc chỉ cần cho phép ACK/NACK và bật/tắt bit trạng thái ACK/NACK (bật là NACK, tắt là ACK).

Thân,


Múi giờ GMT. Hiện tại là 10:46 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