ขออธิบายหน่อย บางท่านอาจจะไม่ทราบ ว่าทำแบบนี้หมายถึงอะไร
อย่างการกลับบิทแล้ว AND อย่างนี้
DDRD &= ~(1<<DDD3); // port D3 is input
ซึ่งที่เรา include ไฟล์ io.h ไว้ในไฟล์ wdt.c ของเราใช่ไหม เพราะตอนเราสร้าง new project ใน AVR Studio 4.17 เราระบุเลือกเบอร์ ATmega328p เอาไว้ใช่ไหม ทำให้ไฟล์ io.h จะลิ้งค์ไปสู่ไฟล์ iom328p.h คราวนี้เราก็มาดูที่ไฟล์ iom328p.h ว่ามีอะไรบ้าง (ไฟล์จะอยู่ใน C:\WinAVR-20100110\avr\include\avr)
#define DDRD _SFR_IO8(0x0A)
#define DDD0 0
#define DDD1 1
#define DDD2 2
#define DDD3 3
#define DDD4 4
#define DDD5 5
#define DDD6 6
#define DDD7 7
ก็จะมีการ define เอาไว้ อย่างเช่น DDRD ก็จะเป็น special function register IO ตำแหน่งอยู่ที่แอดเดรส 0x0A ใช่ไหม
อย่าง DDD3 ก็ถูก define ไว้ว่ามีค่าเท่ากับ 3
คราวนี้เราก็มาดูตรงนี้ก่อนนะ (1<<DDD3) หมายถึงเรา shift left ข้อมูล "1" ของข้อมูลชั่วคราว 8 บิท ไป 3 ตำแหน่ง เพราะ DDD3 = 3 ก็จะได้ข้อมูล 8 บิทชั่วคราวเป็น 0b00001000
คราวนี้ต่อไปก็ทำกลับบิท ~(1<<DDD3) ก็จะทำการกลับบิทข้อมูลชั่วคราว 8 บิทจาก 0b00001000 ก็จะได้เป็น 0b11110111
คราวนี้มา &(AND) กับรีจีสเตอร์ DDRD &= ~(1<<DDD3); ก็จะมีความหมายว่า DDRD = DDRD & 0b11110111
ก็จะหมายถึงว่าเอาข้อมูลในรีจีสเตอร์ DDRD 8 บิทมา AND กับข้อมูลชั่วคราว 0b11110111
ก็จะหมายถึงว่าให้ข้อมูลในรีจีสเตอร์ DDRD อยู่คงเดิม ให้เฉพาะบิทที่ 3 กลายเป็น 0 เพียงบิทเดียว
ส่วนการ OR กันอย่างนี้ ก็จะคล้ายๆกัน ลองทำความเข้าใจดู ว่าให้บิทไหนในรีจีสเตอร์ WDTCSR เป็น "1" บ้าง ส่วนบิทอื่นจะคงเดิม ดูตำแหน่งบิทของรีจีสเตอร์นั้น ในดาต้าชีทประกอบเอานะ
WDTCSR |= (1<<WDCE) | (1<<WDE);
ส่วนการ = ก็จะไม่เหมือนการ OR เพราะจะทำให้บิทที่แสดงนั้นเป็น "1" ส่วนบิทอื่นในรีจีสเตอร์จะกลายเป็น "0" หมด
WDTCSR = (1<<WDE) | (1<<WDP2) | (1<<WDP1)| (1<<WDP0);
ลองทำความเข้าใจดูนะ ไม่เข้าใจก็สอบถามมาได้ครับ