teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

また修正

2021/01/07 22:14

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -7,7 +7,7 @@
7
7
  普通は'0'に対応した値を引くという処理をする(48-48=0 ~ 57-48=9)ことが多いのですが、
8
8
  そのサンプルでは下位4bit(16進数で言えば下位1桁)を取り出す、という考え方をしたようです。
9
9
 
10
- &はビット論理演算積(and演算)の演算子です。まぁ、記号って検索するのは難しいですけど、C/C++入門書の一冊も読み通せば出てきていると思うので確認しておいてください。
10
+ &はビット論理演算積(and演算)の演算子です。まぁ、記号って検索するのは難しいですけど、C/C++入門書の一冊も読み通せば出てきていると思うので確認しておいてください。
11
11
  二進数で表記したとき、二つの数の各桁の両方が1になっていればその桁に1を出力、そうでなければその桁を0を出力するという働きを持ちます。そうすると、0xfとandを取るということは
12
12
  '0' & 0xf = 0b00110000 & 0b00001111 同じ桁で両方1のビットは無いので 結果は0
13
13
  '1' & 0xf = 0b00110001 & 0b00001111 最下位が両方1 結果は0b00000001 (つまり1)
@@ -35,7 +35,7 @@
35
35
 
36
36
  余談ですが、<<は優先度の低い演算子なので、
37
37
  0b00110001 << 4 + 1 とすると4+1が優先的に行われて0b00100000になります。1+0b00110001<<4では先に0b00110001+1が計算されて0b00110010 << 4の演算になります。
38
- '10'に1を足して21を求めるイメージのときには(0b00110001 << 4 )+1としないといけません。これ、割とハマります。
38
+ '10'に1を足して11を求めるイメージのときには(0b00110001 << 4 )+1としないといけません。これ、割とハマります。
39
39
 
40
40
  以上より、
41
41
 

3

修正

2021/01/07 22:14

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -35,7 +35,7 @@
35
35
 
36
36
  余談ですが、<<は優先度の低い演算子なので、
37
37
  0b00110001 << 4 + 1 とすると4+1が優先的に行われて0b00100000になります。1+0b00110001<<4では先に0b00110001+1が計算されて0b00110010 << 4の演算になります。
38
- '1'に1を足して2を求めるイメージのときには(0b00110001 << 4 )+1としないといけません。これ、割とハマります。
38
+ '10'に1を足して21を求めるイメージのときには(0b00110001 << 4 )+1としないといけません。これ、割とハマります。
39
39
 
40
40
  以上より、
41
41
 

2

さらに追記

2021/01/07 22:10

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -1,5 +1,5 @@
1
1
  前提:
2
- シリアル入力からASCIIコード数字でYYMMDDWの順でデータが流し込まれること。
2
+ シリアル入力からASCIIコード数字でYYMMDDWの順でデータが流し込まれていること。(Serial.available()等で全てのデータが受信済みであることを確認するとか、ある一定時間内にデータが流し込まれる手順が保証されている等。Serial.read()は受信データがないと-1を返して来ますから)
3
3
 
4
4
  ASCIIコードは、数字'0'に対し数値0x30(十進数では48, 二進数では0b00110000)、'1'に対し0x31(49,0b00110001)...'9'に対し0x39(57,0b00111001)が対応しています。
5
5
 

1

ちょいと書き足し

2021/01/06 23:54

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -7,7 +7,7 @@
7
7
  普通は'0'に対応した値を引くという処理をする(48-48=0 ~ 57-48=9)ことが多いのですが、
8
8
  そのサンプルでは下位4bit(16進数で言えば下位1桁)を取り出す、という考え方をしたようです。
9
9
 
10
- &はビット論理演算積(and演算)の演算子です。まぁ、記号って検索するのは難しいですけど、入門書の一冊も読み通せば出てきていると思うので確認しておいてください。
10
+ &はビット論理演算積(and演算)の演算子です。まぁ、記号って検索するのは難しいですけど、C/C++気入門書の一冊も読み通せば出てきていると思うので確認しておいてください。
11
11
  二進数で表記したとき、二つの数の各桁の両方が1になっていればその桁に1を出力、そうでなければその桁を0を出力するという働きを持ちます。そうすると、0xfとandを取るということは
12
12
  '0' & 0xf = 0b00110000 & 0b00001111 同じ桁で両方1のビットは無いので 結果は0
13
13
  '1' & 0xf = 0b00110001 & 0b00001111 最下位が両方1 結果は0b00000001 (つまり1)
@@ -19,6 +19,7 @@
19
19
 
20
20
  曜日は、元データが'0'~'6'の可能性しか無いので、別に0xfとのandでもよかったのでしょうがなんとなく(?)7=0b00000111とのandをとることにしたのでしょう。'0'~'6'ではbit3が1になることはないので0xfとandをとっても0x7とandをとっても同じことになります。
21
21
 
22
+ このように&演算で特定のビットだけを取り出すこと(言い方を変えれば特定のビットを0にすること)を(ビット)マスクと言ったりもします。マイコンをいじる人なら覚えておくべき言葉かと思います。
22
23
 
23
24
  さて。[DS3107データシート](https://datasheets.maximintegrated.com/en/ds/DS1307.pdf) 8ページを見ると、設定すべき値の形式がわかります。
24
25
  8bitデータの上位に日/月/年の10の桁が入るような形式になっていますね(二進化十進数:BCDってやつ)。