AVRマイコンでの入力は入出力設定レジスタであるDDRX(Xは任意)で0を設定します。
その後、PORTXの指定のビットを1にすることによりプルアップ抵抗を内部で設定することができます。
また指定のレジスタのあるビットがセットされているかクリアされているかを調べる関数がある(おそらくavr/io.hで定義されている)
・bit_is_set() 指定レジスタの指定のビットがセット(1)されているかどうかチェック
・bit_is_clear() セット(1)されてされていないかチェック
入出力レジスタがおのおのにあり
・PORTX → 出力用
・PINX → 入力用
プルアップ抵抗(某ページの丸パクリ解説) ボタンをつけてON,OFFを判断しようという回路を考えると次のような回路が考えられます。 画像1 しかし書いてある通りこれではスイッチOFFのときの電圧が不明で0か1かわからないので次の回路が考えられます。 画像2 また、上のような問題があるので普通は下の回路だそうです。 画像3 これでできました
#include <avr/io.h> #include <util/delay.h> #define INVERT_BIT(x, n) (x ^= (1 << n)) #define OUTPUT 0 #define INPUT 1 #define FALSE 0 #define TRUE 1 int main(void) { DDRD = 0x01; // 0000 0001 PD0を出力 PD1を入力 PORTD = 0xFE; // 1111 1110 入力をプルアップする uint8_t bButton; //前回のボタン情報を保持 bButton = bit_is_clear(PIND, INPUT); //ONで1 OFFで0 while(1) { if(bButton ^ bit_is_clear(PIND, INPUT)) { //前回のボタン情報と違った場合 if(bButton == 0) { //押した時 }else{ //離した時 INVERT_BIT(PORTD, OUTPUT); } bButton = bit_is_clear(PIND, INPUT); //更新 } } }
・回路図
タクトスイッチについてはチャタリング対策をしないといけません。
ここでは「RC積分回路」を使いたいと思います。(詳しいことは電電の先輩に聞きましょう 時定数の求め方とか(5ms) )
プログラム中でWaitしたりバッファにデータをためて判断することにより回避することもできます。
注意:下の回路は電子回路について無知な電電一回生が考えていますので変更の必要があります というか動きません
勉強会ということなのでこの課題についてみんなで考えていきたい思います。
画像4