Cách đọc dữ liệu nối tiếp từ máy hiện sóng


21

Tôi có một vi điều khiển (PICAXE 20X2) và một đồng hồ đo nồi. Tôi đã lập trình micro để nó gửi bất kỳ thay đổi nào của đồng hồ sang cổng nối tiếp của PC. Rõ ràng đó là một ADC 8 bit. Bây giờ điều thú vị đối với tôi là có thể giải mã dữ liệu nối tiếp này trên máy hiện sóng.

Đây là hai hình ảnh, đầu tiên là khi micro gửi "0" tới PC và bức ảnh tiếp theo là khi nó gửi "255". Dữ liệu đang được truyền bằng cách sử dụng 9600 buad và tôi có thể nhận chúng tại thiết bị đầu cuối PC.

Bức ảnh đầu tiên nhập mô tả hình ảnh ở đây

Hình thứ hai nhập mô tả hình ảnh ở đây

Vì vậy, câu hỏi của tôi là, tôi đã nắm bắt đúng dữ liệu trong phạm vi của mình chưa, và thứ hai là làm thế nào người ta có thể đọc và giải mã các xung này thành định dạng hex hoặc ascii. Ý tôi là làm thế nào để đọc xung tăng giảm này (0/1).

Cảm ơn.


3
các dòng nối tiếp không hoạt động ở trạng thái logic '1', vì vậy hãy lưu ý rằng bạn có 1 ở dưới cùng và 0 ở trên cùng ở đây. Tôi biết mọi người đã khóa vào đó. Nhận xét của tôi là nhằm mục đích hướng dẫn phạm vi thu thập dữ liệu nối tiếp trong tương lai; bạn có thể thăm dò mọi thứ để trạng thái nhàn rỗi cao.
JustJeff

Câu trả lời:


14

Đầu tiên, một điều mà Olin cũng nhận thấy: các cấp độ là mặt trái của những gì một vi điều khiển thường tạo ra:

nhập mô tả hình ảnh ở đây

Không có gì phải lo lắng, chúng ta sẽ thấy rằng chúng ta cũng có thể đọc nó theo cách này. Chúng ta chỉ cần nhớ rằng trên phạm vi, bit start sẽ là 1bit dừng và bit dừng 0.

μμμ1μ0

0x001μ
0xFFμ

guesstimates:

0b11001111 = 0xCF
0b11110010 = 0xF2

0b11001101 = 0xCD
0b11001010 = 0xCA
0b11001010 = 0xCA
0b11110010 = 0xF2

chỉnh sửa
Olin là hoàn toàn đúng, đây là một cái gì đó giống như ASCII. Thực tế, đây là phần bổ sung của ASCII.

0xCF ~ 0x30 = '0'
0xCE ~ 0x31 = '1'
0xCD ~ 0x32 = '2'
0xCC ~ 0x33 = '3'
0xCB ~ 0x34 = '4'
0xCA ~ 0x35 = '5'

0xF2 ~ 0x0D = [CR]

Điều này xác nhận rằng giải thích của tôi về ảnh chụp màn hình là chính xác.


chỉnh sửa 2 (cách tôi diễn giải dữ liệu, theo yêu cầu phổ biến :-))
Cảnh báo: đây là một câu chuyện dài, bởi vì đó là bản ghi lại những gì xảy ra trong đầu tôi khi tôi cố gắng giải mã một điều như thế này. Chỉ đọc nó nếu bạn muốn tìm hiểu một cách để giải quyết nó.

Ví dụ: byte thứ hai trên ảnh chụp màn hình thứ 1, bắt đầu bằng 2 xung hẹp. Tôi bắt đầu với byte thứ hai trên mục đích vì có nhiều cạnh hơn trong byte đầu tiên, vì vậy sẽ dễ dàng hơn để làm cho đúng. Mỗi xung hẹp là khoảng 1/10 của một phân chia, do đó, mỗi xung có thể cao 1 bit, với một bit thấp ở giữa. Tôi cũng không thấy bất cứ điều gì hẹp hơn thế này, vì vậy tôi đoán đó là một chút. Đó là tài liệu tham khảo của chúng tôi.
Sau đó, sau 101một khoảng thời gian dài hơn ở mức thấp. Nhìn rộng gấp đôi so với những cái trước, vì vậy có thể được 00. Cao theo sau đó là rộng gấp đôi, vì vậy sẽ được 1111. Bây giờ chúng ta có 9 bit: một bit start ( 1) cộng với 8 bit dữ liệu. Vì vậy, bit tiếp theo sẽ là bit stop, nhưng bởi vì nó0nó không thể nhìn thấy ngay lập tức. Vì vậy, đặt tất cả chúng ta lại với nhau 1010011110, bao gồm bit start và stop. Nếu bit stop không bằng 0, tôi đã có một giả định tồi ở đâu đó!
Hãy nhớ rằng UART gửi LSB (bit có ý nghĩa nhỏ nhất) trước tiên, vì vậy chúng tôi sẽ phải đảo ngược 8 bit dữ liệu: 11110010= 0xF2.

Bây giờ chúng ta biết chiều rộng của một bit đơn, một bit kép và chuỗi 4 bit và chúng ta đã xem xét byte đầu tiên. Chu kỳ cao đầu tiên (xung rộng) rộng hơn một chút so với 1111byte thứ hai, do đó sẽ rộng 5 bit. Mỗi khoảng thời gian thấp và cao theo sau nó đều rộng bằng bit kép trong byte khác, vì vậy chúng tôi nhận được 111110011. Lại 9 bit, do đó, bit kế tiếp nên là bit thấp, bit stop. Điều đó không sao, vì vậy nếu dự đoán của chúng tôi là chính xác, chúng tôi lại có thể đảo ngược các bit dữ liệu: 11001111= 0xCF.

Sau đó, chúng tôi đã nhận được một gợi ý từ Olin. Giao tiếp đầu tiên dài 2 byte, ngắn hơn 2 byte so với lần thứ hai. Và "0" cũng ngắn hơn 2 byte so với "255". Vì vậy, nó có thể là một cái gì đó giống như ASCII, mặc dù không chính xác. Tôi cũng lưu ý rằng byte thứ hai và thứ ba của "255" là như nhau. Tuyệt vời, đó sẽ là gấp đôi "5". Chúng tôi đang làm tốt! (Thỉnh thoảng bạn phải tự động viên mình.) Sau khi giải mã "0", "2" và "5" Tôi nhận thấy rằng có sự khác biệt 2 giữa các mã cho hai mã đầu tiên và chênh lệch 3 giữa các mã cuối cùng hai. Và cuối cùng tôi nhận thấy đó 0xC_là phần bổ sung của 0x3_, đó là mẫu cho các chữ số trong ASCII.


Cảm ơn các mẹo, tôi sẽ cố gắng nắm bắt dạng sóng phù hợp và cập nhật câu hỏi của tôi.
Sean87

Cảm ơn, bạn có phiền đánh dấu hình ảnh như cách bạn tìm thấy những dữ liệu đó không?
Sean87

1
@ Sean87 - Nó trở thành một câu chuyện dài, tôi đã thêm nó vào câu trả lời của mình. Nó minh họa cách tôi làm việc này, người khác có thể đi theo những con đường khác nhau. Đừng lo lắng nếu bạn nghĩ rằng bạn sẽ không thấy một nửa số đó; hầu hết chỉ là kinh nghiệm và trí tưởng tượng. Không có thông tin tình báo đặc biệt liên quan.
stevenvh

Những câu trả lời và câu hỏi rất hay, nhưng tôi đang tự hỏi tại sao bạn lại nói rằng Máy chiếu dao động cho thấy sự đảo ngược của những gì thực sự là. Tôi biết rằng dòng nhàn rỗi hầu như luôn luôn cao, nhưng không phải là máy hiện sóng để chụp một hình ảnh chính xác của vật thật? Ngoại trừ nếu người dùng thay đổi một tham số cài đặt của máy hiện sóng.
Nikos

7

Một cái gì đó không thêm vào. Tín hiệu của bạn dường như đạt cực đại 3,3V đến cực đại, điều đó hàm ý rằng chúng nằm ngoài vi mô. Tuy nhiên, các mức UART của vi điều khiển (hầu như) luôn ở mức cao và không hoạt động ở mức thấp. Tín hiệu của bạn được đảo ngược từ đó, điều đó không có ý nghĩa.

Để cuối cùng có được dữ liệu này vào PC, nó phải được chuyển đổi thành các cấp RS-232. Đây là những gì một cổng PC COM mong đợi để xem. RS-232 ở mức thấp không hoạt động và hoạt động ở mức cao, nhưng mức thấp dưới -5V và mức cao là trên + 5V. May mắn thay, có những con chip giúp dễ dàng chuyển đổi giữa các tín hiệu UART mức vi điều khiển thông thường và RS-232. Những con chip này chứa các bơm tích điện để tạo ra điện áp RS-232 từ nguồn điện 3,3V của bạn. Đôi khi những con chip này được gọi chung là "MAX 232" vì đó là số phần của một loại chip sớm và phổ biến thuộc loại đó. Bạn cần một biến thể khác vì rõ ràng bạn đang sử dụng nguồn 3,3V chứ không phải 5V. Chúng tôi tạo ra một sản phẩm về cơ bản là một trong những con chip này trên một bảng có đầu nối. Truy cập http://www.embedinc.com/products/rslink2và nhìn vào sơ đồ để thấy một ví dụ về cách nối một con chip như vậy.

Một điều nữa không thêm vào là cả hai chuỗi dường như nhiều hơn một byte, mặc dù bạn nói rằng bạn chỉ gửi 0 và 255. Loại dữ liệu nối tiếp này được gửi với một bit bắt đầu, sau đó là 8 bit dữ liệu, sau đó một chút dừng lại. Bit bắt đầu luôn ở cực đối diện từ mức nhàn rỗi của dòng. Trong hầu hết các mô tả, mức nhàn rỗi của dòng được gọi là "không gian" và ngược lại là "đánh dấu". Vì vậy, bit start luôn luôn ở mức. Mục đích của bit start là cung cấp đồng bộ hóa thời gian cho các bit còn lại. Vì cả hai bên đều biết một bit dài bao nhiêu, nên câu hỏi duy nhất là khi bắt đầu một byte. Bit bắt đầu cung cấp thông tin này. Về cơ bản, bộ thu bắt đầu một đồng hồ ở cạnh đầu của bit start và sử dụng nó để biết khi nào các bit dữ liệu sẽ xuất hiện.

Các bit dữ liệu được gửi ít nhất theo thứ tự quan trọng nhất, với dấu là 1 và dấu cách là 0. Một bit dừng ở mức không gian được thêm vào để bắt đầu của bit bắt đầu tiếp theo là một cạnh mới và để lại một ít thời gian giữa các byte. Điều này cho phép một chút lỗi giữa người gửi và người nhận. Nếu người nhận chậm hơn người gửi dù chỉ một chút, nó sẽ bỏ lỡ phần bắt đầu của bit bắt đầu tiếp theo. Bộ thu đặt lại và bắt đầu đồng hồ của nó một lần nữa mỗi bit start mới, để lỗi thời gian không tích lũy.

Vì vậy, từ tất cả những điều này, bạn sẽ có thể thấy rằng dấu vết đầu tiên dường như đang gửi ít nhất hai byte và cuối cùng trông giống như có thể là 5.

Nó sẽ giúp nếu bạn mở rộng quy mô thời gian của dấu vết. Bằng cách đó bạn có thể đo được một chút thời gian thực sự là gì. Điều đó sẽ cho phép bạn xác minh rằng bạn thực sự có 9600 baud (104 Pha / bit) và cho phép bạn giải mã các bit riêng lẻ của một bản chụp. Như bây giờ, không có đủ độ phân giải để xem các bit đang ở đâu, và do đó thực sự giải mã những gì đang được gửi.

Thêm:

Tôi nhận thấy rằng hệ thống của bạn có thể đang gửi dữ liệu trong ASCII thay vì nhị phân. Đó không phải là cách nó thường được thực hiện kể từ khi chuyển đổi sang ASCII trong hệ thống nhỏ chiếm nhiều tài nguyên hạn chế, sử dụng băng thông kém và dễ dàng thực hiện chuyển đổi trên PC nếu bạn muốn hiển thị dữ liệu cho người dùng. Tuy nhiên, nếu truyền của bạn là các ký tự ASCII sẽ giải thích tại sao các chuỗi nhiều hơn một byte, tại sao chuỗi thứ hai dài hơn ("255" có nhiều ký tự hơn "0") và tại sao cả hai ký tự dường như kết thúc trong cùng một byte. Byte cuối cùng có lẽ là một loại kết thúc của ký tự dòng, thường sẽ là trả về vận chuyển hoặc nguồn cấp dữ liệu.

Dù sao, mở rộng thang thời gian và chúng ta có thể giải mã chính xác những gì nó được gửi.


1
Bit dừng (và nó đối diện với bit start) cũng buộc một cạnh khi bắt đầu truyền mới.
stevenvh

@steven: Vâng, tôi nhận ra rằng tôi đã bỏ qua câu đó khi đọc lại câu trả lời của mình và thêm nó vào một bản chỉnh sửa, có lẽ cùng lúc bạn đang viết bình luận của mình.
Olin Lathrop

4
Mặc dù gửi ASCII là "không hiệu quả" nhưng nó vẫn có thể là một lựa chọn rất tốt. Hầu hết các hệ thống nhúng của tôi không chỉ gửi ASCII, chúng còn nhận được các lệnh ASCII, cho phép thử nghiệm thủ công bằng cách "trò chuyện" với chúng từ một chương trình đầu cuối. Tiêu chuẩn SCPI (một loại cải tiến trên GPIB, được mở rộng sang các giao diện điện khác) là một phương pháp rất chính thức hoạt động dọc theo các dòng này.
Chris Stratton

4
Đi đến không đồng ý mạnh mẽ . Ascii lấy một số lượng mã nhỏ như vậy, thậm chí chạy kim loại trần trên một chút 8 đắng. Chắc chắn, bạn có thể viết một chương trình tùy chỉnh, nhưng điều gì xảy ra sau 10 năm kể từ khi nó bị mất và nó sẽ mất một máy ảo để chạy nó ngay cả khi nó có thể được tìm thấy? Và chắc chắn, bất kỳ lập trình viên nào xứng đáng với muối của mình đều có thể hack một thiết bị đầu cuối nhị phân để đảo ngược thứ gì đó. Nhưng các giao diện có thể đọc được của con người rất xứng đáng với chi phí nhỏ trong hầu hết các hệ thống quan trọng và hạn chế bộ nhớ nghiêm trọng nhất. Ngoài ra, nếu bạn có bộ nhớ, bạn có thể nhúng đầu ra gỡ lỗi với bật / tắt.
Chris Stratton

2
Tôi nên đề cập rằng tôi đã bắt đầu trên các giao diện ASCII vì đó là yêu cầu của khách hàng ... nhưng tôi đã giữ chúng vì chúng hữu ích như thế nào. Tôi có thể thêm một ý tưởng như một lệnh trong phần sụn và sau đó kiểm tra nó ở bất cứ đâu trong cơ sở. Không phải triển khai bản cập nhật cho máy khách cấu hình mỗi lần tôi đăng phiên bản phần mềm thử nghiệm với các tính năng bổ sung để xem xét vấn đề mà ai đó đang gặp phải trong một hệ thống phức tạp, trong đó có một mô-đun. Trên điện thoại với một khách hàng, tôi có thể yêu cầu họ kích hoạt một thiết bị đầu cuối và hướng dẫn họ sử dụng các chức năng kiểm tra nhà máy chưa được công bố.
Chris Stratton

1

Bạn cần biết chi tiết đầy đủ: tốc độ, nếu có bit start, số bit dữ liệu, nếu có bit stop và nếu có bit chẵn lẻ. Đây phải là một chức năng về cách cấu hình UART trong vi điều khiển.

Nếu phạm vi Rigol không có tùy chọn giải mã nối tiếp (nhiều DSO làm), bạn có thể sử dụng con trỏ X để hỗ trợ giải mã. Đặt con trỏ đầu tiên ở cạnh đầu của dữ liệu và di chuyển con trỏ thứ hai qua luồng bit. Đồng bằng giữa các con trỏ có thể được sử dụng để xác định 'bit' nào bạn hiện đang di chuột qua bằng số học đơn giản. Bỏ qua các bit start / stop / parity, rõ ràng.


Luôn có một bit start và luôn có ít nhất một bit stop. Có thể có thêm các bit dừng, nhưng chúng không thể phân biệt được từ thời gian chết giữa các byte. Bộ giải mã cơ học cũ đôi khi cần hai bit stop để có thời gian cho cơ chế thiết lập lại. Ngày nay hầu như luôn có 8 bit dữ liệu và không có bit chẵn lẻ, nhưng như bạn nói, điều đó có thể thay đổi.
Olin Lathrop
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.