Lesson Outline Interrupts Admin Assignment #9 due next lesson

Slides:



Advertisements
Similar presentations
Interrupts, Low Power Modes and Timer A (Chapters 6 & 8)
Advertisements

Chung-Ta King National Tsing Hua University
Real-Time Library: RTX
Chung-Ta King National Tsing Hua University
Interrupts Chapter 8 – pp Chapter 10 – pp Appendix A – pp 537 &
ECE 447 Fall 2009 Lecture 9: TI MSP430 Interrupts & Low Power Modes.
68HC11 Polling and Interrupts
Notes on the ez430-RF2500. Sources
CS4101 嵌入式系統概論 Timers and Clocks 金仲達教授 國立清華大學資訊工程學系 Materials from MSP430 Microcontroller Basics, John H. Davies, Newnes, 2008.
The 8051 Microcontroller and Embedded Systems
CS4101 嵌入式系統概論 Software UART Revisited Prof. Chung-Ta King Department of Computer Science National Tsing Hua University, Taiwan ( Materials from MSP430.
INTERRUPTS PROGRAMMING
Chung-Ta King National Tsing Hua University
LAB 7: WDT+ and Low-Power Optimization
Interrupts. What Are Interrupts? Interrupts alter a program’s flow of control  Behavior is similar to a procedure call »Some significant differences.
A Simple Tour of the MSP430. Light LEDs in C LEDs can be connected in two standard ways. Active high circuit, the LED illuminates if the pin is driven.
OPERATING SYSTEM OVERVIEW. Contents Basic hardware elements.
MSP430 Mixed Signal Microcontroller – Parte 2 Afonso Ferreira Miguel Source: slau056d – Texas instruments.
Khaled A. Al-Utaibi  Interrupt-Driven I/O  Hardware Interrupts  Responding to Hardware Interrupts  INTR and NMI  Computing the.
Lecture 11: TI MSP430 Timers Compare Modes
LAB 8: Program Design Pattern and Software Architecture
13-Nov-15 (1) CSC Computer Organization Lecture 7: Input/Output Organization.
CSNB374: Microprocessor Systems Chapter 5: Procedures and Interrupts.
1 © Unitec New Zealand Interrupt Lecture 6 Date: - 20 Sept, 2011 Embedded Hardware ETEC 6416.
1 Interrupts, Resets Today: First Hour: Interrupts –Section 5.2 of Huang’s Textbook –In-class Activity #1 Second Hour: More Interrupts Section 5.2 of Huang’s.
1 Computer Systems II Introduction to Processes. 2 First Two Major Computer System Evolution Steps Led to the idea of multiprogramming (multiple concurrent.
6-1 Infineon 167 Interrupts The C167CS provides 56 separate interrupt sources that may be assigned to 16 priority levels. The C167CS uses a vectored interrupt.
ECE 447 Fall 2009 Lecture 7: MSP430 Polling and Interrupts.
Embedded Systems Design 1 Lecture Set 8 MCS-51 Interrupts.
CS4101 嵌入式系統概論 Interrupt 金仲達教授 國立清華大學資訊工程學系 ( Materials from MSP430 Microcontroller Basics, John H. Davies, Newnes, 2008 )
CS-280 Dr. Mark L. Hornick 1 Sequential Execution Normally, CPU sequentially executes instructions in a program Subroutine calls are synchronous to the.
UNIT 2. CPUXV2 20-bit addressing User-definable Boot Strap Loader RAM starts at 0x1C00 Beginning of MAIN flash moves according to RAM Vector table starts.
An Introduction to Embedded Systems, and the PIC Microcontroller Lecture 8: Interrupts The aims of this session are to explore the structure and application.
ECE 382 Lesson 32 Lesson Outline Lab 6 Introduction Pulse Width Modulation Capture / Compare Example Lab 6 Tips Admin Lab#6 “prelab” due BOC lesson 33.
Introduction Why low power?
Introduction Why low power?
Architectures of Digital Information Systems Part 1: Interrupts and DMA dr.ir. A.C. Verschueren Eindhoven University of Technology Section of Digital.
ECE 382 Lesson 22 Readings Lesson Outline Writing Clean Code
Lecture 8: TI MSP430 Interrupts, ISRs
8085 Interrupts LAKSHMI.B.E..
CS4101 嵌入式系統概論 Interrupts Prof. Chung-Ta King
CS4101 Introduction to Embedded Systems Lab 6: Low-Power Optimization
68HC11 Interrupts & Resets.
Microprocessor Systems Design I
Lesson Objectives Aims Key Words Interrupt, Buffer, Priority, Stack
CS4101 嵌入式系統概論 Interrupts Prof. Chung-Ta King
Timer and Interrupts.
Chapter 6 General Purpose Input/Output
CS4101 Introduction to Embedded Systems Lab 1: General Purpose IO
Protection of System Resources
Computer Architecture
Prof. Chung-Ta King Department of Computer Science
ECE 3430 – Intro to Microcomputer Systems
Interrupts In 8085 and 8086.
CS4101 嵌入式系統概論 General Purpose IO
Interrupts, Counter and Timers
8259 Chip The Intel 8259 is a family of Programmable Interrupt Controllers (PIC) designed and developed for use with the Intel 8085 and Intel 8086 microprocessors.
ECE 3430 – Intro to Microcomputer Systems
CS4101 Introduction to Embedded Systems Lab 4: Interrupt
* * * * * * * 8051 Interrupts Programming.
Interrupts, Tasks and Timers
Advisor: Prof. Gandhi Puvvada
Interrupts Interrupt is a process where an external device can get the attention of the microprocessor. The process starts from the I/O device The process.
ECE 3430 – Intro to Microcomputer Systems
Lecture 9: TI MSP430 Interrupts & Low Power Modes
Md. Mojahidul Islam Lecturer Dept. of Computer Science & Engineering
Md. Mojahidul Islam Lecturer Dept. of Computer Science & Engineering
CS4101 Introduction to Embedded Systems Lab 2: Basic IO and Timer
Prof. Chung-Ta King Department of Computer Science
MSP430 Clock System and Timer
Presentation transcript:

Lesson Outline Interrupts Admin Assignment #9 due next lesson ECE 382 Lesson 26 Lesson Outline Interrupts Admin Assignment #9 due next lesson

Interrupts What is an interrupt? Why is it better than polling?

Lesson 25 Polling - Example Code Main.c #include <msp430g2553.h> void main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_8MHZ; // Set SMCLK 8 MHz DCOCTL = CALDCO_8MHZ; P1DIR = BIT6; // Set the green LED as an output TACCR0 = 256 - 1; // Set the interval TA0CTL &= ~TAIFG; // Clear any rollover flag TA0CTL |= ID_0 | TASSEL_2 | MC_1; // Important Timer stuff! while(1) { while ((TA0CTL & TAIFG) == 0); // Polling timer flag? Would this be good for pong game? TA0CTL &= ~TAIFG; // Clear rollover flag P1OUT ^= BIT6; // toggle LED } // end infinite loop } Let's examine what's going on here. The first line of code moves r1 (the stack pointer) into r4. The compiler is using r4 as the frame pointer. When you call a function (main() in this case), all of its local variables are allocated on the stack. We call the space on the stack used by a function a stack frame. However, the stack pointer changes as you allocate more variables on the stack. So a variable that was at 4(r1) at one point in your function could later be at 8(r1) if the stack pointer changes. The frame pointer ensures a consistent address for the same variable throughout the function. If we store the address of the base of the stack frame in the frame pointer, each variable will always be stored at the same place relative to the frame pointer - so a variable at 4(r4) will always be accessible at 4(r4). So the first line of code is setting the frame pointer. Next, the compiler adds 2 to the frame pointer. In most functions, the first thing you do is push the frame pointer onto the stack via push r4 - main is the exception. Adding two puts the base of the stack frame below this value, which is what we want. Next, the compiler subtracts two from the stack pointer. This is because we're allocating our int variable on the stack, so we're giving it two bytes. If we allocated two ints, the compiler would subtract 4 from the stack pointer. Our first four instructions are identical to our first sample program. We're setting up the frame pointer and allocating our variable on the stack. Next, we're moving our variable into r15. Remember, our ABI says that the first parameter to a function should be passed in through r15 - so we move our there. Next, we call the recursiveSummation subroutine the compiler has created. Once inside the recursiveSummation subroutine, we push the framePointer onto the stack so we don't destroy it. Then, we establish a new frame pointer and allocate a variable on the stack - just like we did in main. Next, the compiler moves the parameter we passed in r15 into the variable we established. It compares the variable to 1. If it's greater than or equal to 1, we jump to .L3 - the label that holds the code in our else case. We move our parameter into r15 (the register that holds the first parameter we pass to functions), subtract one, and call our recursiveSummation subroutine again. This code is the recursiveSummation(numberToSum - 1) piece of our code. The final instruction adds the current parameter to the result passed back in r15. This code is the return numberToSum + piece of our code. If it's less than 1, we're finished. We move 0 into r15, deallocate our variable from the stack, retrieve the frame pointer we pushed initially, and return. If you're interested in learning more, check out this Wikipedia reading on the Call Stack. After we're done, we'll add 2 to the stack pointer to deallocate int variable since we're done using it.

Lesson 25 Interrupt - Example Code #include <msp430.h> char flag = 0; // global variable to share info between main and ISR void main(void) { WDTCTL = WDTPW|WDTHOLD; // stop the watchdog timer P1DIR |= BIT0|BIT6; // set LEDs to output TA0CTL &= ~(MC1|MC0); // stop timer TA0CTL |= TACLR; // clear TAR TA0CTL |= TASSEL_2; // configure for SMCLK - what's the frequency (roughly)? TA0CTL |= ID_3; // divide clock by 8 - what's the frequency of interrupt? TA0CTL &= ~TAIFG; // clear interrupt flag TA0CTL |= MC_1; // set count mode to continuous TA0CTL |= TAIE; // enable interrupt __enable_interrupt(); // enable maskable interrupts int count = 0; while(1) // do other useful stuff // respond to interrupt if it occurred // flag is global variable used to share information between main and the ISR if (flag) flag = 0; P1OUT ^= BIT0; if (count) P1OUT ^= BIT6; count = 0; } else count++; } Let's examine what's going on here. The first line of code moves r1 (the stack pointer) into r4. The compiler is using r4 as the frame pointer. When you call a function (main() in this case), all of its local variables are allocated on the stack. We call the space on the stack used by a function a stack frame. However, the stack pointer changes as you allocate more variables on the stack. So a variable that was at 4(r1) at one point in your function could later be at 8(r1) if the stack pointer changes. The frame pointer ensures a consistent address for the same variable throughout the function. If we store the address of the base of the stack frame in the frame pointer, each variable will always be stored at the same place relative to the frame pointer - so a variable at 4(r4) will always be accessible at 4(r4). So the first line of code is setting the frame pointer. Next, the compiler adds 2 to the frame pointer. In most functions, the first thing you do is push the frame pointer onto the stack via push r4 - main is the exception. Adding two puts the base of the stack frame below this value, which is what we want. Next, the compiler subtracts two from the stack pointer. This is because we're allocating our int variable on the stack, so we're giving it two bytes. If we allocated two ints, the compiler would subtract 4 from the stack pointer. Our first four instructions are identical to our first sample program. We're setting up the frame pointer and allocating our variable on the stack. Next, we're moving our variable into r15. Remember, our ABI says that the first parameter to a function should be passed in through r15 - so we move our there. Next, we call the recursiveSummation subroutine the compiler has created. Once inside the recursiveSummation subroutine, we push the framePointer onto the stack so we don't destroy it. Then, we establish a new frame pointer and allocate a variable on the stack - just like we did in main. Next, the compiler moves the parameter we passed in r15 into the variable we established. It compares the variable to 1. If it's greater than or equal to 1, we jump to .L3 - the label that holds the code in our else case. We move our parameter into r15 (the register that holds the first parameter we pass to functions), subtract one, and call our recursiveSummation subroutine again. This code is the recursiveSummation(numberToSum - 1) piece of our code. The final instruction adds the current parameter to the result passed back in r15. This code is the return numberToSum + piece of our code. If it's less than 1, we're finished. We move 0 into r15, deallocate our variable from the stack, retrieve the frame pointer we pushed initially, and return. If you're interested in learning more, check out this Wikipedia reading on the Call Stack. After we're done, we'll add 2 to the stack pointer to deallocate int variable since we're done using it. // Flag for continuous counting is TAIFG #pragma vector=TIMER0_A1_VECTOR __interrupt void TIMER0_A1_ISR() { TA0CTL &= ~TAIFG; // clear interrupt flag flag = 1; }

Interrupts What is an interrupt? Why is it better than polling? Polling is inefficient… wastes CPU resources Interrupts can free the processor to do more useful work Interrupts can save power For example: In low-power mode, processor can go to sleep, until the time wakes it up to do something, and then go back to sleep How do interrupts work?

Interrupts How do interrupts work? Initialize interrupt Interrupt Vector Interrupt Service Routine (ISR) Interrupt Flag (clear before use) Interrupt Enable (turn it on) Run normal program Interrupt Occurs !!!! Processor saves its state Jumps to ISR Do ISR work Clear Flag? Restores the state Return to normal program Have you used an interrupt yet?

Interrupts Have you used an interrupt yet? Yes…. RESET RESET mov.w #__STACK_END,SP ; Initialize stackpointer StopWDT mov.w #WDTPW|WDTHOLD,&WDTCTL ; Stop watchdog timer ; ; YOUR CODE ;------------------------------------------------------------------ ; Interrupt Vectors .sect ".reset" ; MSP430 RESET Vector .short RESET What if we didn’t define this interrupt vector? Where are these interrupt vectors located?

Interrupt Vector Table

pp 109 of Blue Book pp 11 of Device Specific

What happens on an Interrupt On Interrupt: Currently executing instruction is completed. PC is pushed onto the stack. SR is pushed onto the stack. Selects highest priority interrupt. If single interrupt, interrupt request flag reset. Multiple interrupts, flag remains set. SR is cleared - terminates low-power mode and disables maskable interrupts. Interrupt vector content loaded into PC. What about preserving other registers? On ISR Completion: Pop SR off stack - restoring previous settings. Pop PC off stack - resume execution at previous point.

Maskable vs Non-maskable Interrupts Remember the Status Register? GIE: General Interrupt Enable Setting this bit Enables maskable interrupts How to control in “C”? __enable_interrupt() __disable_interrupt()  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 Reserved V SCG1 SCG0 OSCOFF CPUOFF GIE N Z C

Interrupt Service Routines (ISRs) #pragma vector=XXXXX_VECTOR __interrupt void XXXXX_ISR(void) { // do some stuff in response to an interrupt } #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) P1IFG &= ~BIT3; // P1.3 IFG cleared P1OUT ^= BIT0; // P1.0 = toggle What if we didn’t clear P1IFG? Caution: Spend as little time as possible inside an ISR!

Using Interrupts: Programmer's Job Initialize Configure subsystem Set parameters to generate the interrupt you're interested in Clear interrupt flag Clear the flag for the interrupt you're interested in Make sure an interrupt isn't generated immediately once you enable it Turn on local switch Set the interrupt enable bit for the interrupt you're interested in Turn on global switch Set the GIE bit in the SR Write ISR Include #pragma vector statement and subroutine itself #pragma vector loads address into interrupt vector table Accomplish task Give interrupt opportunity to occur It might take some time!

Example: P1 Interrupt Go to pp 331 of Family Users Guide. P1IFG Contains flags for each pin specifying whether or not an interrupt has occurred P1IES Selects the edge to trigger on 0 - low-to-high transition 1 - high-to-low transition P1IE Enables / disables the associated interrupt 0 - disabled 1 - enabled

Example Push Button Interrupt char interruptFlag = 0; // global variable? Bad or good? void main(void) { WDTCTL = WDTPW|WDTHOLD; // stop the watchdog timer P1DIR |= BIT0|BIT6; // set LEDs to output P1DIR &= ~BIT3; // set button to input P1REN |= BIT3; // enable internal pull-up/pull-down network P1OUT |= BIT3; // configure as pull-up P1IES |= BIT3; // configure interrupt to sense falling edges P1IFG &= ~BIT3; // clear P1.3 interrupt flag P1IE |= BIT3; // enable the interrupt for P1.3 __enable_interrupt(); // main program loop while (1) { // if (interruptFlag) // respond } #pragma vector=PORT1_VECTOR __interrupt void Port_1_ISR(void) { P1IFG &= ~BIT3; // clear P1.3 interrupt flag P1OUT ^= BIT0|BIT6; // toggle LEDs interruptFlag = 1;

Multiple Push Button Interrupts int main(void) { WDTCTL = WDTPW|WDTHOLD; // stop the watchdog timer P1DIR |= BIT0|BIT6; // set LEDs to output P1DIR &= ~(BIT1|BIT2|BIT3); // set buttons to input P1IE |= BIT1|BIT2|BIT3; // enable the interrupts P1IES |= BIT1|BIT2|BIT3; // config interrupt for falling edges P1REN |= BIT1|BIT2|BIT3; // enable pull-up/pull-down network P1OUT |= BIT1|BIT2|BIT3; // configure as pull-up P1IFG &= ~(BIT1|BIT2|BIT3); // clear flags __enable_interrupt(); while (1) {} return 0; } #pragma vector=PORT1_VECTOR __interrupt void Port_1_ISR(void) { if (P1IFG & BIT1) { P1IFG &= ~BIT1; // clear flag P1OUT ^= BIT6; // toggle LED 2 } if (P1IFG & BIT2) P1IFG &= ~BIT2; // clear flag P1OUT ^= BIT0; // toggle LED 1 if (P1IFG & BIT3) P1IFG &= ~BIT3; // clear P1.3 // interrupt flag P1OUT ^= BIT0|BIT6; // toggle both LEDs

Multiple Push Button Interrupts void main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer P1DIR |= BIT0|BIT6; // set LEDs to output P2DIR &= ~(BIT0|BIT1|BIT3); // set buttons to input P2IE |= BIT0|BIT1|BIT3; // enable the interrupts P2IES |= BIT0|BIT1|BIT3; // config interrupt f/ falling edge P2REN |= BIT0|BIT1|BIT3; // enable pull-up/pull-down network P2OUT |= BIT0|BIT1|BIT3; // configure as pull-up P2IFG &= ~(BIT0|BIT1|BIT3); // clear flags __enable_interrupt(); // main program loop while (1) { // respond } #pragma vector=PORT2_VECTOR __interrupt void Port_2_ISR(void) { if (P2IFG & BIT0) { P2IFG &= ~BIT0; // clear interrupt // flag P1OUT ^= BIT6; // toggle LED 2 } if (P2IFG & BIT1) P2IFG &= ~BIT1; // clear interrupt // flag P1OUT ^= BIT0; // toggle LED 1 if (P2IFG & BIT3) P2IFG &= ~BIT3; // clear P2.3 //interrupt flag P1OUT ^= BIT0|BIT6; // toggle both // LEDs

_____ 𝑐𝑙𝑘𝑠 1𝑥 10 −6 𝑠 × 1 𝑐𝑛𝑡 _____ 𝑐𝑙𝑘𝑠 × 16 𝑚𝑠 1 𝑇𝐴𝑅 𝑟𝑜𝑙𝑙 𝑜𝑣𝑒𝑟 = In-Class Programming Create a C program that utilizes interrupts to Blink the Green LED (i.e. P1.6) using Timer A to create a 16ms delay. Assume SMCLK = 1 MHz, TASSEL_2, ID_2, MC_1, and TAR starts at 0 _____ 𝑐𝑙𝑘𝑠 1𝑥 10 −6 𝑠 × 1 𝑐𝑛𝑡 _____ 𝑐𝑙𝑘𝑠 × 16 𝑚𝑠 1 𝑇𝐴𝑅 𝑟𝑜𝑙𝑙 𝑜𝑣𝑒𝑟 =

Example Timer Interrupt (see lec26.c) int main(void) { WDTCTL = WDTPW|WDTHOLD; // stop the watchdog timer P1DIR |= BIT6; // Set the green LED as an output TA0CCR0 = 0xFFFF; // create a 16mS roll-over period TA0CTL &= ~TAIFG; // clear flag before enabling interrupts = good practice TA0CTL = ID_2 | TASSEL_2 | MC_1 | TAIE; // Use 1:8 presclar off MCLK and enable interrupts _enable_interrupt(); // main program loop while (1) { // if (interruptFlag) // respond } return 0; #pragma vector = TIMER0_A1_VECTOR // This is from the MSP430G2553.h file __interrupt void timerOverflow (void) { P1OUT ^= BIT6; // This provides some evidence that we were in the ISR TA0CTL &= ~TAIFG; // See what happens when you do not clear the flag

3 1 4 5 Timer Block Diagram 2 clks cnts Family User Guide pp 357 clks cnts 4 5 Family User Guide pp 357 Blue Book pp 46