Atmega328P Datasheet 17. External Interrupt

Started by tha, August 09, 2019, 01:36:22 PM

Previous topic - Next topic

tha

ว่างๆก็มาทำสรุปรวมทั้ง 5 interrupt เลยนะ มีอะไรบ้าง INT0, INT1, PCINT0, PCINT1, PCINT2
INT0, INT1 ก็ใช้สวิทช์ปุ่มกดเอา ให้อินเตอร์รัพท์ที่ขอบขาลง(falling edge)
ส่วน PCINT0, PCINT1, PCINT2 ก็ใช้สวิทช์ปิด-เปิด ถ้าใครมีสวิทช์มากๆก็เพิ่มสวิทช์เอาได้ คงจะเข้าใจการเขียนโปรแกรมแล้วนะ อธิบายมากเดี๋ยวจะสับสน

http://www.mediafire.com/file/m34f7nmfki0kd32/Interrupt.rar/file




tha

มีพรายกระซิบบอก การทำ pin change interrupt PCINT ด้วยสวิทช์ สวิทช์มันมีบร๊าวน์(คือจะเป็น "0" เป็น "1" หลายครั้ง ตอนปิดเปิด) ก็เลยเอา ATmega328p อีกบอร์ด มาทำ output ให้เป็น ON-OFF และมีการดีเลย์ คราวนี้ไม่เกิดบร๊าวน์แน่ เลยมาลอง ก็สามารถทำงานได้ครับ

นี่มีตัวอย่างโปรแกรม:
http://www.mediafire.com/file/f2p15qsoitj4iht/Test_PCINT_Board1.rar/file

http://www.mediafire.com/file/19pvvi4icot7dat/Test_PCINT_Board2.rar/file



ได้แบตสำรองมือถือมาจากที่ไปเที่ยวตัวเมืองกำแพงเพชรมา ก็เลยมาทำเป็น power supply 5V (เอามิเตอร์วัดได้ 5.09V) ให้กับบอร์ดเลย ตัวนี้ขนาด 20000mAh แต่เป็นของเก่า



ตอนนี้ fuse bits ก็ตั้งประมาณนี้ ลองไล่บิทเอาดูนะ ผมก็ลืมแล้ว ได้หน้าลืมหลังไปเรื่อย สมองคนเราก็ประมาณนี้แหละ  ;D

tha

คราวนี้เอาบอร์ดที่ 1 มาทำเป็น 6 output เลย(เป็นสวิทช์ 6 ตัวเลย) แล้วมาเข้า pin change interrupt ทั้ง 3 interrupt เลย คือเอา 2 output ของบอร์ดที่ 1 มาเข้าต่อ 1 interrupt ของบอร์ดที่ 2 (จะโมลองทำให้หลาย output มากกว่านี้ก็ได้ ดูที่ขา ATmega328p ว่าได้
PCINT interrupt ละกี่ขา) ก็ไม่ยากแล้วใช่ไหม

ก็ต่อขาดังนี้
                        บอร์ดที่ 1                                      บอร์ดที่ 2
          ขา             PB0                 ต่อกับ                 PCINT0(PB0)          PCINT0 Interrupt
          ขา             PB1                 ต่อกับ                 PCINT1(PB1)                    "
          ขา             PB2                 ต่อกับ                 PCINT8(PC0)          PCINT1 Interrupt
          ขา             PB3                 ต่อกับ                 PCINT9(PC1)                    "
          ขา             PB4                 ต่อกับ                 PCINT19(PD3)        PCINT2 Interrupt
          ขา             PB1                 ต่อกับ                 PCINT20(PD4)                  "

อย่างนี้หลอด LED จะกระพริบหลอดละ 2 ครั้งใช่ไหม เพราะมี 2 output ต่อ 1 interrupt

มีโปรแกรมตัวอย่าง
บอร์ดที่ 1 http://www.mediafire.com/file/sriyd6zquk8ttkg/Test_PCINT_Board1_1.rar/file
บอร์ดที่ 2 http://www.mediafire.com/file/1tf7z4je0e41bix/Test_PCINT_Board2_1.rar/file

มีแท๊บเล็ตแล้วก็ถ่ายรูปให้ดูด้วย



เดี๋ยวลองแช่ทิ้งไว้นานๆ จะดูว่าแบตสำรองนี้ จ่ายไฟได้นานเท่าไร


tha

คราวนี้มาลองทำเป็นไฟวิ่งดู ใช้ pin change interrupt 0 ตัวเดียว แต่เซท pin change mask register 0 ไว้ 4 บิท 
// Pin Change Enable Mask select PCINT0(PB0), PCINT1(PB1), PCINT2(PB2), PCINT3(PB3)
ก็เสียบสาย PB0-3 ของทั้งสองบอร์ดถึงกัน เสียบสาย PD0-7 ของบอร์ดที่ 2 เข้าหลอด LED คราวนี้ไฟก็จะวิ่งจาก LED0-LED7

นี่ตัวอย่างโปรแกรม
บอร์ดที่ 1 http://www.mediafire.com/file/qmnzsaap7vgr0da/Test_PCINT_Board1_2.rar/file
บอร์ดที่ 2 http://www.mediafire.com/file/33ob2h53baidvn5/Test_PCINT_Board2_2.rar/file



เข้าใจกันมั๊ยหล่ะ ลองไล่เช็คดูใน register ที่แปลมา กับเช็คขา ATmega328p ว่าขาไหนเป็นขาไหนนะ

ปล. ผมจบ ปวส.ไฟฟ้ามาก็เป็นแต่ตีกิ๊บนะ มาสู้ชีวิตที่กรุงเทพ ก็มาตีกิ๊บตามบ้านจัดสรรนะ คราวนี้มาสอบเข้าโรงปูนตรานก สอบข้อเขียนก็ไม่ได้สอบสัมภาษณ์ก็ไม่ได้ พอดีเขาจะเอาคนมากันพวกรุ่นพี่ในโรงปูนประท้วง เขาเลยรับมาเป็นพนักงานชั่วคราว ไอ้เราก็ไม่รู้ว่าเขาจะปลดเมื่อไหร่ พอเข้าโรงปูนมาแล้ว ก็เลยรีบเร่งศึกษาหาความรู้ ถูๆไถๆมาเรื่อย จบปวส.มาถึงห้าปีถึงไปสอบปริญญาตรีได้ ปริญญาตรีก็เรียนกันแต่ทฤษฎี ลืมไปหมดแล้ว ดีอยู่อย่างเดียวคือมันทำให้เราติดการอ่านหนังสือมากๆเท่านั้นเอง
เข้าใจอยู่นะว่าบางคนอาจไม่เข้าใจ ก็ถามกันได้ครับ

tha

ประกาศตัวแปร b ไว้ ถ้า a เท่ากับ b อยู่ ก็จะติดอยู่กับลูป while นี้อยู่ พออินเตอร์รัพย์ a เพิ่มค่าถึงจะหลุดมาจากลูป while นี้ไป

Quote
   while(a==b);

คราวนี้ a เพิ่มค่าแล้ว เราก็มาให้ b = a อีก ก็วนไปติดที่ลูป while ก่อน รอการอินเตอร์รัพต่อไปอีก ไม่ให้มันวนทำงานซ้ำๆตลอดเวลาโดยไม่จำเป็น

tha

ลองอัฟโหลดยูทูปตามคำเรียกร้องนะ เคยอัฟโหลดมาวีดีโอเดียวนานหลายปีแล้ว คราวนี้อัฟโหลดอีก พอจะเป็นแล้ว
มาดูกัน pin change interrupt PCINT0 มาทำเป็นไฟวิ่งคัรบ

https://www.youtube.com/v/U7J5K175SMQ

tha

น่าเสียดายที่มันอินเตอร์รัพท์ทั้งขึ้นทั้งลงเลย แล้วสวิทช์มันมีบร๊าวน์(เป็น "0" เป็น "1" หลายครั้งตอนปิดเปิดสวิทช์) มันจะเซ้นส์ไวมากด้วย อย่างเราใช้ clock 16Mhz คำสั่งหนึ่งก็ไซเคิลเดียว ก็ใช้เวลาเพียง 1/16Mhz = 1/16 us เอง

มีวิธีอื่นไหมที่ไม่ต้องใช้บอร์ดมาทำเป็นสัญญาน ON-OFF อย่างนี้ แล้วไม่เกิดบร๊าวด้วย

ถ้าสวิทช์ไม่มีบร๊าวน์ เราก็สามารถใช้สวิทช์ได้ถึงมากสุด 8 ตัว on-off หลอดไฟดวงเดียวได้เลย

tha

พรายกระซิบบอก ให้ลองทำ ON ไปก่อนทั้ง 4 สวิทช์ แล้วค่อย OFF ทั้ง 4 สวิทช์ ก็จะได้ผลเหมือนกัน เมื่อสวิทช์ใดเปลี่ยนก็จะเกิด interrupt เหมือนกันหมด

มีตัวอย่างของบอร์ดที่ 1 ส่วนบอร์ดที่ 2 ยังคงเดิม
http://www.mediafire.com/file/rdhtq7vuapw8hld/Test_PCINT_Board1_2%25282%2529.rar/file

ส่วนฟังชั่น delay ms เราก็มาเขียนแบบนี้ ให้เป็นฟังชั่นย่อย ถ้าเขียนแบบเดิม code size จะใหญ่มาก เพราะโปรแกรมเราไม่ได้บีบอัดแล้ว optimization = -O0 (ดูใน configuration options) เขียนเป็นฟังชั่นย่อยอย่างนี้ก็จะลด code size ลง