見出し画像

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レジスタに入力値が格納されます。


DDR*レジスタ
PORT*レジスタ
PIN*レジスタ

<プログラム>

// 名称			: ピン操作
// ファイル名	: 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 条件が満足することになります。

ここから先は

0字
単体で有料公開している記事を集めていますので、まとめてご覧いただくとおトクです。

AVRマイコンプログラミング入門用として、レッスン形式にまとめました。 マイコンの機能の理解にも役立ちます。 対象とするマイコンはATme…

期間限定 PayPay支払いすると抽選でお得に!

この記事が気に入ったらサポートをしてみませんか?