Bỏ qua nội dung

Vi xử lý và Hệ thống nhúng

Kỹ thuật Điện Đại học · Chủ đề 8

8.1

Khóa học này là gì và cách sử dụng nó

Đây là khóa học thứ tám trong Kỹ thuật Điện Đại học: vi xử lý và hệ nhúng. EE03 xây dựng logic; khóa học này xây dựng máy tính chạy chương trình, và nghệ thuật thiết kế phần cứng và phần mềm giao thoa.

  • Đơn vị 8.1 mô tả kiến trúc: CPU, thanh ghi, bộ nhớ, và chu kỳ chu kỳ lấy-lệnh-thực thi.
  • Các đơn vị 8.2–8.3 lập trình nó: C nhúng và assembly, sau đó I/O ánh xạ bộ nhớ.
  • Các đơn vị 8.4–8.5 bổ sung yếu tố thời gian: ngắt/timer và giao thức nối serial.
  • Các đơn vị 8.6–8.7 kết thúc bằng giao diện tương tự và phương pháp gỡ lỗi.

Câu chuyện vận hành là một sản phẩm nhỏ: một nút cảm biến chạy bằng pin có nút bấm, đèn LED, kết nối serial và cảm biến 12-bit. Mỗi bước dưới đây sẽ đẩy nút này tiến lên, và mỗi con số đều được kiểm tra theo cách kỹ sư firmware kiểm tra — thông qua độ rộng bit và giới hạn (giá trị có vừa không?), đồng hồ mà nó giả định (mọi thời điểm đều khớp với 84 MHz), và bằng cách theo dõi chính xác các thay đổi trạng thái của từng đoạn mã.

Từ vựng Luyện tập
English Tiếng Việt
assembly Lập trình assembly
timer bộ đếm thời gian
8.1

Kiến trúc vi điều khiển

Tại sao điều đó quan trọng. Bộ điều nhiệt trên tường, bộ điều khiển chống bó cứng phanh và tai nghe trong bàn đều chạy một trong số những thiết bị này: một máy tính hoàn chỉnh trên con chip có kích thước hạt gạo, giá thành thấp hơn cả phí vận chuyển gửi nó đi.

Ý tưởng, kèm hình ảnh. Một vi điều khiển tích hợp ba thứ trên một con chip: bộ nhớ flash chứa chương trình, SRAM chứa dữ liệu, và CPU thực hiện chu kỳ lấy-lệnh-thực thi: đếm chỉ thị lệnh (PC) giữ địa chỉ của lệnh tiếp theo, bộ điều khiển giải mã nó, đường dẫn dữ liệu thực thi nó, và PC tăng (hoặc đơn vị điều khiển giải mã nó, đường dữ thực thi nó, và PC tăng tiến (hoặc nhảy). Mọi truyền dữ liệu đều chạy trên b总线 — các đường địa chỉ chỉ định vị trí, các đường dữ liệu mang theo nội dung, các đường điều khiển báo đọc hay ghi — được sắp xếp theo đồng hồ.

Chu kỳ lấy lệnh-giải mã-thực thi dưới dạng vòng lặp qua CPU, kèm theo bản đồ bộ nhớ bên cạnh
Một lệnh mỗi vòng: lấy lệnh từ PC, giải mã, thực thi, tiến lên

Sự suy luận. Địa chỉ là số nguyên không dấu, nên một trường địa chỉ N bit chính xác $2^{N}$ vị trí. Toàn bộ bản đồ bộ nhớ như sau:

$$\text{size} = 2^{N} \text{ bytes} \quad\Longleftrightarrow\quad N = \log_{2}(\text{size}) \text{ address lines}.$$

Flash tại 0x0000_0000 và SRAM tại 0x2000_0000 không bao giờ xung đột vì các bit cao khác nhau — bộ giải mã địa chỉ chỉ cần xem xét các bit [31:16].

Ví dụ minh họa 1 — tính toán kích thước bản đồ bộ nhớ. Chip của nút có 64 KB flash và 8 KB SRAM. Flash: $64\,\text{KB} = 2^{16}$ byte → 16 đường địa chỉ, do đó nó chiếm lĩnh 0x0000_0000–0x0000_FFFF. SRAM: $8\,\text{KB} = 2^{13}$ byte → 13 đường, nằm ở 0x2000_0000–0x2000_1FFF. Kiểm tra: bất kỳ địa chỉ nào có các bit [31:16] = 0x0000 và [15:0] ≤ 0xFFFF sẽ rơi vào flash; 0x2000_… sẽ rơi vào SRAM; các vùng này không thể chồng lấn vì các bit cao của chúng khác nhau ✓.

Ví dụ minh họa 2 — tốc độ của chính vòng lặp này là bao nhiêu? CPU của nút hoạt động ở 84 MHz với tiêu chuẩn một lệnh mỗi chu kỳ (một lõi thuộc dòng Cortex-M): $84 \times 10^{6}$ lệnh mỗi giây, do đó một lệnh mất $\dfrac{1}{84 \times 10^{6}} = 11.9$ ns. Một lần duyệt điều khiển gồm 100 lệnh vì thế tốn 1.19 µs — và một vòng lặp điều khiển dài 1 ms có chỗ cho khoảng 840 truyền nếu không có gì khác can thiệp. Phép tính ngân sách bắt đầu từ đây được tái sử dụng trong mọi đơn vị sau.

Lỗi thường gặp. Trộn lẫn bit địa chỉ với bit dữ liệu (các đường dẫn địa chỉ đếm số vị trí, các đường dẫn dữ liệu đếm độ rộng của chúng). Quên rằng bản đồ cố định trong tập lệnh liên kết: cùng một chip khởi động ở bất kỳ địa chỉ nào mà nhà cung cấp phần cứng đã chọn. Và trích dẫn kích thước chương trình bằng bit khi dung lượng flash có đơn vị byte — một hệ số gấp tám lần khiến việc lựa chọn linh kiện trở nên sai lầm.

Tóm tắt. Một chip: flash + SRAM + CPU thực hiện chu kỳ lấy, giải mã, thực thi. Một trường địa chỉ N-bit truy cập $2^{N}$ byte; các vùng có bit đầu tiên khác nhau không thể chồng lên nhau; đồng hồ biến số lượng lệnh thành giây.

Khám phá

Which byte does this address select?

$address=base+offset,\quad N=\lceil\log_2(size\ in\ bytes)\rceil$

Compare the worked 64 KiB flash and 8 KiB SRAM regions. Move from the last mapped byte to the next address, separate the base from the offset bits, and explore why 96 KiB needs 17 offset bits but leaves 32 KiB unused in its address window.

8.2

C nhúng và Assembly

Tại sao nó quan trọng. Firmware của nút là vài nghìn dòng C tiếp xúc trực tiếp với các thanh ghi phần cứng. Không có gì ngăn cách dòng code của bạn và một transistor — đó chính là lý do tại sao ánh xạ từ C sang máy phải chính xác tuyệt đối.

Khái niệm, kèm hình ảnh. Một thanh ghi được ánh xạ bộ nhớ chỉ là một địa chỉ; C truy cập nó thông qua một con trỏ volatile (volatile báo cho trình biên dịch: bộ nhớ này thay đổi bên ngoài tầm nhìn của bạn, tiếp xúc mỗi lần). Trình biên dịch chuyển C thành các lệnh tải, lưu, toán học và nhánh; lập trình assembly là cùng một chương trình được viết bằng những lệnh đó bằng tay, mỗi dòng tương ứng một lệnh.

C một dòng lệnh được trình bày dưới dạng mã C, mã assembly đã biên dịch và phép chuyển đổi thanh ghi nó thực hiện
Một dòng C, một chuỗi lệnh, một phép chuyển đổi thanh register — ba góc nhìn của cùng một hành động

Sự suy diễn. Đọc-sửa-ghi là hành động cơ bản: để thay đổi một chân mà không làm ảnh hưởng đến các chân lân cận, CPU phải tải thanh register, lọc bit tại chỗ, và lưu trữ lại. Điều đó tương đương ba thao tác nhưng chỉ có hai lượt truyền bus: một đọc và một ghi. Ví dụ này sử dụng thanh ghi từ read/write đơn giản; một số ngoại vi thực tế cũng cung cấp thanh ghi set/clear nguyên tử: bảng đăng ký từ; một số thiết bị ngoại vi thực cũng cung cấp bảng đăng ký đặt/xóa nguyên tử:

volatile uint32_t *const GPIO_OUT = (uint32_t *)0x40000000u;
*GPIO_OUT |= (1u << 5);   // load, OR, store — set bit 5 only

Ví dụ minh họa 1 — theo dõi bộ đếm. Vòng lặp C

uint32_t count = 0;
while (1) { count = count + 1; }

Một ví dụ minh họa về việc theo dõi thực thi tăng-giải-lưu-trừ và nhánh $0, 1, 2, 3, \ldots$. Thay vào đó, trình biên dịch có thể giữ lại bộ đếm không thay đổi này trong một thanh ghi CPU. Kiểm tra giới hạn: giá trị lớn nhất là $2^{32} - 1 = 4\,294\,967\,295$; lần tăng tiếp theo sẽ quay về zero sau khi tăng $2^{32}$ lần từ zero. Giả sử bốn chu kỳ đồng hồ cho mỗi vòng lặp ở 84 MHz, thời điểm quay về $\dfrac{4\,294\,967\,296 \times 4}{84 \times 10^{6}} \approx 204$ s — là phép tính toán học, không cần chờ ba phút bằng đồng hồ bấm giờ.

Ví dụ minh họa 2 — mặt nạ bit, nâng cao. Để đảo ngược các bit 5 và 6 và xóa bit 3 trong một biểu thức: mặt nạ là $(1 \ll 5) \,|\, (1 \ll 6) = 0x60$. Sau đó *GPIO_OUT = (*GPIO_OUT & ~0x08) ^ 0x60 xóa bit 3 và đảo 5 và 6 trong một lần đọc-sửa-ghi. Kiểm chứng trên giấy với GPIO_OUT = 0xCE: 0xCE & ~0x08 = 0xC6, sau đó 0xC6 ^ 0x60 = 0xA6 — bit 3 giờ đây là 0 (trước là 1), các bit 6 và 5 đảo ngược từ 1, 0 sang 0, 1 ✓. Việc kiểm tra hex trên giấy là trình debug nhanh nhất trong đơn vị này.

Lỗi thường gặp. Bỏ sót volatile (trình biên dịch lưu/cache thanh register trong một thanh ghi CPU và vòng lặp của bạn đọc nó mãi mãi). Giả sử thứ tự đánh giá C giữa hai lần ghi thanh ghi khi phần cứng cần chúng theo trình tự — hãy chèn một hàng rào hoặc đọc lại. Và ghi bit 5 thành *GPIO_OUT = 0x20, điều này xóa mọi bit khác trên cổng.

Tóm tắt. Thanh ghi là các địa chỉ; volatile giữ cho trình biên dịch trung thực; ví dụ thanh ghi từ đơn giản này sử dụng giải mã-mặt nạ-lưu. Theo dõi trạng thái bằng giấy trước tin vào phần cứng.

Khám phá

Mask the CPU copy, then store the whole word

$result=(original\;\&\;\sim clearMask)\;\oplus\;toggleMask$

Start with the worked low byte 0xCE, clear bit 3 and toggle bits 5 and 6 to get 0xC6 then 0xA6. Step through the load, local CPU operations and store; the GPIO word stays unchanged until the store. Compare OR-setting bit 5 with plain assignment, and set upper neighbours to see which operations preserve them.

Từ vựng Luyện tập
English Tiếng Việt
microprocessors and embedded systems vi xử lý và hệ thống nhúng
microcontroller vi điều khiển
fetch-decode-execute cycle Chu kỳ lấy mã, giải mã, thực thi
program counter/ˈprəʊɡræm ˈkaʊntə/ bộ đếm chương trình
bus/bʌs/ bus
GPIO GPIO
memory-mapped I/O I/O ánh xạ bộ nhớ
8.3

Bộ nhớ và I/O

Tại sao nó quan trọng. Nút bấm, đèn LED và cảm biến của node đều nằm bên ngoài CPU. Cách chúng kết nối quyết định liệu firmware có phải là bảng địa chỉ gọn gàng hay một đống số ma thuật.

Ý tưởng, kèm hình ảnh. I/O ánh xạ bộ nhớ khiến một thanh ghi ngoại vi trông y hệt một vị trí bộ nhớ: đọc thanh ghi dữ liệu nhận được một byte; ghi một thanh thì gửi đi. Một cổng GPIO có hai thanh ghi như vậy — hướng (input hoặc output, một bit cho mỗi chân) và dữ liệu (mức độ của chân) — nên cấu hình một lần, sau đó đọc hoặc ghi mãi mãi. dữ liệu (mức tín hiệu của chân) — vì vậy cấu hình một lần, sau đó đọc hoặc ghi mãi mãi.

Cổng GPIO dưới dạng hai thanh ghi: bit hướng chọn đầu vào hay đầu ra, bit dữ liệu mang mức tín hiệu Sự suy diễn. Abandoning là chuẩn cơ bản trung thực: bit hoàn tất của thanh ghi trạng thái là một phép đọc bộ nhớ trong vòng lặp. Mỗi vòng quay tốn các

lệnh của vòng lặp; chờ T giây làm tiêu hao bit hoàn thành của thanh ghi là một phép đọc bộ nhớ trong vòng lặp. Mỗi vòng lặp tốn thời gian T giây sẽ tiêu hao

$$T \times f_{\text{clock}}$$

chu kỳ CPU, hoặc khoảng $T f_{\text{clock}}/C$ vòng hoàn chỉnh khi mỗi vòng tốn $C$ chu kỳ đồng hồ. Hệ số $C$ thay đổi số lần kiểm tra, không phải thời gian CPU bị chiếm bởi vòng lặp chờ liên tục. Các bài kiểm tra phát hiện và quá hạn được lượng hóa hóa thành các thời điểm kiểm tra của vòng lặp.

Ví dụ minh họa 1 — chi phí của việc yêu cầu. Nút hỏi liên tục bit sẵn sàng cảm biến ở 84 MHz; mỗi vòng lặp mất 4 chu kỳ (tải, AND, nhánh, tăng), do đó CPU thực hiện $84 \times 10^{6}/4 = 21$ triệu vòng lặp mỗi giây. Thời gian chờ 1 ms tương đương ~21 000 vòng = 84 000 chu kỳ: chiếm 100% CPU trong mili giây đó, trong khi không thực hiện công việc hữu ích nào.

Ví dụ minh họa 2 — bản đồ toàn bộ node. Các thiết bị ngoại vi của node nằm ở 0x4000_0000 (GPIO), 0x4001_0000 (UART), 0x4002_0000 (bộ đếm thời gian), 0x4003_0000 (ADC). Bảng hằng phần mềm định vị ánh xạ mỗi trình điều khiển với địa chỉ cơ sở của nó; một lỗi đánh máy trong một mục (0x4001_0000 so với 0x4001_0004) sẽ đẩy vào đúng bốn byte Tóm tắt. Thiết bị ngoại vi là bộ nhớ: địa chỉ gốc cộng các độ dịch mang tên. Cấu hình địa chỉ offset, chứ không phải địa chỉ thô. Kiểm tra: sau khi khởi tạo, đọc lại thanh ghi ID của mỗi thiết bị ngoại vi; nếu địa chỉ cơ sở sai thì lần đọc đầu tiên sẽ thu được dữ liệu vô nghĩa. Lỗi thường gặp. Quên thiết lập thanh ghi hướng (chân vẫn giữ trạng thái đầu vào và lệnh ghi không có tác dụng). Giám sát (polling) mà không đặt thời gian giới hạn — một cảm biến chết sẽ khiến sản phẩm bị treo. Và nhầm lẫn giữa số bit của cổng với số chân trên bao bì đóng gói: bảng chân trên datasheet, chứ không phải macro tiện lợi của file header, mới là sự thật.

Lỗi thường gặp. Quên thanh ghi hướng (chân pin vẫn ở chế độ đầu vào và lệnh ghi không làm gì cả). Quét.polling mà không có quá hạn — một cảm biến chết làm treo toàn bộ sản phẩm. Và nhầm lẫn số bit của cổng với số chân pin trên package: bảng chân pin trong datasheet, không phải trong file header hangs the whole product. And mixing up a port's bit number with the pin number on the package: the datasheet's pin table, not the header's macro tiện ích, điều này là đúng.

Tóm tắt. Thiết bị ngoại vi là bộ nhớ: địa chỉ cơ sở cộng với các offset có tên. Cấu hình một lần định hướng, poll với thời gian chờ, và để kiểm tra ID đọc lại chứng minh bản đồ trước khi bất kỳ công việc thực tế nào chạy.

Khám phá

Fewer polling checks do not mean a less busy CPU

$cycles=checks\times C,\quad checks\approx T f_{clock}/C,\quad cycles\approx T f_{clock}$

Start with the worked 1 ms wait at 84 MHz and four cycles per polling lap. The loop makes 21000 checks and occupies 84000 cycles. Increase the lap cost to reduce the number of checks without freeing the CPU during the wait. Put readiness between checks to see detection lag, or remove the ready event and watch the timeout stop the wait.

Từ vựng Luyện tập
English Tiếng Việt
clock/klɒk/ đồng hồ
memory-mapped register register ánh xạ bộ nhớ
polling khám phá
UART cổng truyền nhận song song bất đồng bộ
ADC/ˌeɪ diː ˈsiː/ ADC
8.4

Ngắt và bộ đếm thời gian

Tại sao điều đó quan trọng. Nút chạy bằng pin trong một năm. Polling tiêu thụ pin bằng cách hỏi các câu hỏi; ngắt cho phép CPU ngủ cho đến khi thế giới cần nó — sự khác biệt giữa một tuần và một năm.

Ý tưởng, kèm hình ảnh. Một ngắt tạm dừng chương trình chính đang ở đâu: phần cứng đẩy trạng thái trả về, vectors đến một routine phục vụ ngắt (ISR) do NVIC (cơ chế mạng lưới bộ điều khiển ngắt vectơ lồng nhau, cũng sắp xếp mức ưu tiên), ISR chạy và trở về. Một bộ đếm thời gian chỉ là một bộ đếm được xung clock qua một bộ chia — bộ phân tần. Trong bộ đếm tăng kiểu STM32 được sử dụng ở đây, một sự kiện cập nhật xảy ra khi CNT quay vòng từ ARR về lại số không; một ngắt có thể được kích hoạt sau đó để gọi ISR (hàm xử lý ngắt).

Chuỗi khối: 84 MHz clock, prescaler chia cho 8400 thành 10 kHz, bộ đếm tải lại 10000, 1 Hz ngắt
Hai lần chia biến 84 MHz thành một ngắt 1 Hz

Sự suy luận. Tần số bộ đếm thời gian chia hai lần:

$$f_{\text{interrupt}} = \frac{f_{\text{clock}}}{P R},\qquad P=PSC+1,\quad R=ARR+1,$$

trong đó PSC và ARR là các giá trị thanh ghi lưu trữ 16-bit, tối đa là 65,535. Mỗi hệ số chia có thể đạt đến 65,536 vì số không cũng được tính. Một thiết kế hợp lệ khi các giá trị lưu trữ vừa khít với AND $PR=f_{\text{clock}}/f_{\text{interrupt}}$. Ở đây ARR khác không và bộ đếm chạy liên tục.

Ví dụ minh họa 1 — nhịp tim 1 Hz. Từ 84 MHz: hệ số chia 8400 tạo ra $84 \times 10^{6}/8400 = 10$ kHz; hệ số chia tiếp theo là 10,000 cho chính xác 1 Hz. Gán PSC = 8399 và ARR = 9999. Cả hai giá trị lưu trữ đều vừa khít trong 16 bit, và $8400 \times 10\,000 = 84 \times 10^{6}$ ✓ hoàn thành thiết kế. Hệ số chia là 84,000 sẽ yêu cầu PSC = 83,999, nhưng không vừa khít.

Tóm tắt. Ngắt = vector + ISR ngắn + xóa cờ; timer = bộ chia tần số × tải lại so với xung clock, với cả hai yếu tố nằm trong thanh ghi tương ứng. Ngắt ưu thế ở tốc độ sự kiện thấp; quét tuần tự thắng vượt ~2 MHz. Ngắt với 12 chu kỳ vào, ISR gồm 30 lệnh và 10 chu kỳ trả lại tốn $12 + 30 + 10 = 52$ chu kỳ $= 0.62$ µs ở tốc độ 84 MHz — so với 21 000 vòng lặp chờ.poll đã tiêu hao. Nhưng chi phí của ISR phải trả cho mỗi lần sự kiện: tại 1 kHz sự kiện, đó là 52 000 chu kỳ/giây = 0.06% CPU; tại 1 MHz sự kiện, nó chiếm 62% — vượt qua một tốc độ nhất định, việc quét (polling) ngoại vi nhanh tiết kiệm hơn việc kích hoạt ngắt. Phép tính chuyển giao này là quyết định thiết kế.

Lỗi thường gặp. Một ISR quên xóa cờ ngắt của nó — CPU quay lại và ngay lập tức vào lại, mãi mãi. Các ISR dài (làm tối thiểu, CPU trả lại và ngay lập tức vào lại, mãi mãi. Các ISR dài (thực hiện tối thiểu, trên bus 16-bit cần đọc byte cao hai lần hoặc giữ nguyên, hoặc nếu có bộ đếm trên bus 8-bit cần đọc byte cao hai lần hoặc giữ dữ liệu, hoặc một dấu carry Tóm tắt. Ngắt = vector + ISR ngắn + xóa cờ; bộ đếm thời gian =

prescaler × tải lại so với xung nhịp, với cả hai hệ số nằm trong $(PSC+1)(ARR+1)$ so với xung clock, với cả hai giá trị lưu trữ nằm bên trong các thanh ghi. Ngắt thắng thế ở tốc độ sự kiện thấp; chờ.poll thắng thế vượt quá ~1 MHz.

Khám phá

The divider factor includes the zero count

$f_{update}=f_{clock}/[(PSC+1)(ARR+1)]$

Start with the worked 84 MHz to 1 Hz heartbeat. Divider factors 8400 and 10000 require stored PSC = 8399 and ARR = 9999 in this STM32-style upcounter. Advance exact clock edges, counter ticks and update events, then use a small 4 × 5 example to see zero counted. Compare writing the factors directly to the registers and observe the changed rate.

Từ vựng Luyện tập
English Tiếng Việt
interrupt/ˈɪntərʌpt/ ngắt
interrupt service routine/ˈɪntərʌpt ˈsɜːvɪs ruːˈtiːn/ hàm phục hồi ngắt
prescaler bộ chia tần
8.5

Giao thức Serial

Ý tưởng, kèm hình ảnh. UART gửi dữ liệu bất đồng bộ Việc lựa chọn UART, SPI hay I2C — và định giá dây dẫn theo tốc độ — là một quyết định hàng tuần trong công việc nhúng.

cần hai dây (SDA dữ liệu, SCL xung)}), địa chỉ thiết bị bằng tốc độ baud mà cả hai đầu đã thỏa thuận. SPI chia sẻ clock: master điều khiển SCLK và chip-select, dữ liệu chảy trên MOSI ra và MISO vào — toàn duplex. I8C cần hai dây (SDA dữ liệu, SCL clock), địa chỉ thiết bị với 2 bit, và nối chúng dạng open-drain để bất kỳ thiết bị nào cũng có thể kéo đường tín hiệu xuống mức thấp. cần hai dây (SDA dữ liệu, SCL xung clock), địa chỉ hóa thiết bị với 7 bit, và dùng cấu hình mở-drain để bất kỳ thiết bị nào cũng có thể kéo đường tín hiệu xuống mức thấp.

One UART frame: idle high, start bit low, eight data bits of 0x41 sent least significant first, stop bit high
Khung 8N1: 10 thời gian bit mỗi byte, 86.8 µs ở 115 200 baud

Sự suy luận. UART không có đường dẫn xung clock, nên cả hai đầu phải tái tạo thời gian từ tốc độ baud đã thỏa thuận: một byte trong khung 8N1 chiếm đúng 10 khoảng thời gian bit,

$$T_{\text{byte}} = \frac{10}{\text{baud}}, \qquad \text{throughput} = \frac{\text{baud}}{10} \text{ bytes/s}.$$

trong khi SPI thay thế bằng cách gửi một bit mỗi chu kỳ xung hoàn chỉnh, do đó một byte mất 8 xung cộng thêm thời gian thiết lập: $T_{\text{byte}} \approx 8/f_{\text{SCLK}}$ — chính tốc độ xung là yếu tố quyết định.

Ví dụ minh họa 1 — xác định kích thước UART. Tại 115 200 baud, 8N1: tốc độ truyền dữ liệu là đợt burst $115\,200/10 = 11\,520$ byte (mất $10/115\,200 = 86.8$ ms) vượt quá ngân sách — cần chia nhỏ hoặc tăng baud. Việc So với vòng điều khiển 1 ms của node: 11 byte vừa khít (0.95 ms) ✓; nhưng một lệnh truyền khối chặn 100-byte (8.68 ms) sẽ vượt quá ngân sách thời gian — cần chia nhỏ hoặc tăng tốc độ baud. Các việc xác định kích thước phụ thuộc vào yêu cầu kỹ thuật, không phải sở thích cá nhân.

Ví dụ minh họa 2 — giá cả ba chiều. SPI ở 10 MHz clock một byte trong $8/10\,\text{MHz} = 0.8$ µs — nhanh hơn khoảng 108 lần so với UART trong trường hợp này — nhưng tốn kém hơn dây chọn chip cho mỗi thiết bị. I2C ở 400 kHz cần 9 xung clock cho 8 bit dữ liệu cộng ACK: $9/400\,\text{kHz} = 22.5$ µs, trước khi địa chỉ, bắt đầu và kết thúc tốn thêm. Ở các tốc độ đã chọn này, nó nằm giữa SPI và UART, nhưng chỉ hai dây serve the whole board (7-bit address = up to 112 devices at 1 address per thiết bị). Cảm biến trên I2C, flash nhớ trên SPI, console trên UART — cách chia tiêu chuẩn, mỗi loại được định giá dựa trên phép tính này.

Lỗi thường gặp. Tốc độ baud không khớp (khung vẫn 'hoạt động' và các byte là dữ liệu rác — hãy kiểm tra toán học của bộ chia đối với xung clock ngoại vi, không phải xung clock lõi). Đọc địa chỉ I2C như là 8 bit: phần địa chỉ 7-bit cộng với bit đọc/ghi được đóng gói vào một byte, và tài liệu kỹ thuật liệt kê cả hai dạng. Và bỏ sót chế độ SPI (cực tính và pha xung clock): có bốn chế độ tồn tại vì các thiết bị khác nhau; chế độ sai sẽ làm lệch từng byte đi một bit so với nhịp.

Tóm tắt. UART: 10 đơn vị thời gian bit cho mỗi byte, không có dây clock, hai đầu tương đồng tốc độ baud. SPI: một bit mỗi nhịp clock, một dây cho mỗi thiết bị. I2C: hai dây, địa chỉ 7-bit drain mở. So sánh chi phí theo byte/millisecond với số lượng dây trước khi lựa chọn.

Khám phá

Eight useful bits occupy ten bit times

$T_{frame}=10/B_t,\quad t_{sample,i}=(1.5+i)/B_r,\quad t_{stop}=9.5/B_r$

Start with the worked 115200-baud link and a repeated 0x41 byte. Read the start, least-significant-first data and stop cells; a 100-byte burst occupies 8.68 ms, while only 11 complete frames fit in 1 ms. Change the receiver baud to move its sampling points and distinguish wrong data, a low stop sample and a sample exactly on a transition.

Từ vựng Luyện tập
English Tiếng Việt
SPI giao diện ngoại vi serial
I2C Bus tích hợp I2C
baud rate Tốc độ baud
8.6

ADC, DAC và cảm biến

Tại sao nó quan trọng. Thế giới vật lý nói bằng volt; CPU nói bằng số. Độ chính xác của giá trị nhiệt độ đọc từ node phụ thuộc hoàn toàn vào bộ chuyển đổi và kết nối của nó — và những lỗi ở đây rất âm thầm, không gây tiếng ồn lớn.

Ý tưởng, kèm hình ảnh. Một ADC thực hiện việc lượng tử hóa: một bộ chuyển đổi N-bit phạm vi trên điện áp tham chiếu $V_{\text{ref}}$ có độ phân giải của một LSB $= V_{\text{ref}}/2^{N}$. Việc chọn N là việc chọn mức độ chi tiết mà thế giới được đo lường; mạch điện quyết định liệu mức độ chi tiết đó có tồn tại hay không.

Sơ đồ chuyển đổi bậc thang ADC từ 0 đến V_ref cho bộ chuyển đổi 12-bit, với các bước kích thước 1-LSB và mã trung tâm được đánh dấu
Mỗi mã sở hữu một dải điện áp đầu vào bằng 1-LSB; giá trị trung tâm là mã 2048

Phân tích chi tiết. Quá trình lượng tử hóa ánh xạ điện áp thành mã có dải chứa nó: mã $= \lfloor V_{\text{in}}/V_{\text{ref}} \times 2^{N} \rfloor$ (kèm các biến thể ở biên). Tái tạo từng dải đầu vào tại điểm giữa của nó cho ra sai số lượng tử hóa lý tưởng giới hạn bởi nửa LSB trong phạm vi đầu nhập; một đầu vào cá nhân có thể có sai số bằng không.

Ví dụ minh họa 1 — cảm biến 12-bit. Với $V_{\text{ref}} = 3.3$ V, mỗi LSB tương đương $3.3/4096 = 0.806$ mV. Tín hiệu vào 1.65 V sẽ cho kết quả đọc $1.65/3.3 \times 4096 = 2048$ — đúng chính xác mức trung tâm ✓. Nếu nút cần resolve 0.1 °C and the sensor gives 10 mV/°C, it needs 1 mV of resolution — một bộ chuyển đổi 12-bit (0.806 mV) đạt yêu cầu, trong khi bộ 10-bit (3.22 mV) không đáp ứng được: chính yêu cầu thực tế, không phải danh mục sản phẩm, quyết định chọn N.

Ví dụ minh họa 2 — bẫy trở kháng nguồn. tụ giữ mẫu của ADC ($\approx 7$ pF trên chip này) nạp điện qua trở kháng nguồn, và thời gian ổn định về ½ LSB đòi hỏi thời gian lấy mẫu ít nhất điện trở, và thời gian ổn định về ½ LSB đòi hỏi thời gian lấy mẫu tối thiểu $R_{\text{source}} C \ln(2^{N+1})$. For a 50 kΩ source that is $50\,000 \times 7\,\text{pF} \times 9.01 \approx 3.2$ µs cho một bước nhảy đầu vào toàn thang trong mô hình RC đơn giản này. Thu hẹp cửa sổ xuống 1 µs và cùng giới hạn đó chỉ cho phép $16$ kΩ. Một bộ chia nhiệt trở 100 kΩ (50 kΩ Thevenin) do đó cần ít nhất một cửa sổ 3.2 µs — hoặc giảm một nửa bộ chia điện áp A DAC thực hiện bước thang ngược lại: khi ghi 2048 vào DAC 12 bit với $V_{\text{ref}} = 3.3$ V sẽ tạo ra 1.650 V.

Lỗi thường gặp. Trích dẫn độ phân giải theo bit và bỏ qua điện áp tham chiếu (0.806 mV chỉ đúng ở 3.3 V). Coi đầu vào ADC như một volt kế: dòng lấy mẫu của nó tải lên cảm biến trở kháng cao, như giới hạn RC trên đã chứng minh. Và trung bình hóa để "mua" bit — trung bình 16 mẫu nhiễu trắng tăng thêm khoảng 2 bit độ phân giải hiệu dụng, nhưng không thể khắc phục được độ lệch hệ thống hay mẫu bị sụt áp.

Tóm tắt. Một LSB = $V_{\text{ref}}/2^{N}$; yêu cầu xác định N. Tái tạo trung điểm đưa ra giới hạn sai số lượng tử hóa nửa LSB; giới hạn RC $t_{s} \ge R C \ln(2^{N+1})$ đánh đổi trở kháng nguồn với thời gian lấy mẫu — trở kháng nguồn cho phép phụ thuộc vào mô hình và cửa sổ thu thập.

Khám phá

Fine ADC steps need time for the sample to settle

$V_{error}=\Delta V e^{-t_s/(RC)},\quad t_s\ge RC\max[0,\ln(2^{N+1}\Delta V/V_{ref})]$

Start with the worked 50 kΩ source and 7 pF sampling capacitor on a 12-bit ADC. A 3.2 µs acquisition window meets the half-LSB settling budget; a 1 µs window misses it. Lower the source resistance or lengthen acquisition, then compare 16 bits to see why finer voltage steps demand a smaller remaining error. Separate acquisition error from quantisation.

Từ vựng Luyện tập
English Tiếng Việt
resolution/ˌrezəˈluːʃn/ độ phân giải
LSB bit có ý nghĩa thấp nhất
DAC/ˌdiː eɪ ˈsiː/ Bộ chuyển đổi số sang tương tự (DAC)
watchdog chó giữ cửa
debounce chống rung
8.7

Chẩn đoán lỗi và tích hợp

Tại sao điều này quan trọng. Phần mềm được kiểm thử bằng cách chạy trực tiếp trên phần cứng chính xác mà nó sẽ được giao hàng, và mọi lỗi đều xuất hiện dưới dạng tin đồn ("nó bị đóng băng hai lần đêm qua"). Phương pháp là sự khác biệt giữa việc sửa chữa và chỉ đặt tên mới cho nó. Ý tưởng, kèm hình ảnh. Vòng lặp: tái tạo với tín hiệu đầu vào nhỏ nhất; chia đôi ranh giới giữa mã đáng tin cậy và mã nghi ngờ (một đèn LED, một

Ý tưởng, kèm hình ảnh. Vòng lặp: tái tạo với đầu vào nhỏ nhất nhất; chia đôi ranh giới giữa mã tin cậy và mã đáng ngờ (một đèn LED, một điểm ngắt, hoặc một lần in UART); sửa MỘT thứ; xác minh lại. Một bảo vệ là lưới an toàn sẽ khởi động lại hệ thống bị treo — đếm trước khi hết hạn, hoặc sản phẩm tự khởi động theo thiết kế thay vì bị đóng băng do sự cố.

Vòng lặp kiểm tra lỗi: tái tạo, cô lập tại ranh giới, sửa một thứ, xác minh lại, với bảo vệ là lưới an toàn bao ngoài
Tái tạo, chia đôi, sửa một thứ, xác minh lại — và một bảo vệ bên ngoài vòng lặp

Sự suy luận. Chia đôi là thuật toán: nếu lỗi tái tạo với đầu dò ranh giới đặt ở giữa phạm vi nghi ngờ, thì lỗi nằm ở nửa đầu; ngược lại nằm ở nửa sau. Mỗi đầu dò giảm một nửa phạm vi, nên $\log_{2}(\text{suspicious instructions})$ lần đầu dò là đủ — mười lần đầu dò cho một nghìn lệnh. Sự chia đôi đó chạy thang ADC cũng chính là chạy vòng lặp kiểm tra lỗi.

Ví dụ minh họa 1 — lọc rung như một truy vết trạng thái. Nút nút của nơ-đơ đọc 1, 0, 0, 1 qua bốn 10 ms mẫu (một tiếp điểm rung). Quy tắc: yêu cầu hai lần đọc liên tiếp bằng nhau. Truy vết: t = 0 ms đọc 1 (chưa có kết luận); t = 10 ms đọc 0 (một lần, chưa có kết luận); t = 20 ms đọc 0 lần nữa → ổn định 0 được tuyên bố. Giá trị 1 tại t = 30 ms chỉ là một mẫu, chưa ổn định, và bị bỏ qua đúng cách. Lọc rung = N mẫu liên tiếp = một nhịp đồng hồ + một đọc GPIO + một quyết định trạng thái: cả hành trình trong một truy vết.

Ví dụ minh họa 2 — chia đôi sự đóng băng. Nơ-đơ đóng băng trong một thời gian của một chuỗi log cụ thể; vùng đáng ngờ chứa 1 024 lệnh của trình điều khiển giao tiếp. Làm cho lệnh 512 bật đèn LED: nếu nút bị treo với đèn LED vẫn tắt, lỗi nằm ở nửa đầu; nếu đèn LED bật trước khi đóng băng, nó nằm ở bước thứ hai. Mỗi lần chạy chia đôi vùng: 512 → 256 → 128 → … — mười lần chạy giới hạn nó vùng lại thành một lệnh. Toán học giải thích tại sao chia đôi thắng hơn việc đọc lại mã nguồn hy vọng nhìn thấy nó: $2^{10} = 1024$.

Lỗi thường gặp. Sửa hai thứ cùng lúc (một cái đúng, một cái gây ra sự cố khác — giờ có ba lỗi). Debug trên một bản sửa đổi bo mạch khác với bản đang bị lỗi. Và tắt bộ đếm thời gian 'tạm thời': lỗi hoạt động thực tế mà bộ đếm thời gian đã vượt qua chính là lỗi đó đang được gửi đi bán hàng. tàu.

Tóm tắt. Tái tạo, chia đôi, sửa một, xác nhận lại; $\log_{2}$ phép thử giới hạn cuộc truy tìm.Debouncing chuyển nhiễu thành sự kiện bằng N mẫu liên tiếp. Bộ đếm thời gian là tuyến phòng thủ cuối cùng: kích hoạt nó trong vòng lặp chính, không bao giờ trong ISR.

Khám phá

One contrary reading does not erase the qualified state

$N\text{ equal sampled readings span }(N-1)\Delta t$

Step through the worked 1,0,0,1 trace at 10 ms intervals with two equal readings required. The first qualified 0 appears at 20 ms; the later single 1 does not reverse it. Edit samples, compare a one-sample pulse and an alternating input, and change N to distinguish input chatter from accepted output changes. Startup remains unqualified until a state earns enough consecutive readings.

Bài học tương tác về chủ đề này

Làm theo từng bước, kèm theo bài tập kiểm tra ngay lập tức.

Nhiều chủ đề hơn trong Kỹ thuật Điện Đại học

Đăng nhập hoặc tạo tài khoản

IGCSE, A-Level & AP