Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
learn:microprocessor:tutorials:pic32-interrupts:start [2017/12/18 20:20] – Marthalearn:microprocessor:tutorials:pic32-interrupts:start [2022/10/04 11:38] (current) – external edit 127.0.0.1
Line 13: Line 13:
  
 ==== Inventory ==== ==== Inventory ====
-  * 1 [[http://store.digilentinc.com/digilent-pro-mx7-pic32-based-embedded-systems-trainer-board/| Digilent Pro MX7]]+  * 1 [[https://digilent.com/shop/digilent-pro-mx7-pic32-based-embedded-systems-trainer-board/| Digilent Pro MX7]]
   * [[http://www.microchip.com/mplab/mplab-x-ide| MPLAB X IDE]]   * [[http://www.microchip.com/mplab/mplab-x-ide| MPLAB X IDE]]
-  * 1 [[http://store.digilentinc.com/pmod-step-stepper-motor-driver/| Pmod STEP]]+  * 1 [[https://digilent.com/shop/pmod-step-stepper-motor-driver/| Pmod STEP]]
   * 1 Stepper Motor (5V – 12V, 25 Ω, unipolar or bi-polar)   * 1 Stepper Motor (5V – 12V, 25 Ω, unipolar or bi-polar)
-  * 1 Logic analyzer or oscilloscope (Digilent [[http://store.digilentinc.com/analog-discovery-100msps-usb-oscilloscope-logic-analyzer-limited-time/| Analog Discovery]] or [[http://store.digilentinc.com/analog-discovery-2-100msps-usb-oscilloscope-logic-analyzer-and-variable-power-supply/| Analog Discovery 2]] recommended)+  * 1 Logic analyzer or oscilloscope (Digilent [[https://digilent.com/reference/test-and-measurement/analog-discovery/start| Analog Discovery]] or [[https://digilent.com/shop/analog-discovery-2-100ms-s-usb-oscilloscope-logic-analyzer-and-variable-power-supply/| Analog Discovery 2]] recommended)
  
 ---- ----
Line 26: Line 26:
 \\ \\
 <html> <html>
-<a href="https://reference.digilentinc.com/learn/microprocessor/tutorials/pmod-step-parts-layout/start" class="btn btn-success" role="button">Pmod STEP Parts Layout</a>+<a href="/learn/microprocessor/tutorials/pmodstep-parts-layout/start" class="btn btn-success" role="button">Pmod STEP Parts Layout</a>
 </html> </html>
 \\ \\
 \\ \\
 <html> <html>
-<a href="https://reference.digilentinc.com/learn/microprocessor/tutorials/pic32-interrupts/start" class="btn btn-success" role="button">PIC32 Interrupts</a>+<a href="/learn/microprocessor/tutorials/pic32-interrupts-appendices/start" class="btn btn-success" role="button">PIC32 Interrupts</a>
 </html> </html>
 \\ \\
Line 114: Line 114:
  
 <html> <html>
-<a href="https://reference.digilentinc.com/learn/microprocessor/tutorials/pic32-interrupts/start" class="btn btn-success" role="button">PIC32 Interrupts</a>+<a href="/learn/microprocessor/tutorials/pic32-interrupts-appendices/start" class="btn btn-success" role="button">PIC32 Interrupts</a>
 </html> </html>
 \\ \\
Line 137: Line 137:
 Change notice (CN) interrupts are generated on selected enabled digital I/O pins whenever the voltage of the pin changes, causing the processor to read a logic value that is different from the previous reading of the PORT register. Pins designated as CN interrupt pins are shown in Table 1. Only BTN1 and BTN2 on the Digilent Pro MX7 processor board have the capability to generate CN interrupts. The I/O pin associated with BTN3 cannot generate a CN interrupt. Change notice (CN) interrupts are generated on selected enabled digital I/O pins whenever the voltage of the pin changes, causing the processor to read a logic value that is different from the previous reading of the PORT register. Pins designated as CN interrupt pins are shown in Table 1. Only BTN1 and BTN2 on the Digilent Pro MX7 processor board have the capability to generate CN interrupts. The I/O pin associated with BTN3 cannot generate a CN interrupt.
  
-^ CN<sub>x</sub> ^^ Port        ^ +^ CNx      |^ Port        ^ 
-| RC13        || RC13        | +| CN0      || RC13        | 
-| RC14        || RC14        | +| CN1      || RC14        | 
-| RB0         || RB0         | +| CN2      || RB0         | 
-| RB1         || RB1         | +| CN3      || RB1         | 
-| RB2         |  RB2         | +| CN4      || RB2         | 
-| RB3         |  RB3         | +| CN5      || RB3         | 
-| RB4         |  RB4         | +| CN6      || RB4         | 
-| RB5         |  RB5         | +| CN7      || RB5         | 
-| RG6 — BTN1  | +| CN8      || RG6 — BTN1  | 
-| RG7 — BTN2  | +| CN9      || RG7 — BTN2  | 
-| RG8         | +| CN10     || RG8         | 
-| RG9         | +| CN11     || RG9         | 
-| RB15        | +| CN12     || RB15        | 
-| RD4         | +| CN13     || RD4         | 
-| RD5         | +| CN14     || RD5         | 
-| RD6         | +| CN15     || RD6         | 
-| RD7         | +| CN16     || RD7         | 
-| RF4         | +| CN17     || RF4         | 
-| RF5         | +| CN18     || RF5         | 
-| N/A         |+| CN19     || N/A         |
  
-{{tag>learn microprocessors tutorial uno32 uc32 max32 debouncing rc-filter resistors capacitors mpide}}+**Table 1. I/O pins with CN interrupt capability.** 
 + 
 +CN interrupts can be disabled to protect segments of code using mCNIntEnable(0); to disable the interrupts and using mCNIntEnable(1); to enable them again . Listing 4 shows how to setup change notice interrupts using peripheral library code macros. In this code, CN interrupts are turned on for CN8 and CN9, which correspond to BTN1 (RG6) and BTN2 (RG7). The last parameter with value zero directs that internal pull-up resistors be disabled, because these pins have external pull-up resistors on the chipKIT Pro MX7 processor board. The code in Listing 4 enable CN interrupts at priority level 1 and sub priority level zero. 
 + 
 +**Listing 4.** Initializing CHANGE NOTICE interrupts. 
 +<code> 
 +/* Declaration of interrupt ISR for CN at interrupt level 1 */ 
 +void cn_interrupt_initialize(void) // This code is executed only once 
 +{ 
 +  
 +// BTN1 and BTN2 pins are set as inputs by including the file  
 +// chipKit_Pro_MX7.h and calling chipKit_Pro_MX7_Setup(); 
 +// PORTSetPinsDigitalIn(BIT_6 | BIT7);  
 +  
 +// Enable CN for BTN1 and BTN2 
 +mCNOpen(CN_ON,(CN8_ENABLE | CN9_ENABLE), 0); 
 +  
 +// Set CN interrupts priority level 1 sub priority level 0 
 +mCNSetIntPriority(1);   // Group priority range: 1 to 7 
 +mCNSetIntSubPriority(0);    // Subgroup priority range: 0 to 3 
 +mCNIntEnable(1);        // Enable T1 interrupts 
 +  
 +// Global interrupts must enabled to complete the initialization. 
 +} 
 +</code> 
 + 
 +A single interrupt vector is used for all CN interrupts. The interrupt does not tell you if the pin went high or low; only that the condition on one of the selected pins has changed. The ISR code must return a type void and have no parameters passed to it. The CN interrupt flag must be cleared prior to exiting the ISR using the instructions mCNClearIntFlag();. 
 + 
 +**Listing 5.** Change Notice interrupt service routine. 
 +<code> 
 +void __ISR(__CHANGE_NOTICE_VECTOR, ipl1) CNIntHandler(void)  
 +{ 
 +/* User ISR code inserted here */ 
 +  
 +/* Required to clear the interrupt flag in the ISR */ 
 +mCNClearIntFlag();      // Macro function 
 +} 
 +</code> 
 + 
 +---- 
 + 
 +===== Project Tasks ===== 
 +This project implements a system that runs entirely using foreground processes. The Timer 1 interrupt is used to generate an interrupt once each millisecond. The PIC32 change notice interrupt generates an interrupt when a button is pressed or released. The project consists of writing a program that meets the specifications listed below: 
 + 
 +<html> 
 +<ol type="1"> 
 +  <li>Functionality for main function.</li> 
 +  <ol type="a"> 
 +  <li>Calls system_init function (see step 2).</li> 
 +  <li>Continuously executes the while(1); statement.</li> 
 +  </ol> 
 +   
 +  <li>Create a system_init function that implements a fully nested interrupt scheme for Timer 1 and change notice interrupts using the following steps.</li> 
 +  <ol type="a"> 
 +  <li>Initialize the processor board using the function chipKit_Pro_MX7_Setup();. This function initializes the PIC32 processor for:</li> 
 +  <ol type="i"> 
 +  <li>Set the I/O PORT B pins for LEDA, LEDB, LEDC, and stepper motor as outputs.</lo> 
 +  <li>Set the I/O PORT G to read the button inputs for BTN1 and BTN2 as inputs.</li> 
 +  </ol> 
 +  <li>Initialize Timer 1 to generate an interrupt once each ms . Set the group priority for level 2 and the subgroup level for 0. (Refer to Listing 2.)</li> 
 +  <li>Initialize the PIC32MX7 system for change notice detection. Set change notice interrupts to detect activity on BTN1 and BTN2 only, the group priority level 1 and the subgroup level 0. (Refer to Listing 4.)</li> 
 +  <li>Set the system for multiple vectored interrupts. (Refer to Listing 1.)</li> 
 +  </ol> 
 +   
 +  <li>Functionality for change_notice_ISR (replaces read_buttons function in Project 4). (Refer to Listing 5.)</li> 
 +  <ol type="a"> 
 +  <li>Set LEDC on at the beginning of the ISR and off at the end of the ISR.</li> 
 +  <li>Call the sw_delay function for 20 ms delay to debounce button contacts.</li> 
 +  <li>Assign port data to the button_status variable.</li> 
 +  <li>Call decode_buttons function with arguments of button status.</li> 
 +  <li>Clear CNIntFLag.</li> 
 +  </ol> 
 +   
 +  <li>Functionality for Timer1_ISR . (Refer to Listing 3.)</li> 
 +  <ol type="a"> 
 +  <li>Set for a 1 ms interval (Refer to Project 4).</li> 
 +  <li>Toggle LEDA.</li> 
 +  <li>Decrement the step_delay variable.</li> 
 +  <li>When step delay is zero:</li> 
 +  <ol type="i"> 
 +  <li>Call stepper_state_machine function.</li> 
 +  <li>Reset step_delay variable to the value stored in the step_period global variable.</li> 
 +  </ol> 
 +  <li>Clear T1IntFlag.</li> 
 +  </ol> 
 +    
 +  <li>Functionality for decode_buttons (Refer to Project 4).</li> 
 +  <ol type="a"> 
 +  <li>Determine values for global variables step_dir, step_mode, and step_period.</li> 
 +  </ol> 
 +   
 +  <li>Functionality for stepper_state_machine (Refer to Project 4).</li> 
 +  <ol type="a"> 
 +  <li>Toggle LEDB.</li> 
 +  <li>Determine stepper motor output signals for step_code (local).</li> 
 +  <li>Call output_to_stepper_motor function with value of step_code.</li> 
 +  </ol> 
 +   
 +  <li>Functionality for output_to_stepper_motor (Refer to Project4).</li> 
 +  <ol type="a"> 
 +  <li>Output step_code to Port B using the read-modify-write sequence.</li> 
 +  </ol> 
 +   
 +  <li>Functionality for sw_delay (Refer to Project 2).</li> 
 +  <ol type="a"> 
 +  <li>Implement a hardware assisted software delay using the core timer that can be preempted.</li> 
 +  <ol> 
 +</ol> 
 +</html> 
 + 
 + 
 +---- 
 + 
 +===== Project Testing ===== 
 +There are significant timing requirements for this project: the Timer 1 interrupt rate, the stepper motor step rate, and the button debounce delay. Table 2 is provided below to assist you in determining where to place the instructions to control the instrumentation LEDs. The red tab above shows where to connect an oscilloscope or logic analyzer to the test points for LEDA through LEDC on the PmodSTEP to instrument this project. An example of a logic analyzer screen capture is shown below in Fig. 1. 
 + 
 +| LED   ^ Operation      ^ When              ^ 
 +| LEDA  | Toggle         | Each millisecond  | 
 +| LEDB  | Toggle         | Each step         | 
 +| LEDC  | SET (on)       | Start of CN ISR   | 
 +| LEDC  | Cleared (off)  | End of CN ISR     | 
 + 
 +**Table 2. Instrumentation LED Operations.** 
 + 
 +{{ :learn:microprocessor:tutorials:pic32-interrupts:oscilloscope-screencap.png?nolink |Figure 1. Screen capture for the instrumentation of Project 5.}} 
 +Figure 1. Screen capture for the instrumentation of Project 5. Screenshot of Digilent WaveForms running on Microsoft Windows 7. 
 + 
 +---- 
 + 
 +===== Test Your Knowledge! ===== 
 +Now that you've completed this project, you should look at the following questions/problems: 
 + 
 +<html> 
 +<ol type="1"> 
 +<li>Develop a DFD and a CFD for this project.</li> 
 +</br> 
 +<font color="red">ANSWER: The data flow diagram shown in Fig. 2 is essentially the same as it was for Project 3. However, the control flow diagram shown in Fig. 3 now consists of three independent programs. The background code initializes the system. The two foreground processes run as independent programs and run to a termination.</font> 
 +</ol> 
 +</html> 
 +{{ :learn:microprocessor:tutorials:pic32-interrupts:interrupt-dfd.png?nolink&500 |Figure 2. Data flow diagram.}} 
 + 
 +{{ :learn:microprocessor:tutorials:pic32-interrupts:interrupt-cfd.png?nolink&500 |Figure 3. Control flow diagram.}} 
 + 
 +<html> 
 +<ol start="2"> 
 +<li>Explain how the oscilloscope capture required for step 4 demonstrates that your program implements a nested interrupt preemption scheme.</li> 
 +</br> 
 +<font color="red">ANSWER: The signal for LEDC is high during the period that the Change Notice interrupt is being served. The signal for LEDA continues to toggle due to servicing the Timer 1 interrupt. Hence, the timer interrupt is interrupting the Change Notice interrupt.</font> 
 +</br></br> 
 + 
 +<li>What are the requirements that dictate which sections of code must be protected from interrupts?</li> 
 +</br> 
 +<font color="red">Port B is changed in the Timer ISR (changing LEDA and SM1 through SM4) and LEDC is modified in the Change Notice ISR. If the instruction to modify the LEDC bit of Port B is not atomic (meaning that the order of execution cannot be changed), then it would be possible that a Timer 1 interrupt could change the contents of the LATB register in between instructions in the Change Notice ISR. Two of the three conditions needed for requiring protecting code are met: using a global variable (LATB) and modification in two ISR operating at different levels. If the modification of the global variable is not atomic, then the third condition is met and the code will need to be protected.</font> 
 +</br></br> 
 + 
 +<li>What constitutes the worst-case latency for systems that use polling to detect events?</li> 
 +</br> 
 +<font color="red">ANSWER: It is the main function loop time—all functions in the main function while(1) loop must be completed within the required time or some functions will be executed more slowly that the design requires.</font> 
 +</br></br> 
 + 
 +<li>Explain why the stepper motor is potentially running at a more accurate and consistent speed compared to the Project 4 implementation.</li> 
 +</br> 
 +<font color="red">ANSWER: The interrupt that causes the stepper motor to step is at the highest level. The latency is constant and predictable regardless of when the interrupt occurs. Hence the latency between the Timer 1 interrupt and the time when the stepper motor actually steps is always the same.</font> 
 +</br></br> 
 + 
 +<li>Discuss the advantages and disadvantages of polling versus interrupts in real-time control.</li> 
 +</br> 
 +<font color="red">ANSWER: The C code to implement polling is relatively simple to write and verify. The C code to setting up and ISR can be confusing to someone who is unfamiliar with the PIC32 processor. There are no memory requirements to store the processor context. Systems that do not use interrupts are deterministic albeit predictably slow.</font> 
 +</br></br> 
 + 
 +<li>Describe how you would change the Project 5 program to allow you to control the stepper motor at speeds other than those that are multiples of one millisecond.</li> 
 +</br> 
 +<font color="red">ANSWER: Increase the Timer 1 interrupt frequency.</font> 
 +</br></br> 
 + 
 +<li>Why are interrupt service routines restricted so that no variables can be passed to or returned from the function?</li> 
 +</br> 
 +<font color="red">ANSWER: Since one cannot predict when the ISR code will be executed, there is no way to prepare the processor registers to receive or return data. The only means of passing data to and from ISRs is by using global variables.</font> 
 +</br></br> 
 +</ol> 
 +</html> 
 + 
 +{{tag>learn microprocessors tutorial pro-mx7 chipkit-pro pic32 interrupts }}