Electoday 2025

ไมโครคอนโทรลเลอร์ => AVR and Arduino => Topic started by: tha on August 06, 2019, 09:54:04 AM

Title: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 06, 2019, 09:54:04 AM
16. Interrupt
ในบทนี้อธิบายลักษณะเฉพาะของ interrupt handling ของ ATmega328p สำหรับคำอธิบายทั่วไปของ AVR interrupt handling, จัดอยู่ในกลุ่มคำอธิบายของ Reset and Interrupt Handling.
     • แต่ละ Interrupt Vector จะใช้ 2 instruction words .
     • Reset Vector ถูกย้ายได้โดย BOOTRST fuse, และ Interrupt Vector start address ถูกย้ายได้โดยบิท IVSEL ใน MCUCR

(https://i.imgur.com/xgHKVMq.png)
(https://i.imgur.com/gLJ5yS1.png)

    Note:
     1. เมื่อ BOOTRST Fuse ถูกโปรแกรม, mcu นี้จะกระโดดไปยัง Boot Loader ตำแหน่งที่ reset, ดู "Boot Loader Support –
     Read-While-Write Self-Programming"
     2. เมื่อบิท IVSEL ใน MCUCR ถูกเซท, Interrupt Vectors จะถูกย้ายไปยังจุดเริ่มต้นของ Boot Flash Section. ตำแหน่งของแต่ละ
     Interrupt Vector นั้นก็จะเป็นตำแหน่งในตารางนี้บวกด้วยตำแหน่งเริ่มต้นของ Boot Flash Section.
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 06, 2019, 01:20:05 PM
ตาราลข้างล่างนี้แสดงการวางตำแหน่ง reset และ Interrupt Vectors สำหรับการตั้งค่า BOOTRST และบิท IVSEL ผสมกันในแบบต่างๆ ถ้าโปรแกรมไม่เคยเปิดใช้งานแหล่ง interrupt เลย Interrupt Vectors จะไม่ถูกใช้และโค๊ดโปรแกรมปกติสามารถถูกวางที่ตำแหน่งที่ตั้งเหล่านี้(จะเอาโปแกรมปกติมาต่อที่ reset vector ได้เลย แทนที่ตำแหน่ง Interrupt Vectors ได้เลย) นี่เป็นกรณีถ้า Reset Vector อยู่ใน Application section ขณะที่ Interrupt Vectors อยู่ใน Boot section หรือในทางกลับกัน

(https://i.imgur.com/XD36nNi.png)

Note : 1. สำหรับ BOOTRST Fuse "1" หมายถึงไม่ถูกโปรแกรม ขณะที่ "0" หมายถึงถูกโปรแกรม

โดยปกติส่วนมากและการเซทอัฟโปรแกรมโดยทั่วไป สำหรับตำแหน่ง Reset และ Interrupt Vector Addresses เป็นอย่างนี้ :

(https://i.imgur.com/UKipI3H.png)
(https://i.imgur.com/XDKDezM.png)

ปล. ถ้าเกิดการรีเซท จาก Power-on Reset, External Reset (กดสวิทช์รีเซท), Brown-out Detection หรือ Watchdog System Reset สักอย่างหนึ่ง program counter ก็จะมาชี้ที่แอดเดรส 0x0000 ก่อนเลยใช่ไหม ที่ตำแหน่ง 0x0000 นี้ ก็จะมีคำสั่ง jump ไปที่ main program เลย โดยที่จะข้ามแอดเดรสของ interrupt vector เลย แล้ว program counter ก็จะชี้เพิ่มขึ้นต่อไปเรื่อยๆ โปรแกรมก็จะทำงานไป

อย่างถ้าเราตั้งใช้อินเตอร์รัพท์ INT0 เอาไว้ พอเกิดอินเตอรัพท์นี้ program counter ก็จะมาชี้ที่แอดเดรส 0x0002 (INT0) ที่แอดเดรสนี้ก็จะคำสั่งให้กระโดดไปทำโปรแกรมย่อยบริการอินเตอร์รัพท์ (interrupt service routine) ต่อไป พอทำเสร็จแล้ว ก็จะกลับมาทำโปรแกรมที่แอดเดรสต่อจากแอดเดรสโปรแกรมหลักที่ตอนถูกอินเตอร์รัพท์ใช่ไหม (เวลาถูกอินเตอร์รัพท์ ก็จะ push แอดเดรสนี้ไว้ใน stack พอทำโปรแกรมย่อยบริการอินเตอร์รัพท์เสร็จ ก็จะ pop เอาแอดเดรสนี้กลับคืน)
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 06, 2019, 01:40:42 PM
วันนี้อากาศเย็นนะ มีฝน เลยช่วงบ่ายได้มาอีกหนึ่งตอน ถ้าเป็นวันที่ร้อนๆมีแดด ก็คงจะจอดป้ายนะ นี่เป็นสาเหตุที่ไทยเราผลิตรถไม่ได้อย่างญี่ปุ่น ผลิตมือถือไม่ได้อย่างเกาหลีจีน ร้อน โทสะก็จะแรงด้วย ก็จะมีอารมณ์รุนแรง ก็จะใช้อารมณ์กันหน่อย ชอบทะเลาะกัน ชาวบ้านถึงจะรู้เรื่อง
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 07, 2019, 09:31:46 AM
เมื่อ BOOTRST Fuse ไม่ถูกโปรแกรม ขนาด Boot section เซทไว้ 2Kbytes และ MCUCR.IVSEL ถูกเซทก่อน  Interrupt ต่างๆจะถูก enable โดยปกติส่วนมากและการเซทอัฟโปรแกรมโดยทั่วไป สำหรับตำแหน่ง Reset และ Interrupt Vector Addresses เป็นอย่างนี้ :

(https://i.imgur.com/KjjCaFF.png)

ลองมาคำนวณขนาดของโปรแกรม flash ดู เขาบอกว่ามีขนาด 32Kbytes ใช่ไหม
                         ก็เท่ากับ    32*1024 = 32768   bytes
                                                    = 16384   words
                    ทำให้เป็นฐานสิบหก         = 0x4000   
   Boot section มีขนาด 2Kbytes = 1Kword = 1024 word
                    ทำให้เป็นฐานสิบหก         = 0x0400
   Start Boot section จะอยู่จากข้างบนลงมา ก็จะได้ = 0x4000 - 0x0400 = 0x3C00

การตั้งขนาด Boot section ก็จะตั้งที่ Fuses นี้ BOOTSZ = 1024 words(2Kbytes)
ส่วน BOOTRST ไม่โปรแกรม

(https://i.imgur.com/s1cF1MI.png)

ส่วนโปรแกรมการย้าย interrupt ไปที่ boot flash section ผมก็ลองทำอย่างนี้นะ interrupt vector ก็ย้ายไปที่ boot flash section
แต่การ INT0 interrupt จะไม่ทำงาน ถ้าไม่ย้ายจะทำงาน
หรือการย้าย interrupt ไปนี่ เขาต้องการในกรณีที่โปรแกรมเราไม่มี Interrupt หรือป่าว? เขาจะได้เอา main program มาเริ่มต้นที่จุดเริ่มต้น(0x0000)ของโปรแกรมเลย

http://www.mediafire.com/file/20xs9ck800e512o/Boot_IVSEL.rar/file (http://www.mediafire.com/file/20xs9ck800e512o/Boot_IVSEL.rar/file)
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 07, 2019, 09:43:00 AM
เมื่อ BOOTRST Fuse ถูกโปรแกรม ขนาด Boot section เซทไว้ 2Kbytes โดยปกติส่วนมากและการเซทอัฟโปรแกรมโดยทั่วไป สำหรับตำแหน่ง Reset และ Interrupt Vector Addresses เป็นอย่างนี้ :

(https://i.imgur.com/QOQjMo2.png)

ปล. อันนี้ย้ายไปแต่ Label RESET: คือย้าย main program ไปที่แอดเดรส 0x3C00 เลย
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 07, 2019, 09:48:03 AM
เมื่อ BOOTRST Fuse ถูกโปรแกรม ขนาด Boot section เซทไว้ 2Kbytes และ MCUCR.IVSEL ถูกเซทก่อน  Interrupt ต่างๆจะถูก enable โดยปกติส่วนมากและการเซทอัฟโปรแกรมโดยทั่วไป สำหรับตำแหน่ง Reset และ Interrupt Vector Addresses เป็นอย่างนี้ :

(https://i.imgur.com/9fSBCTU.png)

ปล. อันนี้ย้ายไปทั้ง RESET ทั้ง interrupt vector และย้าย main program ไปที่แอดเดรส 0x3C00 หมดเลย อันนี้เขาเอาไว้ทำ boot loader หรือป่าว ข้าน้อยก็ไม่รู้
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 07, 2019, 09:56:51 AM
16.2. Register Description

16.2.1. Moving Interrupts Between Application and Boot Space (การย้าย  Interrupts ระหว่าง Application Space และ Boot Space)
The MCU Control Register ควบคุมการย้ายตำแหน่งของ the Interrupt Vector table.

(ส่วน MCU Control Register ก็ไปดูที่ Atmega328P Datasheet 14. PM - Power Management and Sleep Modes แถวที่ 6 เอานะ ก็ตัวเดียวกัน ก็แปลแล้ว)   
                              http://www.electoday.com/index.php/topic,15922.40.html (http://www.electoday.com/index.php/topic,15922.40.html)
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 07, 2019, 01:19:35 PM
โปรแกรมปกติโดยทั่วไปของเรา ไม่ต้องโปรแกรม BOOTRST Fuse เลย เพราะจะไปย้าย main program ของเราไป Boot Flash Section เลย และ Boot flash size เราก็ตั้งค่าไว้น้อยๆก็ได้ ถ้าเราไม่ได้ใช้ Boot section

(https://i.imgur.com/s1cF1MI.png)

พอเราตั้งค่าอะไรเสร็จ เราก็ต้องกด program ด้วย mcu ถึงจะรับค่าที่เราตั้งใหม่เข้าไป

แต่โปรแกรม Boot_IVSEL ทำใมถึงทำ INT0 interrupt ไม่ได้นะ ถ้าย้าย interrupt ไป Boot section ก็ยังงงๆอยู่ มันเกี่ยวกับ Boot Lock Bits ด้วยหรือเปล่า

(https://i.imgur.com/uZQSMaW.png)

Boot Lock Bits ก็ดูได้ที่บท 31. MEMPROG- Memory Programming
ส่วนคำสั่งแอสเซมบลี่ SPM (Store Program Memory  or Load Program Memory (LPM) ก็ดูได้ที่บท 36. Instruction Set Summary
ช่วยๆกันตรวจสอบให้หน่อยนะ พวกท่านๆนักโปรแกรมเมอร์ทั้งหลาย ข้าน้อยก็จนปัญญา ไม่งั้นจะข้ามไปเลยนะ ไม่ค่อยจะได้ใช้ใช่ไหมหล่ะ
Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 07, 2019, 03:46:28 PM
อันนี้ลองทำเซทบิท IVSEL ย้าย interrupt ไปยัง boot section แต่ไม่โปรแกรม BOOTRST Fuse ก็สามารถทำงานได้แล้ว แต่จะต้องไม่บีบอัดโปรแกรมเลย คือต้องตั้ง Optimization : -O0 เลย เวลาคอมไพล์ได้ program size = 4258 bytes( 13.0% full) เลย แต่ถ้าบีบอัดโปรแกรมโดยตั้ง Optimization : -Os เวลาคอมไพล์ได้ program size = 330 bytes( 1.0% full) เอง แต่โปรแกรมทำงานไม่ได้ รวมถึงการเซท flag ด้วย ไม่ทำงานเลย เป็นเพราะอะไร ควรตั้งอย่างไรดีครับ

http://www.mediafire.com/file/oahhv06fkt2eyew/Boot_IVSEL_1.rar/file (http://www.mediafire.com/file/oahhv06fkt2eyew/Boot_IVSEL_1.rar/file)

(https://i.imgur.com/QtKHZu0.png)

Title: Re: Atmega328P Datasheet 16. Interrupt
Post by: tha on August 07, 2019, 04:09:27 PM
ลองมาใช้ AVR8 GNU Toolchain จะได้ program size = 1998 bytes( 6.1% full) โดยตั้ง Optimization : -O0 เหมือนกัน ก็ทำงานได้ เล็กกว่ากันครึ่งต่อครึ่งเลย หามาลงกันเลยนะ ไม่รู้มีท่านใดบอกมาไหม ก็ขอขอบคุณมา ณ ที่นี้ด้วยครับ ที่แนะนำมา

(https://i.imgur.com/rwwgyjR.png)

นี่ AVR8 GNU Toolchain
https://www.microchip.com/mplab/avr-support/avr-and-arm-toolchains-c-compilers (https://www.microchip.com/mplab/avr-support/avr-and-arm-toolchains-c-compilers)

นี่ Makefile
http://gnuwin32.sourceforge.net/packages/make.htm (http://gnuwin32.sourceforge.net/packages/make.htm)