Lỗi đọc / ghi I2C dưới tải nặng


10

Trong hệ thống của tôi, tôi đang sử dụng I2C và tôi nhận ra dưới tải nặng ngắt (từ các nguồn khác), giao tiếp I2C dễ bị gián đoạn. Đây có phải là hành vi dự kiến ​​cho I2C? Tôi đã mong đợi mặc dù tải gián đoạn, nó vẫn ổn vì I2C không chính xác là giao diện quan trọng về thời gian, đồng hồ được cung cấp dữ liệu.

Cập nhật:

Bộ xử lý là STM32. Các ngắt là do ADC, tôi không thể vô hiệu hóa các ngắt trong các sự kiện đọc do đó tôi phải tìm một giải pháp để tôi có thể làm cho giao tiếp i2c ổn định hơn. STM32 là chủ và nô lệ là một thiết bị khác (gia tốc kế).

Cập nhật2:

Khi tôi kết nối máy phân tích logic với đồng hồ bằng một dây cáp nhỏ, vấn đề sẽ biến mất. Thật thú vị, không có tải ngắt, đọc ghi hoạt động tốt, khi có tải gián đoạn, họ không. Tuy nhiên, nếu tôi gắn đầu dò vào đồng hồ, hãy đọc ghi hoạt động dưới tải gián đoạn. Tôi nghĩ rằng, có một vấn đề điện dung ở đâu đó.


1
Câu hỏi của bạn rất chung chung vì tất cả phụ thuộc vào thiết kế hệ thống của bạn. Cách xử lý I2C thực sự phụ thuộc vào các thiết bị trên xe buýt. Bạn có thể bỏ qua chúng và đến sau? Trong một đồ họa, bạn có thể thiết kế logic để chăm sóc rất nhiều cho bạn và tránh điều này. Một lần nữa, chúng tôi cần thêm thông tin về vi điều khiển và những thứ khác bạn có. Thông thường một giải pháp tốt ở đây là sử dụng RTOS và thiết kế đúng các tác vụ.
Gustavo Litovsky

Hai điều cần tìm, Điện áp chùng xuống trên pullups hoặc trên nguồn cho chủ i2c và nô lệ của bạn, hoặc các vấn đề về emi hoặc điện dung. Đối với tải gián đoạn, bạn có nghĩa là chủ của bạn đang dừng để xử lý một ngắt? Một số chip sẽ không cho phép kéo dài đồng hồ vô hạn.
Người qua đường

@GustavoLitovsky bạn đúng nhưng 80% chu kỳ CPU đang phục vụ ngắt ADC và không có đủ thời gian để thực hiện chu trình đọc trong cửa sổ không phải ISR. Vì vậy, việc đọc sẽ bị gián đoạn cho dù tôi có thiết kế hệ điều hành tốt đến đâu.
Ktc

@Passerby bạn có thể đúng. Vấn đề biến mất khi tôi gắn đầu dò của máy phân tích logic vào dòng đồng hồ.
Ktc

Giá trị hiện tại của bạn cho pull-up là gì. Bạn đã thử thay đổi chúng thành một giá trị khác chưa? (Hãy thử 10k hoặc 4k7 hoặc 2k chỉ cho lần đoán đầu tiên)
Tom L.

Câu trả lời:


9

Đây là một vấn đề phần mềm, bạn đang dành quá nhiều thời gian để phục vụ các ngắt và thói quen I2C của bạn không thể xử lý được (vì vậy đó là hai điều không đúng). Tôi đã trải qua một số tình huống tương tự.

Đầu tiên: Bạn cần thực hiện ít nhất có thể trong các ngắt, chỉ đọc và lưu trữ dữ liệu, không thực hiện bất kỳ xử lý nào bạn có thể làm ngoài ISR, toán học có thể mất rất nhiều chu kỳ CPU và CPU không thể làm gì khác Trong khi đó ngắt quãng.

Thứ hai: Điều tra DMA để tự động hóa mọi thứ, do đó, các ngắt của bạn gần như trở thành một quy trình tự động nền.

Thứ ba: Nếu I2C là quan trọng, hãy đặt THAT trong một ngắt quá, nhưng hãy chắc chắn rằng bạn làm việc ưu tiên!

Thứ tư: Tìm hiểu lý do tại sao thói quen I2C của bạn không thành công, bản thân I2C có thể chịu được thời gian rất gián đoạn, tạm dừng và chờ đợi, do đó, thói quen của bạn có thể cần sửa đổi để cho phép điều này.

Thứ năm: Xem nếu bạn có thể "xâu chuỗi" các ngắt, bạn có thể thấy bạn có thể phục vụ ADC đọc hiệu quả hơn hoặc đặt ADC ở chế độ khác, nơi nó hoạt động nhiều hơn cho bạn trước khi ngắt (EG chờ tất cả các bài đọc có sẵn, sau đó đọc tất cả trong một lần nhấn, thay vì 8 ngắt riêng biệt cho 8 lần đọc kênh ADC riêng biệt).

Thứ sáu: Sử dụng máy hiện sóng hoặc máy phân tích logic và các chân IO dự phòng trên bảng, để theo dõi xem bạn dành bao nhiêu thời gian cho mỗi bit mã, để xem liệu bạn có thể tăng tốc nó không. (Đặt pin cao khi bạn nhập chức năng / ISR, đặt lại mức thấp khi thoát).

Thứ bảy: Quyết định nếu bạn thực sự cần đọc ADC quá nhiều, việc đi chậm sẽ khiến mọi thứ tồi tệ hơn? Nó phản trực giác nhưng đôi khi chạy chậm hơn thực sự mang lại kết quả đẹp hơn, thực hiện công việc lấy trung bình tín hiệu cho bạn và cắt giảm các xung / quá độ có thể gây ra sự cố hoặc yêu cầu xử lý thêm để loại bỏ. Chúng tôi đã cải thiện thói quen điều khiển động cơ PID bằng cách chạy tốc độ bằng 1/4 tốc độ, giải phóng thời gian tải CPU trong quá trình.


Cảm ơn những lời đề nghị. Vấn đề bằng cách nào đó chỉ ra phần cứng.
Ktc

4

Một nô lệ xe buýt bận rộn với những thứ khác có khả năng kéo dài thời gian để mua thời gian cho đến khi nó có thể thực hiện kết thúc giao tiếp. Nó thực hiện điều này bằng cách không gửi ngay xung đồng hồ ACK / NACK, giữ cho giao tiếp ở trạng thái trung gian cho đến khi nó sẵn sàng trả lời.

Đồng hồ kéo dài là cách thích hợp để đối phó với tình huống này. Một thiết bị không kéo dài và làm những việc xấu khác (treo / khởi động lại xe buýt, NACK một địa chỉ hoặc lệnh hợp lệ, v.v.) có thể có vấn đề và gây thêm gánh nặng cho chủ để giữ mọi thứ được sắp xếp (nó phải lặp lại các lệnh , theo dõi NACK, v.v.)


Bạn đúng nhưng vấn đề là chủ nhà. Chủ nhà bận rộn với những thứ khác, không phải nô lệ. Vì vậy, không chắc chắn tôi có thể làm một đồng hồ kéo dài.
Ktc

Bạn có đang sử dụng phần cứng I2C trên bo mạch hoặc đập giao thức ra khỏi các dòng GPIO không? Không có khoảng thời gian chờ I2C cụ thể được xác định trong tiêu chuẩn, vì vậy nô lệ nên chờ đợi vô thời hạn để chủ hoàn thành một gói.
Adam Lawrence

Tôi sử dụng API ST232 IC2. Xin vui lòng xem bản cập nhật, có vẻ như vấn đề điện dung.
Ktc

1

Tùy thuộc vào khả năng của STM32 (tôi chưa bao giờ sử dụng một), bạn có thể thử một trong các phương pháp sau. Nếu bạn có thể cung cấp chi tiết hơn về những gì bạn đang cố gắng thực hiện và có một lập luận thuyết phục về lý do tại sao mỗi ngắt là cần thiết ở dạng bạn có bây giờ, thì có thể nghĩ đến một câu trả lời cụ thể hơn. Tuy nhiên, cụ thể trong trường hợp của bạn, I2C đủ chậm để điều này không thành vấn đề với các thói quen ngắt được viết tốt.

  • Ngắt cho bất cứ điều gì thường có thể bị vô hiệu hóa. Có nhiều nhất một hoặc hai Ngắt không thể che dấu trong bất kỳ bộ điều khiển thông thường nào, một trong số đó được đặt lại. Nếu bạn không cần điều khiển ngắt điều khiển một cái gì đó (ADC hoặc I2C, trong trường hợp của bạn), thì hãy biến mã ngoại vi đó thành mã không sử dụng ngắt, sau đó vô hiệu hóa ngắt.

  • Xử lý ngắt không nên dài. Cố gắng làm ít nhất có thể từ chính vectơ ngắt. Cách tiếp cận tối giản cực đoan đối với các ngắt là chỉ cần đặt cờ từ bên trong quy trình xử lý ngắt và có, vòng lặp chính thực hiện tất cả các công việc nặng nề từ đó trở đi. Kiến trúc ứng dụng và phần sụn cụ thể của bạn yêu cầu có thể không đơn giản như điều đó, nhưng thực sự đáng để nỗ lực để xem có bao nhiêu thực sự phải được thực hiện từ bên trong các ngắt.

  • Nếu bạn có DMA ngoại vi, hãy sử dụng nó thay vì ngắt ở mỗi byte. Thông thường, việc đưa ADC lên DMA sẽ dễ dàng hơn so với I2C, nhưng các chip khác nhau có cách triển khai khác nhau. Tôi sẽ không ngạc nhiên nếu có một cách rõ ràng để thực hiện trao đổi I2C với DMA. DMA cho phép bạn giảm số lượng ngắt và để lõi xử lý của bạn không phải đối phó với mọi khối dữ liệu.

  • Cố gắng xác định các trường hợp cụ thể mà bạn đang thấy hỏng dữ liệu và cơ chế xảy ra tham nhũng dữ liệu. Điều này khó thực hiện hơn nhiều, nhưng với việc sử dụng sáng tạo máy phân tích logic / dao động hiện đại, bạn có thể thấy một số vấn đề. Cụ thể, đảm bảo sự cố xảy ra với thời gian chứ không phải bộ nhớ (đó là khả năng có sự kết hợp giữa mã khủng và trình biên dịch tự do)

EDIT: Một số lưu ý cụ thể liên quan đến trường hợp này của vấn đề, từ nhận xét của bạn về câu hỏi:

  • Có 80% CPU được sử dụng để đọc ADC thường không phải là điều đáng làm. Thu thập dữ liệu là vô ích nếu bạn không thể hành động hoặc thậm chí lưu dữ liệu.
  • Ngay cả khi bạn đang thu thập (một cách hữu ích) một lượng dữ liệu khổng lồ, các ngắt ADC không nên kéo dài đến mức triệt tiêu hoàn toàn thiết bị ngoại vi I2C trong một thời gian đủ lâu để làm mất dữ liệu. I2C chạy với tốc độ tối đa 100 / 400KHz. Bạn sẽ cần một ngắt thực sự, thực sự rất dài để ngắt đủ lâu để khiến nó trông giống như một thứ gì đó nghiêm trọng hơn jitter đồng hồ trên I2C.

Cảm ơn. Hệ thống của chúng tôi yêu cầu loại ISR ​​phức tạp và dài này, đó là một câu chuyện dài. Mặc dù vậy, bạn đã đúng, I2C phải duy trì ngay cả dưới tải gián đoạn này và không thể. Tôi nghi ngờ vấn đề là trong phần cứng, xem bản cập nhật.
Ktc

Đối với giá trị của nó, theo kinh nghiệm của tôi, hầu hết các trường hợp sử dụng dường như bắt buộc một ISR cực kỳ dài thực sự là những trường hợp xứng đáng với RTOS. Và vâng, mỗi lần chỉnh sửa mới nhất của bạn, nó có vẻ như là một vấn đề phần cứng. Hãy thử đặt một tụ điện nhỏ trên đường dây có bộ phân tích logic của bạn và có thể bạn sẽ ổn. Tại sao điều đó là cần thiết, mặc dù, có phần khó trả lời hơn. Tôi sẽ kiểm tra các điện trở pullup I2C (có thể quá thấp so với điện dung bus của bạn) và kiểm tra bảng dữ liệu của bất kỳ bộ đệm / bộ lặp I2C nào bạn có thể đang sử dụng.
Chintalagiri Shashank

0

Trong một hệ thống nhất định, có thể có tiếng ồn đi vào đồng hồ và xe buýt dữ liệu. Thực tế là bộ xử lý logic của bạn loại bỏ vấn đề cho thấy điều này. Để thực hiện thực tế và nhanh nhất, chỉ cần làm theo các gợi ý được đưa ra bởi quan sát của bạn. Trên xe buýt i2c với tốc độ 400kbits / giây, dựa trên quan sát tương tự, tôi đã kết nối 2M song song với 12pf để nối đất từ ​​các điểm đồng hồ và dữ liệu và thấy rằng vấn đề đã được giải quyết. Điều này loại bỏ / lọc tiếng ồn bên ngoài dải quan tâm cần thiết cho giao tiếp i2c cụ thể. Hãy thử và tư vấ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.