Làm thế nào để giải mã hiệu quả tín hiệu nối tiếp không chuẩn


11

Tôi là thành viên đại học của nhóm nghiên cứu làm việc trong một dự án liên quan đến ASIC truyền RF và bộ thu không dây của nó sẽ gửi dữ liệu tới PC.

Máy thu phát tín hiệu nối tiếp nhanh , liên tục, không đồng bộ, không chuẩn (nghĩa là không phải SPI, I2C, UART, v.v.) vì vậy công việc của tôi là viết phần mềm vi điều khiển để giao tiếp máy thu với máy tính. Hiện tại phương pháp của tôi là sử dụng các ngắt kích hoạt cạnh để đặt dữ liệu vào bộ đệm tròn và thực hiện toàn bộ quá trình giải mã từng bit trong vòng lặp chính. Bộ vi điều khiển phải xuất đồng thời dữ liệu này bằng USB (cổng com ảo) cho máy tính.

Đây là một vấn đề tôi đang gặp phải, và một vấn đề tôi đang dự đoán:

  1. Tôi không thể xử lý dữ liệu được đệm đủ nhanh ngay cả với bộ xử lý ARM Cortex M3 72 MHz khá mạnh mẽ của mình. Tốc độ bit là 400 Kb / giây (2,5 us / bit). Để tham khảo chỉ để lại 180 chu kỳ trên mỗi bit (bao gồm cả giải mã VÀ ISR, có ~ 30 chu kỳ ouch trên đầu!). MCU cũng phải xử lý rất nhiều nhiệm vụ khác mà nó bỏ phiếu trong vòng lặp chính.

  2. Trình điều khiển cổng com ảo USB cũng bị gián đoạn. Điều này khiến tôi gần như chắc chắn rằng trình điều khiển cuối cùng sẽ khiến bộ xử lý bị gián đoạn quá lâu đến nỗi nó bỏ lỡ cửa sổ 2,5 micro giây (180 chu kỳ) trong đó một bit có thể được truyền đi. Tôi không chắc làm thế nào các xung đột / cuộc đua như thế này thường được giải quyết.

Vì vậy, câu hỏi chỉ đơn giản là, người ta có thể làm gì để giải quyết những vấn đề này hay đây không phải là phương pháp đúng đắn? Tôi cũng sẵn sàng xem xét các cách tiếp cận ít tập trung vào phần mềm. Ví dụ: sử dụng chip USB chuyên dụng với một số loại máy trạng thái phần cứng để giải mã, nhưng đây là lãnh thổ xa lạ.


Tôi phải nói rằng, rất hiếm khi tôi thấy rằng nhiều gợi ý tôi thích đã trả lời nhanh chóng, nói tốt câu hỏi của bạn. Tôi sẽ quan tâm để biết thêm về các dữ liệu. Có phải chúng đang bùng nổ, đột ngột hết tốc độ và sau đó là những khoảng thời gian dữ liệu thấp hoặc bạn có thể sử dụng thời gian dài với dữ liệu liên tục không?
Kortuk

Miễn là ASIC có sức mạnh, nó sẽ gửi một luồng dữ liệu liên tục. Không bùng nổ chút nào. Đây là một ứng dụng cảm biến y tế thời gian thực với máy tính đọc. Bạn đã bao giờ nhìn thấy EKG chưa?
Keegan Jay

Rất nhiều câu trả lời tuyệt vời ở đây. Tôi đã thấy một sự phân chia rõ ràng giữa các giải pháp liên quan đến các thay đổi đối với các ngắt và các giải pháp liên quan đến phần cứng / logic kỹ thuật số chuyên dụng. Những thứ như FPGA và Verilog tôi quen thuộc, nhưng chưa có kinh nghiệm nên điều này có nghĩa là chúng phải được lưu trong thời gian dài. Trong @rocketmagnets ngắn hạn, phương pháp ít gián đoạn là tốt. Tôi thích sự tao nhã của việc cống hiến các nhiệm vụ cấp bách cho logic kỹ thuật số và tiết kiệm ARM cho tính toán thực sự. Trong tương lai, sức mạnh của ARM sẽ được sử dụng để phân tích và lọc dữ liệu nối tiếp không dây.
Keegan Jay

Là tín hiệu đồng bộ hay không đồng bộ?
đánh dấu

Không đồng bộ. 4 bit start, 10 bit dữ liệu, 2 bit stop. Do bản chất của ASIC đang truyền, thời gian HI và LO khác nhau rất nhiều từ chip này sang chip khác. Tôi đã viết một thuật toán để suy ra tốc độ truyền.
Keegan Jay

Câu trả lời:


5

Một câu trả lời khác: Ngừng sử dụng ngắt.

Mọi người nhảy để sử dụng ngắt quá dễ dàng. Cá nhân, tôi hiếm khi sử dụng chúng vì chúng thực sự lãng phí rất nhiều thời gian, như bạn đang khám phá.

Bạn thường có thể viết một vòng lặp chính để thăm dò mọi thứ nhanh đến mức độ trễ nằm trong thông số kỹ thuật và rất ít thời gian bị lãng phí.

loop
{
    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (serial_byte_ready)
    {
        // decode serial data
    }

    if (enough_serial_bytes_available)
    {
        // more decoding
    }        

    if (usb_queue_not_empty)
    {
        // handle USB data
    }        
}

Có thể có một số điều trong vòng lặp xảy ra thường xuyên hơn những thứ khác. Có lẽ các bit đến chẳng hạn, trong trường hợp đó, thêm nhiều thử nghiệm đó, để nhiều bộ xử lý được dành riêng cho nhiệm vụ đó.

loop
{
    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (serial_byte_ready)
    {
        // decode serial data
    }

    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (enough_serial_bytes_available)
    {
        // more decoding
    }        

    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (usb_queue_not_empty)
    {
        // handle USB data
    }        
}

Có thể có một số sự kiện mà độ trễ của phương pháp này quá cao. Ví dụ, bạn có thể cần một sự kiện hẹn giờ rất chính xác. Trong trường hợp đó, có sự kiện đó bị gián đoạn và có mọi thứ khác trong vòng lặp.


Tôi thích câu trả lời của bạn hơn câu trả lời của người Rocketmagnet khác. Thay vì có nhiều phần mềm, phần cứng nhanh hơn, nhiều thứ khác, Rocketmagnet, đề xuất: làm ít hơn, tốt hơn, đơn giản hơn.

Được rồi, tôi đã thấy nhiều trường hợp bị gián đoạn làm cho một giải pháp tốt hơn nhiều. Họ làm những điều tuyệt vời, cho phép mã có cấu trúc tốt, độ trễ thấp và nhiều lợi thế khác, nhưng tôi phải đồng ý với bạn ở đây. Có vẻ như quá trình này rất mạnh mẽ, 1 bộ điều khiển có thể cần dành mọi sự chú ý của nó để xử lý luồng nối tiếp. Mặt trước kỹ thuật số nghe có vẻ lý tưởng đối với tôi nhưng nhiều lần bạn có một số micros và không có FPGA xung quanh khi nó là một dự án trường học, tôi có thể sẽ dành một micro để xử lý nó cho tôi trước và cố gắng lắp vào một FPGA sau để thay thế nó cho Giá cả.
Kortuk

Đây có lẽ là giải pháp tôi sẽ đi cùng trong thời gian ngắn. Tôi đã hy vọng tránh điều này bởi vì nó liên quan đến việc viết lại khá nhiều trình điều khiển nối tiếp hiện có, nhưng đó là một giải pháp tao nhã nằm trong khả năng của tôi trong một khung thời gian ngắn.
Keegan Jay

1
@JayKeegan - Có, đó có lẽ là con đường nhanh nhất dẫn đến giải pháp. PSoC và FPGA có thể là cách tiếp cận cho dự án tiếp theo.
Rocketmagnet

6

Bạn có thể có thể sử dụng một FPGA thay vì Vi điều khiển để giải mã và đệm dữ liệu không dây. Sau đó, sử dụng bộ xử lý ARM để xóa các bộ đệm của FPGA (ví dụ: sử dụng giao diện SPI) và chuyển nội dung ra cổng USB Comm. Nó hoạt động, nhưng một GPU sẽ có thể theo kịp dễ dàng miễn là bạn có thể phục vụ nó thường xuyên đủ để đảm bảo rằng bộ đệm phần cứng của nó không bị tràn ngập (hoặc nếu bạn có thể xử lý dữ liệu bị rớt ở cấp độ cao hơn của giao thức ).


Đây có thể là một giải pháp tuyệt vời trong thời gian dài. Tôi đã hy vọng tôi nhận được rất nhiều giải pháp logic / phần cứng kỹ thuật số bên cạnh các giải pháp phần mềm bởi vì bây giờ tôi có một cái cớ để tìm hiểu về những điều này! Thật không may, tôi không có kinh nghiệm với các GPU.
Keegan Jay

6

Dễ dàng: Sử dụng vi điều khiển PSoC5 .

PSoC

Bạn có tất cả sự dễ dàng sử dụng của một vi điều khiển, cộng với nó có chứa CPLD, vì vậy bạn có thể viết các thiết bị ngoại vi phần cứng của riêng bạn trong Verilog. Chỉ cần viết bộ giải mã dữ liệu nối tiếp của bạn trong verilog và sử dụng DMA để truyền phát nó đến cổng USB.

Trong khi đó, lõi ARM 32-bit mạnh mẽ có thể được điều chỉnh bằng ngón tay cái.


Trang tổng quan không liệt kê tần số đồng hồ, điều này làm tăng sự nghi ngờ của tôi. Datasheet cho biết 40 MHz (tôi cũng lưu ý 6mA ở mức 6 MHz). Đó là một nửa những gì OP có bây giờ. "MCU cũng phải xử lý rất nhiều nhiệm vụ khác", vì vậy nó có thể phụ thuộc vào những gì đó có phải là một ý tưởng tốt hay không.
stevenvh

Chúng lên đến 67 MHz. Vì vậy, nó gần như nhanh như bộ xử lý hiện tại của OP, ngoại trừ phần lớn công việc sẽ được thực hiện trong phần cứng, khiến CPU có nhiều thời gian rảnh hơn.
Rocketmagnet

1
Tôi đã không nhìn vào tất cả các bảng dữ liệu. Cái đầu tiên tôi chọn là 40 MHz.
stevenvh

@stevenvh - Họ có các cấp tốc độ khác nhau. Số thứ ba trong PN là cấp tốc độ. (4 = 48 MHz, 6 = 67 MHz).
Rocketmagnet

1
Đây cũng là một giải pháp tuyệt vời trong thời gian dài, giống như ý tưởng về đồ họa. Tôi chưa bao giờ nghe nói về loại chip này nhưng nó mang rất nhiều chức năng trên phần còn lại của bo mạch của tôi thành một con chip. Trong tương lai, điều này có thể có nghĩa là toàn bộ máy thu phù hợp với thứ gì đó có kích thước của một ngón tay cái, đó là tầm nhìn của dự án của tôi. Tôi sẽ học Vereme tiếp theo semeeter.
Keegan Jay

4

Tôi nghĩ rằng bạn có một lựa chọn kỹ thuật cổ điển để thực hiện: nhanh, rẻ, hoạt động: chọn hai.

Giải pháp của @ madatcu chắc chắn là một giải pháp tốt, nhưng nếu bạn không thể hoặc sẽ không thêm phần cứng vào nó (và điều này bao gồm bộ xử lý nhanh hơn) thì bạn phải lựa chọn. Nếu liên kết nối tiếp này là quan trọng nhất, bạn nên ngồi trong ISR cho đến khi tất cả các bit được thu thập. 180 hướng dẫn trên mỗi bit thực sự không tệ chút nào, nhưng đừng cố gắng làm mọi thứ. Khi bạn phát hiện bắt đầu chuyển tiền, hãy quay cho đến khi quá trình chuyển hoàn tất. Nhồi kết quả vào một bộ xếp hình và sau đó tiếp tục xử lý bình thường.

Bạn không nói mỗi lần truyền là bao lâu nhưng nếu chúng ngắn và bùng nổ thì đây sẽ là một giải pháp khả thi. Tôi sẵn sàng đặt cược rằng việc triển khai cổng COM ảo của bạn cũng có một số bộ đệm phần cứng, do đó, một dịch vụ ngắt "lag" cho nó không gặp quá nhiều rắc rối. Theo như phần còn lại của những gì MCU cần làm ... bạn có một số quyết định thiết kế để đưa ra.


Giải pháp này bổ sung cho cách tiếp cận phần mềm của tên lửa với việc giảm số lượng trình điều khiển dựa trên ngắt. Tôi có thể giữ trình điều khiển nối tiếp chính mà tôi đã đề cập là dựa trên ngắt. Ngoài ra, tôi sẽ thử quay cho đến khi toàn bộ khung được đọc như bạn đề cập.
Keegan Jay

3

Trước hết, tôi thích một số câu trả lời ở đây và một số đã nhận được phiếu bầu của tôi.

Nhưng chỉ cần đưa ra một giải pháp khả thi khác: đưa ra các ràng buộc của dự án của bạn, việc thêm một vi điều khiển thứ hai có tệ không (điều đó có liên quan đến việc chạy bảng khác không)? Có thể là một vi điều khiển 8 bit đơn giản kết nối với Cortex-M3 của bạn thông qua một thiết bị ngoại vi nhanh như SPI. Bộ điều khiển 8 bit mà bạn chọn sẽ thăm dò các bit và tạo thành byte giống như trong câu trả lời đã chọn, nhưng khi nó có một byte, nó có thể chuyển nó sang thanh ghi dữ liệu SPI để chuyển ra ngoài.

Phía vỏ não-M3 đơn giản sẽ làm gián đoạn dữ liệu SPI nhận được. Điều đó cắt giảm ngắt kích hoạt cạnh ngoài 400 KHz trước đó của bạn xuống còn 50 KHz.

Hai lý do tại sao tôi đề xuất điều này là do một số phương pháp khác (PSoC hoặc thêm vào FPGA) hơi tốn kém (mặc dù điều này có thể không quan trọng đối với một dự án học thuật khối lượng thấp) và vì nó có thể cho phép bạn bảo tồn một số cấu trúc của mã hiện tại của bạn.

Ngoài ra, tôi nghĩ rằng ý tưởng PSoC là tuyệt vời với việc chuyển ngoại vi tùy chỉnh của riêng bạn qua DMA sang USB.


Đây thực sự là kế hoạch tôi có trong đầu ngay khi đăng bài này. Nếu tôi không thể hợp lý hóa phần mềm bằng cách giảm sự phụ thuộc vào các ngắt (câu trả lời được chọn) thì chắc chắn đây là điều tôi sẽ làm. Nhưng vâng, nó sẽ yêu cầu một hội đồng quản trị khác chạy, có thể là hai vì tôi không nhận được thiết kế của mình ngay lần đầu tiên.
Keegan Jay

@JayKeegan, haha ​​chào mừng đến với câu lạc bộ!
Jon L

2

Nếu định dạng dữ liệu của bạn giống với định dạng của UART, nhưng với tốc độ truyền không thể đoán trước nhưng không nhất quán, xu hướng của tôi sẽ là sử dụng CPLD để chuyển đổi mọi từ dữ liệu đến thành định dạng SPI hoặc async tiêu chuẩn. Tôi không nghĩ rằng cần phải đẩy tất cả các lĩnh vực của CPLD. Trên thực tế, thậm chí logic rời rạc gần như có thể thực hiện được. Nếu bạn có thể tạo đồng hồ có tốc độ dữ liệu lớn hơn gấp 5 lần tốc độ dữ liệu mong muốn của mình, bạn có thể sử dụng bộ đếm chia cho năm và chia cho 16 với một vài cổng. Sắp xếp bộ đếm chia cho năm để nó sẽ được giữ lại bất cứ khi nào đầu vào không hoạt động và bộ đếm chia cho 16 ở mức 0. Mặt khác, tạo xung đồng hồ SPI và va chạm vào bộ đếm chia 16 bất cứ khi nào bộ đếm chia 5 chạm 2.

Với đồng hồ 5x, người ta có thể tạo đồng hồ SPI bằng cách sử dụng 16V8 (thiết bị logic lập trình nhỏ nhất và rẻ nhất hiện có). Một 16V8 hoặc 22V10 thứ hai có thể được sử dụng như một bộ chia tỷ lệ phân đoạn để tạo ra đồng hồ 5x hoặc người ta có thể sử dụng một con chip lớn hơn một chút (CPLD) và làm mọi thứ trong một.

Chỉnh sửa / Phụ lục

Sau khi xem xét thêm, nếu một người sẽ sử dụng CPLD, người ta có thể dễ dàng thêm một vài cải tiến bổ sung cho mạch. Ví dụ, người ta có thể dễ dàng thêm logic để có mạch dừng cho đến khi nhận được ít nhất 1,5 bit lần bit dừng, tiếp theo là 3,5 bit của bit start; nếu nó nhận được một bit start quá ngắn, nó sẽ quay trở lại tìm kiếm bit stop. Ngoài ra, nếu một người đang sử dụng SPI, người ta có thể sử dụng tín hiệu / CS để đảm bảo rằng thiết bị nhận sẽ nhìn thấy dữ liệu được đóng khung chính xác. Nếu thiết bị nhận dữ liệu SPI có thể xử lý các khung 10 bit, người ta có thể gửi các khung đó trực tiếp. Mặt khác, mỗi khung mười bit có thể được gửi dưới dạng khung 8 bit với bộ LSB (7 bit dữ liệu) và khung có tất cả các dữ liệu rõ ràng của LSB (3 bit dữ liệu); đồng hồ SPI sẽ được tăng tốc trong các bit dừng để tất cả dữ liệu sẽ được gửi.

Một số bộ vi điều khiển có các mô-đun tạo ra PWM khá linh hoạt, bao gồm những thứ như khả năng được giữ lại bằng tín hiệu bên ngoài và đồng bộ hóa thời gian của chúng với việc phát hành tín hiệu đó. Nếu vi điều khiển của bạn có thể làm điều đó, tùy thuộc vào các tính năng chính xác của nó, điều đó có thể đơn giản hóa đáng kể CPLD hoặc mạch tạo thời gian.

Một cách tiếp cận khác mà Rocketmagnet hơi cảm động, sẽ là có một micro nhỏ với mục đích duy nhất là giải mã dữ liệu nối tiếp và chuyển đổi nó thành định dạng có thể sử dụng được bởi micro chính. Tốc độ dữ liệu 400KHz của bạn khá nhanh để giải mã phần mềm, nhưng một cái gì đó như PIC có thể xử lý nó nếu nó không phải làm bất cứ điều gì khác cùng một lúc. Tùy thuộc vào thiết bị nào bạn quen thuộc, việc này có thể dễ hơn hoặc khó hơn so với sử dụng CPLD.


Tất cả điều này sẽ rất có giá trị khi thiết kế logic kỹ thuật số để giải mã. Tôi thực sự sẽ xuất ra như SPI. Hiện tại, tôi chỉ đang thực hiện giải mã bằng MCU độc lập (hạn chế thời gian). Cảm ơn bạn!
Keegan Jay
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.