Thể loại: Mạch vi điều khiển
Số lượt xem: 41940
Bình luận về bài viết: 5
Phương pháp đọc và quản lý cổng Arduino I / O
Để tương tác với thế giới bên ngoài, bạn cần cấu hình các đầu ra của vi điều khiển để nhận hoặc truyền tín hiệu. Kết quả là, mỗi pin sẽ hoạt động ở chế độ đầu vào và đầu ra. Có hai cách để làm điều này trên mọi bo mạch Arduino mà bạn yêu thích, chính xác là cách bạn học được từ bài viết này.

Phương pháp thứ nhất - Ngôn ngữ chuẩn cho Arduino IDE
Mọi người đều biết rằng Arduino Nó được lập trình trong C ++ với một số điều chỉnh và đơn giản hóa cho người mới bắt đầu. Nó được gọi là dây. Ban đầu, tất cả các cổng arduino được định nghĩa là đầu vào và không cần chỉ định điều này trong mã.
Các cổng thường được viết trong hàm khởi tạo biến:
thiết lập void ()
{
// mã
}
Để làm điều này, sử dụng lệnh pinMode, nó có một cú pháp khá đơn giản, đầu tiên chỉ ra số cổng, sau đó là vai trò của nó, được phân tách bằng dấu phẩy.
pinMode (nomer_porta, naznachenie)
Với lệnh này, mạch bên trong của vi điều khiển được cấu hình theo một cách cụ thể.
Có ba chế độ mà cổng có thể hoạt động: INPUT - đầu vào, trong chế độ này xảy ra đọc dữ liệu từ các cảm biến, trạng thái nút, tín hiệu tương tự và kỹ thuật số. Cổng nằm trong cái gọi là trạng thái trở kháng cao, nói một cách đơn giản - đầu vào có điện trở cao. Giá trị này được đặt, ví dụ: 13 pin của bảng, nếu cần, như sau:
pinMode (13, INPUT);
OUTPUT - đầu ra, tùy thuộc vào lệnh được quy định trong mã, cổng nhận giá trị bằng một hoặc không. Đầu ra trở thành một loại nguồn năng lượng được kiểm soát và tạo ra dòng điện tối đa (trong trường hợp của chúng tôi, 20 mA và 40 mA ở cực đại) được kết nối với tải. Để gán một cổng làm đầu ra cho Arduino, bạn cần nhập:
pinMode (13, ĐẦU RA);
INPUT_PULLUP - cổng hoạt động như một đầu vào, nhưng cái gọi là kết nối với nó. Điện trở kéo lên 20 kΩ.
Các mạch bên trong có điều kiện của cổng ở trạng thái này được hiển thị dưới đây. Một tính năng của đầu vào này là tín hiệu đầu vào được cảm nhận là đảo ngược (đơn vị LĐNH ở đầu vào được bộ vi điều khiển cảm nhận là một số 0 0). Trong chế độ này, bạn không thể sử dụng điện trở kéo lên bên ngoài khi làm việc với các nút.
pinMode (13, INPUT_PULLUP);

Dữ liệu được nhận từ các cổng và được truyền đến chúng bằng các lệnh:
-
digitalWrite (pin, value) - chuyển đổi chân đầu ra thành logic 1 hoặc 0 tương ứng, điện áp 5V xuất hiện hoặc biến mất ở đầu ra, ví dụ digitalWrite (13, CAO) - cung cấp 5 volt (đơn vị logic) thành 13 chân và digitalWrite (13, thấp ) - chuyển 13 chân sang trạng thái logic 0 (0 volt);
-
digitalRead (pin) - đọc giá trị từ đầu vào, ví dụ digitalRead (10), đọc tín hiệu từ 10 chân;
-
analogRead (pin) - đọc tín hiệu analog từ cổng analog, bạn nhận được giá trị trong phạm vi từ 0 đến 1023 (trong ADC 10 bit), một ví dụ là analogRead (3).
Phương pháp hai - quản lý cổng thông qua các thanh ghi Atmega và tăng tốc mã
Điều khiển như vậy tất nhiên là đơn giản, nhưng trong trường hợp này có hai nhược điểm - tiêu thụ bộ nhớ lớn hơn và hiệu năng kém khi làm việc với các cổng. Nhưng hãy nhớ Arduino là gì, bất kể bảng tùy chọn (uno, micro, nano) là gì? Trước hết, cái này vi điều khiển gia đình ATM ATMEGA, gần đây đã sử dụng MK atmega328.
Trong Arduino IDE, bạn có thể lập trình ngôn ngữ C AVR có nguồn gốc từ họ này, như thể bạn đang làm việc với một vi điều khiển riêng. Nhưng điều đầu tiên trước tiên. Để quản lý cổng Arduino theo cách này, trước tiên bạn cần xem xét cẩn thận hình minh họa sau.
Có lẽ ai đó sẽ kiểm tra rõ hơn các cổng ở dạng này (giống trong hình, nhưng trong một thiết kế khác):

Ở đây bạn thấy sự tương ứng của các kết luận của Arduino và tên của các cổng của Atmega. Vì vậy, chúng tôi có 3 cổng:
-
PORTB;
-
PORTC;
-
PORTD.
Dựa trên những hình ảnh được hiển thị, tôi đã biên soạn một bảng tương ứng giữa các cổng của Arduino và Atmega, nó sẽ hữu ích cho bạn trong tương lai.

Atmega có ba thanh ghi 8 bit điều khiển trạng thái của các cổng, ví dụ, cổng B sẽ tìm ra mục đích của chúng bằng cách vẽ các phép tương tự với các công cụ nối dây tiêu chuẩn được mô tả ở đầu bài viết này:
-
PORTB - Quản lý trạng thái đầu ra. Nếu chân ở chế độ "Đầu ra", thì 1 và 0 xác định sự hiện diện của các tín hiệu tương tự ở đầu ra. Nếu chân ở chế độ Đầu vào của Đầu vào, thì 1 kết nối điện trở kéo lên (giống như INPUT_PULLUP đã thảo luận ở trên), nếu 0 là trạng thái trở kháng cao (tương tự INPUT);
-
PINB là một thanh ghi đọc. Theo đó, nó chứa thông tin về trạng thái hiện tại của các chân cổng (đơn vị logic hoặc số không).
-
DDRB - thanh ghi hướng cổng. Với nó, bạn chỉ ra cho vi điều khiển biết cổng đó là đầu vào hay đầu ra, với một đầu ra và 1 0 một đầu vào.
Thay vì chữ cái Bọ, có thể có bất kỳ chữ nào khác theo tên của các cổng, ví dụ, các lệnh khác của PORTD hoặc PORTC hoạt động tương tự.
Chúng tôi nháy đèn LED, thay thế hàm digitalWrite () tiêu chuẩn. Trước tiên, hãy nhớ lại ví dụ ban đầu từ thư viện Arduino IDE trông như thế nào.

Đây là mã của trò chơi nhấp nháy nổi tiếng, cho thấy nhấp nháy của đèn LED tích hợp trong bảng.

Các ý kiến giải thích mã. Logic của công việc này là như sau.
Lệnh PORTB B00100000 đặt PB5 ở trạng thái của một đơn vị logic, nhìn và các hình ảnh và bảng được đặt bên dưới và thấy rằng PB5 tương ứng với 13 pin của Arduina.
Chữ "B" phía trước các con số chỉ ra rằng chúng ta đang viết các giá trị ở dạng nhị phân. Đánh số trong nhị phân đi từ phải sang trái, tức là ở đây, đơn vị nằm ở bit thứ sáu từ cạnh phải của bit, thông báo cho vi điều khiển về sự tương tác với trạng thái của bit thứ sáu của thanh ghi cổng B (PB5). Bảng dưới đây cho thấy cấu trúc của cổng D, nó tương tự và được đưa ra làm ví dụ.

Bạn có thể đặt giá trị không phải ở dạng nhị phân, nhưng ở dạng thập lục phân, ví dụ, để làm điều này, chúng tôi mở máy tính windows và trong chế độ VIII XEM, chọn tùy chọn Lập trình viên.

Nhập số mong muốn:

Và bấm vào HEX:

Trong trường hợp này, chúng tôi chuyển tất cả điều này sang Arduino IDE, nhưng thay vì tiền tố "B", nó sẽ là "0x".

Nhưng với đầu vào này có một vấn đề. Nếu bạn có bất cứ thứ gì được kết nối với các chân khác, sau đó nhập lệnh như B00010000 - bạn sẽ đặt lại tất cả các chân ngoại trừ 13 (PB5). Bạn có thể nhập dữ liệu cho từng pin riêng lẻ. Nó sẽ trông như thế này:

Một hồ sơ như vậy có vẻ khó hiểu, hãy tìm ra nó.

Đây là một hoạt động bổ sung hợp lý, | = có nghĩa là thêm một cái gì đó vào nội dung của cổng.

Điều này có nghĩa là bạn cần thêm một từ 8 bit trong thanh ghi với một đơn vị được dịch chuyển 5 bit - kết quả là, nếu 11000010 hóa ra là 110.110.010. Trong ví dụ này, có thể thấy rằng chỉ PB5 đã thay đổi, các bit còn lại của thanh ghi này vẫn không thay đổi, cũng như Trạng thái của các chân vi điều khiển vẫn không thay đổi.
Nhưng với sự bổ sung hợp lý, một vấn đề phát sinh - bạn không thể biến thiết bị thành số không, bởi vì:
0+0=1
1+0=1
0+1=1
Phép nhân và đảo ngược logic sẽ đến với sự trợ giúp của chúng tôi:

& = có nghĩa là nhân nội dung của cổng với một số cụ thể.

Và đây là con số mà chúng tôi nhân lên. Dấu hiệu ~ ~ chỉ ra sự đảo ngược. Trong trường hợp của chúng tôi, đơn vị đảo ngược bằng không. Đó là, chúng tôi nhân nội dung của cổng bằng 0, được dịch chuyển bằng 5 bit. Ví dụ, nó là 10110001, nó trở thành 10100001. Các bit còn lại không thay đổi.

Điều tương tự có thể được thực hiện bằng thao tác đảo ngược (^):
Đọc từ các cổng, tương tự của digitalRead () được thực hiện bằng thanh ghi PIN, trong thực tế, nó trông như thế này:

Ở đây chúng tôi kiểm tra xem biểu thức trong ngoặc có bằng trạng thái thực của các cổng hay không, tức là tương tự nếu chúng ta đã viết if (digitalRead (12) == 1).
Kết luận
Tại sao có những khó khăn như vậy với quản lý cổng nếu bạn có thể sử dụng các chức năng thuận tiện tiêu chuẩn? Đó là tất cả về tốc độ và kích thước mã. Khi sử dụng phương pháp thứ hai, được thảo luận trong bài viết, kích thước mã được giảm đáng kể và tốc độ tăng thêm vài bậc độ lớn. DigitalWrite () được thực hiện trong 1800 ands và ghi trực tiếp vào cổng trong 0,2 s và digitalRead () trong 1900 s, và cũng trở thành 0,2 s. Phương pháp điều khiển này được tìm thấy trên các không gian mở của mạng và thường được tìm thấy trong mã. hoàn thành dự án.
Xem thêm tại electro-vi.tomathouse.com
: