ATMEGAで学習しよう(レッスン1)
「ピン操作」
<目的>
・ポートの設定方法について学ぶ。
・ビット操作について学ぶ。
<動作概要>
・SW1 が押されたらLED1 を点灯させる。
・SW2 が押されたらLED2 を点灯させる。
<ポイント>
・DDRはポート方向レジスタ。
・DDRのビット値が0 は入力、1 は出力になる。
・PORTの値は、DDRの対応するピンを出力に設定した場合、1 はHigh、0 はLow を出力する。
・PORTの値は、DDRの対応するピンを入力に設定した場合、1 はプルアップあり、0 はプルアップなしになる。
(プルアップありはピンがマイコン内で自動的に抵抗経由で+電源に接続される)
・PIN*はそのときのピンの状態(High かLow か)を読み出す。
・if ((P_SW & (1<<B_SW1)) == 0)というのは、PD の入力レジスタと第2 ビットだけ1 にした8 ビット(0b00000100)のAND を取った値が0 だったらという意味。
・SW1 が押されていなければ、PIND の第2 ビットはピンがプルアップされて1 なのでAND をとれば(0b00000100)となり0 ではない。
・押されていればPIND の第2 ビットは0 になり、AND をとれば(0b00000000)となり0 になる。
<レジスタ説明>
ポートPxnのxはポート名を表し本マイコンではB,C,D,Fです。またnはビット位置(0〜7)を表します。Pxnを入力、出力のどちらにするかはDDRxレジスタにより決定します。
出力にした場合は出力をHigh、LowのどちらにするかがPORTxレジスタにより決定します。
入力にした場合はPORTxレジスタの指定ビットが1であればプルアップされます。
またPINxレジスタに入力値が格納されます。
<プログラム>
// 名称 : ピン操作
// ファイル名 : avrlesson01.c
/*
<目的>
・ポートの設定方法について学ぶ。
・ビット操作について学ぶ。
<動作概要>
・SW1が押されたらLED1を点灯させる。
・SW2が押されたらLED2を点灯させる。
<ポイント>
・DDR*はポート方向レジスタ。
・DDR*のビット値が0は入力、1は出力になる。
・PORT*の値は、DDR*の対応するピンを出力に設定した場合、1はHigh、0はLowを出力する。
・PORT*の値は、DDR*の対応するピンを入力に設定した場合、1はプルアップあり、0はプルアップなしになる。
(プルアップありはピンがマイコン内で自動的に抵抗経由で+電源に接続される)
・PIN*はそのときのピンの状態(HighかLowか)を読み出す。
・if ((P_SW & (1<<B_SW1)) == 0)というのは、PDの入力レジスタと第2ビットだけ1にした8ビット(0b00000100)の
ANDを取った値が0だったらという意味。
SW1が押されていなければ、PINDの第2ビットはピンがプルアップされて1なのでANDをれば(0b00000100)となり0ではない。
押されていればPINDの第2ビットは0になり、ANDをとれば(0b00000000)となり0になる。
*/
#include <avr/io.h>
//*******************************************************************************
// 各種定義
//*******************************************************************************
#define P_LED PORTB // LED1と2を接続したポート
#define B_LED1 0 // LED1を接続したポートのビット位置
#define B_LED2 1 // LED2を接続したポートのビット位置
#define P_SW PIND // スイッチを接続したポート
#define B_SW1 2 // スイッチ1を接続したポートのビット位置
#define B_SW2 3 // スイッチ2を接続したポートのビット位置
//*******************************************************************************
// メインルーチン(MAIN)
//*******************************************************************************
int main(void)
{
//---- DDR,PORT 設定 ----//
DDRB = 0b11101111;
PORTB = 0b00010111;
DDRC = 0b10111110;
PORTC = 0b01000000;
DDRD = 0b00100010;
PORTD = 0b00111101;
//---- ループ処理 ----
while(1)
{
//---- SW1判定 ----//
if ((P_SW & (1<<B_SW1)) == 0) // SW1が押されてるか
P_LED &= ~(1<<B_LED1); // 押されているのでLED1点灯
else
P_LED |= (1<<B_LED1); // 押されていないのでLED1消灯
//---- SW2判定 ----//
if ((P_SW & (1<<B_SW2)) == 0) // SW2が押されてるか
P_LED &= ~(1<<B_LED2); // LED2点灯
else
P_LED |= (1<<B_LED2); // LED2消灯
}
}
<プログラム説明>
下記は、SW 入力判定と、LED のピン設定の部分です。
//---- SW1 判定 ----//
if ((P_SW & (1<<B_SW1)) == 0) // SW1 が押されてるか
P_LED &= ~(1<<B_LED1); // 押されているのでLED1 点灯
else
P_LED |= (1<<B_LED1); // 押されていないのでLED1 消灯
P_SW は各種定義のところでPIND の別名として、またB_SW1 は2 の別名として定義しているので、(P_SW & (1<<B_SW1))
は、(PIND & (1<<2))と同義です。
・PIN*はそのときのピンの状態(High かLow か)を読み出します。
・(PIND & (1<<2))というのは、PD の入力レジスタと、第2 ビットだけ1 にした8 ビット(0b00000100)のAND を取るという意味で、SW1 が押されていなければ、PIND の第2 ビットはピンがプルアップされて1 なのでAND を取れば(0b00000100)となり0 ではない。
押されていればPIND の第2 ビットは0 になり、AND をとれば0b00000000)となり0 になります。
・よって、if ((P_SW & (1<<B_SW1)) == 0)というのは、SW1 が押されているかの判定となります。SW2 についても同様です。
なお、if ((P_SW & (1<<B_SW1)) == 0) のところを if (!(P_SW & (1<<B_SW1))) と書く書き方もあります。
!は反転記号で、(P_SW & (1<<B_SW1))の結果を反転します。
SW1 が押されていたら、(P_SW & (1<<B_SW1))は0 になり、それを!で反転するので値は1 となってif 条件が満足することになります。
ここから先は
ATMEGAで学習しよう
AVRマイコンプログラミング入門用として、レッスン形式にまとめました。 マイコンの機能の理解にも役立ちます。 対象とするマイコンはATme…
この記事が気に入ったらチップで応援してみませんか?