UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING CMPE13/L: INTRODUCTION TO PROGRAMMING IN C SPRING 2013

Similar documents
Lab 6 - Bouncing LEDs Commit ID Form:

Lab 7 - Toaster Oven Commit ID Form:

Lab 10 - Role-Playing Game

UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING CMPE13/L: INTRODUCTION TO PROGRAMMING IN C SPRING 2011.

UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING CMPE-13/L: COMPUTER SYSTEMS AND C PROGRAMMING WINTER 2014

UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING

By the end of Class. Outline. Homework 5. C8051F020 Block Diagram (pg 18) Pseudo-code for Lab 1-2 due as part of prelab

Lab 5 - Linked Lists Git Tag: Lab5Submission

ECGR 4101/5101, Fall 2016: Lab 1 First Embedded Systems Project Learning Objectives:

Announcements Homework #3 due today. Ports. Outline for Today C8051 SFRs & Port I/O Worksheet #4 - simple I/O code. Using Ports

Lecture test next week

Lab 4 - Linked Lists

ECE 375: Computer Organization and Assembly Language Programming

Microprocessors B (17.384) Spring Lecture Outline

EL6483: Brief Overview of C Programming Language

C Language Programming

12.1. Unit 12. Exceptions & Interrupts

ECE 362 Lab Verification / Evaluation Form Experiment 5

Welcome to Lab! Feel free to get started until we start talking! The lab document is located on the course website:

Embedded programming, AVR intro

MICROPROCESSORS A (17.383) Fall Lecture Outline

Lab 4: Interrupts and Realtime

Microcontrollers and Interfacing week 8 exercises

Timer2 Interrupts. NDSU Timer2 Interrupts September 20, Background:

Project Data: Manipulating Bits

ECE2049 Embedded Computing in Engineering Design. Lab #0 Introduction to the MSP430F5529 Launchpad-based Lab Board and Code Composer Studio

PATTERN SEQUENCER GUIDE

Course Outline Introduction to C-Programming

Arduino Uno. Power & Interface. Arduino Part 1. Introductory Medical Device Prototyping. Digital I/O Pins. Reset Button. USB Interface.

CSCI 2212: Intermediate Programming / C Chapter 15

Using programmed I/O on the M16C; and Writing an Interrupt Service Routine (ISR)

Timer0..Timer3. Interrupt Description Input Conditions Enable Flag

CS401 - Computer Architecture and Assembly Language Programming Glossary By

Welcome to Lab! You do not need to keep the same partner from last lab. We will come around checking your prelabs after we introduce the lab

Ch. 11: References & the Copy-Constructor. - continued -

If you note any errors, typos, etc. with this manual or our software libraries, let us know at

A flow chart is a graphical or symbolic representation of a process.

Chapter 7 Central Processor Unit (S08CPUV2)

Introduction to Internet of Things Prof. Sudip Misra Department of Computer Science & Engineering Indian Institute of Technology, Kharagpur

Lab 3a: Scheduling Tasks with uvision and RTX

Handy Cricket Programming

ENGR 40M Project 3c: Switch debouncing

University of Texas at El Paso Electrical and Computer Engineering Department. EE 3176 Laboratory for Microprocessors I.

CS 051 Homework Laboratory #2

Using peripherals on the MSP430 (if time)

Before Class Install SDCC Instructions in Installing_SiLabs-SDCC- Drivers document. Solutions to Number Systems Worksheet. Announcements.

GO - OPERATORS. This tutorial will explain the arithmetic, relational, logical, bitwise, assignment and other operators one by one.

1 Overview. 2 Basic Program Structure. 2.1 Required and Optional Parts of Sketch

Introduction to C++ with content from

CENG-336 Introduction to Embedded Systems Development. Timers

INTERRUPTS in microprocessor systems

Lab 0 Introduction to the MSP430F5529 Launchpad-based Lab Board and Code Composer Studio

16.317: Microprocessor Systems Design I Fall Exam 3 December 15, Name: ID #:

Why embedded systems?

Beginning C Programming for Engineers

CS 211 Programming Practicum Fall 2018

Introduction to the MC9S12 Hardware Subsystems

Lab 9 Battleboats Commit ID Form:

Cpr E 281 FINAL PROJECT ELECTRICAL AND COMPUTER ENGINEERING IOWA STATE UNIVERSITY. FINAL Project. Objectives. Project Selection

Unit-II Programming and Problem Solving (BE1/4 CSE-2)

Welcome to Lab! Feel free to get started until we start talking! The lab document is located on the course website:

BIL220, Spring 2012 Data Lab: Manipulating Bits Assigned: Feb. 23, Due: Wed., Mar. 8, 23:59PM

I/O handling. Purpose. Seven-segment displays. Digital Systems 15 hp

EECE.2160: ECE Application Programming

University of California at Berkeley College of Engineering Department of Electrical Engineering and Computer Sciences. Spring 2010 May 10, 2010

CprE 288 Introduction to Embedded Systems Exam 1 Review. 1

Laboratory 10. Programming a PIC Microcontroller - Part II

Fundamental of Programming (C)

There are a number of ways of doing this, and we will examine two of them. Fig1. Circuit 3a Flash two LEDs.

C Formatting Guidelines

M.EC201 Programming language

Optimized Scientific Computing:

CS 24: INTRODUCTION TO. Spring 2015 Lecture 2 COMPUTING SYSTEMS

Some Basic Concepts EL6483. Spring EL6483 Some Basic Concepts Spring / 22

Interrupts, timers and counters

Shift and Rotate Instructions

Practical C++ Programming

Introduction to Computers and C++ Programming p. 1 Computer Systems p. 2 Hardware p. 2 Software p. 7 High-Level Languages p. 8 Compilers p.

Interrupt handling. Purpose. Interrupts. Computer Organization

Computers Programming Course 6. Iulian Năstac

Effective Programming in C and UNIX Lab 6 Image Manipulation with BMP Images Due Date: Sunday April 3rd, 2011 by 11:59pm

Embedded Systems - FS 2018

CSCE374 Robotics Fall 2013 Notes on the irobot Create

Review of the syntax and use of Arduino functions, with special attention to the setup and loop functions.

An Introductory Guide to SpecTRM

ECE2049 E17 Lecture 4 MSP430 Architecture & Intro to Digital I/O

CS261: HOMEWORK 2 Due 04/13/2012, at 2pm

Introduction to C++ Introduction. Structure of a C++ Program. Structure of a C++ Program. C++ widely-used general-purpose programming language

In examining performance Interested in several things Exact times if computable Bounded times if exact not computable Can be measured

CS50 Supersection (for those less comfortable)

Functions BCA-105. Few Facts About Functions:

CpSc 1011 Lab 3 Integer Variables, Mathematical Operations, & Redirection

Experiment 3. Interrupts. Hazem Selmi, Ahmad Khayyat

CS201- Introduction to Programming Latest Solved Mcqs from Midterm Papers May 07,2011. MIDTERM EXAMINATION Spring 2010

CpSc 111 Lab 3 Integer Variables, Mathematical Operations, & Redirection

MIDI CPU Firmware V User Manual

Assignment #2: Intro to Java Due: 11AM PST on Wednesday, July 12

CSE101-lec#12. Designing Structured Programs Introduction to Functions. Created By: Amanpreet Kaur & Sanjeev Kumar SME (CSE) LPU

Special Topics for Embedded Programming

C Functions. CS 2060 Week 4. Prof. Jonathan Ventura

Transcription:

Introduction Reading Concepts UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING CMPE13/L: INTRODUCTION TO PROGRAMMING IN C SPRING 2013 Lab 2 Bouncing LEDs In this lab, you will start to work with microcontrollers in C. You will learn about timers and interrupt service routines (ISRs or interrupts for short), which are used heavily in embedded systems. This lab highlights two typical applications: reading sensors and triggering output. Provided files K&R Chapters 1-3, 6.1 CKO Chapters 5.0 5.7 Bit manipulation handout Variable Scope Structs Interrupts Bit manipulation/bit masks Implementing libraries Event-driven programming bounce.c contains main() and other setup code. There is no support for user input or output in this lab. Debugging will require the use of breakpoints. Buttons.h contains an enum with all the possible states of your Button Events: BUTTON_EVENT_NONE, BUTTON_EVENT_3UP, BUTTON_EVENT_3DOWN, etc. Also includes a macro to read the current state of the buttons, as well as prototypes for the two functions you will implement in a Buttons.c file. Leds.h - Defines an interface for interacting with the 8 LEDs on the Explorer 16 board. You will implement this in a Leds.c file. Assignment requirements

Your program should light a single LED (D3-D8) at a time on the development board. This LED will move, starting in one direction and reversing direction upon reaching the end, in essence bouncing back and forth between the D3 and D8 LEDs. This means that LED D9 should ONLY be lit by pressing button S4. o Provided for you is the definition of a struct called "timerresult" and adcresult. Two module-level variables, one of each struct, have been declared for you. These will be used for persistant data storage in the ISRs and for checking for events in main(). o Define the constants LEFT (value: 1) and RIGHT (value: 0) and use them with your while-loop and for the direction of your bouncing LED. o Only update the LEDs every 10 counter increments by checking it in the Timer1 interrupt service routine. The value 10 should never appear as a constant in bounce.c, but rather this value should be stored as a defined constant named TIMER_TRIGGER and that constant should be used instead. o Map the 10-bit ADC input into a full 16-bit range that will be used to alter the timer preload register s (PR1) so that the timer ends up triggered faster as the input gets higher. You may not use arithmetic to do this! Buttons should modify your LEDs in the following ways: o S3 UpEvent toggles LEDs D3 and D4 (Simultaneously) on and off. o S6 UpEvent toggles LEDs D5 and D6 (Simultaneously) on and off. o S5 UpEvent toggles LEDs D7 and D8 (Simultaneously) on and off. o S4 UpEvent toggles LED D9 on and off. o Note that the effects of pressing a button should be independent of the LED bouncing from right to left. If all of the LEDs are toggled on by the buttons, then the bouncing LED should still be changing positions invisibly underneath the toggled LEDs. o Make sure that all data types, variables, macros, etc. that you code for your buttons library are not exposed in the header file. You will not be submitting your header file so any code that relies on it will not work and you will receive a 0 for this part of the lab. Additionally if this causes your code to fail to compile you will receive a 0 for the entire lab so be careful. Also, any global variables in your library

should be declared as static so they are not accessible from outside the library. Implement the Timer1 ISR and within it: o Increment the value member of the struct timerresult by 1. o If value ends up being greater than TIMER_TRIGGER, set the event member to true. Also reset value to 0 if that is the case. o Reset Timer1 s interrupt flag at the end of the interrupt. o Replace the multiline comment above to describe what the function does. Implement the ADC1 ISR o Read the current ADC value. If it is different than the last reading of the ADC, store it in the value member of the adcresult struct and set the value member to true. o Reset the interrupt flag at the end of the interrupt. o Replace the multiline comment above to describe what the function does. Implement the Buttons library in a Buttons.c file o Add comments for your name and any collaborators. o Implement all of the functions described in Buttons.h. These functions provide a more robust and general interface than you'll need to implement bounce.c, but it must be implemented and working anyways! You'll want to write test code to check this. Implement the Leds library in a Leds.c file o Add comments for your name and any collaborators. o Implement all of the functions described in Leds.h. These functions provided a more robust and general interface than you'll need to implement bounce.c, but it must be implemented and working anyways! You'll want to write test code to check this. Document your code! Add inline comments to explain your code. Not every line needs a comment, but instead group your code into coherent sections, like paragraphs in an essay, and give those comments. Add the following to the top of your bounce.c and Buttons.c file as comments: o Your name o The names of colleagues who you have collaborated with Format your code to match the style guidelines that have been provided. Make sure that your code triggers no errors or warnings when compiling. Compilation errors in libraries will result in no credit for that section. Compilation errors in the main file will result in

NO CREDIT. Any compilation warnings will result in two lost points. Submit bounce.c, Buttons.c, and Leds.c. Grading Grading for this lab will be different in that your source files will not necessarily be compiled together. Since part of this assignment entails the creation of libraries, those will be tested independently of your bounce.c file and instead with a program written to test your libraries' functionality. If your libraries aren't properly self-contained or significantly deviate from the specifications you've been given, you may encounter a compilation error. This would result in a significant loss of points. An easy way to prevent this is to only use the libraries in accordance with their descriptions and the functions & variables defined in the header. If you have concerns please ask BEFORE the assignment has been submitted. This assignment again consists of 11 points: 2 points Properly implementing the interrupts 3 points Implementing main() 3 points Correctly implementing the Leds library 2 points Correctly implementing the Buttons library 1 point Style guidelines were followed with < 10 errors You will lose points for the following: If a source file doesn't compile, you'll lose all points that rely on that file -2 points: any compiler warnings -2 points: if gotos were used -2 points: no name or collaborators given at the top of Buttons.c and bounce.c Program flow The ISRs will trigger asynchronously as main() runs, updating the sensor values. Those values will be checked in the main event loop and light the LEDs appropriately. Your program should follow the outline below: initialize leds library initialize buttons library while true: check buttons for events if Button 3 up event: toggle D3 and D4 LEDs in bitmask if Button 6 up event: toggle D5 and D6 LEDs in bitmask

Program input/output if Button 5 up event: toggle D7 and D8 LEDs in bitmask if Button 4 up event: toggle D9 LED in bitmask if timer event: if next LED should be triggered trigger next LED if we re at the last LED reverse direction update LEDs with bitmask and LED position if ADC event: update the PR1 register This program uses some of the hardware features of the Proteus simulator, specifically a potentiometer, four buttons, and a row of 8 LEDs. You have used the LEDs in a previous lab, but the potentiometer and the buttons are new. On the left is the potentiometer (in the oval) along with two arrows: up and down. These change its value and increase and decrease respectively the output of the ADC (described later). The push buttons highlighted by the top-left square each have two possible events: down and up. The up events will be used to signal the release of a button and the desire to toggle certain LEDs. Event Driven Programming

Buttons The provided pseudo code for the program flow shows the use of a very powerful approach to programming known as Event-driven Programming. This lab introduces you to the concepts of system state and event checking. A state is the present condition of a system or entity. For example, a car has many states: such as what gear it s in, its speed, the position of the driver s seat, etc. Buttons have states, though they re simpler, up and down. Notice that these completely define the button. Systems use states to determine what actions they should undertake. For example, when we re in the MOVING_LEFT state, the next time the LED should move it will move to the left. Systems can also transition between states using either external triggers (such as the timer interrupt that we will use in this lab) or via other properties of the system. For instance, if you are moving to the right and are at the last LED then you will want to transition to the state of moving to the left. Within the examples of states above, event checking has already been implied. Event checking involves testing for changes in the triggers that the program watches: Has button S3 been pressed? Has the counter reached 10? Following the event checking code is the transition code that checks if a state transition should occur given the most recent events and if so what that should entail. Like the example above, when your direction is to the right and the last LED is already lit then it is time to update your direction state. In this lab you are required to use four buttons (S3-S6, note that they are not in numerical order, this detail will become important when matching which buttons toggle which LEDs). The functionality of these buttons requires some knowledge of the PIC24f series itself and relies on code defined in the p24fxxxx.h header file that is included for you in Buttons.h The buttons library will need a static variable of type char to store the last button state in order to compare this value to the current button state. The ButtonsInit() function will have to enable the D6/7/13 and A7 pins as inputs for the micro processor. This is done with the following two statements: TRISD = 0x20C0; TRISA = 0x0080;

Also, ButtonsInit() will need to initialize the last button state to hold the 8-bits of data returned by READ_STATE() (which should be stored in a static variable of type char ). Remember that this function must be called at the start of your program before ButtonsCheckEvents() can be used. The ButtonsCheckEvents() function will handle the logic to signal a transition in events. This means that when this function is called it should read in the current button state from the READ_STATE() macro provided for you in Buttons.h, compare this value to the last button state, and if they are not equivalent determine what events have been triggered. Deciding what to do depends on the transition you have taken. For example, if the last button state was Button3Up and the current state is not Button3Up then the event that has occurred is the Button3Down event. Notice that more than one button event can occur at a time. You should therefore use bit masking to set the event variable that is returned by ButtonsCheckEvents(). Interrupts Interrupts are a way for a processing to handle a time-sensitive event. When an interrupt occurs whatever code the processor had been executing is paused and it shifts over to executing something special code defined just for this event generically called an Interrupt Service Routine (ISR). ISRs should be written so that when the interrupt is called the processor can quickly handle it and then get back to normal execution of the program. This means that expensive operations, such as input or output, SHOULD NOT be done within interrupts as it will affect normal program execution. Interrupts can also occur at any time and so your code can be interrupted at any time. A special case occurs when the processor is inside of an ISR and another interrupt is triggered. The processor uses interrupt flags to keep track of when it is inside of an interrupt. These flags must be cleared (set to 0) at the end of every interrupt so that they and other interrupts can trigger. CPUs and microcontrollers regularly handle interrupts, as they are generally a part of normal operation. Some interrupts involve the internal operation of the CPU while others are triggered externally, like when the CPU receives data over a serial port. ISRs look very similar to functions, though they have specific names and include some additional annotations that you may safely ignore. For the PIC24F, ISRs are declared as follows, with INTERRUPT_NAME replaced by the actual interrupt name such as T1Interrupt : void attribute ((interrupt, auto_psv))_interrupt_name(); Note that it returns nothing and takes no arguments. Also, an interrupt should not deal with any function-level static variables. Since your

code doesn't call these functions directly, there is no way to pass arguments or process the return value. The way to work around this and get data into and out of an ISR is to declare variables at the module-level: outside of any functions or curly-braces (look for the comment above main()). Since interrupts are halt normal code execution, they should be short so that the main code can be run again. There should be no complex logic within ISRs. For the code you will writing in the Timer1 and ADC1 ISRs, you will only use simple comparisons and arithmetic operators. LEDs The LEDs D3-D10 are controlled by configuring pins on the processor: setting these pins high turns them on and low turns them off. These LEDs are all connected to the A-pins and so are controlled by the LATA register (a uint16) where each bit in this register controls the output of a pin: 1 means high and 0 means low. The LEDs are on pins A0 through A7 and a high output corresponds to the LED being enabled or on. Remember that bit-numbering generally starts at 0! Enabling the proper A-pins to be outputs so that they can control the LEDs is done with the TRISA register (like the Buttons library did). Setting a bit (to 1) in the TRISA register turns that pin into an input and clearing that bit (to 0) sets it to an output. For the LEDs we want to control, the corresponding pins (and therefore bits in TRISA) should be set to outputs and therefore a 0. The following code snippet enabled LEDs D3 and D5 and turns them both on: // Turn on the LEDs D3 and D4 TRISA = 0xF6; LATA = 0x05; Timers Timers trigger an interrupt repeatedly at a programmed frequency. These are commonly used for triggering output repeatedly like in this lab. In this lab you will use timer1 (there are several) and the provided code configures timer1 for you already. Whenever Timer1 triggers the _T1Interrupt() interrupt is called. In this ISR you should increment the bouncesensors counter member. Timer1 s interrupt flag is IFS0bits.T1IF, and this bit should be cleared at the end of the ISR. The timer is configured to apply a prescalar to the processor frequency to slow it down (in turn changing the frequency at which the interrupt is called). Timer1 s prescalar is set by the register PR1, with a valid range from 1 to 65536 (or 0xFFFF) with 1 being the highest frequency/fastest interrupt rate. For the PR1 register, 0 is a special control value and if it is set to that no timer interrupts will be triggered!

While the prescalar can adjust the frequency of the timer over a large range, even at its slowest it is 10x faster than we would like. Account for this within main() the pseudo code above does in the Program flow section of this lab manual. Analog to digital converters (ADC) Think of a volume dial, an input with infinite settings between a minimum and maximum. This is what's called an analog control: as it has a large range of possible values. This compares to a digital control, which has only 2 possible values. Hardware called an analog-to-digital converter is used to translate these analog signals into digital values that a processor can understand in the form of an integer. For this lab you will use just one of the ADCs available on the processor: ADC1. Like timer1, it has already been configured for you. It has been set to sample the voltage from the potentiometer on the development board and then store the result as an unsigned 10-bit value in the integer register ADC1BUF0 before calling the ISR ADC1Interrupt(). It repeats this process continually and as fast as possible. Your job is to map this 10-bit value into a 16 bit value that is used by the PR1 register used as a prescalar for Timer1. More information about integer range mapping is given below, but you will have to keep the following in mind: The value stored into ADC1BUF0 is a 10-bit value that stores the current value of the ADC that you are working with. Since your interrupt service routine needs to be short you will only save the three most significant bits into the 8-bit speed member of your struct. The PR1 register holds a 16-bit value which controls the frequency at which the Timer1 ISR will be called (so higher values will call the ISR less frequently than lower values). The PR1 register should contain 1 of only 8 significant values, all of which have equal distances from each other on a number line. The interrupt flag for ADC1Interrupt() is IFS0bits.AD1IF so be sure to clear this bit before returning from the ISR. Integer range mapping Imagine writing a program which monitors the conditions of a drill bit used to dig for oil, stopping the drill string automatically if it gets over 2500 degrees Fahrenheit. Unfortunately, the temperature gauge was manufactured in Britain and gives a reading in Celsius. Your first job, then, would be to map the temperature reading to Fahrenheit.

This is quite a common mathematical operation when working with embedded systems. Luckily C's arithmetic and bitwise operators make mapping easy. In embedded systems, however, multiplications and division are very slow and can cause performance problems if relied on exclusively. The way to work around this is to use the bit-shift operators. Remember that the bit-shifting operations in C are specified with << for a left bit-shift and a >> for a right bit-shift. Now you may just think of bit-shifting as moving bits around, but when integers are stored as bits, what is happening to the value of the integer? A left bit-shift moves all the bits up 1 bit to higher-valued bits, which is the same as multiplying by 2. Shift more to multiply by higher powers of two: so bitshifting 4 times would multiply the integer by 2 4 or 16. A similar process holds for bit-shifting right, it just acts as division instead of multiplication. Bit-shifting isn t just used for replacing multiplication and division operations; it can also be used for removing all of the lower-ordered bits from a number. As an example if you right bit-shift 0xA5 by 4 the result would be 0x0A, which are just the highest 4 bits. For example, take an integer in the range of [0,1023] (means from 0 to 1023 and including both). You should first notice that this number is stored entirely in the lowest 10 bits of that integer. Now map that number into the range [0,31], which can be represented in 5 bits. This mapping, therefore, will just remove the lowest 5 bits of the input with a right shift and use the result. The reason we don t just use the lowerorder bits is because we want the lowest values in each range to correspond to each other and the highest ones to also correspond, and to be increasing for both. If the lowest are used we would see something like the following picture. The black line shows a proper mapping of the range [0,1023] to [0,31] while the red shows the improper mapping described above.

Bit masks Usually when mapping integer ranges it is the lower-order bits that get dropped as the higher-order bits contain more data as they represent large values of the number (the 5 th bit of a number represents 16 versus the 1 st bit represents 2, so if the 1 st bit was lost the resultant number would be closer to the actual number versus if the 5 th bit was lost ). Now when writing a mapping operation from some integer range to another integer range, you will probably need to do something a little more complex than the bit-shift in the example above. Many operations will often need to be combined to get the desired result which sometimes can take six or more operations! Here are some common uses of the operators for manipulating bits and integers: left bit-shift: multiplying by powers of 2, moving bits higher right bit-shift: dividing by powers of 2, removing lower-order bits, selecting higher-order bits bitwise-and: clearing bits (to 0), selecting specific bits bitwise-or: setting bits (to 1), combining numbers bitwise-xor: inverting specific bits bitwise-not: inverting all bits negation: reversing the ordering of a range

When working with bits it's common to refer to a bit mask. A bit mask is a filter used when modifying a value such that only certain bits are affected. In fact this concept was already introduced in the Buttons section with: TRISD = 0x20C0; What that statement does is mask on the 6 th, 7 th, and 13 th bits in the TRISD register by OR-ing it with 0x20C0. While in this case the bit mask involved setting the bits (to 1) by using an OR operation, bit-masking can also refer to clearing bits (to 0) or toggling bits (changing their value) by using AND or XOR operations respectively. In the case of this lab masking will come in with the LED library, where only the indicated LEDs should be enabled or set. It will also be used for determining which LEDs should be lit based on button input and the bouncing LED. By masking together the permanently-lit LEDs set by the buttons along with the bouncing LED, the final values for which LEDs should be lit can be determined. Incremental Development Approach for this Lab For this lab we again provide you an example iterative design plan. It is not quite as detailed as the one in Lab 1, and you may add more steps when you actually implement this lab, but this is just to get you started: 1. Light up LED D3 2. Implement Timer1's ISR 3. At every timer event move the LED right one position (let it run off the end). 4. Add limit-checking to the LED movement so that the LED doesn't bounce off the end. 5. Add direction to the LED bouncing so that it now bounces back and forth. 6. Implement the ADC ISR so that it can trigger ADC changed events. Toggle LED D9 when the ADC changes to test. 7. Implement ButtonsInit(). Test by lighting up a specific LED based on which button is pressed by using READ_STATE() directly in main(). 8. Implement ButtonsCheckEvents(). Test by switching cost test code for Part 7 to use ButtonsCheckEvents(). 9. Add the required button event checking to main(). 10.Double-check your code style, formatting, and comments before submitting the assignment. After this lab we will no longer provide an iterative design plan. It is recommended that you have an implementation plan for all

labs in order to maximize the points you receive and to minimize the time spent on the labs. A TA or tutor may ask to see your design plan before helping you with trouble shooting, so you should have at least an idea of how to approach the lab. For all labs it is generally recommended to start with the libraries first and test them and then move onto the core functionality of the lab. With the libraries usually being 2/3 of the available points, this will be the best way to score highly in these labs.