Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
shiftOut()

shiftOut()

概要

shiftOut()は、1バイトのデータを、1ビットずつ送信します。概念図を以下に示します。

shiftOut()のリファレンスはこちらをご覧ください。

ソースコード

shiftOut()は、hardware/arduino/avr/cores/arduino/wiring_shift.c に定義されています。以下に全ソースコードを示します。

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
	uint8_t i;

	for (i = 0; i < 8; i++)  {
		if (bitOrder == LSBFIRST)
			digitalWrite(dataPin, !!(val & (1 << i)));
		else	
			digitalWrite(dataPin, !!(val & (1 << (7 - i))));
			
		digitalWrite(clockPin, HIGH);
		digitalWrite(clockPin, LOW);		
	}
}

入力はdataPin、clockPin、bitOrder、valで、すべてuint8_tです。戻り値はありません。

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
	uint8_t i;

8ビット分のデータを書き出すためループします。その中で、1ビットずつ値を出力します。

	for (i = 0; i < 8; i++)  {
		if (bitOrder == LSBFIRST)
			digitalWrite(dataPin, !!(val & (1 << i)));
		else	
			digitalWrite(dataPin, !!(val & (1 << (7 - i))));

bitOrderがLSBFIRSTの場合は入力値valの最下位ビットから送信します。このため、i番目のループでvalの第iビットを送信します。bitOrderがLSBFIRSTでない場合は、入力値valの最上位ビットから送信します。このため、i番目のループでvalの第(7-i)ビットを送信します。値の送信には、digitalWrite()を使います。

digitalWrite()の第2引数は、HIGH(0x1)もしくはLOW(0x0)です。一方、val & (1 << i)で取得した値は、iの値により異なります。例えば、iが3のときには、val & (1 << i) は、0もしくは8になります。このため、val & (1 << i)の値は、iが0でない場合には、digitalWrite()への入力としてはふさわしくない値となる場合があります。論理否定(!)を2回適用することで値を修正しています。論理否定は、オペランドが0ならば1を、0以外ならば0を返します。このため、0→1→0、0以外→0→1と変換され、無事digitalWrite()の引数にふさわしい値となります。

余談ですが、digitalWrite()では、入力された値がLOWかそうでないかの区別しかしていないので、前記の処理は行わなくても問題なく動作するのではないかと思います。

最後に、clockPinをHIGHにし、直後にLOWとすることで、パルスを一つ送信します。

		digitalWrite(clockPin, HIGH);
		digitalWrite(clockPin, LOW);		
	}
}

shiftOut()は、8ビット固定で書き出すので、異なるビット数の書き出しを行う場合には、このソースを参考にすればいいと思います。

バージョン

Arduino 1.8.3



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2017 garretlab all rights reserved.
inserted by FC2 system