Tần số xung nhịp được thiết lập giữa master và Slave trong giao thức I2C như thế nào?


8

Đây là câu hỏi tiếp theo Điều gì xảy ra nếu tôi bỏ qua các điện trở pullup trên các đường I2C?

Trong một chiếc đồng hồ treo tường kỹ thuật số do tôi thiết kế (sử dụng DS1307 RTC và ATmega328 MCU), tôi đã vô tình bỏ qua các điện trở kéo lên phải được nối với cả hai đường I2C. Cuối cùng, tôi đã rất may mắn khi các pull-up bên trong trên các dòng ATmega I2C đủ để (hầu như không) cho phép giao tiếp giữa các thiết bị. Kết quả là thời gian tăng dài trên các dòng I2Cvà giảm tốc độ xuống 32kHz như đã thấy trong các bức ảnh phạm vi dưới đây.

Chỉnh sửa: Trên thực tế, tần số chính xác là 100kHz - có 2 đỉnh trên 20us trên dấu vết màu xanh lá cây. Ban đầu tôi nghĩ đã giảm xuống còn 32kHz vì phạm vi của tôi đã tính tần số trên dấu vết màu vàng.

Phạm vi bắn 1 Phạm vi bắn 2

Điều làm tôi bối rối bây giờ là làm thế nào các thiết bị quyết định rằng 32kHz là đủ để giao tiếp diễn ra. Bảng dữ liệu DS1307 nói rằng thiết bị hỗ trợ tần số 100kHz trên bus I2C. Làm thế nào mà nó kết thúc bằng cách sử dụng 32kHz? Có một số loại bắt tay trong đó tần số được thiết lập?

Cuối cùng, câu hỏi của tôi thực sự là: Tần số xung nhịp được thiết lập giữa master và Slave trong giao thức I2C như thế nào?

Tôi không thể tìm thấy thông tin tìm kiếm trên Net.

Trong trường hợp này, tôi đang sử dụng Arduino IDE 1.03 và phần sụn của tôi xử lý RTC bằng cách sử dụng DS1307RTC Arduino lib (thông qua các chức năng của nó RTC.read()RTC.write()). Lib đó lần lượt sử dụng Wire.hđể nói chuyện với RTC.


4
Tiêu chuẩn cho I2C là ở đây
Warren Hill

1
Đây không phải là bạn có thể mã hóa tần số đó một cách tùy tiện mà không biết nó sao?
Dzarda

@Warren Tài liệu tham khảo đó thực sự hữu ích, cảm ơn. Tôi không thể yêu cầu Google đưa tôi đến THE. Thay vào đó, nó đưa tôi đến bài viết Wikipedia và các tài liệu tiếp tuyến khác. Tuy nhiên, tôi không thể hiểu tốc độ được xác định như thế nào. Tôi nghĩ những gì tôi muốn biết là trong phần 3.1.7 Đồng bộ hóa đồng hồ , nhưng tôi thực sự đánh giá cao nếu ai đó có thể giải thích điều đó cho tôi bằng những thuật ngữ đơn giản hơn, vì nó vẫn còn hơi quá đầu tôi.
Ricardo

1
Trong hệ thống của bạn, DS1307 là nô lệ và dòng SCL chỉ là đầu vào. Tần số được đặt bởi chủ MCU. Bất cứ ai viết phần sụn cho nó đều quyết định tốc độ họ muốn. Không có cuộc đàm phán mã hóa cứng của nó.
Warren Hill

1
Đúng hầu hết các hệ thống chỉ có một chủ, đồng bộ hóa đồng hồ chỉ có ý nghĩa trong môi trường đa chủ
Warren Hill

Câu trả lời:


4

Theo dõi các ý kiến:

Có, tần số được mã hóa cứng vào một số thanh ghi liên quan đến I2C cụ thể. Trong thời gian chạy.

Điều đó nói rằng, thư viện Arduino của bạn thể thực hiện một số phép đo thời gian thăm dò và tăng trên xe buýt để xác định tốc độ xung nhịp khả thi. Hãy xem nào.


Sau khi thực hiện một chút đào nguồn, câu trả lời là trong twi.h

#ifndef TWI_FREQ
#define TWI_FREQ 100000L
#endif

Một phần khác từ chính tập tin đó:

TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;

Nơi TWBR là viết tắt của Hai Dây Baudrate Register tôi nghi ngờ.

Tôi gọi đó là đủ bằng chứng và chắc chắn nói rằng, có tần số I2C của bạn được đặt trực tiếp bởi thư viện của bạn mà không có bất kỳ cuộc đàm phán nào. Nếu bạn muốn thay đổi nó, tôi khuyên bạn nên #define TWI_FREQ trước khi bạn #include twi.h (hoặc gián tiếp thông qua Wire.h)


1
"Nếu bạn muốn thay đổi nó, tôi sẽ đề xuất #undefvà tiếp #definetục TWI_FREQsau khi bạn bao gồm Wire.h" Không, điều đó không chính xác. Cách twi.hviết, bạn nên #definetùy chỉnh TWI_FREQ trước khi bạn #include twi.h. (Và "Wire.h" phải làm gì với bất cứ điều gì?)
Dave Tweed

Trên thực tế, tần số luôn chính xác là 100kHz - có 2 đỉnh trên 20us trên dấu vết màu xanh lá cây. Ban đầu tôi nghĩ đã giảm xuống còn 32kHz vì phạm vi của tôi đã tính tần số trên dấu vết màu vàng. Điều này làm cho câu trả lời của bạn chính xác. Cảm ơn!!
Ricardo

5

Để cạnh đồng hồ tăng lên xảy ra trong I2C, chủ phải xác nhận đồng hồ, điều này có thể khiến một số nô lệ tham gia để khẳng định nó, và sau đó, chủ và tất cả nô lệ phải đồng ý giải phóng đồng hồ. Cho đến khi tất cả các thiết bị phát hành đồng hồ, nó sẽ vẫn được xác nhận và tất cả các thiết bị sẽ thấy rằng nó được khẳng định.

Khi mọi thiết bị đã phát hành đồng hồ, thì mỗi thiết bị nô lệ sẽ "khởi động lại" mạch giữ đồng hồ trừ khi hoặc cho đến khi nó sẵn sàng cho cạnh tăng tiếp theo [một số thiết bị luôn "sẵn sàng" cho các cạnh tăng nhanh như chủ có thể gửi chúng, và do đó không cần một mạch giữ đồng hồ; những người khác đôi khi có thể biết rằng họ sẽ không quan tâm đến bất kỳ cạnh tăng nào cho đến khi điều kiện bắt đầu tiếp theo xuất hiện và không khởi động lại mạch giữ đồng hồ của họ cho đến khi đó]. Khi chủ nhân thấy rằng đồng hồ được giải phóng, nó sẽ đợi một khoảng thời gian tối thiểu để đảm bảo rằng bất kỳ ai cần thiết lập lại mạch giữ xe buýt đều có cơ hội để làm như vậy, sau đó xác nhận lại đồng hồ và đảm bảo rằng nó được tổ chức đủ lâu để cho phép bất kỳ mạch giữ xe buýt vũ trang nào tham gia giữ nó. Chu kỳ sau đó có thể lặp lại.

Các thiết bị nô lệ thường không có tốc độ hoạt động tối thiểu, nhưng sẽ có tối đa. Một số thiết bị đồng bộ hóa tất cả logic I2C của chúng với đồng hồ bên trong và do đó có thể yêu cầu một chu kỳ hoặc hai để kích hoạt hoặc kích hoạt mạch giữ đồng hồ của chúng. Ngoài ra, I2C yêu cầu các thiết bị phải xác định đáng tin cậy 100% các cạnh trên dây đồng hồ xảy ra trước hay sau các cạnh trên dây dữ liệu; do thay đổi dòng dữ liệu thường xảy ra gần như ngay lập tức sau khi giảm các cạnh đồng hồ, các thiết bị có thể thêm một số độ trễ khi chúng nhận thấy thay đổi dòng dữ liệu. Điều này đòi hỏi phải thêm độ trễ giữa bất kỳ lúc nào chủ thay đổi dữ liệu đầu ra và thời gian tăng đồng hồ. Miễn là mọi thiết bị đều có yêu cầu độ trễ tối thiểu thỏa mãn, chủ có thể trì hoãn miễn là nó muốn; Tuy nhiên, thời gian trễ chính càng lâu, việc gửi dữ liệu sẽ càng mất nhiều thời gian.


3

Từ trang web Arduino- Thư viện dây Tham khảo chi tiết :

Cuộc gọi twi.init () là nội bộ của thư viện Dây. Nó thực hiện các tác vụ sau: đặt tần số xung nhịp mà phần cứng TWI sẽ sử dụng nếu / khi đó là bản gốc trên bus I2C. Nó được đặt trong mã nguồn thành 100kHz, nhưng về mặt lý thuyết, ít nhất bạn có thể đặt lại tần số này bằng cách xác định lại TWBR trước khi gọi Wire.begin (), ví dụ: TWBR = 400000L nên đặt nó thành 400kHz.

Thư viện RTC bạn sử dụng không thay đổi TWBR. Một cái gì đó khác mà bạn đang sử dụng có thể đã thay đổi nó. Hoặc thời gian kéo chậm chậm từ các lần kéo bên trong siêu yếu đã khiến động cơ i2c của ATMega chậm lại. Động cơ sẽ kiểm tra xem dòng cao hay thấp trước khi thay đổi.

Điều đó nói rằng, tần số xung nhịp i2c là tùy ý , lên đến tần số được hỗ trợ tối đa thấp nhất của bất kỳ thiết bị nào trên xe buýt (và có thể thêm vài chục Hz nữa). Bất kỳ nhanh hơn và bạn bắt đầu nhận được đọc và viết các vấn đề. Một số thiết bị có tần số tối thiểu trước khi hết thời gian, nhưng tôi đã thấy các thiết bị 400khz hoạt động ở mức 10khz. Tốc độ đồng hồ chỉ được quyết định bởi chủ (tức là bạn, người viết mã).

Có một tùy chọn cho đồng hồ kéo dài trên phần của nô lệ (nó giữ dòng đồng hồ ở mức thấp cho đến khi nó sẵn sàng và thông số i2c yêu cầu kiểm tra chính cho điều này), nhưng hình ảnh phạm vi dường như không chỉ ra rằng điều này đang xảy ra ở đây .

Nếu bạn đã thêm một số pullups bên ngoài thích hợp, mà không thay đổi bất kỳ mã nào, bạn sẽ thấy tần số tăng gần hơn tới 100kHz vì Thư viện dây xác định là tiêu chuẩn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.