Làm thế nào để chuyển nhanh 16 bit trên bảng arduino


7

Tôi đang mã hóa một hệ thống cần chuyển nhanh 16 bit từ biến uint16_t sang hai thanh ghi dịch chuyển 74HC595 được ghép nối. Tôi đang chạy mã trên Arduino (atmega328 @ 16Mhz) và shiftOut trong Arduino quá chậm. Các thư viện chức năng digitalWrite cũng chậm.

Ý tưởng tốt nhất tôi nghĩ ra là một vòng lặp for lặp qua tất cả 16 bit của biến và ghi 1/0 vào pin dữ liệu, đặt bit đồng hồ càng cao càng ngắn càng tốt và sau đó chuyển sang bit tiếp theo của biến.

Đây có phải là giải pháp nhanh nhất và nếu vậy, làm thế nào để tôi lặp qua các bit biến uint16_t trong c ++?


Tôi đã thực hiện một số thử nghiệm với SRAM, bạn có thể thấy kết quả thú vị: arduino.stackexchange.com/questions/36871/ Kết luận: một kỹ thuật sốRead / WriteFast là không thể bỏ qua, tuy nhiên một ca làm việc có giá 120 chúng tôi.
Michel Keijzers

Câu trả lời:


8

Điều này là đủ đơn giản với thư viện SPI.

Kết nối đầu vào thanh ghi thay đổi của bạn với chân MOSI (Master Out, Slave In) - Chân kỹ thuật số 11 - và bạn sẽ có chuyển khoản nhanh đẹp.

Sẽ có một độ trễ rất nhỏ giữa 8 bit trên và dưới của mỗi từ được truyền.

Ví dụ:

#include <SPI.h>

void begin()
{
    SPI.begin();
}

void loop()
{
    unsigned int val;

    val = rand()%0xFFFF; // Generate a random 16 bit number

    SPI.transfer(val >> 8);  // Output the MSB first
    SPI.transder(val & 0xFF); // Followed by the LSB

    delay(1000);  // Wait a sec...
}

1
Những gì về chốt chốt? Điều này dường như chỉ làm thay đổi dòng dữ liệu nối tiếp, nhưng tôi không thấy bất cứ điều gì được chốt vào sổ đăng ký.
captncraig

Tôi chưa bao giờ sử dụng một trong các thanh ghi thay đổi trong câu hỏi, vì vậy tôi không biết những gì được yêu cầu. Thông thường, bạn bọc SPI trong một DigitalWrite (x, THẤP) và DigitalWrite (x, CAO) để chuyển đổi một dòng IO kỹ thuật số mà bạn chọn là "chọn chip" hoặc "chốt chuyển đổi" hoặc bất cứ điều gì (rõ ràng là đảo ngược chuyển đổi cho hoạt động cao ). Sử dụng bất cứ pin nào bạn thích.
Majenko

8

Nếu bạn đang muốn sử dụng truyền dữ liệu phần mềm, bạn không muốn sử dụng các chức năng digitalWrite. Chúng rất chậm, điều này là do chúng cần dịch số pin thông qua một bảng thành một thanh ghi thực tế (PORTx), che dấu đúng bit và thay đổi nó. Tất cả các chân trong arduino được ánh xạ tới các số, trong khi bên dưới chúng có thể thuộc về cổng A, B, C, và thậm chí nhiều hơn trên phiên bản MEGA của Arduino.

Nó nhanh hơn nhiều để sửa đổi trực tiếp các thanh ghi AVR. Chẳng hạn như PORTB và a-like. Bạn thực sự cần phải bước qua từng bit. Tôi sẽ tạo một vòng lặp for từ 0 đến 15 và thực hiện một số thay đổi và mặt nạ bit.

Bởi vì tôi không biết cấu hình ghim nên tôi không thể đưa ra một ví dụ chính xác. Tuy nhiên nó có thể sẽ trông rất gần với điều này. Với 'rất gần' tôi có nghĩa là điều này chưa được kiểm tra.

void ShiftOut(UI16_t data)
{
 // Initialize (you may want to set CLK to low) - as we're toggling later on.

// step from bit 0 to 15 for(UI08_t i = 0; i < 15; i++) { // Check the content of this data bit // Shift data so this bit is LSB, and mask it with 1 so we only look at this bit. if ((data >> i) & 0x1 == 1) { // set data pin high, like PORTB |= 1<<4; // when pin 4 of portB is your data pin // Doing an OR will make pin B4 always high } else { // set data pin low, like PORTB &= ~(1<<4); // Doing an AND with the inverse means all pins except B4 will be unchanged }

// Generate clk to 'transfer' the bit: // This can likely be done by using PORTB ^= 1 << 5; (pin B5 in this example) // ^= toggle // Do this TWICE, so CLK goes high/low }

// as you're using a shift register, you may want to toggle LATCH pin as well.. }

Để tìm ra số pin phần cứng nào (đừng cho rằng chân 4 là chân B4 hoặc A4!) Bạn cần xem sơ đồ của Arduino.

Tôi đã chạy một mã tương tự trên PIC32 (chạy ở tốc độ 80 MHz). PIC32 có thể thực hiện điều này ở khoảng 1,5 MHz, nhưng một vài dòng mã bổ sung đang chạy trong main () để tính toán một đầu ra mới. Tuy nhiên, nó có thể được thực hiện rất nhanh.


Cảm ơn câu trả lời chi tiết, tôi sẽ thử cách tiếp cận SPI trước vì nó có vẻ nhanh hơn. Tôi cũng tìm thấy nhiều ví dụ cho cách tiếp cận phần mềm tại bildr.org/2011/02/74hc595
tirithen

5

Bạn cần sử dụng thiết bị ngoại vi SPI thay vì thực hiện chuyển đổi trong phần mềm. Tôi chưa bao giờ sử dụng Arduino, nhưng tài liệu tham khảo trực tuyến cho thấy có thư viện SPI mà bạn có thể sử dụng. Nếu điều đó không phù hợp với nhu cầu của bạn, bạn có thể tra cứu thiết bị ngoại vi SPI trong biểu dữ liệu ATMega. Thiết bị ngoại vi SPI thường khá dễ cài đặt và sử dụng.


1

Tôi là trường học cũ, đã được mã hóa từ bộ xử lý 100 kHz. Sử dụng mã nội tuyến để thao tác bit trực tiếp vào cổng, thay vì vòng lặp. Vòng lặp yêu cầu phí, nội tuyến nhanh hơn mặc dù chiếm nhiều không gian chương trình hơn. Xem AVR035: Mã hóa C hiệu quả cho AVR để thao tác bit của các cổng.

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.