PIC32 vs DSPIC vs ARM vs AVR, kiến ​​trúc có quan trọng khi chúng ta lập trình bằng ngôn ngữ C không? [đóng cửa]


10

Chúng tôi hiện đang sử dụng Vi điều khiển PIC32 32 bit. Nó hoạt động tốt cho nhu cầu của chúng tôi, nhưng chúng tôi cũng đang khám phá các bộ vi điều khiển khác có thể giúp chúng tôi tốt hơn + chúng tôi có các dự án khác mà chúng tôi đang chọn MCU. Vì mục đích đó, chúng tôi đã chọn bộ vi điều khiển SAM DA dựa trên ARM , cùng loại 32 bit nhưng dựa trên ARM (phổ biến hơn PIC32 - thông minh trong ngành).

Bây giờ đối với PIC32, chúng tôi sử dụng MPLAB nhưng đối với ARM cortex-M0, chúng tôi sẽ sử dụng Atmel Studio. Chúng tôi sẽ sử dụng ngôn ngữ C trong cả hai nền tảng. Điều tôi quan tâm là, chúng tôi sẽ sử dụng hai bộ vi điều khiển 32 bit (từ cùng một công ty) nhưng có kiến ​​trúc khác nhau. Điều này sẽ yêu cầu chúng tôi học hai thiết bị khác nhau và sẽ tăng "thời gian học" + thời gian giao hàng. Nhưng mặt khác, tôi cũng nghĩ rằng vì chúng ta sẽ sử dụng Ngôn ngữ C trong cả hai trường hợp, nên đường cong học tập cho ARM không nên được nghe và cũng đáng để khám phá bộ xử lý đó.

Câu hỏi chính của tôi là, kiến trúc tạo ra sự khác biệt lớn như thế nào khi chúng ta lập trình bằng Ngôn ngữ C vì nó cung cấp một sự trừu tượng hóa các phần bên trong của vi điều khiển. những khác biệt chính trong MPLAP và Atmel Studio , xem xét lập trình ngôn ngữ C.


2
Nếu mọi thứ đang hoạt động với PIC32, thì điểm chuyển đổi là gì? Ngay cả khi mã hoàn toàn cổng (nó sẽ không), vẫn có chuỗi công cụ mới và IDE để làm quen. Vấn đề ở đây là gì? Chuyển đổi vì lý do tôn giáo hoặc là "dựa trên ARM" (hoặc bất cứ điều gì khác dựa trên) là ngớ ngẩn. Bạn cần phải có một lý do chính đáng, nhưng bạn đã không cho chúng tôi thấy bất kỳ.
Olin Lathrop

Tôi không hỏi về việc chuyển đổi. Tôi đã nói về việc chọn một kiến ​​trúc khác cho các dự án khác vì chúng tôi đang làm việc trên nhiều dự án + có chỗ để cải tiến trong thiết kế hiện tại của chúng tôi. Điểm chính là về việc học đường cong và những thách thức khi làm việc với hai kiến ​​trúc khác nhau cùng một lúc.
kỹ sư

Một điều tôi đã thấy rằng Atmel Studio cung cấp thời gian vượt trội hơn video youtube
kỹ sư

Câu trả lời:


20

Đây là một chủ đề khá tranh luận. Tôi có thể tự nói (AVR, ARM, MSP430).

Sự khác biệt 1 (quan trọng nhất) là ở các thiết bị ngoại vi. Mỗi MCU có UART, SPI, bộ định thời tương tự, v.v. - chỉ cần đăng ký tên và bit là khác nhau. Hầu hết thời gian nó là vấn đề chính mà tôi phải giải quyết khi di chuyển mã giữa các chip. Giải pháp: viết trình điều khiển của bạn với một API phổ biến, để ứng dụng của bạn có thể di động.

Sự khác biệt 2 là kiến ​​trúc bộ nhớ. Nếu bạn muốn đặt các hằng số trong flash trên một AVR, bạn phải sử dụng các thuộc tính đặc biệt và các chức năng đặc biệt để đọc chúng. Trong thế giới ARM, bạn chỉ cần vô hiệu hóa một con trỏ bởi vì có một không gian địa chỉ duy nhất (tôi không biết các PIC nhỏ xử lý nó như thế nào, nhưng sẽ cho rằng chúng gần với AVR hơn).

Sự khác biệt 3 là khai báo gián đoạn và xử lý. avr-gccISR()vĩ mô. ARM chỉ có một tên hàm (như someUART_Handler () - nếu bạn sử dụng các tiêu đề CMSIS và mã khởi động). Các vectơ ngắt ARM có thể được đặt ở bất cứ đâu (bao gồm RAM) và được sửa đổi trong thời gian chạy (rất tiện dụng nếu bạn có hai giao thức UART khác nhau có thể được chuyển đổi). AVR chỉ có tùy chọn sử dụng vectơ trong "flash chính" hoặc "phần bootloader" (vì vậy nếu bạn muốn xử lý các ngắt khác nhau, bạn phải sử dụng một ifcâu lệnh).

Sự khác biệt 4 - chế độ ngủ và kiểm soát năng lượng. Nếu bạn có nhu cầu tiêu thụ năng lượng thấp nhất, thì bạn phải tăng tất cả các tính năng của MCU. Điều này có thể khác nhau rất nhiều giữa MCU - một số có chế độ tiết kiệm năng lượng thô hơn, một số có thể bật / tắt các thiết bị ngoại vi riêng lẻ. Một số MCU có bộ điều chỉnh có thể điều chỉnh để bạn có thể chạy chúng với điện áp thấp hơn ở tốc độ chậm hơn, v.v. Tôi không thấy một cách dễ dàng để đạt được hiệu quả tương tự trên MCU (giả sử) với 3 chế độ năng lượng toàn cầu và một chế độ khác với 7 chế độ năng lượng và điều khiển đồng hồ ngoại vi cá nhân.

Điều quan trọng nhất khi quan tâm đến tính di động là phân chia rõ ràng mã của bạn thành các bộ phận phụ thuộc vào phần cứng (trình điều khiển) và độc lập với phần cứng (ứng dụng). Bạn có thể phát triển và kiểm tra cái sau trên PC thông thường với trình điều khiển giả (ví dụ: bảng điều khiển thay vì UART). Điều này đã tiết kiệm cho tôi nhiều lần vì 90% mã ứng dụng đã hoàn tất trước khi phần cứng nguyên mẫu ra khỏi lò phản chiếu :)

Theo tôi, điểm hay của ARM là "độc canh" - có sẵn nhiều trình biên dịch (gcc, Keil, IAR ... để đặt tên cho một số), nhiều IDE miễn phí và được hỗ trợ về mặt kỹ thuật (ít nhất là cho NXP, STM32, Silicon Labs, Bắc Âu), nhiều công cụ gỡ lỗi (SEGGER - đặc biệt là Ozone, ULINK, OpenOCD ...) và nhiều nhà cung cấp chip (tôi thậm chí sẽ không bắt đầu đặt tên cho chúng). PIC32 chủ yếu giới hạn ở Microchip (nhưng nó chỉ quan trọng nếu bạn không thích các công cụ của họ.

Khi nói đến mã C. Nó giống nhau đến 99%, một ifcâu lệnh giống nhau, một vòng lặp hoạt động theo cùng một cách. Tuy nhiên, bạn nên quan tâm đến kích thước từ bản địa. Ví dụ, một forvòng lặp trên AVR là nhanh nhất nếu bạn sử dụng uint8_tcho bộ đếm, trong khi trên ARM uint32_tlà loại nhanh nhất (hoặc int32_t). ARM sẽ phải kiểm tra lỗi tràn 8 bit mỗi lần nếu bạn sử dụng loại nhỏ hơn.

Chọn MCU và / hoặc nhà cung cấp nói chung chủ yếu là về chính trị và hậu cần (trừ khi bạn có những hạn chế kỹ thuật rất rõ ràng, ví dụ: nhiệt độ cao - sử dụng MSP430 hoặc Vorago). Ngay cả khi ứng dụng có thể chạy trên mọi thứ và chỉ có 5% mã (trình điều khiển) phải được phát triển và hỗ trợ trong suốt vòng đời sản phẩm - đó vẫn là một chi phí phụ cho công ty. Tất cả những nơi tôi từng làm việc đều có một nhà cung cấp và dòng MCU yêu thích (như "chọn bất kỳ Kinetis nào bạn muốn trừ khi có lý do rất chính đáng để chọn thứ gì đó khác biệt"). Nó cũng có ích nếu bạn có người khác yêu cầu giúp đỡ, vì vậy với tư cách là người quản lý, tôi sẽ tránh việc bộ phận phát triển 5 người trong đó mọi người sử dụng một con chip hoàn toàn khác nhau.


3
AVR AVR là nhanh nhất nếu bạn sử dụng uint8_t cho bộ đếm, trong khi trên ARM uint32_t là loại nhanh nhất (hoặc int32_t). ARM sẽ phải kiểm tra lỗi tràn 8 bit mỗi lần nếu bạn sử dụng loại nhỏ hơn. bạn có thể sử dụng uint_fast8_t nếu bạn chỉ cần ít nhất 8 bit.
Michael

@Michael - chắc chắn bạn có thể sử dụng các loại _fast, nhưng bạn không thể tin tưởng vào hành vi tràn. Trong stdint.h gcc của tôi. Tôi có "typedef unsign int uint_fast8_t", về cơ bản là một uint32_t :)
filo

Cố gắng viết một API hiệu quả, phổ quát và đầy đủ là khó khăn vì các nền tảng khác nhau có các khả năng khác nhau. CPU có thể ít quan trọng hơn các thiết bị ngoại vi và các quyết định thiết kế được thực hiện với chúng. Ví dụ, một số thiết bị đã cho phép các thiết bị ngoại vi khác nhau được định cấu hình lại bất cứ lúc nào trong tối đa vài micrô giây, trong khi các thiết bị khác có thể yêu cầu nhiều bước trải ra trong hàng trăm micro giây hoặc thậm chí là mili giây. Một hàm API dành cho mẫu cũ có thể sử dụng được trong một thói quen dịch vụ ngắt chạy ở tần số 10.000Hz, nhưng ...
supercat

... không thể hỗ trợ việc sử dụng như vậy trên các nền tảng sẽ yêu cầu trải rộng các hoạt động trong hàng trăm micro giây. Tôi không biết tại sao các nhà thiết kế phần cứng dường như không cố gắng hết sức để hỗ trợ ngữ nghĩa API "hoạt động nhanh bất cứ lúc nào", nhưng nhiều người sử dụng một mô hình đồng bộ hóa các hoạt động riêng lẻ thay vì nêu ra nếu yêu cầu được đưa ra bật thiết bị và mã nhận ra rằng nó không cần phải bật, mã phải đợi thiết bị bật trước khi thiết bị có thể tắt yêu cầu tắt. Xử lý trơn tru trong API thêm các biến chứng lớn.
supercat

11

Tôi đã sử dụng một số MCU từ bốn nhà sản xuất khác nhau. Công việc chính mỗi lần nữa là làm quen với các thiết bị ngoại vi.

Ví dụ, bản thân UART không quá phức tạp và tôi dễ dàng tìm thấy cổng trình điều khiển của mình. Nhưng lần cuối cùng tôi phải mất gần một ngày để đồng hồ, chân I / O bị gián đoạn, kích hoạt, v.v.

GPIO có thể rất phức tạp. Bit-set, bit-Clear, bit-togle, Chức năng đặc biệt bật / tắt, ba trạng thái. Tiếp theo bạn nhận được các ngắt: bất kỳ cạnh, tăng, giảm, mức thấp, mức cao, tự xóa hoặc không.

Sau đó, có I2C, SPI, PWM, Timers và hai chục loại thiết bị ngoại vi khác, mỗi loại có đồng hồ riêng cho phép và mỗi khi các thanh ghi khác nhau với các bit mới. Đối với tất cả những người đó phải mất nhiều giờ để đọc biểu dữ liệu làm thế nào để thiết lập bit nào trong hoàn cảnh nào.

Nhà sản xuất cuối cùng có rất nhiều ví dụ mã mà tôi thấy không thể sử dụng được. Tất cả mọi thứ đã được trừu tượng hóa. Nhưng khi tôi truy tìm nó, mã đã trải qua sáu! các mức gọi hàm để thiết lập bit GPIO. Thật tuyệt nếu bạn có bộ xử lý 3GHz nhưng không có MCU 48 MHz. Mã của tôi cuối cùng là một dòng duy nhất:

GPIO->set_output = bit.

Tôi đã cố gắng sử dụng trình điều khiển chung chung hơn nhưng tôi đã từ bỏ. Trên MCU, bạn luôn phải vật lộn với không gian và chu kỳ đồng hồ. Tôi thấy rằng lớp trừu tượng là lớp đầu tiên đi ra ngoài cửa sổ nếu bạn tạo một dạng sóng cụ thể trong một thói quen ngắt được gọi là 10KHz.

Vì vậy, bây giờ tôi có mọi thứ hoạt động và tôi dự định KHÔNG chuyển đổi lại trừ khi vì một lý do rất, rất tốt.

Tất cả những điều trên phải được khấu hao theo số lượng sản phẩm bạn bán và những gì bạn tiết kiệm được. Bán một triệu: tiết kiệm 0,10 để chuyển sang loại khác có nghĩa là bạn có thể chi 100.000 cho giờ làm việc của phần mềm. Bán 1000 bạn chỉ có 100 để chi tiêu.


1
Cá nhân đây là lý do tại sao tôi gắn bó với lắp ráp. Nhị phân đáng yêu, không trừu tượng.
Ian Bland

Bộ tiền xử lý của C có thể làm khá tốt với các công cụ, đặc biệt là khi kết hợp với nội tại __builtin_constant. Nếu người ta xác định các hằng số cho mỗi bit I / O của mẫu (số cổng * 32 + số bit), có thể viết một macro OUTPUT_HI(n)sẽ mang lại mã tương đương với GPIOD->bssr |= 0x400;nếu nlà hằng số như 0x6A, nhưng hãy gọi một chương trình con đơn giản nếu nlà không đổi Điều đó đã được nói, hầu hết các API nhà cung cấp mà tôi đã thấy phạm vi giữa tầm thường và khủng khiếp.
supercat

8

Đây là một ý kiến ​​/ nhận xét nhiều hơn là một câu trả lời.

Bạn không muốn và không nên lập trình trong C. C ++, khi được sử dụng đúng cách , vượt trội hơn nhiều. (OK, tôi phải thừa nhận, khi sử dụng sai cách, nó còn tệ hơn nhiều so với C.) Điều đó giới hạn bạn với các chip có trình biên dịch C ++ (hiện đại), gần như là mọi thứ được GCC hỗ trợ, bao gồm cả AVR (với Một số hạn chế, filo đề cập đến các vấn đề của không gian địa chỉ không đồng nhất), nhưng loại trừ gần như tất cả các PIC (PIC32 có thể được hỗ trợ, nhưng tôi chưa thấy cổng nào tốt cả).

Khi bạn đang lập trình các thuật toán trong C / C ++, sự khác biệt giữa các lựa chọn bạn đề cập là nhỏ (ngoại trừ việc chip 8 hoặc 16 bit sẽ gặp bất lợi nghiêm trọng khi bạn thực hiện nhiều phép tính số học 16, 32 hoặc cao hơn). Khi bạn cần hiệu suất cuối cùng, có thể bạn sẽ cần sử dụng trình biên dịch chương trình (mã của riêng bạn hoặc mã do nhà cung cấp hoặc bên thứ ba cung cấp). Trong trường hợp đó, bạn có thể muốn xem xét lại chip bạn đã chọn.

Khi bạn đang mã hóa phần cứng, bạn có thể sử dụng một số lớp trừu tượng (thường được cung cấp bởi nhà sản xuất) hoặc tự viết (dựa trên bảng dữ liệu và / hoặc mã ví dụ). Các tóm tắt C hiện tại của IME (mbed, cmsis, ...) thường có chức năng (gần như) chính xác, nhưng không thành công khủng khiếp (kiểm tra oldfarts về 6 lớp cảm ứng cho hoạt động của bộ pin), tính khả dụng và tính di động. Họ muốn tiết lộ tất cả chức năng của con chip cụ thể cho bạn, trong hầu hết các trường hợp bạn sẽ không cần và không quan tâm, và nó khóa mã của bạn cho nhà cung cấp cụ thể đó (và có thể là con chip cụ thể đó).

Đây là C ++ có thể làm tốt hơn nhiều: khi được thực hiện đúng cách, một bộ pin có thể đi qua 6 lớp trừu tượng trở lên (vì điều đó làm cho giao diện (di động!) Tốt hơn và mã ngắn hơn có thể), nhưng cung cấp giao diện độc lập với mục tiêu đối với các trường hợp đơn giảnvẫn dẫn đến mã máy giống như bạn viết trong trình biên dịch chương trình .

Một đoạn của phong cách mã hóa mà tôi sử dụng, có thể khiến bạn say mê hoặc quay lưng lại với nỗi kinh hoàng:

// GPIO part of a HAL for atsam3xa
enum class _port { a = 0x400E0E00U, . . . };

template< _port P, uint32_t pin >
struct _pin_in_out_base : _pin_in_out_root {

   static void direction_set_direct( pin_direction d ){
      ( ( d == pin_direction::input )
         ? ((Pio*)P)->PIO_ODR : ((Pio*)P)->PIO_OER )  = ( 0x1U << pin );
   }

   static void set_direct( bool v ){
      ( v ? ((Pio*)P)->PIO_SODR : ((Pio*)P)->PIO_CODR )  = ( 0x1U << pin );    
   }
};

// a general GPIO needs some boilerplate functionality
template< _port P, uint32_t pin >
using _pin_in_out = _box_creator< _pin_in_out_base< P, pin > >;

// an Arduino Due has an on-board led, and (suppose) it is active low
using _led = _pin_in_out< _port::b, 27 >;
using led  = invert< pin_out< _led > >;

Trong thực tế có một số lớp trừu tượng hơn. Tuy nhiên, việc sử dụng cuối cùng của đèn led, giả sử bật nó lên, không cho thấy sự phức tạp hoặc chi tiết của mục tiêu (đối với một arduin uno hoặc một viên thuốc màu xanh ST32, mã sẽ giống hệt nhau).

target::led::init();
target::led::set( 1 );

Trình biên dịch không bị đe dọa bởi tất cả các lớp đó và vì không có chức năng ảo nào liên quan đến trình tối ưu hóa nhìn xuyên qua mọi thứ (một số chi tiết, được bỏ qua, như bật đồng hồ ngoại vi):

 mov.w  r2, #134217728  ; 0x8000000
 ldr    r3, [pc, #24]   
 str    r2, [r3, #16]
 str    r2, [r3, #48]   

Đó là cách tôi đã viết nó trong trình biên dịch chương trình - NẾU tôi đã nhận ra rằng các thanh ghi PIO có thể được sử dụng với các offset từ một cơ sở chung. Trong trường hợp này có lẽ tôi sẽ làm, nhưng trình biên dịch tốt hơn nhiều trong việc tối ưu hóa những thứ như vậy hơn tôi.

Theo như tôi có câu trả lời, đó là: viết một lớp trừu tượng cho phần cứng của bạn, nhưng hãy làm nó trong C ++ (khái niệm, mẫu) hiện đại để nó không gây hại cho hiệu suất của bạn. Với vị trí đó, bạn có thể dễ dàng chuyển sang chip khác. Bạn thậm chí có thể bắt đầu phát triển trên một số chip ngẫu nhiên mà bạn đã đặt xung quanh, là familiair với, có các công cụ sửa lỗi tốt, v.v. và hoãn lựa chọn cuối cùng cho đến sau này (khi bạn có thêm thông tin về bộ nhớ cần thiết, tốc độ CPU, v.v.).

IMO, một trong những yếu tố quan trọng của sự phát triển được đặt ra là chọn chip trước tiên (đó là câu hỏi thường được hỏi trên diễn đàn này: tôi nên chọn chip nào cho .... Câu trả lời tốt nhất nói chung là: không thành vấn đề.)

(chỉnh sửa - phản hồi cho "Vì vậy, hiệu suất khôn ngoan, C hoặc C ++ sẽ ở cùng cấp độ?")

Đối với các cấu trúc giống nhau, C và C ++ là như nhau. C ++ có nhiều cấu trúc hơn cho sự trừu tượng hóa (chỉ một vài: lớp, mẫu, constexpr) có thể, giống như bất kỳ công cụ nào, được sử dụng cho mục đích tốt hoặc xấu. Để làm cho các cuộc thảo luận trở nên thú vị hơn: không phải ai cũng đồng ý điều gì là tốt hay xấu ...


Vì vậy, hiệu suất khôn ngoan, C hoặc C ++ sẽ ở cùng cấp độ? Tôi sẽ nghĩ rằng C ++ sẽ có quá tải. Chắc chắn bạn đã chỉ cho tôi đi đúng hướng, C ++ là con đường để đi không C.
kỹ sư

Các mẫu C ++ buộc tính đa hình thời gian biên dịch có thể bằng 0 (hoặc thậm chí âm) về mặt hiệu suất, vì mã được biên dịch cho từng trường hợp sử dụng cụ thể. Tuy nhiên, điều này có xu hướng cho vay tốt nhất với tốc độ nhắm mục tiêu (O3 cho GCC). Đa hình thời gian chạy, giống như các chức năng ảo, có thể chịu hình phạt lớn hơn nhiều, mặc dù có thể tranh luận dễ dàng hơn để duy trì và trong một số trường hợp đủ tốt.
Hans

1
Bạn cho rằng C ++ tốt hơn, nhưng sau đó bạn đi và sử dụng phôi kiểu C. Vì xấu hổ.
JAB

@JAB Tôi chưa bao giờ cảm thấy nhiều cho các diễn viên kiểu mới, nhưng tôi sẽ thử. Nhưng ưu tiên hiện tại của tôi là trên các phần khác của thư viện này. Tất nhiên, vấn đề thực sự là tôi không thể vượt qua các con trỏ làm tham số mẫu.
Wouter van Ooijen

@Hans kiểu cto (Compile Time Object) của tôi có trường hợp sử dụng khá hẹp (gần với phần cứng, tình huống thời gian biên dịch), nó giống như một kẻ giết người C hơn là sự thay thế cho việc sử dụng OO dựa trên ảo. Một phụ kiện hữu ích là việc không có sự gián tiếp giúp tính toán kích thước ngăn xếp.
Wouter van Ooijen

4

Nếu tôi hiểu chính xác, bạn muốn biết các tính năng cụ thể về kiến ​​trúc của nền tảng "bật lên" trong môi trường ngôn ngữ C của bạn, khiến việc viết mã di động, có thể duy trì trên cả hai nền tảng trở nên khó khăn hơn.

C đã khá linh hoạt ở chỗ nó là một "trình biên dịch di động". Tất cả các nền tảng bạn đã chọn đều có sẵn trình biên dịch GCC / thương mại có hỗ trợ các tiêu chuẩn ngôn ngữ C89 và C99, nghĩa là bạn có thể chạy mã tương tự trên tất cả các nền tảng.

Có một vài cân nhắc:

  • Một số kiến ​​trúc là Von Neumann (ARM, MIPS), một số khác là Harvard. Các hạn chế chính phát sinh khi chương trình C của bạn cần đọc dữ liệu từ ROM, ví dụ như để in chuỗi, có dữ liệu được xác định là "const" hoặc tương tự.

Một số nền tảng / trình biên dịch có thể che giấu "giới hạn" này tốt hơn những nền tảng khác. Ví dụ, trên AVR, bạn cần sử dụng các macro cụ thể để đọc dữ liệu ROM. Trên PIC24 / dsPIC cũng có các bản in tblrd dành riêng. Tuy nhiên, ngoài ra, một số phần còn có tính năng "hiển thị không gian chương trình" (PSVPAG) có sẵn cho phép ánh xạ một trang của FLASH vào RAM, cung cấp địa chỉ dữ liệu ngay lập tức mà không cần tblrd. Trình biên dịch có thể làm điều này khá hiệu quả.

ARM và MIPS là Von Neumann, do đó có các vùng bộ nhớ cho ROM, RAM và các thiết bị ngoại vi được đóng gói trên 1 bus. Bạn sẽ không nhận thấy bất kỳ sự khác biệt nào giữa việc đọc dữ liệu từ RAM hoặc "ROM".

  • Nếu bạn lặn xuống dưới C và xem hướng dẫn được tạo cho một số thao tác nhất định, bạn sẽ tìm thấy một số khác biệt lớn xung quanh I / O. ARM và MIPS là kiến trúc thanh ghi lưu trữ tải RISC . Điều này có nghĩa là việc truy cập dữ liệu trên bus bộ nhớ phải thông qua các lệnh MOV. Điều này cũng có nghĩa là bất kỳ sửa đổi nào của giá trị ngoại vi sẽ dẫn đến hoạt động đọc-sửa đổi-ghi (RMW). Có một số phần ARM hỗ trợ Bit-Banding, bản đồ đó đặt / thanh ghi clr-bit trong không gian ngoại vi I / O. Tuy nhiên, bạn cần phải mã hóa quyền truy cập này lên chính mình.

Mặt khác, PIC24 cho phép các hoạt động ALU đọc và ghi dữ liệu trực tiếp thông qua địa chỉ gián tiếp (ngay cả khi sửa đổi con trỏ ..). Điều này có một số đặc điểm từ một kiến ​​trúc như CISC, vì vậy 1 lệnh có thể thực hiện nhiều công việc hơn. Thiết kế này có thể dẫn đến các lõi CPU phức tạp hơn, xung nhịp thấp hơn, tiêu thụ năng lượng cao hơn, v.v ... May mắn thay cho bạn phần đã được thiết kế. ;-)

Những khác biệt này có thể có nghĩa là PIC24 có thể hoạt động I / O wrt "mạnh mẽ hơn" so với chip ARM hoặc MIPS có xung nhịp tương tự. Tuy nhiên, bạn có thể nhận được phần ARM / MIPS đồng hồ cao hơn nhiều cho cùng một ràng buộc về giá / gói / thiết kế. Tôi đoán đối với các thuật ngữ thực tế, tôi nghĩ rằng rất nhiều "học nền tảng" đang nắm bắt được những gì kiến ​​trúc có thể và không thể làm, một vài thao tác sẽ diễn ra nhanh như thế nào, v.v.

  • Thiết bị ngoại vi, quản lý đồng hồ, vv khác nhau cho mỗi gia đình của các bộ phận. Nói đúng ra, điều này cũng sẽ thay đổi trong hệ sinh thái ARM giữa các nhà cung cấp, ngoại trừ một vài thiết bị ngoại vi ràng buộc Cortex m như NVIC và SysTick.

Những khác biệt này có thể được gói gọn phần nào bởi trình điều khiển thiết bị, nhưng cuối cùng, phần sụn nhúng có mức độ khớp nối cao với phần cứng, do đó đôi khi không thể tránh được công việc tùy chỉnh.

Ngoài ra, nếu bạn rời khỏi hệ sinh thái của Microchip / Atmel trước đây, bạn có thể thấy rằng các bộ phận ARM yêu cầu thiết lập nhiều hơn để khiến chúng hoạt động. Ý tôi là về mặt; cho phép đồng hồ đến các thiết bị ngoại vi, sau đó định cấu hình các thiết bị ngoại vi và "bật" chúng, thiết lập NVIC riêng, v.v ... Đây chỉ là một phần của đường cong học tập. Một khi bạn nhớ làm tất cả những điều này, theo đúng thứ tự, viết trình điều khiển thiết bị cho tất cả các bộ vi điều khiển này sẽ cảm thấy khá giống nhau ở một số điểm.

  • Ngoài ra, hãy thử sử dụng các thư viện như stdint.h, stdbool.h, v.v. nếu bạn chưa có. Các kiểu số nguyên này làm cho độ rộng rõ ràng, làm cho hành vi mã dễ dự đoán nhất giữa các nền tảng. Điều này có thể có nghĩa là việc sử dụng các số nguyên 32 bit trên một AVR 8 bit; Nhưng nếu mã của bạn cần nó thì hãy là nó.

3

Có và không. Từ góc độ lập trình viên, bạn lý tưởng là ẩn các chi tiết của tập lệnh. Nhưng đó là ở một mức độ nào đó không liên quan đến các thiết bị ngoại vi, đó là toàn bộ điểm viết chương trình không phải là một phần của tập lệnh. Bây giờ, cùng lúc bạn không thể so sánh các phần flash 4096Byte trên các tập lệnh đó, đặc biệt nếu sử dụng C, mức tiêu thụ của flash / bộ nhớ được xác định rất nhiều bởi tập lệnh và trình biên dịch, một số sẽ không bao giờ thấy trình biên dịch (ho PIC ho) do bao nhiêu chất thải của những tài nguyên đó được tiêu thụ bằng cách biên dịch. Những người khác tiêu thụ flash là một chi phí nhỏ hơn. Hiệu suất cũng là một vấn đề khi sử dụng ngôn ngữ cấp cao và các vấn đề về hiệu suất trong các ứng dụng MCU, do đó, nó có thể tạo ra sự khác biệt giữa việc chi 3 đô la mỗi bảng cho mcu hoặc 1 đô la.

Nếu đó là về việc làm cho việc lập trình trở nên dễ dàng hơn (với chi phí chung của sản phẩm), bạn có thể tải xuống gói nhà phát triển cho mcu sao cho kiến ​​trúc tập lệnh là thứ bạn không bao giờ thấy, vì vậy nếu đó là mối quan tâm chính của bạn, thì đó là không phải là một mối quan tâm Bạn vẫn phải trả tiền cho chi phí sản phẩm để sử dụng các thư viện này, nhưng, thời gian để tiếp thị thể ngắn hơn, tôi thấy các thư viện mất nhiều thời gian / công việc hơn để sử dụng so với nói chuyện trực tiếp với các thiết bị ngoại vi.

Dòng dưới cùng các bộ hướng dẫn là ít lo lắng nhất của bạn, chuyển sang các vấn đề thực sự.

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.