Sunteți pe pagina 1din 10

ESD2 : Development of a simple embedded system scheduler

Introduction:
For the two previous experiments, we have been using this code structure:
void main (void)
{ / *initialize task x* /
x_Init ( ) ;
while(1)
{ x() ; /* run task x*/
}
{
The problem with this code structure is that it is very hard to execute task X at precise intervals
of time; especially if we code in C language. Very often, embedded system application requires
periodic execution of tasks. Examples are:
The display must be refreshed the display every 40ms

The keypad must be scanned every 20ms


The stepper motor excitation pattern must be updated every 5ms
and many more

One solution would be to add a delay to simulate the periodicity of the task:
Void main (void)
{ /* initialize task X*/
X_Init ( ) ;
while(1){
x(); /* run task x*/
Delay_50ms ( ) ; /* delay for 50ms */
}
}
This is fine ,if we know the precise duration of task X with the condition that the duration never
changes. However, in real-world applications, these conditions are very hard to meet.
Result and discussion:
Part 1 ; Using Timer Interrupt
To obtain periodic function executions, and to avoid wasting processor cycles, we can use
interrupt. An interrupt is a hardware mechanism used to notify processor that an event has taken
place. Timer overflows are a particularly effective and widely used source of interrupts in
embedded applications. The AT89C51RB2 on the lab training kit has three on-chip timers which
can be used to generate an interrupt (a tick) at regular and precise intervals. This interrupt can
be used to call an appropriate function periodically.
We shall consider how to create and handle timer interrupts using the KEIL compiler.
The sample code is provided in the file timer_isr_led.c . Timer 2 is used to generate the ticks.
The overflow interrupt is handled by the function:
void Timer _2_Tick (void) interrupt 5
{
//manually clear overflow flag
TF2 = 0;
// call task
} //Notice the interrupt keyword

The timer is configured into 16-bit auto-reload mode. TH2 and TL2 together form the 16-bit
timer register that keep the timer count. When this 16-bit register overflows, the processor will
execute the interrupt service routine. At the same time, the contents of TH2 AND TL2 are loaded
with the values stored in RCAP2H and RCAP2L. This automatic reload facility ensures that the
timer keeps generating the required tick with very little software load and without any
intervention from the users program.

QUESTION 1:
Note that the code assumes that the crystal frequency is 12 MHz. However, the crystal on the
training kit is oscillating at 11.0592 MHz. With this value, it is not possible to setup a precise
1ms timer tick. Knowing that the timer register increments once for very 12 crystal oscillation
cycles, calculate the reload value if we want to have 5ms timer tick.
Answer : RCAP2H = 0XEE
RCAP2L = 0X00
Part 2: Flashing LED
With this timer interrupt properly setup, we are now ready to implement a simple scheduler that
allows us to execute tasks at the required periodicity. The file timer_isr_led.c has been
provided for the experiment. Create a project in D:\ESD2 to execute the code. Note that the
timer reload values are not given. Use the answer that you have calculated to replace the ? in
the code so that the timer tick is 5ms.
QUESTION 2:
Modify, compile and run the revised version of timer_isr_led.c on the embedded board.
Demonstrate to the lab instructor.

#include < reg52.h >


sbit LED8=P2^7;
unsigned int led_duration_count;
#define LED_DURATION 100 // demo
void LED_Update(void);
void Timer_init()
{
T2CON = 0x04; // Load Timer 2 control register
TH2 = 0xEE; // Load Timer 2 high byte
RCAP2H = 0xEE; // Load Timer 2 reload capt. reg. high byte
TL2 = 0x00; // Load Timer 2 low byte
RCAP2L = 0x00; // Load Timer 2 reload capt. reg. low byte
// Timer 2 interrupt is enabled, and ISR will be called
// whenever the timer overflows - see below.
ET2 = 1;
// Start Timer 2 running
TR2 = 1;
}
void timer2(void)interrupt 5
{
// must manually clear timer 2 overflow flag
TF2 = 0;
LED_Update();
}
void main(void)
{
LED8=1;
Timer_init();
EA = 1; // Globally enable interrupts
while(1)
{
}
}
void LED_Update(void)
{
led_duration_count++;
if(led_duration_count==LED_DURATION)
{ led_duration_count=0;
if(LED8==1)
{
LED8=0;
}
else
{
LED8=1;
}
}

QUESTION 3:
What is the flashing frequency of the LED?
Time for 1 period = 5ms + 5ms = 10ms
Flashing frequency, f = 1/10ms = 100 Hz
Part 3: Stepper Motor Control
The sample code is given in the file LAB_2.c.Notice that after each call to run_motor_phase(),
we have to insert a_wait_ms() call to provide some interval between each step. This is inefficient
because during this time, the processor is not going to do anything useful.

#include <stdio.h>
#include <reg51.h>

// STEP Motor type = PM35S-048-HPE8 wired as UNI-POLAR STEP MTR


// ( brand NMB = Minibea Electronics Ltd )

/****************
OUT0 - > P2.0
OUT1 - > P2.1
OUT2 - > P2.2
OUT3 - > P2.3
****************/

const char pattern[] = {1, 5, 4, 6, 2, 10, 8, 9};


#define PHASE_MASK 0x7

void _wait_ms(unsigned int DelayMS)


{
unsigned int x,y;
for(x=0;x<DelayMS;x++)
for(y=0;y<120;y++);
}
void run_motor_phase(char direction)
{
static char phase;
if (direction)
phase = (++phase) & PHASE_MASK;
else
phase = (--phase) & PHASE_MASK;

P2 = ~pattern[phase];
}

void run_motor_step(char direction, char speed, short steps)


{
short i;

for (i=0; i<steps; i++){


run_motor_phase(direction);
_wait_ms(speed);
}
}

void main(void){
for( ;; ){
run_motor_step(0, 10, 2000);
}
}
Part 4: Simple Multi-Tasking
There are two programs: one is to flash the LED periodically and another is to run the stepper
motor efficiently. Combine both programs so that while the motor is running continuously, the
LED is also flashing.
Depending on the time spend in each task, the precise time for the tasks to actually get executed
may not be possible to control. However, as long as the task is scheduled to execute during a
particular interval, we are able to maintain the periodicity, up to the precision of the duration of
the timer tick period.

QUESTION 5:
Your objective now is to design a new program by combining the two programs using timer
interrupt/ interrupts: one flashing the LED and another running the motor, into a single program.
The LED should flash while the motor runs simultaneously. Demonstrate to the lab instructor.

#include<reg52.h>
sbit LED8=P2^7;
unsigned int motor_duration_count;
unsigned int led_duration_count;
#define LED_DURATION 100 // demo
#define MOTOR_DURATION 3 // DEMO

void MOTOR_Update (void);


void LED_Update(void);
void Timer_init();
void run_motor_phase(char direction);

const char pattern[] = {1, 5, 4, 6, 2, 10, 8, 9};


#define PHASE_MASK 0x7

void Timer_init()
{
T2CON = 0x04; // Load Timer 2 control register
TH2 = 0xEE; // Load Timer 2 high byte
RCAP2H = 0XEE; // Load Timer 2 reload capt. reg. high byte
TL2 = 0X00; // Load Timer 2 low byte
RCAP2L = 0X00; // Load Timer 2 reload capt. reg. low byte
// Timer 2 interrupt is enabled, and ISR will be called
// whenever the time oveflows- see below
ET2 = 1;
//Start Timer 2 running
TR2 = 1;
}

void timer2(void)interrupt 5
{
//must manuaaly clear timer 2 overflow flag
TF2 = 0;

LED_Update();
MOTOR_Update();
}

void main(void)
{
LED8=1;

Timer_init();
EA = 1; // Globally enable interrupts

while(1)
{
}
}

void LED_Update(void)
{
led_duration_count++;
if(led_duration_count==LED_DUR ATION)
{
led_duration_count=0;
if(LED8==1)
{
LED8=0;
}
else
{
LED8=1;
}
}
}

void MOTOR_Update ()
{
motor_duration_count++;
if(motor_duration_count==MOTOR _DURATION)
{
run_motor_phase(0);
}
}

void run_motor_phase(char direction)


{
static char phase;

if(direction)
phase = (++phase) & PHASE_MASK;
else
phase = (--phase) & PHASE_MASK;

P2 = ~pattern[phase];
}

Conclusion:
From this experiment, I have learnt how to write code in C programming by doing
calculation for the timer and frequency. I also gain knowledge how to design and implement the
sample code that already provided by the lecturer. Besides that, I also develop software programs
to control the running of motor and flashing of LED at the same time and at the same time get to
enhancing my viewing of electrical schematic, create c, generate HEX file in keil software and
combine it into hardware task given to us.