Hey I need some help with C programming used to program a PIC 32 MICRO CONTROLLER. the step 7 files have necessary header and source files .
ECE 2534 ? Homework 4 (60 points)
Timers (recap), Interrupt Service Routines, Advanced Timer Usage
For each problem, write the code that solves the problem in its own .c file. Name your files accordingly:
hw4_problem1.c, hw4_problem2.c, etc. Give consistent names to any header files you produce for the purpose of
completing this assignment.
Submit a zipped archive containing the source code for Problems 1, 2, and 3 and the document containing your
answers for the Comprehension Questions included within the assignment. Use this naming convention for the
archive that you submit:
<Last name>_<First name>_HW4.zip
Replace <Last name> and <First name> by your family name and given name respectively. Problem 1 (16 points)
Recall that the PIC32MX7 microprocessor uses Type A timers (Timer 1) and Type B timers (Timers 2, 3, 4, and 5).
Each of Timers 1 through 5 is a 16-bit timer, but the user can configure two Type B timers (Timers 2 and 3 or
Timers 4 and 5) as a single 32-bit timer. Besides differing in configurability, Type A and Type B timers offer
different pre-scale values.
Write a C routine that uses timer interrupts to update the information contained in an OLED message. Using the
configuration of TMR2 in Lab 1 as a model, configure TMR23 (the 32-bit timer consisting of Type B timers 2 and 3)
to have a period of 1 second. Inside of an infinite-WHILE loop, your code should poll an interrupt flag for TMR23,
increment the value of a second counter when the poll succeeds, and update an OLED message indicating the
number of seconds (here shown as X) that have passed since the beginning of execution.
Time Elapsed =
X seconds The interrupt service routine of the existing Lab 1 code uses one function to get the value of the TMR2 Interrupt
Flag and another to clear the TMR2 interrupt flag. If you open the code and Control-Left Click on one of the
functions in the C file, the header file containing that function will open. (This is a good way to navigate to PLIB
functions ? it also works for things like configuration and option flags.)
Use the Lab 1 code to navigate to the header files timer.h, int.h, and int_5xx_6xx_7xx.h. These header files contain
the TMR2 functions, TMR2 configuration options, interrupt functions, and interrupt source definitions that Lab 1
uses to configure and manage its real-time interrupts. You should be able find the corresponding functions and
configuration options that will allow you to use TMR23.
THIS IS IMPORTANT!
1. When using a 32-bit timer TMRxy, the Cerebot uses the interrupt enable and interrupt flag for TMRy to enable and
monitor interrupts for TMRxy.
2. Even though the flag is called an interrupt flag, it always sets when the value in the Timer Register comes to equal
the value in the Period Register ? even when the user does not enable interrupts. Thus, we can use it in two
different ways: poll the interrupt flag and carry out some behavior when the poll succeeds, or enable interrupts
and have the flag?s occurrence trigger an interrupt service routine containing the behavior.
Your code for Problem 1 should rely on polling an appropriate interrupt flag to increment the count variable. You
should not enable interrupts or write code to serve as an interrupt service routine in this problem. Write your poll
so that it is non-blocking. The OLED routine should not ?wait? for the poll to succeed, but should update
?continuously? in the infinite-WHILE loop that contains the poll.
3. An interrupt flag like the one we are using must be cleared so that it can be reasserted when the system repeats
the behavior that is supposed to assert the flag. This is true even when the processor is not using the flag to trigger
the execution an interrupt service routine. Thus, your poll must clear the flag each time it succeeds.
If you write your code for Problem 1 properly, then your code for Problem 2 will be simple to create. Problem 2 (16 points)
Repeat Problem 1, but use the Lab 1 code as a model for configuring TMR23 to trigger interrupts.
If you wrote it properly, your polling code from Problem 1 will form the basis of your interrupt service routine.
Therefore, you should use the Lab 1 code as a basis for configuring TMR23 and enabling it to trigger interrupts, and
for writing an interrupt service routine that increments the count value on the occurrence of a TMR23 interrupt.
This time, your main routine should only initialize the OLED, configure TMR23 and TMR23 interrupts, and (in an
infinite-WHILE loop) update the OLED message shown in Problem 1.
Remember: when in doubt, control-Left click on a PLIB function or configuration flag to open the header file that
contains it. Look at the documentation for existing code and use it as a model for the code that you must write.
SOMETHING TO THINK ABOUT!
This is a perfect time to start (if you have never done it) or continue (if you have) the process of structuring your
code around functions that perform coherent tasks. Your main function can call these functions instead of having
the code appearing ?naked? in your main routine.
Here are a few examples of function prototypes that I have written to collect related tasks into organized units:
initInterrupts(void); As with other ?wrapper? functions, the job of these functions is to call other peripheral library functions that
perform the desired initialization tasks. The count parameter in the initTimer function serves as the value the
user wants to place into the Period Register of the timer.
Comprehension Questions for Problems 1 and 2 (8 points)
1. In Program 1 (the poll-driven counter), how does the behavior of the program differ when you comment the
?interrupt? acknowledge out of your main routine? Why does this happen?
2. In Program 2 (the interrupt-driven counter), how does the behavior of the program differ when you comment
the interrupt acknowledge out of your interrupt service routine? Why does this happen?
3. If the behavior that results from commenting out the interrupt acknowledge of Program 2 differs from the
behavior that results from doing so in Program 1, explain the difference.
4. Why do you think Programs 1 and 2 used a 32-bit timer instead of a 16-bit timer? (Your answer should focus on
why a 32-bit timer would provide better results or otherwise do something that a 16-bit timer would be
incapable of doing.) Problem 3 (20 points)
One ?inconvenient? factor of using the PIC32MX timer comes in the form of a recommendation that the user not
change the value of the period register while the corresponding timer is on. Thus, if a user wanted to cause the
amount of time measured by a timer to vary at run-time, the user would have to turn off the timer, reconfigure it
with a new period register value, and turn it back on.
Another strategy for modulating the period involves choosing a time base that is much smaller than the range of
periods. If I wanted to perform an action with a period that varied between 0.1 second and 2 seconds, I could
establish a millisecond counter and perform the action once every 100 milliseconds, once every 2000 milliseconds,
or with any period that I could establish. The period of the counter (1 millisecond) remains constant, but the
variable that I am using to ?collect? milliseconds together can vary at run-time and have its value changed by the
occurrence of almost any input I see fit to use.
Write code that will cause a count variable to increment at a variable rate. The default period of the count variable
should be 1 second. When the Cerebot detects a debounced press of BTN 1, the period should decrease by 0.1
second, down to a minimum of 0.1 second. When the Cerebot detects a debounced press of BTN 2, the period
should increase by 0.1 second, up to a maximum of 2 seconds.
Your code should display the following message on the OLED:
BTN 1: Faster
BTN 2: Slower
Y X represents the value of your count variable. Y represents a displayed version of the millisecond counter. When
your code is working properly, you should see that the variance in the incrementing period of X is ?synched? with
the constant 1 millisecond period of Y.
Use the Lab 1 code that configures Timer 2 and configures Timer 2 interrupts as the base for your main routine,
and the interrupt service routine that increments the millisecond count variable as the base for your interrupt
service routine. Your buttons should be non-blocking and debounced; follow the state machine approach that you
used in Homework 3. Review your work in Lab 1 for information on how to use the GPIO functions in ports.h to
configure and read the bits that correspond to BTN1 and BTN2.