Objectives
The objective of this lab is to schedule operations and generate time-based control signals in an electronic system. For this purpose, the system clock will be utilized to generate a module that monitors time. While it is expected that an end product will be delivered on a micro-controller, the designer is asked to develop and test the software on a personal computer.
Assignment requirement
In order to do this assignment, you should have
• A C compiler with an IDE, either DevC++, or Visual Studio (preferably DevC++)
Assessment
Here is what needs to be done
1 • Definition of the objectives, as well as functions, and constraints
2 • Software Design
– Show and describe a dataflow diagram.
3 • Program
– Functioning code in C, with adequate functions, variables, and comments.
4 • Embedded processor conceptual design
– Show and describe a circuit diagram of the processor with attached peripherals (LEDs and buttons)
– Register assignments to create a 1 msec clock.
– Explain the instructions in C to enable and disable a light on one PIN, while not affecting the other PINS.
5 • Format, including a title page, proper English, figures, introduction and conclusion
The below is for you to help you with using codes and examples, you can skip to instructions to seed what is the actual assignment is about.
Experiment 1: Schedules
4 .1 Background
In automated systems, there is often a need to apply specific commands following a schedule. For example, a traffic light controller has multiple cycles.
4 .2 Scheduling
A schedule can be programmed on a computer. It utilizes the time information to change activities. A generic data flow graph is shown in Figure 1 to implement a sequential schedule. After the timer is reset, the scheduler enters a loop. Activities are processed sequentially, and when the expected activity period has elapsed, the program advances to the next activity. In Figure 1, two activities are defined, but any number of activities can be implemented in the loop.
To verify if the time has expired for each activity, it is important to record the initial time at the beginning of the activity and compare the current value with the initial value.
An example of a dataflow chart to represent the program of a schedule is shown in Figure 1. The filled circle in black represents the start of the program, a rectangular box represents an action, while a diamond represents a decision-making element. In the example shown, two timed activities are defined and repeated periodically until the end of the program, represented by the white circle.
Next, we will learn how to monitor time.
Figure 1: Data flow graph for a schedule with 2 activities
4 .3 Monitoring Time
To follow a schedule, a timer is necessary to monitor time. To maintain a high-resolution counter on an
embedded processor, the clock can be configured to generate an event –a tick– at a periodic interval. When the tick occurs, the on-board processor clock can be refreshed. This clock can be used for scheduling.
4 .3.1 Monitoring time on a personal computer
On a personal computer, the time can be monitored using the
standard_library/time_h.htm
The clock_t variable stores the processor time, and its resolution is defined by the macro CLOCKS_PER_SEC and its units are ticks per seconds.
To manage a schedule, one can monitor the time elapsed for a given activity by recording the start time using a variable, for example, start_time = clock(); at a given point in the program, then monitoring, the
time elapsed using time_elapsed = clock() – start_time;
4 .3.2 Tick Generation and Clock Update on an Embedded Processor
Similarly, to a personal computer, a processor requires an input clock to run operations on registers synchronously (for example, apply logic, add, multiply). Your embedded processor evaluation board input clock is a crystal oscillator with a nominal frequency of 16 MHz.
On the embedded processor, the clock can be used to control 3 different counters. The operation of the
counters are detailed in the ATmega328P datasheet. Two of these counters are represented on 8 bits, thus counting from 0 to 2^8 – 1, the other is represented on 16 bits, counting up to 2^16 -1. Optionally, it is possible to scale the input clock frequency from 16 MHz by specific ratios, before feeding it to the counter. This reduces the counter update frequency.
The counters can be configured to produce, among others, 1) a square pulse on the GPIO, 2) interrupt
functions, or 3) a pulse width modulated signal. To control the counter, specific registers in the embedded
processor must be set.
To generate a tick, the counter generates an interrupt. An interrupt is an event that calls a function. The
reason it is called an interrupt is that the it interrupts the regular sequential program. In the interrupt function, one can update a global variable (such as Cnt in the example below). The timer resolution (in ticks per seconds) is defined by the rate of the interrupt function call.
An example sample code to produce a tick on counter TIMER0 overflow is shown in Figure 2. In this
case, the interrupt handler ISR(TIMER0_OVF_vect) is called every time the 8-bit counter has reached its
maximum value, i.e 255. The Cnt variable holds the time information.
Instead of producing an interrupt on the counter overflow, it is also possible to produce an interrupt when the counter has reached a specific value. Sample code to do this is shown in Figure 3. Basically, one must:
Figure 2: Sample Code to Generate an Interrupt on TIMER0 overflow
Figure 3: Sample code to generate an Interrupt when TIMER0 matches the comparator content.
1. Define the timer control registers (TCCRxA/TCCRxB/TIMSKx).
2. The reference value is placed in a compare register (OCRxA/OCRxB).
3. The proper interrupt handler must be defined in the program (TIMERx_COMPn_vect).
4. The interrupt vector must be enabled using sei().
4 .4 Instructions
In this experiment, you will write a program that generates a tick with a short period, such as 1 msec. You will use this internal tick time to manage a schedule and implement a traffic light controller. You can assume a very basic set of traffic lights (green, orange, red). Your controller will produce the signals that will control the 3 lights on one of the three corners (use 3 LEDs for this purpose). For testing purposes, assume that the green light stays on 6 seconds, the orange light 2 second, and that the red light is on 8 seconds.
Use a user input to control a master reset of the traffic lights. Upon reset, your set of corner lights indicates that you must stop (only the red light is on). You can assume that the other traffic lights are synchronized accordingly.
An additional feature of this traffic light controller is a fourth light for pedestrians. It will be synchronized
with the other lights: when the green light turns on, the pedestrian light turns on solid for 4 seconds. Then it blinks for 4 seconds. When the light turns red, the pedestrian light turns off.
4 .5 Developing the code on windows
• Define the objectives, functions and constraints for the traffic light controller.
• Draw the dataflow diagram that represents the sequence of actions for the traffic light controller.
• Write the main function of the program in C, using your preferred IDE (Integrated Development Environment). Your main function should be structured such that there is an initialization stage, followed by an infinite loop. In the initialization stage, the inputs as well as the counter settings are configured. In
the main loop, the program waits for a user input, such as the character ’S’ to start the schedule. Then, it
implements the traffic light controller cycle.
• Define a global variable that will represent the time elapsed for the current activity.
• Define a function to print the status of each light, once, on a change of status.
• Write a function to get the value of the time elapsed, and a second function to reset the value of the time
elapsed. These functions should be called by the main.
• Test and show the output of your console. Using your code, and console output, the LEDs should change at the right time.
4 .6 Designing the schedule on the embedded processor
You are required to generate a timer with a period of 1 msec. You will configure TIMER0 to update the tick value at a period of 1 msec. The code developed in this section of the report does not need to be compiled. Nonetheless, if the Microchip IDE is installed you may develop the functions using this IDE, since the Arduino compatible variables are defined in this environment.
• Read the ATMega datasheet section on 8-bit Timer/Counter0. Define the pre-scale value of the input
clock, as well as the count that you will compare with to generate the interrupt with the best time accuracy. Calculate precisely the expected period of the tick with these settings
• What values will you set to the control registers, TIMSK0,TCCR0A and TCCR0B? Provide your answer in binary format.
• What value will you set to the OCR0A register?
• What are different solutions to improve the accuracy of your timer?
• Write the interrupt handler ISR (TIMER0_COMPA_vect). The interrupt handler updates the timer
value, which is a global variable.
• Re-write the function to set the status of each light on PINS.
• Update, if necessary, the function to get the value of the time elapses, and a second function to reset the
value of the time elapsed.
• Explain in your report what changes needed to be made to manage the schedule on the embedded processor, rather than the windows-based program. To follow a good software design process, avoid changing the main() function, and only change the content of specific functions.