Điều gì gây ra lỗi UART?


8

Tôi muốn biết để biết tại sao xảy ra lỗi UART và khi nào nên kiểm tra các lỗi đó. Có một bài đăng ở đây hỏi về việc xử lý các lỗi riêng lẻ, chẳng hạn như tràn, chẵn lẻ, v.v ... Tôi rõ ràng về lý do tại sao dữ liệu tràn ngập xảy ra, tại sao lỗi chẵn lẻ xảy ra, nhưng tôi muốn biết nguyên nhân gốc là gì. Câu hỏi của tôi tập trung nhiều hơn vào lý do tại sao những lỗi này có thể xảy ra (lý do vật lý) và khi nào nên thực hiện lỗi kiểm tra một yếu tố cho ứng dụng của họ.

Cho đến nay chương trình của tôi dường như hoạt động rất tốt (không có kiểm tra lỗi), nhưng tôi biết rằng tiếng ồn có thể làm mọi thứ rối tung lên. Làm cách nào tôi có thể mô phỏng các điều kiện có thể khiến các cổng UART Rx / Tx không thành công?

Câu trả lời:


8

Có một số nguồn tiềm năng cho tiếng ồn trong bất kỳ mạch. Một số phổ biến nhất bao gồm:

  • Nguồn cung cấp điện quy định kém;
  • Chuyển đổi nguồn điện;
  • Việc tách rời điện dung không đủ của đường ray điện gần MCU;
  • Khớp cảm ứng của các nguồn điện từ gần đó (bao gồm 50 hoặc 60Hz từ nguồn điện lưới; ngay cả khi mạch được cấp nguồn bằng pin, nó sẽ gặp nhiễu này khi đủ gần nguồn điện chính);
  • Nguồn RF gần tần số cộng hưởng của một dấu vết trên bảng mạch, hoặc một trong các sóng hài của nó;
  • Định tuyến các dấu vết dòng điện cao trên bảng mạch gần các đường tín hiệu;
  • Vân vân.

Ngoài ra (như @jippie đã đề cập), đồng hồ lệch là nguyên nhân rất phổ biến gây ra lỗi trong bất kỳ loại giao tiếp nối tiếp nào sử dụng tốc độ dữ liệu được xác định trước. Nếu bạn đang sử dụng một tinh thể bên ngoài và giao tiếp với một hệ thống khác có thể dự kiến ​​là chính xác, thì nó sẽ ít gây ra sự cố hơn. Tuy nhiên, các bộ dao động bên trong có thể có dung sai lớn hơn một số bậc so với tinh thể và có xu hướng thay đổi nhiều hơn trong phạm vi nhiệt độ.

Có một số thử nghiệm cơ bản có thể được thực hiện trên một hệ thống đang chạy để xác định khả năng chống nhiễu cơ bản (và độ lệch) của giao diện của bạn, bao gồm:

  • Đóng băng (làm mát mạch đến mức tối thiểu của các thành phần của nó);
  • Nướng (nhiệt đến mức tối đa);
  • Tiếp xúc với EMI :
    • Đặt bảng lên trên dây nguồn của máy sưởi không gian đang chạy;
    • Khóa một đài phát thanh CB trong vùng lân cận của hội đồng quản trị;
    • Đặt bảng bên cạnh bộ định tuyến không dây của bạn;
    • Sử dụng dây hookup dài (thay vì cáp nối tiếp được xây dựng đúng cách) cho kết nối UART.

Có nhiều người khác - trên thực tế, có những phòng thử nghiệm lớn dành riêng cho trình độ EMC .

Nói chung, trừ khi mức độ mất dữ liệu tối thiểu có thể chấp nhận được, việc bao gồm một số loại kiểm tra lỗi trong mã liên lạc của bạn là điều luôn thận trọng. Ngay cả một tổng kiểm tra đơn giản vẫn tốt hơn không có gì.


6

Một nguồn lỗi phổ biến trên UART bên cạnh chất lượng mức tín hiệu (nhiễu, thời gian tăng / giảm) là độ lệch của đồng hồ. Nếu đồng hồ máy phát và đồng hồ máy thu không xuất phát từ cùng một nguồn (đó là trường hợp thường xuyên nhất), thì cái này sẽ chạy nhanh hơn cái kia. Khi lỗi thời gian quá lớn, đôi khi bạn có thể đọc sai một chút.


Điều gì sẽ khiến đồng hồ bị lệch, nếu vi điều khiển bị bỏ lại một mình trong hộp đen, ở giữa ai biết ở đâu?
user791953

1
Miễn phí chạy đồng hồ địa phương. Mỗi dao động có độ chính xác riêng của nó. Đồng hồ MCU có thể được chia thành tần số có thể sử dụng cho UART, nhưng đôi khi nó bị tắt bởi một tỷ lệ nhỏ. Điều này đến lượt nó được gây ra bởi thực tế là số chia là một số nguyên.
jippie

Ví dụ. Đồng hồ MCU = 16 MHz, UART baudrate = 9600Bd. Sau đó, UART thường có xung nhịp 153600Hz. Nhưng 16000000/153600 không phải là số nguyên, vì vậy baudrate sẽ bị tắt.
jippie

Phải, điều đó sẽ cho một tỷ lệ lỗi nhỏ. Đoán tôi đã may mắn không gặp phải bất kỳ lỗi nào, nhưng nếu đó là dữ liệu quan trọng, kiểm tra nên được thực hiện luôn.
dùng791953

Tốc độ baud thấp hơn, tốc độ xung nhịp cao hơn (tăng độ phân giải lấy mẫu và độ chính xác thời gian).
jippie

1

Hầu hết các lỗi xuất phát từ ba nguyên nhân: (1) tín hiệu được tạo của máy phát không thể hiện dữ liệu hợp lệ; (2) tín hiệu của máy phát không được nhận như đã tạo hoặc (3) máy thu không sẵn sàng xử lý dữ liệu khi nhận được. Nguyên nhân phổ biến nhất tôi gặp phải cho sự cố # 1 là một máy phát được cấu hình lại hoặc tắt trong khi truyền dữ liệu. Vấn đề # 2 có thể dễ dàng xảy ra đối với các tín hiệu truyền qua "thế giới bên ngoài" do các vấn đề như nhiễu sóng vô tuyến (điện thoại di động có thể gây khó chịu một cách đáng ngạc nhiên!), Nhưng nói chung không nên xảy ra đối với các tín hiệu chỉ giới hạn trong một bảng. Vấn đề # 3 có thể xảy ra do có quá nhiều byte đến nhanh hơn mức chúng có thể được xử lý hoặc do bộ thu được cấu hình lại, tắt hoặc khởi động trong khi truyền.

Trong nhiều trường hợp, thật khó để loại bỏ hoàn toàn tất cả những vấn đề này; Mục tiêu của một người là phải đảm bảo rằng tổng "thiệt hại" do họ gây ra (xác suất xảy ra, số lần thiệt hại mỗi lần xảy ra) là thấp. Điều này có thể dễ dàng được thực hiện bằng cách chọn một ước tính đáng tin cậy bi quan, và sau đó thiết kế một giao thức sao cho tác động đến hiệu suất hệ thống của những sự cố tồi tệ nhất phù hợp với ước tính của một người sẽ nằm trong giới hạn chấp nhận được.


0

Lỗi khung có thể được gây ra bởi những gì @jippie đề cập - người nhận đã phát hiện ra bit start và nơi nó mong đợi bit dừng dữ liệu được đảo ngược. Điều này cũng có thể là do tham nhũng dữ liệu gây ra bởi nhiễu đường truyền trên bit stop. Bạn luôn cần kiểm tra điều này cho mỗi byte nhận được.

Lỗi chẵn lẻ xảy ra khi tính chẵn lẻ được thực hiện trên liên kết dữ liệu và có sự tham nhũng gây ra sự không tương đương trong dữ liệu nhận được. Bạn luôn cần kiểm tra điều này cho mỗi byte nhận được.

Nhận ngắt cũng được coi là một lỗi mặc dù đó thực sự là một dấu hiệu cho thấy dữ liệu đến đã giảm xuống mức 0 logic trong thời gian dài hơn 1 byte dữ liệu. Thông thường logic 1 là trạng thái "môi trường" giữa các byte dữ liệu liên tiếp và nó vẫn giữ nguyên như vậy. Tôi nghĩ đó là một sự quay trở lại với các hệ thống điện báo cũ. Tôi sẽ không kiểm tra điều này trừ khi bạn đang sử dụng "tính năng" này để biểu thị (nói) lệnh đặt lại cho người nhận.

Lỗi tràn bộ nhớ là khi một byte mới được nhận trước khi byte trước đó được CPU đọc. Hơi khác một chút khi có một phần tử tham gia nhưng có cùng một điều - dữ liệu nhận được hợp lệ bị mất do sự chậm chạp của CPU. Luôn kiểm tra điều này trước khi đọc một byte và nếu byte là một phần của tin nhắn (hoặc lệnh) dài hơn, hãy ném toàn bộ tin nhắn / lệnh đi và bằng cách nào đó yêu cầu người phát gửi lại toàn bộ tin nhắn / lệnh.

Khi chạy không thực sự là một lỗi nhưng chỉ ra cho UART gửi rằng bộ đệm truyền của nó trống, tức là nó đang yêu cầu một byte mới để truyền. Bạn không cần phải kiểm tra điều này.


Tôi hiểu những lỗi này là gì và tại sao chúng xảy ra, câu hỏi của tôi sẽ giống với câu hỏi khi nào nên cung cấp kiểm tra lỗi cho chúng.
dùng791953

@ user791953 - xong
Andy aka

BTW, phần dưới không phải là vấn đề với hầu hết các giao thức, nhưng một số giao thức sử dụng một dòng nhàn rỗi để chỉ ra phần cuối của gói. Trong những trường hợp như vậy, một lỗi ngầm ở phía truyền có thể khiến người nhận nghĩ không chính xác gói tin kết thúc trước khi nó được yêu cầu.
supercat

0

Để xử lý các lỗi này, bạn phải thực hiện giao thức logic mức cao hơn. một cái gì đó giống với TCP hoặc kiểm tra ngăn xếp OSI để tìm ý tưởng.

về cơ bản, hai phần quan trọng để bắt đầu là tổng kiểm tra và thời gian chờ. sử dụng một thuật toán để tính toán một giá trị dư thừa thể hiện, ở dạng nhỏ hơn, nội dung của mỗi thông báo. sau đó kiểm tra điều này trong tin nhắn nhận được. nếu các khoản tiền không khớp, bạn có thể đã gặp phải lỗi khung, nhiễu bit, v.v. và bạn sẽ cần phải loại bỏ tin nhắn và thử một số loại phục hồi, gửi lại, tín hiệu NACK (không được xác nhận), v.v.

đồng thời, đảm bảo thực hiện thời gian chờ trong giao thức cấp trên của bạn. nếu bạn gặp một số lỗi định khung, UART của bạn có thể không bao giờ khôi phục và bắt đầu xử lý lại. nó có thể đang chờ bit dừng trên một khung mà người gửi UART nghĩ rằng đã được gửi, nhưng bị hỏng do nhiễu, lệch đồng hồ, v.v. điều này sẽ gửi bất kỳ mã đầu vào nào vào một vòng lặp vô hạn. đảm bảo rằng bạn có giới hạn lành mạnh về thời gian đọc đầu vào của bạn sẽ đợi bao lâu cho đến khi quyết định từ bỏ tin nhắn này, và một lần nữa, thử lại, NACK, từ bỏ, v.v.


Thời gian chờ cần được thực hiện trên ít nhất một mặt của bất kỳ giao thức cấp cao hơn nào; trong nhiều trường hợp, tốt nhất là thực hiện chúng ở một bên. Có một bên chờ mãi cho dữ liệu không bao giờ đến chỉ là vấn đề nếu có thứ gì khác hữu ích mà nó có thể đã được thực hiện thay thế. Nếu X yêu cầu Y cung cấp một số dữ liệu, X sẽ cần chuẩn bị để gửi lại yêu cầu của anh ta trong trường hợp Y không nhận được. Tuy nhiên, Y sẽ không cần phải lo lắng về việc liệu X có nhận được phản hồi của mình không. Nếu X không nhận được nó, X sẽ yêu cầu dữ liệu lại. Việc X không hỏi lại dữ liệu có nghĩa là Y không cần gửi lại.
supercat

@supercat đúng, đây là một mô hình tốt, nhưng tôi đang hướng tới dòng cấp thấp hơn bằng mã hóa dòng. bạn sẽ luôn có một vòng lặp đang đọc dữ liệu và cố gắng tìm hiểu xem một tin nhắn hoàn chỉnh đã sẵn sàng chưa, nếu một tin nhắn hoàn chỉnh không bao giờ ở đó, nó có thể treo hệ thống con đầu vào, bất kể không có gì khác ngoài việc chờ đợi làm xong. trong trường hợp này, hệ thống con đầu vào ít nhất phải nhận ra rằng đã xảy ra lỗi, xóa bất kỳ dữ liệu dữ liệu nào và được đặt lại cho lần thử khác.
Andyz Smith

Nếu mỗi gói bắt đầu bằng một chuỗi byte luôn có thể nhận dạng được trong bất kỳ ngữ cảnh nào và nếu người nhận không có gì hữu ích thì nó có thể làm gì cho đến khi nhận được một gói hoàn chỉnh, tại sao nó phải quan tâm nếu vài giờ trôi qua sau khi nhận được một phần gói? Lần tới khi ai đó cố gắng gửi một gói thực, người nhận sẽ thấy điểm đánh dấu bắt đầu của gói và từ bỏ gói một phần.
supercat

@supercat vì sau đó bạn có một vòng lặp đang tìm kiếm nhiều thứ. nó vẫn đang tìm kiếm sự kết thúc của gói một phần và nó đang tìm kiếm sự khởi đầu của một gói mới, chưa được xử lý. điều này làm cho logic phức tạp hơn nhiều về mặt thực tiễn, nếu sau đó, làm trong khi, mã hóa.
Andyz Smith

Tôi không chắc chắn những khó khăn là gì. Nếu ai đó sử dụng vòng lặp byte nhận, người ta sẽ phải thoát ra khỏi nó nếu thời gian chờ xảy ra hoặc byte bắt đầu được nhìn thấy. Cả hai hành vi cần phải được xử lý giống hệt nhau, chỉ lưu lại vì thực tế là chuỗi bắt đầu sẽ đặt cờ, vì vậy mã tiếp theo sẽ tìm kiếm nó sẽ không làm phiền.
supercat
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.