Câu trả lời:
Có, bạn có thể sử dụng các thanh ghi hướng dữ liệu (DDR B , DDR C , DDR D tùy thuộc vào cổng nào) để kiểm tra xem pin đang ở chế độ nào.
Nếu một pin ở chế độ đầu ra thì bit tương ứng trong DDRx sẽ là 1.
Một điều phức tạp là các chức năng Arduino cung cấp cho mỗi pin một số pin "Arduino" và bạn phải xem sơ đồ pin để tìm ra thanh ghi DDR và bit nào tương ứng với pin mà bạn muốn kiểm tra. Bạn có thể tìm thấy bản đồ pin cho Arduinos dựa trên ATMEGA168 / ATMEGA328 (bao gồm cả Uno) tại đây ...
https://www.arduino.cc/en/Hacking/Atmega168Hardware
Vì vậy, ví dụ, nếu bạn muốn kiểm tra xem chân số 4 của Arduino có được đặt cho đầu ra hay không, bạn sẽ nhìn vào bản đồ và xem nó có tương ứng với PD4 không. Điều đó có nghĩa là "cổng D" và "bit 4", vì vậy bạn có thể nói ...
if ( DDRD & _BV(4) ) { // Check bit #4 of the data direction register for port D
// If we get here, then Arduino digital pin #4 was in output mode
} else {
// If we get here, then Arduino digital pin #4 was in input mode
}
Nếu bạn muốn kiểm tra pin kỹ thuật số Arduino # 14, thì bạn sẽ sử dụng DDRB & _BV(5)
.
( _BV(x)
là một macro dịch chuyển 1
x
bit sang phải.)
Có các hàm có thể giúp bạn đăng ký và số bit từ số pin được tích hợp trong API Arduino.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg = portModeRegister(port);
if (*reg & bit) {
// It's an output
} else {
// It's an input
}
Có vẻ như lõi Arduino đang thiếu một chức năng để đọc pinMode (). Đây là một triển khai có thể:
int pinMode(uint8_t pin)
{
if (pin >= NUM_DIGITAL_PINS) return (-1);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg = portModeRegister(port);
if (*reg & bit) return (OUTPUT);
volatile uint8_t *out = portOutputRegister(port);
return ((*out & bit) ? INPUT_PULLUP : INPUT);
}
Nó xử lý số pin bất hợp pháp (trả về -1) và tất cả các chế độ pin; ĐẦU RA, INPUT và INPUT_PULLUP.
Chúc mừng!
BW: Tôi đã thêm vấn đề này vào kho lưu trữ github của Arduino.