Atmel ATMega32U4のArduinoのピン番号に類似したものを実装したいと思います。私はArduinoのdigitalWrite
コマンドとそれに関連するソースファイルを見てきましたが、これは少し複雑ですので、より基本的なバージョンを実装したいと思っています。Arduinoに似たAVRマイクロコントローラのピン番号の実装
アイデアは、AVRチップ上の各I/Oピンを表す整数1からnを持つことです。私は、インデックスは、ピンを表すことになり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に正常にアップロードされますが、出力をテストすると応答しません。私はメモリの場所に書き込む必要がありますが、目的のレジスタに対応するものではないと思います。誰かが私がこれをやろうとしている方法で問題を参照してくださいか?
uint8_t port_out_register = *(pin_port_out_regs[pin]);
あなたが特定のアドレスに配置されたハードウェアレジスタへの書き込みをしたい:
なぜgccで提供されているavrの標準ファイルを使用しないのですか?さらに、pin_writeメソッドのようなものでピンの初期化を書くと、progの開始フェーズでのみ多くのコードが無駄になります。これらのすべては、各ピンだけで動作するのではなく、コンパイル時にテンプレートコードによって実行できます。同じジョブに対してddrとportレジスタを一度8回設定しないでください。 – Klaus
@Klaus、どのような標準ファイルを参照していますか?私は自分がしたいことをする既存のコードを認識していませんでした。 また、この段階ではスタートアップの最適化には関心がありませんが、アドバイスをいただきありがとうございます。 – Sean
貴重なRAMとROMのスペースが私にとってかなり浪費しているようです。あなたの質問はここで話題になっていません。私たちはノーディスカッションサイトであり、あまりにも議論の余地があります。編集:申し訳ありませんが、私は最後のsentencを念頭に置いていました。何が間違っているか詳細をご記入ください。 See [ask]。 – Olaf