我想爲Atmel ATMega32U4實現與Arduino的引腳號類似的東西。我看過Arduino的digitalWrite
命令和相關的源文件,看看它們是如何做的,但我認爲這有點複雜,所以我想實現一個更基本的版本。在AVR微控制器中實現類似於Arduino的引腳號
這個想法是有整數1到n代表AVR芯片上的每個I/O引腳。我開始用指針數組的DDR/PORT寄存器,其中該指數將代表銷地址:
volatile uint8_t *pin_port_dir_regs[] = {
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
&DDRE, // PIN_7
&DDRB, // PIN_8
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
&DDRB, // PIN_15
&DDRB // PIN_16
};
volatile uint8_t *pin_port_out_regs[] = {
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
&PORTE, // PIN_7
&PORTB, // PIN_8
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
0, // NOT USED
&PORTB, // PIN_15
&PORTB // PIN_16
};
我還需要在每一個的DDRx/PORTx寄存器的知道比特數,所以我創造了另一個數組:
const uint8_t pin_bits[] = {
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(6), // PIN_7
_BV(4), // PIN_8
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // NOT USED
_BV(0), // PIN_14
_BV(1), // PIN_15
_BV(3) // PIN_16
};
要設置引腳模式,並寫入到腳,我創建了以下功能:
void pin_mode(uint8_t pin, uint8_t direction) {
// defeference the pointer to the direction register
uint8_t port_dir_register = *(pin_port_dir_regs[pin]);
// get pin mask
uint8_t mask = pin_bits[pin];
// set its mode
if (direction == INPUT) {
port_dir_register &= ~mask;
} else {
port_dir_register |= mask;
}
}
void pin_write(uint8_t pin, uint8_t level) {
// defeference the pointer to the output register
uint8_t port_out_register = *(pin_port_out_regs[pin]);
// get pin mask
uint8_t mask = pin_bits[pin];
// set output
if (level == LOW) {
port_out_register &= ~mask;
} else {
port_out_register |= mask;
}
}
什麼是應該發生的是,你會打電話如pin_mode(7, OUTPUT)
將引腳7設置爲輸出,然後pin_write(7, HIGH)
將輸出設置爲1(其中OUTPUT和HIGH是預定義的宏)。代碼編譯併成功上傳到AVR,但是當我測試輸出時,它不響應。我想我必須寫一些內存位置,但不是對應於預期的寄存器。有沒有人看到我試圖做到這一點的方式有問題?
爲什麼你不使用gcc提供的標準文件avr?另外:如果你使用類似pin_write方法的方式爲引腳寫入一些初始化,則只會爲prog的開始階段浪費大量代碼。所有這些都可以在編譯時通過模板代碼完成,而不是單獨針對每個引腳進行操作。爲相同的作業設置一次不是8次的ddr和端口寄存器。 – Klaus
@Klaus,你指的是什麼標準文件?我沒有意識到現有的代碼可以做我想做的事情。 此外,我並不關心現階段的啓動優化 - 但感謝您的建議。 – Sean
這看起來很浪費寶貴的RAM和ROM空間給我。你的問題不在這裏討論。我們是noi討論網站,它太過於自負。編輯:對不起,我有最後一句話。請提供更詳細的信息。見[問]。 – Olaf