Lab 8: Interrupts and Timers
This lab has you re-implement the Button/Switch/LED I/O problem from Lab 7. You will still follow the state machine approach, however you will now use interrupts rather than polling or software delays. In the second task, you will generate a simple repeating waveform using a timer interrupt.
Basics
The folder chap9 of pic24_code_examples contains a number of reinterpretations of the basic ledsw1 state machine problem.
ledsw1_sampling - "Example of implementing a FSM using input sampling"
ledsw1_cn - "Example of implementing a FSM using a timer and change notification interrupt."
ledsw1_cn_revised - "Example of implementing a FSM using a timer and change notification interrupt. Demonstrates the use of events to create an energy-efficient FSM implementation. All of the FSM work is done in the ISR." [1]
Examine them and see how they differ from one another. Build them and load them on your board. Try them out. You should notice that ledsw1_cn does not work properly.
Prelab (20)
Copy the MPLab project chap9/ledsw1_cn_revised into a new project named myledsw1_cn_revised. Save ledsw1_cn_revised.c as myledsw1_cn_revised.c. Remove ledsw1_cn_revised.c from your myledsw1_cn_revised project. Add myledsw1_cn_revised.c to your myledsw1_cn_revised project.
Replace the state names and state strings in myledsw1_cn_revised.c with the ones from your myledsw1.c file.
Replace the cases in the switch statement with your cases from myledsw1.
Build your project. If it does not build, debug the errors.
Prelab Checkoff
myledsw1_cn_revised project created. Contains myledsw1_cn_revised.c file. (5)
State names and state strings replaced. (5)
Cases in switch statement replaced. (5)
Project builds without errors. (5)
Task 1 - Revised State Machine (20)
Upload myledsw1_cn_revised to your board. It probably behaves erratically. It may jump through states, freeze up, and/or not blink right. This is what you need to do to get it running properly:
The print_state function is missing the line(s) that make it print only if the state changes. Fix that. Add those in. You'll need to define e_last_state, but it no longer forces an initial print of the state, so remove that comment. Remove its intial definition as 0xFFFF.
You need to add the output for the initial state and print the initial state string in main. Do this right above the while loop.
If you used any while loops in your switch statement in the last lab, change them to if statements. For example:
while (PB_PRESSED()) {
do something
}
becomes:
do something
if (PB_RELEASED()) {
stop doing the thing
}
Move all (non-blinking) output changes that occur in a particular state to the transition to that state. For example, if the LED is supposed to turn off in PRESSED1, instead of this:
case PRESSED1:
LED1 = 0;
if (PB_RELEASED()) {
...
do this:
case RELEASED1:
if (PB_PRESSED()) {
e_state = PRESSED1;
LED1 = 0;
}
break;
case PRESSED1:
if (PB_RELEASED()) {
...
If there are multiple transitions into a particular state, you need to edit all of them. Don't worry about blinking - you'll do that next.
Replace the DELAY_MS(xxx) software delays that you use to delay between LED blinks in the switch statement with timer3_arm(xxx) where xxx is the number of milliseconds to delay. You should not have to change the delays.
Add an additional timer3_arm(xxx) statement to the transitions to blinking states.
Upload the program to your PIC and test that it works exactly like it should. Take a screenshot of the console output.
TA Checkoff
Your state machine functions properly. Your code contains no software delay functions. The while(1) loop in main contains only IDLE();
Task 2 - Student ID Squarewave (40)
Your MSU student ID is of the form Y1Y2Y3Y4Y5Y6Y7Y8Y9. Take each digit of your student ID, and add ‘1’ to it. Your task is to generate a waveform on an output pin (you pick the output pin) that looks like the following figure:
So how do you do this? Begin with chap9/squarewave. Copy it to a new project called mysquarewave and use Save As to create a new a source file called mysquarewave.c.
1. Create a state machine that has a state for each digit as well as a state for the 15 ms pulse width. Refer to myledsw for an example of how to declare states and define them in the switch statement. You do not need the state strings or a function to print state names. Initialize the state machine to the Y5 state.
2. In each case of the switch statement:
set the PR2 value like this:
PR2 = msToU16Ticks(X, getTimerPrescale(T2CONbits));
where X is the number of milliseconds for that state.
for testing, use outChar to print the state number. In the last state, also output a new line.
3. Call your state machine in the Interrupt Service Routine for Timer2.
4. Build your project and upload to your PIC.
You should see "56789X" scrolling indefinitely in BullyCPP.
5. Connect the oscilloscope and examine the waveform generated to make sure it is correct.
6. At 57600 baud, it takes about 180 us to output one character. This will affect the timing of the waveform, so remove or comment out the outChar statements.
7. Capture a screenshot of your waveform showing all the pulses.
8. Measure and record the width of your 6 pulses.
TA Checkoff
Your waveform displays properly on the scope. Pulse widths are correct.
15.0 ms!
Report
Your report must have a title page
You must textually describe what all your images are showing the reader, like this webpage does. E.g. "Below is a state diagram, showing the states used when implementing my problem." or "Above: Screenshot showing measurement of falling edge time of button press."
Do not invite the grader to inspect values in screenshots, e.g. "Rise time shown below:" Rather, state the value in your report. "The rise time was 280 ns as seen below."
Label the first section Task 1.
Distance Students: You do not need to include anything from the prelab. This task is worth 30 points.
Describe Task 1 so that an outside reader could understand what you did. Mention how your solution differs from that of Lab 7. What benefits does this new method offer?
Update your state diagram to show the outputs on the transitions and any other changes you made. Use the drawing tools in Powerpoint, Word or some other professional drawing program (not MS Paint or the like) to create the diagram – no scanning of hand-drawn diagrams is allowed. Be sure it is correct and accurately depicts the states you used in your program.
Include the screenshot of BullyCPP showing your console output.
Label the second section Task 2.
Distance students: This task is worth 50 points.
Describe Task 2 so that an outside reader could understand what you did.
Include your screenshot of the waveform.
Make a neat (NOT HANDWRITTEN) table showing your measured pulsewidths vs. what they are supposed to be.
Using the formula PR2 = (Timeout period / (clock period x prescaler)) - 1, determine the frequency of the PIC. (The prescaler and timeout period can be found in squarewave.c. PR2 can be found by setting a watch of that variable.) Show your (NOT HANDWRITTEN) calculations. Adequate calculations are demonstrated in Lab 6. Your answer should be about 60 MHz.
Submit your myledsw_cn_revised.c and mysquarewave.c files.
Remove the default boilerplate header above the asterisks.
Be sure the file descriptions atop the files are correct.
Add a header of your own including name, course number, lab number, lab section number, and filename.
Be sure the indentation and spacing is consistent and neat.
Comment your code, especially mysquarewave.c, so that each portion of the program you added is labelled. For example:
// names of the states
or
static state_t e_state = state_y5_9; // initial state
Make sure all existing comments are applicable to the code you are submitting.
If you notice you've made mistakes but the program still somehow runs, fix them.
Build your code and run your programs again to make sure they still work right.
Grading
If you do not successfully complete a task and your report fails to mention or glosses over this fact, you will receive a zero for the report portion of your grade as well as for the task. If you attempt to deceive the grader, e.g. by including screenshots not generated by the code you submitted, your instructor will be notified and you will be recommended for an Honor Code violation.
The report is worth 20 points for neatly and coherently presenting your information to a reader. The following non-exhaustive list of errors will result in losing credit from the report portion of the lab grade:
bad screenshots (not cropped properly, blurry, too small)
text is "lab jargon" unintelligible to an outside reader ("I put the button, LED and switch on." "Here is the screenshots of my task 3 measurements.")
text is phrased as instructions to a second party ("Take current measurements.")
text is copy-pasted from the lab writeup rather than using your own words
text is a literal recap of the activities you performed rather than communicating your results ("First I connected a small piece of wire to the ground clip. Then I inserted it into the ground rail of the breadboard. Next, I attached another small piece of wire to the scope probe...")
blatantly erroneous text ("These screenshots show the amount of voltage flowing through the pushbutton.")
garbled / confusing / gibberish text ("I used Microsoft Excel to builb the program")
using vague or incorrect terminology
excessive text
careless use of pagebreaks that leave blank pages, 1-2 lines of text on a page, etc.
general unprofessional appearance
state diagram is ugly (arrows criss-crossing, bizarrely-sized state shapes, didn't use arrows, etc)
code is untidy
code is missing header or contains default header
code has inaccurate comments
inadequate calculations
handwritten calculations
The tasks are worth 60 points. If your report indicates that you did not successfully complete or do not understand a task, you will lose credit, even if you performed it during the lab. The same is true for tasks performed during the prelab. There are two tasks. The first task is worth 20 points and the second task is worth 40 points. The following non-exhaustive list of errors will result in losing credit from a task:
missing screenshot/diagram/text
screenshot of the wrong thing
screenshot shows incorrect results
cannot read screenshot
state diagram incorrect
handdrawn state diagram
answered questions incorrectly or gave facile answer
calculations wrong
missing/incorrect units in calculations
code won't build
code performs incorrectly
code is convoluted
code uses incorrect methodology; doesn't follow lab directions.
Lab reports that flagrantly violate submission policy (wrong lab, no screenshots, no title page, no text besides headings/labels, mostly blank, code pasted into pdf, paragraphs of lab text pasted in, extremely sloppy/unprofessional, missing code etc.) will not be accepted. The student will receive a zero for the lab and may resubmit with late penalty.
References
[1] B.A. Jones, R. Reese, and JW Bruce, Microcontrollers: From Assembly Language to C Using the PIC24 Family, 2nd ed. Cengage Learning, 2015.