Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| learn:courses:unit-2:start [2017/03/16 09:31] – [4. Unit Equipment List] Martha | learn:courses:unit-2:start [2022/10/04 04:38] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Unit 2: Elements of Real-time Systems ====== | ====== Unit 2: Elements of Real-time Systems ====== | ||
| + | [[{}/ | ||
| ==Unit 2 Labs== | ==Unit 2 Labs== | ||
| - | * [[https:// | + | * [[/ |
| - | * [[https:// | + | * [[/ |
| Line 19: | Line 20: | ||
| ===== 2. Objectives: ===== | ===== 2. Objectives: ===== | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| ===== 3. Basic Knowledge: ===== | ===== 3. Basic Knowledge: ===== | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| ===== 4. Unit Equipment List ===== | ===== 4. Unit Equipment List ===== | ||
| ==== 4.1. Hardware ==== | ==== 4.1. Hardware ==== | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| ==== 4.2. Software ==== | ==== 4.2. Software ==== | ||
| The following programs must be installed on your development workstation: | The following programs must be installed on your development workstation: | ||
| - | | + | |
| - | | + | |
| - | | + | |
| ===== 5. Project Takeaways ===== | ===== 5. Project Takeaways ===== | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| Line 62: | Line 63: | ||
| The correct operation of a dynamic real-time scheduling scheme is predicated on two requirements. The first is that the worst case (longest) execution time of the timer interrupt service routine (ISR) must be less than the interrupt interval. The second is that the time remaining in the interrupt period after execution of the ISR must be sufficient so that it appears to the user that the processor is acknowledging his or her inputs in a timely manner. | The correct operation of a dynamic real-time scheduling scheme is predicated on two requirements. The first is that the worst case (longest) execution time of the timer interrupt service routine (ISR) must be less than the interrupt interval. The second is that the time remaining in the interrupt period after execution of the ISR must be sufficient so that it appears to the user that the processor is acknowledging his or her inputs in a timely manner. | ||
| - | Real-time operation has two basic requirements: | + | Real-time operation has two basic requirements: |
| The time required to service the ISR includes the execution time of the user ISR code in addition to the time required to save and restore the system context. Using the MPLAB X Stopwatch debugging feature, we find that it requires 33 machine cycles to save and restore the system context. Using a core frequency of 80 MHz, the context saving and restoring time is 1.03 μs. The time to execute the user written code varies. In the case of Labs 2a and 2b, execution of the ISR code will vary based upon the conditional execution of the LED and stepper motor functions. | The time required to service the ISR includes the execution time of the user ISR code in addition to the time required to save and restore the system context. Using the MPLAB X Stopwatch debugging feature, we find that it requires 33 machine cycles to save and restore the system context. Using a core frequency of 80 MHz, the context saving and restoring time is 1.03 μs. The time to execute the user written code varies. In the case of Labs 2a and 2b, execution of the ISR code will vary based upon the conditional execution of the LED and stepper motor functions. | ||
| + | |||
| ---- | ---- | ||
| - | ===== 7. Real-time Operating Systems | + | ===== 7. Background Information ===== |
| + | ==== 7.1. Real-time Operating Systems ==== | ||
| “An operating system (OS) is [[https:// | “An operating system (OS) is [[https:// | ||
| Line 78: | Line 81: | ||
| Although there are different approaches to task switching, the two easiest are cooperative and preemptive. When using the cooperative scheduling approach, each task willingly gives up running its computer code to allow another task to run. To be effective, all tasks must work together “nicely” such that all tasks have an opportunity to meet their time deadlines. Each task is responsible for determining when it is time to switch tasks. The various tasks managed using a cooperative multitasking scheme are scheduled in a [[https:// | Although there are different approaches to task switching, the two easiest are cooperative and preemptive. When using the cooperative scheduling approach, each task willingly gives up running its computer code to allow another task to run. To be effective, all tasks must work together “nicely” such that all tasks have an opportunity to meet their time deadlines. Each task is responsible for determining when it is time to switch tasks. The various tasks managed using a cooperative multitasking scheme are scheduled in a [[https:// | ||
| - | ==== 7.1. Preemption | + | === 7.1.1. Preemption === |
| “In computing, preemption is the act of temporarily interrupting a task being carried out by a computer system, without requiring its cooperation, | “In computing, preemption is the act of temporarily interrupting a task being carried out by a computer system, without requiring its cooperation, | ||
| In software, a task is a basic unit of programming that has a constrained, | In software, a task is a basic unit of programming that has a constrained, | ||
| - | ==== 7.2. Task Scheduling | + | |
| + | === 7.1.2. Task Scheduling === | ||
| Task scheduling for preemptive multitasking requires the use of one or more interrupts to determine when each task is to be executed. These interrupts can be based on external events, such as a communications message, or internal events, such as a timer clock. Typically, real-time systems use both cooperative and preemptive scheduling to implement what’s called [[https:// | Task scheduling for preemptive multitasking requires the use of one or more interrupts to determine when each task is to be executed. These interrupts can be based on external events, such as a communications message, or internal events, such as a timer clock. Typically, real-time systems use both cooperative and preemptive scheduling to implement what’s called [[https:// | ||
| Line 89: | Line 93: | ||
| In Unit 1, the order in which tasks were started and completed was strictly controlled by the order in which code was executed in the program. In this unit, we will investigate the concept of altering program code execution using [[http:// | In Unit 1, the order in which tasks were started and completed was strictly controlled by the order in which code was executed in the program. In this unit, we will investigate the concept of altering program code execution using [[http:// | ||
| - | As illustrated in Fig. 7.1, an __interrupt__ | + | As illustrated in Fig. 7.1, an [[http:// |
| {{ : | {{ : | ||
| //Figure 7.1. PIC32 interrupt handler block diagram.// | //Figure 7.1. PIC32 interrupt handler block diagram.// | ||
| - | The three main types of interrupts are software, internal hardware, and external hardware. Software and internal hardware interrupts that are initiated by some event inside the microprocessor are also commonly referred to as exceptions or traps. Software interrupts are explicitly internally triggered by instructions within the current program, commonly referred to as __trap instructions__. Internally generated hardware interrupts triggered by timers, analog converters, serial communications, | + | The three main types of interrupts are software, internal hardware, and external hardware. Software and internal hardware interrupts that are initiated by some event inside the microprocessor are also commonly referred to as exceptions or traps. Software interrupts are explicitly internally triggered by instructions within the current program, commonly referred to as [[http:// |
| - | === 7.3.1. Context === | + | === 7.1.3.1. Context === |
| The [[http:// | The [[http:// | ||
| Line 103: | Line 108: | ||
| [[https:// | [[https:// | ||
| - | === 7.3.2. Managing Interrupts === | + | |
| - | Preemptive programs usually consist of two types of tasks: | + | === 7.1.3.2. Managing Interrupts === |
| + | Preemptive programs usually consist of two types of tasks: foreground and background. Foreground tasks are those preemptive tasks that the processor executes as soon as the need arises in response to an interrupt. Interrupts are assigned priority levels that dictate the order in which interrupts will be serviced. In the case of multiple foreground tasks both needing service at the same time, the higher the interrupt priority, the sooner the microprocessor executes the code to service that interrupt. Code executed immediately following a power-up reset runs at priority level zero and has no preemptive capability. This initial background task is responsible for setting up the resources for tasks that will eventually run as foreground tasks. | ||
| Foreground tasks have preemptive capability by having higher priorities than background tasks. The foreground task ensures adequate response times, while the background task manages deferred processing of the foreground data. Background tasks are those that the processor executes whenever it has available time and is waiting for something more important to do. Background tasks generally run at the interrupt priority level zero within a //while(1) { … }// program loop, where event detection by polling flags and pins is common. Interrupt only systems, which are those that only have foreground processes, respond quickly to both periodic and sporadic events but ignore potential work that can be allocated to a background process. The use of interrupts falls under the broad category of [[https:// | Foreground tasks have preemptive capability by having higher priorities than background tasks. The foreground task ensures adequate response times, while the background task manages deferred processing of the foreground data. Background tasks are those that the processor executes whenever it has available time and is waiting for something more important to do. Background tasks generally run at the interrupt priority level zero within a //while(1) { … }// program loop, where event detection by polling flags and pins is common. Interrupt only systems, which are those that only have foreground processes, respond quickly to both periodic and sporadic events but ignore potential work that can be allocated to a background process. The use of interrupts falls under the broad category of [[https:// | ||
| - | There are two types of preemptive operating schemes: nested and non-nested. Nested interrupt schemes allow higher priority level interrupts to preempt code that is servicing a lower priority interrupt. A non-nested interrupt scheme completes the execution of the code currently servicing an interrupt before it begins to service the code for any interrupt awaiting service, regardless of interrupt priorities. | + | There are two types of preemptive operating schemes: nested and non-nested. Nested interrupt schemes allow higher priority level interrupts to preempt code that is servicing a lower priority interrupt. A non-nested interrupt scheme completes the execution of the code currently servicing an interrupt before it begins to service the code for any interrupt awaiting service, regardless of interrupt priorities. |
| + | |||
| Non-nested preemptive schemes are usually easier to manage, but they can result in priority inversion, where a low priority task blocks a higher priority task from running. This scheme is easier to manage because the developer only has to focus on one ISR, and the operation that determines which interrupts to service resembles the process of polling, i.e., constantly checking to see if a specific event has occurred, which we did in Lab 1b. For non-nested interrupt schemes, we must individually check the flags set by the interrupting event to determine which event to service. All interrupts are assigned to priority level 1 and are vectored (sent) to the same ISR where the particular interrupt flag must be cleared. For multiple simultaneous interrupts, tasks are serviced in the order that the interrupt flags are polled. A non-nested priority scheme results whenever interrupts are enabled using the instruction // | Non-nested preemptive schemes are usually easier to manage, but they can result in priority inversion, where a low priority task blocks a higher priority task from running. This scheme is easier to manage because the developer only has to focus on one ISR, and the operation that determines which interrupts to service resembles the process of polling, i.e., constantly checking to see if a specific event has occurred, which we did in Lab 1b. For non-nested interrupt schemes, we must individually check the flags set by the interrupting event to determine which event to service. All interrupts are assigned to priority level 1 and are vectored (sent) to the same ISR where the particular interrupt flag must be cleared. For multiple simultaneous interrupts, tasks are serviced in the order that the interrupt flags are polled. A non-nested priority scheme results whenever interrupts are enabled using the instruction // | ||
| Line 120: | Line 126: | ||
| See the [[http:// | See the [[http:// | ||
| - | === 7.3.3. General Interrupt Code Requirements === | + | === 7.1.3.3. General Interrupt Code Requirements === |
| There are four essential code elements required for a program to process interrupts using C: the declaration of the functions that will be used to service the interrupts, the code to initialize the resources that generate the interrupt, the ISR code that will be executed in response to an interrupt, and the instructions that enable interrupts in a global sense. There must be a specific ISR to handle each enabled interrupt, including the instruction to clear the specific interrupt flag. Failing to clear the interrupt will cause the processor to repeatedly execute the ISR, thus preventing the processor from executing any other application code. | There are four essential code elements required for a program to process interrupts using C: the declaration of the functions that will be used to service the interrupts, the code to initialize the resources that generate the interrupt, the ISR code that will be executed in response to an interrupt, and the instructions that enable interrupts in a global sense. There must be a specific ISR to handle each enabled interrupt, including the instruction to clear the specific interrupt flag. Failing to clear the interrupt will cause the processor to repeatedly execute the ISR, thus preventing the processor from executing any other application code. | ||
| Line 126: | Line 132: | ||
| In this project, two different interrupts will be generated: Timer 1 interrupt and an I/O pin change notice interrupt. The programming requirements for each of these two interrupts are discussed below. The two statements in Listing 7.1 apply to all interrupts and should be executed only once after all resources that are to generate an interrupt have been initialized. In this instance, the program is using multi-vectored interrupts. Selected segments of the code used in an application can be protected from preemption by any and all interrupts by bracketing the code segment with the instructions // | In this project, two different interrupts will be generated: Timer 1 interrupt and an I/O pin change notice interrupt. The programming requirements for each of these two interrupts are discussed below. The two statements in Listing 7.1 apply to all interrupts and should be executed only once after all resources that are to generate an interrupt have been initialized. In this instance, the program is using multi-vectored interrupts. Selected segments of the code used in an application can be protected from preemption by any and all interrupts by bracketing the code segment with the instructions // | ||
| + | |||
| ---- | ---- | ||
| Line 139: | Line 146: | ||
| ---- | ---- | ||
| - | ==== 7.4. Microprocessor Timers and Counters ==== | + | ==== 7.2. Microprocessor Timers and Counters ==== |
| - | Counter/ | + | Counter/ |
| The core timer and Timers 1 through 5 can be used to create blocking delays that are similar to the software delay presented in Lab 1b and shown again here in Listing 7.2. The advantages of a software time delay based on CPU execution speed, as shown here in Listing 7.2, are as follows: | The core timer and Timers 1 through 5 can be used to create blocking delays that are similar to the software delay presented in Lab 1b and shown again here in Listing 7.2. The advantages of a software time delay based on CPU execution speed, as shown here in Listing 7.2, are as follows: | ||
| Line 199: | Line 206: | ||
| ---- | ---- | ||
| - | === 7.4.1. Timer Interrupts === | + | === 7.2.1. Timer Interrupts === |
| In the following labs, we will use Timer 1 to control the task execution timing so that the rotor of the stepper motor spins at a constant speed. The two instructions shown in Listing 7.4 will cause the Timer 1 interrupt flag to be set every tenth of a millisecond, | In the following labs, we will use Timer 1 to control the task execution timing so that the rotor of the stepper motor spins at a constant speed. The two instructions shown in Listing 7.4 will cause the Timer 1 interrupt flag to be set every tenth of a millisecond, | ||
| Line 231: | Line 238: | ||
| // Listing 1. | // Listing 1. | ||
| } | } | ||
| - | |||
| </ | </ | ||
| Line 239: | Line 245: | ||
| The code shown in Listing 7.6 illustrates how to declare a function to be an ISR and the general format of an ISR function. For this example, the parameter //IPL2// sets the Timer 1 interrupt level to 2. This method of declaring an ISR eliminates the requirement of a function prototype. | The code shown in Listing 7.6 illustrates how to declare a function to be an ISR and the general format of an ISR function. For this example, the parameter //IPL2// sets the Timer 1 interrupt level to 2. This method of declaring an ISR eliminates the requirement of a function prototype. | ||
| + | |||
| ---- | ---- | ||
| Line 244: | Line 251: | ||
| ==== Listing 7.6. Timer 1 ISR at Interrupt Level 2 ==== | ==== Listing 7.6. Timer 1 ISR at Interrupt Level 2 ==== | ||
| < | < | ||
| - | void __ISR(_TIMER_1_VECTOR, | + | void __ISR(_TIMER_1_VECTOR, |
| { | { | ||
| Line 257: | Line 264: | ||
| ---- | ---- | ||
| - | ==== 7.5. Change Notification Interrupts ==== | + | ==== 7.3. Change Notification Interrupts ==== |
| - | A change notification (CN) interrupt indicates that an input pin has changed level from a high to low or low to high. All of the PIC32MX370 IO pins are capable of generating a CN interrupt, except for RF6. All of the CN interrupts are vectored to the same ISR, thus requiring polling the CN status registers, CNSTATA through CNSTATG, to determine which pin or pins are responsible for generating the CN interrupt. The code in Listing 7.6 will initialize BTNC on the Basys MX3A trainer board to generate a change notification interrupt at group level 1, sub group level 2. Listing 7.8 provides the code for the CN interrupt service routine. | + | A change notification (CN) interrupt indicates that an input pin has changed level from a high to low or low to high. All of the PIC32MX370 IO pins are capable of generating a CN interrupt, except for RF6. All of the CN interrupts are vectored to the same ISR, thus requiring polling the CN status registers, CNSTATA through CNSTATG, to determine which pin or pins are responsible for generating the CN interrupt. The code in Listing 7.6 will initialize BTNC on the Basys MX3 trainer board to generate a change notification interrupt at group level 1, sub group level 2. Listing 7.8 provides the code for the CN interrupt service routine. |
| ---- | ---- | ||
| Line 306: | Line 313: | ||
| A [[https:// | A [[https:// | ||
| - | As an example, consider a simple momentary contact push button that you want to operate in a push-on / push-off fashion. Although the button is in the on condition only while being pressed, we want a system that remembers that it was pressed and maintains the “on” condition. When the button is pressed the next time, we want the on condition to be remembered so the output will transition to the “off” condition. Figure 7.2 is a state diagram representation of the push-on / push-off operation. Although there are many variations to the actual drawing of a state diagram, we will use one that follows the [[http:// | + | As an example, consider a simple momentary contact push button that you want to operate in a push-on / push-off fashion. Although the button is in the on condition only while being pressed, we want a system that remembers that it was pressed and maintains the “on” condition. When the button is pressed the next time, we want the on condition to be remembered so the output will transition to the “off” condition. Figure 7.2 is a state diagram representation of the push-on / push-off operation. Although there are many variations to the actual drawing of a state diagram, we will use one that follows the [[http:// |
| - | + | ||
| Each rounded box in Fig. 7.2 represents a stable state and each directed arrow represents a transition between states. The circle containing the uppercase letter “I” is the initial conditions and is directed to the initial state. Each state is identified by name or number above the horizontal line. The actions ascribed to the state are described below the line. The state action is divided into two actions separated by a colon. The left action declares the action generated on entry to the state. The action to the right of the colon declares the action generated on exit from the state. | Each rounded box in Fig. 7.2 represents a stable state and each directed arrow represents a transition between states. The circle containing the uppercase letter “I” is the initial conditions and is directed to the initial state. Each state is identified by name or number above the horizontal line. The actions ascribed to the state are described below the line. The state action is divided into two actions separated by a colon. The left action declares the action generated on entry to the state. The action to the right of the colon declares the action generated on exit from the state. | ||
| Transitions describe both events (triggers) with guards and actions associated with the transaction. Guards represent conditions that inhibit the transaction. There may be multiple transitions between the same two states. Each path represents differing guard conditions and differing transaction actions. | Transitions describe both events (triggers) with guards and actions associated with the transaction. Guards represent conditions that inhibit the transaction. There may be multiple transitions between the same two states. Each path represents differing guard conditions and differing transaction actions. | ||
| - | {{ : | + | {{ : |
| //Figure 7.2. State diagram for a push-on / push-off button operation.// | //Figure 7.2. State diagram for a push-on / push-off button operation.// | ||
| - | The button action described by Fig. 7.2 shows that four states are required to represent its operation: two states are needed for a button press and release when the switch is on, as well as when the switch is off. There is only one possible event that initiates a transition: the clock event, which for this example is a millisecond timer. The number of clock pulses is counted to hold the system in a fixed state until the predefined delay period has expired. This is used to eliminate multiple transitions due to [[http:// | + | The button action described by Fig. 7.2 shows that four states are required to represent its operation: two states are needed for a button press and release when the switch is on, as well as when the switch is off. There is only one possible event that initiates a transition: the clock event, which for this example is a millisecond timer. The number of clock pulses is counted to hold the system in a fixed state until the predefined delay period has expired. This is used to eliminate multiple transitions due to [[http:// |
| The guard condition on the clock event inhibits the transition between states unless the button is in the proper pressed or released condition. The action associated with the transaction controls an LED to indicate the condition of the push-on/ | The guard condition on the clock event inhibits the transition between states unless the button is in the proper pressed or released condition. The action associated with the transaction controls an LED to indicate the condition of the push-on/ | ||
| - | [[https:// | + | [[https:// |
| ---- | ---- | ||
| Line 336: | Line 343: | ||
| { | { | ||
| case 0: | case 0: | ||
| - | if(button) / | + | if(button) / |
| { | { | ||
| | | ||
| Line 393: | Line 400: | ||
| The main component of such a timing system is a free running binary counter. The counter increments with each incoming timing pulse. The counter counts continuously from 0 to 2n-1, where n is the number of bits in the counter. Since it runs independently, | The main component of such a timing system is a free running binary counter. The counter increments with each incoming timing pulse. The counter counts continuously from 0 to 2n-1, where n is the number of bits in the counter. Since it runs independently, | ||
| - | ==== Watchdog Timer ==== | + | ==== A.1. Watchdog Timer ==== |
| - | A __watchdog timer__ | + | A [[https:// |
| - | ==== The Core Timer ==== | + | ==== A.2. The Core Timer ==== |
| - | Unlike 8 and 16-bit Microchip PIC processors, the PIC32 processor that uses the MIPS32® M4K® core has a core timer that keeps time using the 32-bit MIPS32 internal register 9 named “Count.” Although infrequently used, the [[http:// | + | Unlike 8- and 16-bit Microchip PIC processors, the PIC32 processor that uses the MIPS32® M4K® core has a core timer that keeps time using the 32-bit MIPS32 internal register 9 named “Count.” Although infrequently used, the [[http:// |
| ---- | ---- | ||
| Line 403: | Line 410: | ||
| ==== Listing A.1. Millisecond Delay Based on Polling the Core Timer ==== | ==== Listing A.1. Millisecond Delay Based on Polling the Core Timer ==== | ||
| < | < | ||
| - | #define CORE_MS_TICK_RATE CORE_OSCILLATOR_FREQUERNCY/2/1000 | + | #define CORE_MS_TICK_RATE CORE_OSCILLATOR_FREQUENCY/2/1000 |
| void msDelay(unsigned int mS) | void msDelay(unsigned int mS) | ||
| { | { | ||
| Line 415: | Line 422: | ||
| Refer to Section 2.12 of the [[http:// | Refer to Section 2.12 of the [[http:// | ||
| - | {{ : | + | {{ : |
| //Figure A.1. Core timer block diagram.// | //Figure A.1. Core timer block diagram.// | ||
| - | + | ==== A.3. Types of Timers ==== | |
| - | ==== Types of Timers ==== | + | |
| [[http:// | [[http:// | ||
| Timers 1 through 5 are 16-bit timers which support both synchronous external timer modes of operation. Timer 1 also allows asynchronous external mode which enables operations during sleep mode when the master oscillator is turned off and controller operation is done using a secondary oscillator. | Timers 1 through 5 are 16-bit timers which support both synchronous external timer modes of operation. Timer 1 also allows asynchronous external mode which enables operations during sleep mode when the master oscillator is turned off and controller operation is done using a secondary oscillator. | ||
| - | {{ : | + | {{ : |
| //Figure A.2. Simplified PIC32 timer block diagram.// | //Figure A.2. Simplified PIC32 timer block diagram.// | ||
| Line 429: | Line 435: | ||
| The clock source for Timers 1 through 5 can be an external input or the peripheral clock. The external input for Timer 1 is the output from the secondary oscillator. All timers can be gated by software that generates a timing window. | The clock source for Timers 1 through 5 can be an external input or the peripheral clock. The external input for Timer 1 is the output from the secondary oscillator. All timers can be gated by software that generates a timing window. | ||
| + | |||
| - | ==== Determining the Timer Input Clock and Rollover Frequency ==== | + | ==== A.4. Determining the Timer Input Clock and Rollover Frequency ==== |
| - | The maximum counter value is determined by the size of the register that holds the counts. Common sizes for microprocessors are 8, 16, and 32-bit. Including the core timer, | + | The maximum counter value is determined by the size of the register that holds the counts. Common sizes for microprocessors are 8-, 16-, and 32-bit. Including the core timer, the PIC32 processor has six timers that can be used for delay timing. The core timer is 32 bits wide. Timers 2 and 3 along with Timers 4 and 5 can be used together as 32-bit counters, respectively, |
| - | The period register is used to set the timer’s maximum count. If a period equal to a value of N is set, then N-1 is written to the PR register. The period registers are declared as PR1 for Timer 1, PR2 for Timer 2, and so on. Each Timer 1 count is compared to the value of the PR1 register. When the PR1 register equals the Timer 1 register, the timer has reached its terminal count and initiates two actions: first, the Timer 1 register is reset to zero, and second, the Timer 1 Interrupt Flag (T1IF) bit is set in the Interrupt Flag Status register (IFS0). (See the [[http:// | + | The period register is used to set the timer’s maximum count. If a period equal to a value of N is set, then N-1 is written to the PR register. The period registers are declared as PR1 for Timer 1, PR2 for Timer 2, and so on. Each Timer 1 count is compared to the value of the PR1 register. When the PR1 register equals the Timer 1 register, the timer has reached its terminal count and initiates two actions: first, the Timer 1 register is reset to zero, and second, the Timer 1 Interrupt Flag (T1IF) bit is set in the Interrupt Flag Status register (IFS0). (See the [[http:// |
| - | As Fig. A.3 illustrates, | + | As Fig. A.3 illustrates, |
| $$T1CLK = (XTAL * FPLLMUL / ( FPLLIDIV * FPLLODIV * FPBDIV )) / TCKPS) | $$T1CLK = (XTAL * FPLLMUL / ( FPLLIDIV * FPLLODIV * FPBDIV )) / TCKPS) | ||
| - | {{ : | + | {{ : |
| //Figure A.3. Divider chain from the CPU crystal (oscillator) to the Timer 1 Interrupt flag.// | //Figure A.3. Divider chain from the CPU crystal (oscillator) to the Timer 1 Interrupt flag.// | ||
| - | Since the Timer 1 register is reset to zero, the value set into the PR register is one less than the desired number of Timer 1 clock counts. Hence, the rate that the timer interrupt flag is set equals the timer clock frequency divided by the value written to the PR register, as expressed by Eq. 2. For example, using the values shown in Fig. A.4, the T1PS is set for 8 and the PR1 register is set to 24999. The result of these settings is that the T1 interrupt flag is set at the rate of 50 Hz, provided that the subsequent interrupt flag is cleared in software. The T1IF can be polled or used to generate interrupts. Timers 2 through 5 are similar to Timer 1, with the differences being the timer pre-scale options and the period register. | + | Since the Timer 1 register is reset to zero, the value set into the PR register is one less than the desired number of Timer 1 clock counts. Hence, the rate that the timer interrupt flag is set equals the timer clock frequency divided by the value written to the PR register, as expressed by Eq. 2. For example, using the values shown in Fig. A.3, the T1PS is set for 8 and the PR1 register is set to 24999. The result of these settings is that the T1 interrupt flag is set at the rate of 50 Hz, provided that the subsequent interrupt flag is cleared in software. The T1IF can be polled or used to generate interrupts. Timers 2 through 5 are similar to Timer 1, with the differences being the timer pre-scale options and the period register. |
| - | ==== Timer Interrupts ==== | + | ==== A.5. Timer Interrupts ==== |
| Once the timer interrupt flag is set, it will remain set until a software instruction clears the flag. (Since the timer interrupt has not been enabled, although the timer interrupt flag is set, no interrupt will be generated. Thus, all peripherals that can potentially be used to generate an interrupt can also be used in a polled mode.) | Once the timer interrupt flag is set, it will remain set until a software instruction clears the flag. (Since the timer interrupt has not been enabled, although the timer interrupt flag is set, no interrupt will be generated. Thus, all peripherals that can potentially be used to generate an interrupt can also be used in a polled mode.) | ||
| [[http:// | [[http:// | ||
| + | |||
| < | < | ||
| Line 455: | Line 463: | ||
| The arguments to this procedure are defined in timers.h of the peripheral library. The timer interrupt flag is polled using the macro statement, // | The arguments to this procedure are defined in timers.h of the peripheral library. The timer interrupt flag is polled using the macro statement, // | ||
| - | The PR register for the timers can be changed within the software at any time by simply using the assignment: //PRx = ###//; or // | + | The PR register for the timers can be changed within the software at any time by simply using the assignment: //PRx = ###;// or // |
| ---- | ---- | ||
| Line 476: | Line 485: | ||
| * | * | ||
| * Oscillator Configuration Bit Settings: config_bits.h | * Oscillator Configuration Bit Settings: config_bits.h | ||
| - | * Basys MX3 hardware initialization is provided by Hardware_Setup.c | + | * Basys MX3 hardware initialization is provided by hardware.c and should be included as a project source file. |
| * Notes: | * Notes: | ||
| * - Peripheral clock: BPCLK = FOSC/PB_DIV = 80E6/8 = 10MHz | * - Peripheral clock: BPCLK = FOSC/PB_DIV = 80E6/8 = 10MHz | ||
| * - Timer 1 clock = T1_CLK = PBCLK / T1PS = 10E6 / 8 = 1.25E5 | * - Timer 1 clock = T1_CLK = PBCLK / T1PS = 10E6 / 8 = 1.25E5 | ||
| - | * - To generate a 1 ms delay, PR1 is loaded with T1_TICK = (10000-1) = 9999 | + | * - To generate a 1 ms delay, PR1 is loaded with T1_TICK |
| * | * | ||
| ********************************************************************/ | ********************************************************************/ | ||
| - | #include " | ||
| #include < | #include < | ||
| + | #include " | ||
| + | #include " | ||
| /* Application constant */ | /* Application constant */ | ||
| Line 497: | Line 507: | ||
| /* Configure Timer1 to roll over once each second */ | /* Configure Timer1 to roll over once each second */ | ||
| - | | + | |
| while (1) | while (1) | ||
| Line 510: | Line 520: | ||
| | | ||
| - | | + | |
| } /* End of File main.c */ | } /* End of File main.c */ | ||
| </ | </ | ||
| Line 554: | Line 564: | ||
| / | / | ||
| * The purpose of this example code is to demonstrate the use of the Type A | * The purpose of this example code is to demonstrate the use of the Type A | ||
| - | * Timer 1 interrupts to generate a 1 ms delay. | + | * Timer 1 interrupts to generate a 1 second |
| * | * | ||
| * Platform: | * Platform: | ||
| Line 567: | Line 577: | ||
| * | * | ||
| * Oscillator Configuration Bit Settings: config_bits.h | * Oscillator Configuration Bit Settings: config_bits.h | ||
| - | * Basys MX3 hardware initialization is provided by Hardware_Setup.c | + | * Basys MX3 hardware initialization is provided by hardware.c |
| * Notes: | * Notes: | ||
| * - Peripheral Clock: PBCLK = 80E6 / 8 = 10E6 | * - Peripheral Clock: PBCLK = 80E6 / 8 = 10E6 | ||
| Line 574: | Line 584: | ||
| * | * | ||
| ********************************************************************/ | ********************************************************************/ | ||
| + | |||
| + | #include < | ||
| #include " | #include " | ||
| - | # | + | # |
| /* Application constant */ | /* Application constant */ | ||
| - | #define T1_PRESCALE | + | #define T1_PRESCALE |
| - | #define TOGGLES_PER_SEC | + | #define TOGGLES_PER_SEC |
| #define T1_TICK | #define T1_TICK | ||
| Line 608: | Line 620: | ||
| /* Code background tasks */ | /* Code background tasks */ | ||
| | | ||
| - | | + | |
| } /* End of main */ | } /* End of main */ | ||
| Line 615: | Line 627: | ||
| * SYNTAX: | * SYNTAX: | ||
| * KEYWORDS: | * KEYWORDS: | ||
| - | * DESCRIPTION: | + | * DESCRIPTION: |
| * Parameters: | * Parameters: | ||
| * RETURN: | * RETURN: | ||
| Line 631: | Line 643: | ||
| /* End of File main.c | /* End of File main.c | ||
| </ | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | [[{}learn/ | ||
| + | [[{}/ | ||
| + | [[{}/ | ||
| + | [[{}/ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | {{tag> | ||

