Search for notes by fellow students, in your own course and all over the country.

Browse our notes for titles which look like what you need, you can preview any of the notes via a sample of the contents. After you're happy these are the notes you're after simply pop them into your shopping cart.

My Basket

You have nothing in your shopping cart yet.

Title: Programming Embedded System I
Description: This course is concerned with the implementation of software (and a small amount of hardware) for embedded systems constructed using a single microcontroller. The processors examined in detail are from the 8051 family (including both ‘Standard’ and ‘Small’ devices). All programming is in the ‘C’ language. By the end of the course, you will be able to: 1. Design software for single-processor embedded applications based on small, industry standard, microcontrollers; 2. Implement the above designs using a modern, high-level programming language (‘C’), and 3. Begin to understand issues of reliability and safety and how software design and programming decisions may have a positive or negative impact in this area.

Document Preview

Extracts from the notes are below, to see the PDF you'll receive please use the links above


Programming
Embedded
Systems I

A 10-week course, using C

Michael J
...
3

P0
...
3

P0
...
1

P1
...
5

P0
...
5

P0
...
0

P2
...
2

P2
...
4

P2
...
6

P2
...
7

P1
...
7

P3
...
5

P3
...
3

P3
...
1

RST

P1
...
1

P3
...
0

1
2
3
4
5
6
7
8
9
10

VSS

P1
...
2]

I

Copyright © Michael J
...


II

Seminar 1: “Hello, Embedded World”
Overview of this seminar
Overview of this course
By the end of the course …
Main course textbook
Why use C?
Pre-requisites!
The 8051 microcontroller
The “super loop” software architecture
Strengths and weaknesseses of “super loops”
Example: Central-heating controller
Reading from (and writing to) port pins
SFRs and ports
SFRs and ports
Creating and using sbit variables
Example: Reading and writing bytes
Creating “software delays”
Using the performance analyzer to test software delays
Strengths and weaknesses of software-only delays
Preparation for the next seminar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

III

Seminar 2: Basic hardware foundations (resets, oscillators and port I/O)
Review: The 8051 microcontroller
Review: Central-heating controller
Overview of this seminar
Oscillator Hardware
How to connect a crystal to a microcontroller
Oscillator frequency and machine cycle period
Keep the clock frequency as low as possible
Stability issues
Improving the stability of a crystal oscillator
Overall strengths and weaknesses
Reset Hardware
More robust reset circuits
Driving DC Loads
Use of pull-up resistors
Driving a low-power load without using a buffer
Using an IC Buffer
Example: Buffering three LEDs with a 74HC04
What is a multi-segment LED?
Driving a single digit
Preparation for the next seminar

21
22
23
24
25
27
28
29
30
31
32
34
35
36
38
39
40
41
42
43
44

IV

Seminar 3: Reading Switches
Introduction
Review: Basic techniques for reading from port pins
Example: Reading and writing bytes (review)
Example: Reading and writing bits (simple version)
Example: Reading and writing bits (generic version)
The need for pull-up resistors
The need for pull-up resistors
The need for pull-up resistors
Dealing with switch bounce
Example: Reading switch inputs (basic code)
Example: Counting goats
Conclusions
Preparation for the next seminar

45
46
47
48
49
51
56
57
58
59
61
68
74
75

V

Seminar 4: Adding Structure to Your Code
Introduction
Object-Oriented Programming with C
Example of “O-O C”
The Project Header (Main
...
H)
Re-structuring a “Hello World” example
Example: Re-structuring the Goat-Counting Example
Preparation for the next seminar

77
78
79
82
85
92
96
104
114

VI

Seminar 5: Meeting Real-Time Constraints

115

Introduction
Creating “hardware delays”
The TCON SFR
The TMOD SFR
Two further registers
Example: Generating a precise 50 ms delay
Example: Creating a portable hardware delay
The need for ‘timeout’ mechanisms - example
Creating loop timeouts
Example: Testing loop timeouts
Example: A more reliable switch interface
Creating hardware timeouts
Conclusions
Preparation for the next seminar

116
118
119
120
121
122
126
129
130
132
134
135
137
138

VII

Seminar 6: Creating an Embedded Operating System
Introduction
Timer-based interrupts (the core of an embedded OS)
The interrupt service routine (ISR)
Automatic timer reloads
Introducing sEOS
Introducing sEOS
Tasks, functions and scheduling
Setting the tick interval
Saving power
Using sEOS in your own projects
Is this approach portable?
Example: Milk pasteurization
Conclusions
Preparation for the next seminar

139
140
144
145
146
147
148
153
154
157
158
159
160
174
175

VIII

Seminar 7: Multi-State Systems and Function Sequences
Introduction
Implementing a Multi-State (Timed) system
Example: Traffic light sequencing
Example: Animatronic dinosaur
Implementing a Multi-State (Input/Timed) system
Example: Controller for a washing machine
Conclusions
Preparation for the next seminar

177
178
180
181
189
195
197
208
209

IX

Seminar 8: Using the Serial Interface
Overview of this seminar
What is ‘RS-232’?
Basic RS-232 Protocol
Asynchronous data transmission and baud rates
RS-232 voltage levels
The software architecture
Overview
Using the on-chip U(S)ART for RS-232 communications
Serial port registers
Baud rate generation
Why use 11
...
0

P1
...
1

P1
...
5

17

5

XTL1

P1
...
2

P1
...
3

P1
...
4

P1
...
5

P1
...
7

11

Atmel 2051

1
10 KΩ

5
...
3A lamp
E
B

ZTX751
C

P0
...
3

P1
...
3

P0
...
1

P1
...
5

P0
...
5

P0
...
1

P1
...
2

P1
...
0

P3
...
2

P3
...
4

P3
...
6

P3
...
7

ALE

P2
...
6

P2
...
4

P2
...
2

P2
...
0

40
39
38
37
36
35
34
33
32
31

30
29
28
27
26
25
24
23
22
21

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

The processors examined in detail are from the 8051 family
(including both ‘Standard’ and ‘Small’ devices)
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
Design software for single-processor embedded applications
based on small, industry standard, microcontrollers;
2
...
Begin to understand issues of reliability and safety and how
software design and programming decisions may have a
positive or negative impact in this area
...
PONT, 2001-2003
...
J
...


PES I - 4

Main course textbook
Throughout this course, we will be making heavy use of this book:
Embedded C
by Michael J
...
engg
...
ac
...
htm

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

Overall, C may not be an perfect language for developing embedded
systems, but it is a good choice (and is unlikely that a ‘perfect’ language
will ever be created)
...
PONT, 2001-2003
...
J
...


PES I - 6

Pre-requisites!
• Throughout this course, it will be assumed that you have had

previous programming experience: this might be in - for
example - Java or C++
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
2

VCC

P0
...
0

P1
...
4

P0
...
4

P0
...
0

P1
...
6

P1
...
6

P1
...
7

RST

P3
...
1

1
2
3
4
5
6
7
8
9
10

P3
...
3

P3
...
5

P3
...
7

XTL2

VSS

XTL1

11
12
13
14
15
16
17
18
19
20

‘8051’
P0
...
7

/ PSEN

P2
...
5

P2
...
3

P2
...
1

P2
...

• Internal data (RAM) memory - 256 bytes
...

• Low-power Idle and Power-down modes
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
This
makes them (comparatively) easy to build, debug, test and maintain
...

☺ Super Loops are highly portable
...

The basic Super Loop operates at ‘full power’ (normal operating
mode) at all times
...


[As we will see in Seminar 6, a scheduler can address these
problems
...
PONT, 2001-2003
...
J
...


PES I - 10

Example: Central-heating controller

Temperature
sensor

Temperature
dial

Central
heating
controller

Boiler

void main(void)
{
/* Init the system */
C_HEAT_Init();
while(1) /* 'for ever' (Super Loop) */
{
/* Find out what temperature the user requires
(via the user interface) */
C_HEAT_Get_Required_Temperature();
/* Find out what the current room temperature is
(via temperature sensor) */
C_HEAT_Get_Actual_Temperature();
/* Adjust the gas burner, as required */
C_HEAT_Control_Boiler();
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

All of the ports are bidirectional: that is, they may be used for both
input and output
...
PONT, 2001-2003
...
J
...


PES I - 12

SFRs and ports
Control of the 8051 ports through software is carried out using what
are known as ‘special function registers’ (SFRs)
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
For example, we can send some data to
Port 1 as follows:
unsigned char Port_data;
Port_data = 0x0F;
P1 = Port_data;

/* Write 00001111 to Port 1 */

Similarly, we can read from (for example) Port 1 as follows:
unsigned char Port_data;
P1 = 0xFF;
Port_data = P1;

/* Set the port to ‘read mode’ */
/* Read from the port */

Note that, in order to read from a pin, we need to ensure that the last
thing written to the pin was a ‘1’
...
PONT, 2001-2003
...
J
...


PES I - 14

Creating and using sbit variables
To write to a single pin, we can make use of an sbit variable in the
Keil (C51) compiler to provide a finer level of control
...

sbit Warning_led = LED_PORT^0; /* LED is connected to pin 3
...

Warning_led = LED_ON;

...
/* delay */
Warning_led = LED_ON;

...
PONT, 2001-2003
...
J
...


PES I - 15

Example: Reading and writing bytes

The input port
The output port

void main (void)
{
unsigned char Port1_value;
/* Must set up P1 for reading */
P1 = 0xFF;
while(1)
{
/* Read the value of P1 */
Port1_value = P1;
/* Copy the value to P2 */
P2 = Port1_value;
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 17

Using the performance analyzer to test software delays

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

☺ SOFTWARE DELAY requires no hardware timers
...


BUT:
It is very difficult to produce precisely timed delays
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
This
will give you a chance to focus on the software aspects of
embedded systems, without dealing with hardware problems
...

Please read Chapters 1, 2 and 3
before the next seminar

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 21

Review: The 8051 microcontroller

P0
...
3

P1
...
3

P0
...
1

P1
...
5

P0
...
5

P0
...
1

P1
...
2

P1
...
0

P3
...
2

P3
...
4

P3
...
6

P3
...
7

ALE

/ EA

P2
...
6

P2
...
4

P2
...
2

P2
...
0

40
39
38
37
36
35
34
33
32
31

30
29
28
27
26
25
24
23
22
21

Typical features of a modern 8051:
• Thirty-two input / output lines
...

• Up to 64 kbytes of ROM memory (usually flash)
• Three 16-bit timers / counters
• Nine interrupts (two external) with two priority levels
...


The different members of this family are suitable for everything from
automotive and aerospace systems to TV “remotes”
...
PONT, 2001-2003
...
J
...


PES I - 22

Review: Central-heating controller

Temperature
sensor

Temperature
dial

Central
heating
controller

Boiler

void main(void)
{
/* Init the system */
C_HEAT_Init();
while(1) /* 'for ever' (Super Loop) */
{
/* Find out what temperature the user requires
(via the user interface) */
C_HEAT_Get_Required_Temperature();
/* Find out what the current room temperature is
(via temperature sensor) */
C_HEAT_Get_Actual_Temperature();
/* Adjust the gas burner, as required */
C_HEAT_Control_Boiler();
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

Specifically, we’ll look at:
• Oscillator circuits
• Reset circuits
• Controlling LEDs

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• This circuit is the ‘heartbeat’ of the system and is crucial to

correct operation
...

• If the oscillator runs irregularly, any timing calculations

performed by the system will be inaccurate
...
PONT, 2001-2003
...
J
...


PES I - 25

CRYSTAL OSCILLATOR
Crystals may be used to generate a popular form of oscillator circuit
known as a Pierce oscillator
...
To create such an oscillator, most of the components
are included on the microcontroller itself
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• In later family members, such as the Infineon C515C, a

machine cycle takes six oscillator periods; in more recent
devices such as the Dallas 89C420, only one oscillator
period is required per machine cycle
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

This can be a mistake:
• Many application do not require the levels of performance

that a modern 8051 device can provide
...

• In most modern (CMOS-based) 8051s, there is an almost

linear relationship between the oscillator frequency and the
power-supply current
...

• When accessing low-speed peripherals (such as slow

memory, or LCD displays), programming and hardware
design can be greatly simplified - and the cost of peripheral
components, such as memory latches, can be reduced - if the
chip is operating more slowly
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
In most cases, oscillator stability
is expressed in figures such as ‘±20 ppm’: ‘20 parts per
million’
...
In every million
seconds, your crystal may gain (or lose) 20 seconds
...

Standard quartz crystals are typically rated from ±10 to ±100 ppm, and
so may gain (or lose) from around 5 to 50 minutes per year
...
PONT, 2001-2003
...
J
...


PES I - 30

Improving the stability of a crystal oscillator
• If you want a general crystal-controlled embedded system to

keep accurate time, you can choose to keep the device in an
oven (or fridge) at a fixed temperature, and fine-tune the
software to keep accurate time
...

• ‘Temperature Compensated Crystal Oscillators’ (TCXOs)

are available that provide - in an easy-to-use package - a
crystal oscillator, and circuitry that compensates for changes
in temperature
...
1 ppm (or more): in a clock circuit, this should gain or
lose no more than around 1 minute every 20 years
...
00 per unit
...

For the cost of a small temperature sensor (around $2
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
Typically ±20-100 ppm = ±50 mins per
year (up to ~1 minute / week)
...

☺ Quartz crystals are available at reasonable cost for most common
frequencies
...
Overall, crystal oscillators are more expensive than
ceramic resonators
...

The stability falls with age
...
PONT, 2001-2003
...
J
...


PES I - 32

CERAMIC RESONATOR
Overall strengths and weaknesses
☺ Cheaper than crystal oscillators
...

☺ Many resonators contain in-built capacitors, and can be used without
any external components
...
About half the size of crystal oscillator
...
Typically ±5000
ppm = ±2500 min per year (up to ~50 minutes / week)
...
PONT, 2001-2003
...
J
...


PES I - 33

Reset Hardware
• The process of starting any microcontroller is a non-trivial

one
...
Running this reset routine takes
time, and requires that the microcontroller’s oscillator is
operating
...

Example:
Vcc

10 uF

Vcc

AT89C2051
RESET

XTAL 1

30 pF ±10

10 K
GND

XTAL 2

30 pF ±10

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 35

Driving DC Loads
• The port pins on a typical 8051 microcontroller can be set at

values of either 0V or 5V (or, in a 3V system, 0V and 3V)
under software control
...

• The total current we can source or sink per microcontroller

(all 32 pins, where available) is typically 70 mA or less
...
PONT, 2001-2003
...
J
...


PES I - 36

NAKED LED

Vcc

Rled

Rled =

Vcc − Vdiode
I diode

PX
...

• Supply voltage, Vcc = 5V,
• LED forward voltage, Vdiode = 2V,
• Required diode current, Idiode = 15 mA (note that the data

sheet for your chosen LED will provide this information)
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
Y

8051 Device

Logic 0
to light LED

The value of the pull-up resistor should be between 1K and 10K
...

NOTE:
This is usually only necessary on Port 0
(see Seminar 3 for further details)
...
PONT, 2001-2003
...
J
...


PES I - 38

Driving a low-power load without using a buffer
Vcc

R

Load

PX
...
Y
Logic 0 (0v) to sound buzzer

8051 Device

See “PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS”, p
...
PONT, 2001-2003
...
J
...


PES I - 39

Using an IC Buffer
5V

LED is (fully) ON

“High” output = 5V

LED is OFF

Pin X
...

5V

LED is ON

“High” output = 5V

LED is OFF

Pin X
...


It makes sense to use CMOS logic in your buffer designs wherever
possible
...

See “PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS”, p
...
PONT, 2001-2003
...
J
...


PES I - 40

Example: Buffering three LEDs with a 74HC04
This example shows a 74HC04 buffering three LEDs
...

In this case, we assume that the LEDs are to be driven at 15 mA
each, which is within the capabilities (50 mA total) of the buffer
...
015 A
5V

Port X

8051 Device

(PX
...
b,
PX
...
a)

200R

(Amber)
(PX
...
c)

See “PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS”, p
...
PONT, 2001-2003
...
J
...


PES I - 41

What is a multi-segment LED?
Multiple LEDs are often arranged as multi-segment displays:
combinations of eight segments and similar seven-segment displays
(without a decimal point) are particularly common
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• For example, we can use UDN2585A
...

Vcc

PX
...
7

10
10

R

8

• Note that this is an inverting (current source) buffer
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 44

Seminar 3:
Reading Switches

To pin on:
Port 1,
Port 2,
or
Port 3
...
PONT, 2001-2003
...
J
...


PES I - 45

Introduction
• Embedded systems usually use switches as part of their user

interface
...

• Whatever the system you create, you need to be able to

create a reliable switch interface
...

Before considering switches themselves, we will consider the
process of reading the state of port pins
...
PONT, 2001-2003
...
J
...


PES I - 46

Review: Basic techniques for reading from port pins
We can send some data to Port 1 as follows:
sfr P1 = 0x90;

/* Usually in header file */

P1 = 0x0F;

/* Write 00001111 to Port 1 */

In exactly the same way, we can read from Port 1 as follows:
unsigned char Port_data;
P1 = 0xFF;
Port_data = P1;

/* Set the port to ‘read mode’ */
/* Read from the port */

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 48

Example: Reading and writing bits (simple version)
/*-------------------------------------------------------------*Bits1
...
00)
-*-------------------------------------------------------------*/
#include ...
*/
void main (void)
{
bit x;
/* Set switch pin for reading */
Switch_pin = 1;
while(1)
{
x = Switch_pin;
LED_pin = x;
}
}

/* Read Pin 1
...
1 */

/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
The symbol ‘^’ is used, but the XOR bitwise
operator is NOT involved
...
PONT, 2001-2003
...
J
...


PES I - 50

Example: Reading and writing bits (generic version)
The six bitwise operators:
Operator
&
|
^
<<
>>
~

A
0
0
1
1

B
0
1
0
1

Description
Bitwise AND
Bitwise OR (inclusive OR)
Bitwise XOR (exclusive OR)
Left shift
Right shift
One’s complement

A AND B
0
0
0
1

A OR B
0
1
1
1

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
h>
void Display_Byte(const unsigned char);
/*
...
PONT, 2001-2003
...
J
...


PES I - 52

/* --------------------------------------------------------------- */
void Display_Byte(const unsigned char CH)
{
unsigned char i, c = CH;
unsigned char Mask = 1 << 7;
for (i = 1; i <= 8; i++)
{
putchar(c & Mask ? '1' : '0');
c <<= 1;
}
putchar('\n');
}

x
1s complement [~x]
Bitwise AND [x & 0x0f]
Bitwise OR [x | 0x0f]
Bitwise XOR [x ^ 0x0f]
Left shift, 1 place [x <<= 1]
Right shift, 4 places [x >>= 4]

11111110
00000001
00001110
11111111
11110001
11111100
00001111

Display MS byte of unsigned int y
Display LS byte of unsigned int y

00001010
00001011

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

NOTE: Both pins on the same port
-*-------------------------------------------------------------*/
#include ...
*/
void main (void)
{
bit x;
while(1)
{
x = Read_Bit_P1(0);
Write_Bit_P1(1,x);
}
}

/* Read Port 1, Pin 0 */
/* Write to Port 1, Pin 1 */

/* --------------------------------------------------------------- */
void Write_Bit_P1(const unsigned char PIN, const bit VALUE)
{
unsigned char p = 0x01; /* 00000001 */
/* Left shift appropriate number of places */
p <<= PIN;
/* If we want 1 output at this pin */
if (VALUE == 1)
{
P1 |= p; /* Bitwise OR */
return;
}
/* If we want 0 output at this pin */
p = ~p; /* Complement */
P1 &= p; /* Bitwise AND
*/
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 55

The need for pull-up resistors
To pin on:
Port 1,
Port 2,
or
Port 3
...


An internal resistor on the port ‘pulls up’ the pin to the
supply voltage of the microcontroller (typically 5V)
...

• When the switch is closed (pressed), the pin voltage will be

0V
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

With pull-ups:
Vcc

Switch released:
Reads ‘1’

Vcc

Switch pressed:
Reads ‘0’

Without pull-ups:
Vcc

Switch released:
Reads ‘0’

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

+5v

Voltage

+5v

t1

t2

Time

As far as the microcontroller is concerned, each ‘bounce’ is
equivalent to one press and release of an ‘ideal’ switch
...

• If a switch is depressed once, and then released some time

later, the ‘bounce’ may make it appear as if the switch has
been pressed again (at the time of release)
...
PONT, 2001-2003
...
J
...


PES I - 59

Creating some simple software to check for a valid switch input is
straightforward:
1
...

2
...

3
...

Note that the figure of ‘20 ms’ will, of course, depend on the switch
used
...
PONT, 2001-2003
...
J
...


PES I - 60

Example: Reading switch inputs (basic code)
This switch-reading code is adequate if we want to perform
operations such as:
• Drive a motor while a switch is pressed
...

• Activate a pump while a switch is pressed
...

For example:
• Drive a motor while a switch is pressed

Condition: If the safety guard is not in place, don’t turn the
motor
...

• Switch on a light while a switch is pressed

Condition: To save power, ignore requests to turn on the
light during daylight hours
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

- Reads (and debounces) switch input on Pin 1^0
- If switch is pressed, changes Port 3 output
-*-------------------------------------------------------------*/
#include ...
PONT, 2001-2003
...
J
...


PES I - 62

/* ---------------------------------------------------------------- */
void main(void)
{
bit Sw_state;
/* Init functions */
SWITCH_Init();
DISPLAY_SWITCH_STATUS_Init();
while(1)
{
Sw_state = SWITCH_Get_Input(30);
DISPLAY_SWITCH_STATUS_Update(Sw_state);
}
}
/*-------------------------------------------------------------*SWITCH_Init()
Initialisation function for the switch library
...
PONT, 2001-2003
...
J
...


PES I - 63

/*-------------------------------------------------------------*SWITCH_Get_Input()
Reads and debounces a mechanical switch as follows:
1
...

2
...

Then:
a
...

b
...
H for details of return values
...
*/
DELAY_LOOP_Wait(DEBOUNCE_PERIOD);
/* Check switch again */
if (Switch_pin == 0)
{
Return_value = SWITCH_PRESSED;
}
}
/* Now return switch value */
return Return_value;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

-*-------------------------------------------------------------*/
void DISPLAY_SWITCH_STATUS_Init(void)
{
Output_port = 0xF0;
}
/*-------------------------------------------------------------*DISPLAY_SWITCH_STATUS_Update()
Simple function to display data (SWITCH_STATUS)
on LEDs connected to port (Output_Port)
-*-------------------------------------------------------------*/
void DISPLAY_SWITCH_STATUS_Update(const bit SWITCH_STATUS)
{
if (SWITCH_STATUS == SWITCH_PRESSED)
{
Output_port = 0x0F;
}
else
{
Output_port = 0xF0;
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

Parameter is, *ROUGHLY*, the delay, in milliseconds,
on 12MHz 8051 (12 osc cycles)
...
PONT, 2001-2003
...
J
...


PES I - 66

The output port

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• This is a concern, because in many cases, users will press

switches for at least 500 ms (or until they receive feedback
that the system has detected the switch press)
...

One consequence is that this code is not suitable for applications
where we need to count the number of times that a switch is pressed
and then released
...
PONT, 2001-2003
...
J
...


PES I - 68

Mechanical sensor
at goat body
height

Sensor
Goat detected

If we try to use the code in the previous example, the goat sensor
will not allow us to count the number of goats but will instead
provide an indication of the time taken for the goats to pass the
sensor
...
PONT, 2001-2003
...
J
...


PES I - 69

/*-------------------------------------------------------------*A 'goat counting' program for the 8051
...
h>
/* Connect switch to this pin */
sbit Switch_pin = P1^0;
/* Display count (binary) on this port */
#define Count_port P3
/* Return values from Switch_Get_Input() */
#define SWITCH_NOT_PRESSED (bit) 0
#define SWITCH_PRESSED (bit) 1
/* Function prototypes */
void SWITCH_Init(void);
bit SWITCH_Get_Input(const unsigned char DEBOUNCE_PERIOD);
void DISPLAY_COUNT_Init(void);
void DISPLAY_COUNT_Update(const unsigned char);
void DELAY_LOOP_Wait(const unsigned int DELAY_MS);
/* ---------------------------------------------------------------- */
void main(void)
{
unsigned char Switch_presses = 0;
/* Init functions */
SWITCH_Init();
DISPLAY_COUNT_Init();
while(1)
{
if (SWITCH_Get_Input(30) == SWITCH_PRESSED)
{
Switch_presses++;
}
DISPLAY_COUNT_Update(Switch_presses);
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
If switch is not pressed, return SWITCH_NOT_PRESSED
...
If switch is pressed, wait for the DEBOUNCE_PERIOD (in ms)
...
If switch is no longer pressed, return SWITCH_NOT_PRESSED
...
If switch is still pressed, wait (indefinitely) for
switch to be released, *then* return SWITCH_PRESSED
See Switch_Wait
...

-*-------------------------------------------------------------*/
bit SWITCH_Get_Input(const unsigned char DEBOUNCE_PERIOD)
{
bit Return_value = SWITCH_NOT_PRESSED;
if (Switch_pin == 0)
{
/* Switch is pressed */
/* Debounce - just wait
...
*/
while (Switch_pin == 0);
Return_value = SWITCH_PRESSED;
}
}
/* Now (finally) return switch value */
return Return_value;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

-*-------------------------------------------------------------*/
void DISPLAY_COUNT_Init(void)
{
Count_port = 0x00;
}
/*-------------------------------------------------------------*DISPLAY_COUNT_Update()
Simple function to display tByte data (COUNT)
on LEDs connected to port (Count_Port)
-*-------------------------------------------------------------*/
void DISPLAY_COUNT_Update(const unsigned char COUNT)
{
Count_port = COUNT;
}
/*-------------------------------------------------------------*DELAY_LOOP_Wait()
Delay duration varies with parameter
...

You need to adjust the timing for your application!
-*-------------------------------------------------------------*/
void DELAY_LOOP_Wait(const unsigned int DELAY_MS)
{
unsigned int x, y;
for (x = 0; x <= DELAY_MS; x++)
{
for (y = 0; y <= 120; y++);
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
0)

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

In both cases, we have illustrated how the switch may be
‘debounced’ in software
...
PONT, 2001-2003
...
J
...


PES I - 74

Preparation for the next seminar
In the next seminar, we turn our attention to techniques that can
help you re-use the code you develop in subsequent projects
...
PONT, 2001-2003
...
J
...


PES I - 75

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H)
// Pins 3
...
1 used
// for RS-232 interface

// Switches
sbit Sw_up = P1^2;
sbit Sw_down = P1^3;
Up

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
We will describe how to use an object-oriented style of
programming with C programs, allowing the creation of
libraries of code that can be easily adapted for use in
different embedded projects;
2
...
This file encapsulates key aspects of the hardware
environment, such as the type of processor to be used, the
oscillator frequency and the number of oscillator cycles
required to execute each instruction
...

3
...

This brings together all details of the port access from the
whole system
...

We will use all three of these techniques in the code examples
presented in subsequent seminars
...
PONT, 2001-2003
...
J
...


PES I - 78

Object-Oriented Programming with C

Language generation

Example languages

-

Machine Code

First-Generation Language
(1GL)

Assembly
Language
...
PONT, 2001-2003
...
J
...


PES I - 79

1

Graham notes :
“[The phrase] ‘object-oriented’ has become almost
synonymous with modernity, goodness and worth in
information technology circles
...


O-O languages are not readily available for small embedded systems,
primarily because of the overheads that can result from the use of some
of the features of these languages
...
(1994) “Object-Oriented Methods,” (2nd Ed
...
Page
1
...
(1997) “An Integrated Approach to Software Engineering”, (2nd Ed
...
Page 273
...
PONT, 2001-2003
...
J
...


PES I - 80

It is possible to create ‘file-based-classes’ in C without imposing a
significant memory or CPU load
...
C
Serial
...
C
Switch
...
C
sEOS
...
PONT, 2001-2003
...
J
...


PES I - 81

Example of “O-O C”
/*-------------------------------------------------------------*PC_IO
...
00)
-------------------------------------------------------- see PC_IO
...

-*-------------------------------------------------------------*/
#ifndef _PC_IO_H
#define _PC_IO_H
/* ------ Public constants ------------------------------------ */
/* Value returned by PC_LINK_Get_Char_From_Buffer if no char is
available in buffer */
#define PC_LINK_IO_NO_CHAR 127
/* ------ Public function prototypes -------------------------- */
void PC_LINK_IO_Write_String_To_Buffer(const char* const);
void PC_LINK_IO_Write_Char_To_Buffer(const char);
char PC_LINK_IO_Get_Char_From_Buffer(void);
/* Must regularly call this function
...
PONT, 2001-2003
...
J
...


PES I - 82

/*-------------------------------------------------------------*PC_IO
...
00)
-------------------------------------------------------[INCOMPLETE - STRUCTURE ONLY - see EC Chap 9 for complete library]
-*-------------------------------------------------------------*/
#include "Main
...
H"
/* ------ Public variable definitions ------------------------- */
tByte In_read_index_G;
tByte In_waiting_index_G;

/* Data in buffer that has been read */
/* Data in buffer not yet read */

tByte Out_written_index_G; /* Data in buffer that has been written */
tByte Out_waiting_index_G; /* Data in buffer not yet written */
/* ------ Private function prototypes ------------------------- */
static void PC_LINK_IO_Send_Char(const char);
/* ------ Private constants ----------------------------------- */
/* The receive buffer length */
#define RECV_BUFFER_LENGTH 8
/* The transmit buffer length */
#define TRAN_BUFFER_LENGTH 50
#define XON 0x11
#define XOFF 0x13
/* ------ Private variables ----------------------------------- */
static tByte Recv_buffer[RECV_BUFFER_LENGTH];
static tByte Tran_buffer[TRAN_BUFFER_LENGTH];
/*-------------------------------------------------------------*/
void PC_LINK_IO_Update(
...

}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
)
{

...
)
{

...
)
{

...
)
{

...
PONT, 2001-2003
...
J
...


PES I - 84

The Project Header (Main
...
H)
11
...
H>

...

typedef unsigned char tByte;

...
PONT, 2001-2003
...
J
...


PES I - 85

/*-------------------------------------------------------------*Main
...
00)
-*-------------------------------------------------------------*/
#ifndef _MAIN_H
#define _MAIN_H
/*-------------------------------------------------------WILL NEED TO EDIT THIS SECTION FOR EVERY PROJECT
-------------------------------------------------------- */
/* Must include the appropriate microcontroller header file here */
#include ...
g
...

4 - Dallas 320, 520 etc
...
*/
#define OSC_PER_INST (12)
/* -------------------------------------------------------SHOULD NOT NEED TO EDIT THE SECTIONS BELOW
-------------------------------------------------------- */
/* Typedefs (see
typedef unsigned
typedef unsigned
typedef unsigned

Chap
char
int
long

5)
*/
tByte;
tWord;
tLong;

/* Interrupts (see Chap 7)
*/
#define INTERRUPT_Timer_0_Overflow 1
#define INTERRUPT_Timer_1_Overflow 3
#define INTERRUPT_Timer_2_Overflow 5
#endif
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H
Header file for the Infineon C515C
Copyright (c) 1995-1999 Keil Elektronik GmbH All rights reserved
...

/* A/D Converter
sfr
ADCON0 = 0xD8;

...


*/

/* Ports
sfr
P0
sfr
P1
sfr
P2
sfr
P3
sfr
P4
sfr
P5
sfr
P6
sfr
P7

...


*/

/* Timer0 / Timer1
sfr
TCON
= 0x88;

...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
g
...

4 - Dallas 320, 520 etc
...
*/
#define OSC_PER_INST (12)

We demonstrate how to use this information:
• For creating delays (Embedded C, Chapter 6),
• For controlling timing in an operating system (Chapter 7),

and,
• For controlling the baud rate in a serial interface (Chapter 9)
...
PONT, 2001-2003
...
J
...


PES I - 88

Common data types
typedef unsigned char tByte;
typedef unsigned int tWord;
typedef unsigned long tLong;

In C, the typedef keyword allows us to provide aliases for data
types: we can then use these aliases in place of the original types
...

• The 8051 does not support signed arithmetic and extra code

is required to manipulate signed data: this reduces your
program speed and increases the program size
...

Finally, as in desktop programming, use of the typedef keyword in
this way can make it easier to adapt your code for use on a different
processor
...
PONT, 2001-2003
...
J
...


PES I - 89

Interrupts

As we noted in “Embedded C” Chapter 2, interrupts are a key
component of most embedded systems
...
7
...
PONT, 2001-2003
...
J
...


PES I - 90

Summary: Why use the Project Header?

Use of PROJECT HEADER can help to make your code more
readable, not least because anyone using your projects knows where
to find key information, such as the model of microcontroller and
the oscillator frequency required to execute the software
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H)

Port Header (Port
...
0 and 3
...
PONT, 2001-2003
...
J
...


Down

PES I - 92

The Port Header file is simple to understand and easy to apply
...

File A may include the following:
/* File A */
sbit Pin_A = P3^2;

...


File C may include the following:
/* File C */
sbit Pin_C = P2^7;

...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H header file:
/* ----- Port
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
H"
/* ------ Menu_A
...
C ------------------------------------------ */
/* Pins 3
...
1 used for RS-232 interface */
#endif
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
h>
/* Oscillator / resonator frequency (in Hz) e
...
(11059200UL) */
#define OSC_FREQ (12000000UL)
/* Number of oscillations per instruction (12, etc)
12 - Original 8051 / 8052 and numerous modern versions
6 - Various Infineon and Philips devices, etc
...

1 - Dallas 420, etc
...
PONT, 2001-2003
...
J
...


PES I - 96

/*-------------------------------------------------------------*Port
...
00)
-------------------------------------------------------'Port Header' for project HELLO2 (see Chap 5)
-*-------------------------------------------------------------*/
#ifndef _PORT_H
#define _PORT_H
/* ------ LED_Flash
...
PONT, 2001-2003
...
J
...


PES I - 97

/*-------------------------------------------------------------*Main
...
00)
-------------------------------------------------------A "Hello Embedded World" test program for 8051
...
H"
#include "Port
...
h"
#include "LED_Flash
...
PONT, 2001-2003
...
J
...


PES I - 98

/*-------------------------------------------------------------*LED_flash
...
00)
-------------------------------------------------------- See LED_flash
...

-*-------------------------------------------------------------*/
#ifndef _LED_FLASH_H
#define _LED_FLASH_H
/* ------ Public function prototypes -------------------------- */
void LED_FLASH_Init(void);
void LED_FLASH_Change_State(void);
#endif
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "LED_flash
...

-*-------------------------------------------------------------*/
void LED_FLASH_Init(void)
{
LED_state_G = 0;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

Must call at twice the required flash rate: thus, for 1 Hz
flash (on for 0
...
5 seconds) must call
every 0
...

-*-------------------------------------------------------------*/
void LED_FLASH_Change_State(void)
{
/* Change the LED from OFF to ON (or vice versa) */
if (LED_state_G == 1)
{
LED_state_G = 0;
LED_pin = 0;
}
else
{
LED_state_G = 1;
LED_pin = 1;
}
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
C for details
...
PONT, 2001-2003
...
J
...


PES I - 102

/*-------------------------------------------------------------*Delay_Loop
...
00)
-------------------------------------------------------Create a simple software delay using a loop
...
H"
#include "Port
...
h"
/*-------------------------------------------------------------*DELAY_LOOP_Wait()
Delay duration varies with parameter
...

You need to adjust the timing for your application!
-*-------------------------------------------------------------*/
void DELAY_LOOP_Wait(const tWord DELAY_MS)
{
tWord x, y;
for (x = 0; x <= DELAY_MS; x++)
{
for (y = 0; y <= 120; y++);
}
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
h>
/* Oscillator / resonator frequency (in Hz) e
...
(11059200UL) */
#define OSC_FREQ (12000000UL)
/* Number of oscillations per instruction (12, etc)
12 - Original 8051 / 8052 and numerous modern versions
6 - Various Infineon and Philips devices, etc
...

1 - Dallas 420, etc
...
PONT, 2001-2003
...
J
...


PES I - 104

/*-------------------------------------------------------------*Port
...
00)
-------------------------------------------------------'Port Header' for project GOATS2 (see Chap 5)
-*-------------------------------------------------------------*/
#ifndef _PORT_H
#define _PORT_H
/* ------ Switch_Wait
...
C ---------------------------------------- */
/* Display count (binary) on this port */
#define Count_port P3
#endif
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Switch_wait
...
H"
/* ---------------------------------------------------------------- */
void main(void)
{
tByte Switch_presses = 0;
/* Init functions */
SWITCH_Init();
DISPLAY_COUNT_Init();
while(1)
{
if (SWITCH_Get_Input(30) == SWITCH_PRESSED)
{
Switch_presses++;
}
DISPLAY_COUNT_Update(Switch_presses);
}
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
C for details
...
PONT, 2001-2003
...
J
...


PES I - 107

/*-------------------------------------------------------------*Switch_Wait
...
00)
-------------------------------------------------------Simple library for debouncing a switch input
...
H"
#include "Port
...
h"
#include "Delay_loop
...

-*-------------------------------------------------------------*/
void SWITCH_Init(void)
{
Switch_pin = 1; /* Use this pin for input */
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
If switch is not pressed, return SWITCH_NOT_PRESSED
...
If switch is
a
...
If switch
switch to

pressed, wait for DEBOUNCE_PERIOD (in ms)
...

is pressed, wait (indefinitely) for
be released, then return SWITCH_PRESSED

See Switch_Wait
...

-*-------------------------------------------------------------*/
bit SWITCH_Get_Input(const tByte DEBOUNCE_PERIOD)
{
bit Return_value = SWITCH_NOT_PRESSED;
if (Switch_pin == 0)
{
/* Switch is pressed */
/* Debounce - just wait
...
*/
while (Switch_pin == 0);
Return_value = SWITCH_PRESSED;
}
}
/* Now (finally) return switch value */
return Return_value;
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
C for details
...
PONT, 2001-2003
...
J
...


PES I - 110

/*-------------------------------------------------------------*Display_count
...
00)
-------------------------------------------------------Display an unsigned char on a port
...
H"
#include "Port
...
H"
/*-------------------------------------------------------------*DISPLAY_COUNT_Init()
Initialisation function for the DISPLAY COUNT library
...
PONT, 2001-2003
...
J
...


PES I - 111

/*-------------------------------------------------------------*Delay_Loop
...
00)
-------------------------------------------------------- See Delay_Loop
...

-*-------------------------------------------------------------*/
#ifndef _DELAY_LOOP_H
#define _DELAY_LOOP_H
/* ------ Public function prototype --------------------------- */
void DELAY_LOOP_Wait(const tWord DELAY_MS);
#endif
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Delay_loop
...

Parameter is, *ROUGHLY*, the delay, in milliseconds,
on 12MHz 8051 (12 osc cycles)
...
PONT, 2001-2003
...
J
...


PES I - 113

Preparation for the next seminar

Please read Chapter 6
before the next seminar

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 115

Introduction
In this seminar, we begin to consider the issues involved in the
accurate measurement of time
...

x, y, z = position coordinates
υ, β, ϖ = velocity cordinates
p = roll rate
q = pitch rate
r = yaw rate

q
y,β

Rudder
δr
Elevator
δe

Aileron
δa

x,υ

p
z,ϖ

r
Yaw (rate)
sensor

Pitch
(rate)
sensor

Rudder

Roll
(rate)
sensor

Elevator
Aircraft
Autopilot
System

Main
pilot
controls

Aileron

Position
sensors
(GPS)

Main engine
(fuel)
controllers
Velocity
sensors
(3 axes)

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
DELAY_LOOP_Wait(DEBOUNCE_PERIOD); /* POTENTIAL PROBLEM */
/* Check switch again */
if (Switch_pin == 0)
{
/* Wait until the switch is released
...
Because this delay is
implemented using a software loop it may not be very precisely
timed
...

We’ll see how to deal with both of these problems in this seminar

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

These timers can be used to generate accurate delays
...
PONT, 2001-2003
...
J
...


PES I - 118

The TCON SFR
7
(msb)

Bit

TF1

NAME
TF1

6
TR1

5

4

TF0

TR0

3
IE1

2
IT1

1
IE0

0
(lsb)
IT0

Timer 1 overflow flag

Set by hardware on Timer 1 overflow
...
)
TR1

Timer 1 run control bit

Set / cleared by software to turn Timer 1 either ‘ON’ or ‘OFF’
...

(Cleared by hardware if processor vectors to interrupt routine
...


Note that the overflow of the timers can be used to generate an
interrupt
...

To disable the generation of interrupts, we can use the C statements:
ET0 = 0;
ET1 = 0;

/* No interrupts (Timer 0) */
/* No interrupts (Timer 1) */

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
When cleared timer “x” is enabled whenever “TRx” control bit
is set
...

Cleared for timer operation (input from internal system clock)
...
PONT, 2001-2003
...
J
...


PES I - 120

Two further registers
Before we can see how this hardware can be used to create delays,
you need to be aware that there are an additional two registers
associated with each timer: these are known as TL0 and TH0, and
TL1 and TH1
...
PONT, 2001-2003
...
J
...


PES I - 121

Example: Generating a precise 50 ms delay
/*-------------------------------------------------------------*Hardware_Delay_50ms
...
00)
-------------------------------------------------------A test program for hardware-based delays
...
h>
sbit LED_pin = P1^5;
bit LED_state_G;
void LED_FLASH_Init(void);
void LED_FLASH_Change_State(void);
void DELAY_HARDWARE_One_Second(void);
void DELAY_HARDWARE_50ms(void);
/*
...
PONT, 2001-2003
...
J
...


PES I - 122

/*-------------------------------------------------------------*LED_FLASH_Init()
Prepare for LED_Change_State() function - see below
...

Must call at twice the required flash rate: thus, for 1 Hz
flash (on for 0
...
5 seconds) must call
every 0
...

-*-------------------------------------------------------------*/
void LED_FLASH_Change_State(void)
{
/* Change the LED from OFF to ON (or vice versa) */
if (LED_state_G == 1)
{
LED_state_G = 0;
LED_pin = 0;
}
else
{
LED_state_G = 1;
LED_pin = 1;
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

*** Assumes 12MHz 8051 (12 osc cycles) ***
-*-------------------------------------------------------------*/
void DELAY_HARDWARE_One_Second(void)
{
unsigned char d;
/* Call DELAY_HARDWARE_50ms() twenty times */
for (d = 0; d < 20; d++)
{
DELAY_HARDWARE_50ms();
}
}
/*-------------------------------------------------------------*DELAY_HARDWARE_50ms()
*** Assumes 12MHz 8051 (12 osc cycles) ***
-*-------------------------------------------------------------*/
void DELAY_HARDWARE_50ms(void)
{
/* Configure Timer 0 as a 16-bit timer */
TMOD &= 0xF0; /* Clear all T0 bits (T1 left unchanged) */
TMOD |= 0x01; /* Set required T0 bits (T1 left unchanged) */
ET0 = 0;

/* No interrupts */

/* Values for 50 ms delay */
TH0 = 0x3C; /* Timer 0 initial value (High Byte) */
TL0 = 0xB0; /* Timer 0 initial value (Low Byte) */
TF0 = 0;
TR0 = 1;

/* Clear overflow flag */
/* Start timer 0 */

while (TF0 == 0); /* Loop until Timer 0 overflows (TF0 == 1) */
TR0 = 0;
}

/* Stop Timer 0 */

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

We require a 50 ms delay, so the timer requires the following
number of increments before it overflows:
50ms
× 1000000 = 50000 increments
...

Thus, the initial value we need to load to produce a 50 ms delay is:
65536 - 50000 = 15536 (decimal) = 0x3CB0

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Delay_T0
...
h"
void main(void)
{
LED_FLASH_Init();
while(1)
{
/* Change the LED state (OFF to ON, or vice versa) */
LED_FLASH_Change_State();
/* Delay for *approx* 1000 ms */
DELAY_T0_Wait(1000);
}
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

NOTE: These values are portable but timings are *approximate*
and *must* be checked by hand if accurate timing is required
...
*/
#define PRELOAD01 (65536 - (tWord)(OSC_FREQ / (OSC_PER_INST * 1020)))
#define PRELOAD01H (PRELOAD01 / 256)
#define PRELOAD01L (PRELOAD01 % 256)
/*-------------------------------------------------------------*/
void DELAY_T0_Wait(const tWord N)
{
tWord ms;
/* Configure Timer 0 as a 16-bit timer */
TMOD &= 0xF0; /* Clear all T0 bits (T1 left unchanged) */
TMOD |= 0x01; /* Set required T0 bits (T1 left unchanged)
ET0 = 0;

/* No interrupts */

/* Delay value is *approximately* 1 ms per loop
for (ms = 0; ms < N; ms++)
{
TH0 = PRELOAD01H;
TL0 = PRELOAD01L;
TF0 = 0;
TR0 = 1;

*/

*/

/* Clear overflow flag */
/* Start timer 0 */

while (TF0 == 0); /* Loop until Timer 0 overflows (TF0 == 1) */
TR0 = 0;
}

/* Stop Timer 0 */

}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 128

The need for ‘timeout’ mechanisms - example
The Philips 8Xc552 is an Extended 8051 device with a number of
on-chip peripherals, including an 8-channel, 10-bit ADC
...

This application note includes the following code:
/* Wait until AD conversion finishes (checking ADCI) */
while ((ADCON & ADCI) == 0);

Such code is potentially unreliable, because there are circumstances
under which our application may ‘hang’
...

• If the ADC has been subjected to an excessive input voltage,

then it may not operate at all
...

The Philips example is not intended to illustrate ‘production’ code
...

Two possible solutions: Loop timeouts and hardware timeouts
...
PONT, 2001-2003
...
J
...


PES I - 129

Creating loop timeouts
Basis of loop timeout:
tWord Timeout_loop = 0;

...
PONT, 2001-2003
...
J
...


PES I - 130

/*-------------------------------------------------------------*TimeoutL
...
00)
-------------------------------------------------------Simple software (loop) timeout delays for the 8051 family
...
PONT, 2001-2003
...
J
...


PES I - 131

Example: Testing loop timeouts
/*-------------------------------------------------------------*Main
...
00)
-*-------------------------------------------------------------*/
#include ...
H"
/* Typedefs (see
typedef unsigned
typedef unsigned
typedef unsigned

Chap
char
int
long

5)
*/
tByte;
tWord;
tLong;

/* Function prototypes */
void Test_Timeout(void);
/*-------------------------------------------------------------*/
void main(void)
{
while(1)
{
Test_Timeout();
}
}
/*-------------------------------------------------------------*/
void Test_Timeout(void)
{
tLong Timeout_loop = LOOP_TIMEOUT_INIT_10000ms;
/* Simple loop timeout
...
PONT, 2001-2003
...
J
...


PES I - 132

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
DELAY_T0_Wait(DEBOUNCE_PERIOD);
/* Check switch again */
if (Switch_pin == 0)
{
/* Wait until the switch is released
...
PONT, 2001-2003
...
J
...


PES I - 134

Creating hardware timeouts
/* Configure Timer 0 as a 16-bit timer */
TMOD &= 0xF0; /* Clear all T0 bits (T1 left unchanged) */
TMOD |= 0x01; /* Set required T0 bits (T1 left unchanged)
ET0 = 0;

*/

/* No interrupts */

/* Simple timeout feature - approx 10 ms */
TH0 = PRELOAD_10ms_H; /* See Timeout
...
PONT, 2001-2003
...
J
...


PES I - 135

/*-------------------------------------------------------------*TimeoutH
...
00)
-*-------------------------------------------------------------*/
#ifndef _TIMEOUTH_H
#define _TIMEOUTH_H
/* ------ Public constants ------------------------------------ */
/* Timer T_ values for use in simple (hardware) timeouts */
- Timers are 16-bit, manual reload ('one shot')
...
*/
/* Define initial Timer 0 / Timer 1 values for ~50 µs delay */
#define T_50micros (65536 - (tWord)((OSC_FREQ /
26000)/(OSC_PER_INST)))
#define T_50micros_H (T_50micros / 256)
#define T_50micros_L (T_50micros % 256)

...
PONT, 2001-2003
...
J
...


PES I - 136

Conclusions
The delay and timeout considered in this seminar are widely used in
embedded applications
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 138

Seminar 6:
Creating an Embedded
Operating System

Determine flow rate from pulse stream

Milk pasteurisation system
Milk pasteurisation system

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

For example …

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
At this time,
Guaranteen, who is generally known as a member of the Slafordic School, was …”
“Now turn to your left, and locate Item 346, a small painting which was until recently also
thought to have been painted by Guarateen but which is now …”
...
46, 0
...
17, 0
...
00, 0
...
21, 0
...
84, 0
...
00, 1
...
63, 0
...
42, 0
...
00, 0
...
00, 0
...
42, 0
...
46, 0
...
48, 0
...
54, 0
...
PONT, 2001-2003
...
J
...


PES I - 141

Consider a collection of requirements assembled from a range of
different embedded projects (in no particular order):
• The current speed of the vehicle must be measured at 0
...

• The display must be refreshed 40 times every second
• The calculated new throttle setting must be applied every 0
...

• A time-frequency transform must be performed 20 times

every second
...

• The frequency-domain data must be classified 20 times

every second
...

• The master (control) node must communicate with all other

nodes (sensor nodes and sounder nodes) once per second
...
5

seconds
• The sensors must be sampled once per second

In practice, many embedded systems must be able to support this
type of ‘periodic function’
...
PONT, 2001-2003
...
J
...


PES I - 142

void main(void)
{
Init_System();
while(1) /* 'for ever' (Super Loop) */
{
X();
/* Call the function (10 ms duration) */
Delay_50ms(); /* Delay for 50 ms */
}
}

This will be fine, if:
1
...
This duration never varies
...
PONT, 2001-2003
...
J
...


PES I - 143

Timer-based interrupts (the core of an embedded OS)
#define INTERRUPT_Timer_2_Overflow 5

...

The Timer 2 resolution is then 1
...
reg
...
reg
...
*/
ET2
= 1;
/* Start Timer 2 running */
TR2
= 1;
}
void X(void) interrupt INTERRUPT_Timer_2_Overflow
{
/* This ISR is called every 1 ms */
/* Place required code here
...
PONT, 2001-2003
...
J
...


PES I - 144

The interrupt service routine (ISR)
The interrupt generated by the overflow of Timer 2, invokes the
ISR:
/* --------------------------------------------------------------- */
void X(void) interrupt INTERRUPT_Timer_2_Overflow
{
/* This ISR is called every 1 ms */
/* Place required code here
...
PONT, 2001-2003
...
J
...


PES I - 145

Automatic timer reloads
/* Preload values for 50 ms delay */
TH0 = 0x3C;
/* Timer 0 initial value (High Byte) */
TL0 = 0xB0;
/* Timer 0 initial value (Low Byte) */
TF0 = 0;
TR0 = 1;

/* Clear overflow flag */
/* Start timer 0 */

while (TF0 == 0); /* Loop until Timer 0 overflows (TF0 == 1) */
TR0 = 0;

/* Stop Timer 0 */

For our operating system, we have slightly different requirements:
• We require a long series of interrupts, at precisely-

determined intervals
...

Timer 2 matches these requirements precisely
...
reg
...
reg
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...


Now let’s look at a better way of doing this …

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
c (v1
...

-*--------------------------------------------------------*/
#include "Main
...
H"
#include "Simple_EOS
...
H"
/* ----------------------------------------------------- */
void main(void)
{
/* Prepare for dummy task */
X_Init();
/* Set up simple EOS (60 ms tick interval) */
sEOS_Init_Timer2(60);
while(1) /* Super Loop */
{
/* Enter idle mode to save power */
sEOS_Go_To_Sleep();
}
}
/*--------------------------------------------------------*---- END OF FILE ----------------------------------*--------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

Demonstration version with dummy task X()
...
H"
#include "Simple_EOS
...
H"

*/

/*--------------------------------------------------------*sEOS_ISR()
Invoked periodically by Timer 2 overflow:
see sEOS_Init_Timer2() for timing details
...
PONT, 2001-2003
...
J
...


PES I - 149

/*--------------------------------------------------------*sEOS_Init_Timer2()
-*--------------------------------------------------------*/
void sEOS_Init_Timer2(const tByte TICK_MS)
{
tLong Inc;
tWord Reload_16;
tByte Reload_08H, Reload_08L;
/* Timer 2 is configured as a 16-bit timer,
which is automatically reloaded when it overflows */
T2CON
= 0x04;
/* Load T2 control register */
/* Number of timer increments required (max 65536) */
Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) /
(tLong)OSC_PER_INST;
/* 16-bit reload value */
Reload_16 = (tWord) (65536UL - Inc);
/* 8-bit reload values (High & Low) */
Reload_08H = (tByte)(Reload_16 / 256);
Reload_08L = (tByte)(Reload_16 % 256);
/* Used for manually checking timing (in simulator) */
/*P2 = Reload_08H; */
/*P3 = Reload_08L; */
TH2
RCAP2H
TL2
RCAP2L

=
=
=
=

Reload_08H;
Reload_08H;
Reload_08L;
Reload_08L;

/*
/*
/*
/*

Load
Load
Load
Load

T2
T2
T2
T2

high byte */
reload capt
...
reg l byte */

/* Timer 2 interrupt is enabled, and ISR will be called
whenever the timer overflows
...
PONT, 2001-2003
...
J
...


PES I - 150

/*--------------------------------------------------------*sEOS_Go_To_Sleep()
This operating system enters 'idle mode' between clock ticks
to save power
...

-*--------------------------------------------------------*/
void sEOS_Go_To_Sleep(void)
{
PCON |= 0x01;
/* Enter idle mode (generic 8051 version) */
}
/*--------------------------------------------------------*---- END OF FILE ----------------------------------*--------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

-*--------------------------------------------------------*/
#include "X
...

-*--------------------------------------------------------*/
void X_Init(void)
{
/* Dummy task init
...

-*--------------------------------------------------------*/
void X(void)
{
/* Dummy task
...
PONT, 2001-2003
...
J
...


PES I - 152

Tasks, functions and scheduling
• In discussions about embedded systems, you will frequently

hear and read about ‘task design’, ‘task execution times’ and
‘multi-tasking’ systems
...

• In the case of sEOS, the tasks will be implemented using

functions which are called from the timer-driven
interrupt service routine
...
PONT, 2001-2003
...
J
...


PES I - 153

Setting the tick interval
In the function main(), we can see that the control of the tick
interval has been largely automated:
/* Set up simple EOS (60 ms tick interval) */
sEOS_Init_Timer2(60);

In this example, a tick interval of 60 ms is used: this means that the
ISR (the ‘update’ function) at the heart of sEOS will be invoked
every 60 ms:
/*--------------------------------------------------------*sEOS_ISR()
Invoked periodically by Timer 2 overflow:
see sEOS_Init_Timer2() for timing details
...
PONT, 2001-2003
...
J
...


PES I - 154

The ‘automatic’ tick interval control is achieved using the C preprocessor, and the information included in the project header file
(Main
...
g
...

#define OSC_PER_INST (12)

This information is then used to calculate the required timer reload
values in Simple_EOS
...
reg h byte */
low byte */
reload capt
...
PONT, 2001-2003
...
J
...


PES I - 155

• If using a 12 MHz oscillator, then accurate timing can

usually be obtained over a range of tick intervals from 1 ms
to 60 ms (approximately)
...
g
...
0592 MHz), precise

timing can only be obtained at a much more limited range of
tick intervals
...

/* Used for manually checking timing (in simulator) */
P2 = Reload_08H;
P3 = Reload_08L;

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

This is achieved through the function sEOS_Go_To_Sleep():
/*--------------------------------------------------------*sEOS_Go_To_Sleep()
This operating system enters 'idle mode' between clock ticks
to save power
...

-*--------------------------------------------------------*/
void sEOS_Go_To_Sleep(void)
{
PCON |= 0x01;
/* Enter idle mode (generic 8051 version) */
}

Note that the processor will automatically return to ‘Normal’ mode
when the timer next overflows (generating an interrupt)
...
PONT, 2001-2003
...
J
...


PES I - 157

Using sEOS in your own projects
When using sEOS in your own applications, you will need to
include a copy of the files Simple_EOS
...
H in your
project: the
...
*/
/*===== USER CODE - End =============================== */
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• For example, similar timers are included on other 8-bit

microcontrollers (e
...
Microchip PIC family, the Motorola
HC08 family), and also on 16-bit devices (e
...
the Infineon
C167 family) as well as on 32-bit processors (e
...
the ARM
family, the Motorola MPC500 family)
...
PONT, 2001-2003
...
J
...


PES I - 159

Example: Milk pasteurization

Determine flow rate from pulse stream

Milk pasteurisation system
Milk pasteurisation system

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
C ---------------------------------- */
/* Connect pulse input to this pin - debounced in software */
sbit Sw_pin = P3^0;
/* Connect alarm to this pin (set if pulse is below threshold) */
sbit Alarm_pin = P3^7;
/* ------ Bargraph
...
*/
sbit Pin0 = P1^0;
sbit Pin1 = P1^1;
sbit Pin2 = P1^2;
sbit Pin3 = P1^3;
sbit Pin4 = P1^4;
sbit Pin5 = P1^5;
sbit Pin6 = P1^6;
sbit Pin7 = P1^7;
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
c (v1
...

-*-------------------------------------------------------------*/
#include
#include
#include
#include

"Main
...
H"
"Simple_EOS
...
H"

#include "Pulse_Count
...
PONT, 2001-2003
...
J
...


PES I - 162

/*-------------------------------------------------------------*Simple_EOS
...
00)
-------------------------------------------------------Main file for Simple Embedded Operating System (sEOS) for 8051
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Pulse_count
...

-*-------------------------------------------------------------*/
sEOS_ISR() interrupt INTERRUPT_Timer_2_Overflow
{
/* Must manually reset the T2 flag */
TF2 = 0;
/*===== USER CODE - Begin ================================== */
/* Call 'Update' function here */
PULSE_COUNT_Update();
/*===== USER CODE - End ==================================== */
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

-*-------------------------------------------------------------*/
void sEOS_Init_Timer2(const tByte TICK_MS)
{
tLong Inc;
tWord Reload_16;
tByte Reload_08H, Reload_08L;
/* Timer 2 is configured as a 16-bit timer,
which is automatically reloaded when it overflows */
T2CON
= 0x04;
/* Load T2 control register */
/* Number of timer increments required (max 65536) */
Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;
/* 16-bit reload value */
Reload_16 = (tWord) (65536UL - Inc);
/* 8-bit reload values (High & Low) */
Reload_08H = (tByte)(Reload_16 / 256);
Reload_08L = (tByte)(Reload_16 % 256);
/* Used for manually checking timing (in simulator) */
/*P2 = Reload_08H; */
/*P3 = Reload_08L; */
TH2
RCAP2H
TL2
RCAP2L

=
=
=
=

Reload_08H;
Reload_08H;
Reload_08L;
Reload_08L;

/*
/*
/*
/*

Load
Load
Load
Load

T2
T2
T2
T2

high byte */
reload capt
...
high byte */
low byte */
reload capt
...
low byte */

/* Timer 2 interrupt is enabled, and ISR will be called
whenever the timer overflows
...
PONT, 2001-2003
...
J
...


PES I - 164

/*-------------------------------------------------------------*sEOS_Go_To_Sleep()
This operating system enters 'idle mode' between clock ticks
to save power
...

-*-------------------------------------------------------------*/
void sEOS_Go_To_Sleep(void)
{
PCON |= 0x01;
/* Enter idle mode (generic 8051 version) */
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

___
Responds to falling edge of pulse:
|___
-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Bargraph
...
H"
/* ------ Private function prototypes ------------------------- */
void PULSE_COUNT_Check_Below_Threshold(const tByte);
/* ------ Public variable declarations ------------------------ */
/* The data to be displayed */
extern tBargraph Data_G;
/* ------ Public variable definitions -------------------------- */
/* Set only after falling edge is detected */
bit Falling_edge_G;
/* ------ Private variable definitions ------------------------- */
/* The results of successive tests of the pulse signal */
/* (NOTE: Can't have arrays of bits
...
PONT, 2001-2003
...
J
...


PES I - 166

/*-------------------------------------------------------------*PULSE_COUNT_Init()
Initialisation function for the switch library
...
If it is, the alarm is sounded
...
PONT, 2001-2003
...
J
...


PES I - 167

/*-------------------------------------------------------------*PULSE_COUNT_Update()
This is the main switch function
...

-*-------------------------------------------------------------*/
void PULSE_COUNT_Update(void)
{
/* Clear timer flag */
TF2 = 0;
/* Shuffle the test results */
Test4 = Test3;
Test3 = Test2;
Test2 = Test1;
Test1 = Test0;
/* Get latest test result */
Test0 = Sw_pin;
/* Required
Test4 ==
Test3 ==
Test1 ==
Test0 ==

result:
HI_LEVEL
HI_LEVEL
LO_LEVEL
LO_LEVEL

*/

if ((Test4 == HI_LEVEL) &&
(Test3 == HI_LEVEL) &&
(Test1 == LO_LEVEL) &&
(Test0 == LO_LEVEL))
{
/* Falling edge detected */
Falling_edge_G = 1;
}
else
{
/* Default */
Falling_edge_G = 0;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
] */
if (++Calls_G < 450)
{
Total_G += (int) Falling_edge_G;
}
else
{
/* Update the display */
Data_G = Total_G; /* Max is 9 */
Total_G = 0;
Calls_G = 0;
PULSE_COUNT_Check_Below_Threshold(3);
BARGRAPH_Update();
}
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
h (v1
...
c for details
...
h"
/* ------ Public data type declarations ----------------------- */
typedef tByte tBargraph;
/* ------ Public function prototypes -------------------------- */
void BARGRAPH_Init(void);
void BARGRAPH_Update(void);
/* ------ Public constants ------------------------------------ */
#define BARGRAPH_MAX (9)
#define BARGRAPH_MIN (0)
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
c (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
h"
#include "Bargraph
...
PONT, 2001-2003
...
J
...


PES I - 171

/*-------------------------------------------------------------*BARGRAPH_Init()
Prepare for the bargraph display
...
PONT, 2001-2003
...
J
...


PES I - 172

/*-------------------------------------------------------------*BARGRAPH_Update()
Update the bargraph display
...
PONT, 2001-2003
...
J
...


PES I - 173

Conclusions
• The simple operating system (‘sEOS’) introduced in this

seminar imposes a very low processor load but is nonetheless
flexible and useful
...
For

example, it means that developers themselves can, very
rapidly, port the OS onto a new microcontroller
environment
...

Perhaps the most important side-effect of this form of simple OS is that
- unlike a traditional ‘real-time operating system’ - it becomes part of the
application itself, rather than forming a separate code layer
...
PONT, 2001-2003
...
J
...


PES I - 174

Preparation for the next seminar

Please read Chapter 8
before the next seminar

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 176

Seminar 7:
Multi-State Systems
and Function
Sequences

Sleeping
Sleeping

Waking
Waking

Attacking
Attacking

Growling
Growling

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

For example, the system might begin in State A, repeatedly
executing FunctionA(), for ten seconds
...
It might then move back into State
A, ad infinituum
...

• Multi-State (Input / Timed)

This is a more common form of system, in which the
transition between states (and behaviour in each state) will
depend both on the passage of time and on system inputs
...

The autopilot system discussed at the start of this seminar
might follow this pattern, as might a control system for a
washing machine, or an intruder alarm system
...
PONT, 2001-2003
...
J
...


PES I - 178

For completeness, we will mention on further possibility:
• Multi-State (Input)

This is a comparatively rare form of system, in which the
transition between states (and behaviour in each state)
depends only on the system inputs
...
It will remain
indefinitely in State A if this input is not received
...
We will
not consider such systems in this course
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• Each state may be associated with one or more function

calls
...

• Transitions between states may also involve function calls
...

Please also note that the system states will usually be represented
by means of a switch statement in the operating system ISR
...
PONT, 2001-2003
...
J
...


PES I - 180

Example: Traffic light sequencing

Time
Red
Amber
Green

Note:
European sequence!

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 182

In this simple case, we do not require function calls from (or
between) system states: the required behaviour will be implemented
directly through control of the (three) port pins which – in the final
system – would be connected to appropriate bulbs
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
c (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Simple_EOS
...
H"
/* --------------------------------------------------------------- */
void main(void)
{
/* Prepare to run traffic sequence */
TRAFFIC_LIGHTS_Init(RED);
/* Set up simple EOS (50 ms ticks) */
sEOS_Init_Timer2(50);
while(1) /* Super Loop */
{
/* Enter idle mode to save power */
sEOS_Go_To_Sleep();
}
}
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
C for details
...
PONT, 2001-2003
...
J
...


PES I - 185

/*-------------------------------------------------------------*T_lights
...
00)
-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "T_lights
...

-*-------------------------------------------------------------*/
void TRAFFIC_LIGHTS_Init(const eLight_State START_STATE)
{
Light_state_G = START_STATE; /* Decide on initial state */
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

-*-------------------------------------------------------------*/
void TRAFFIC_LIGHTS_Update(void)
{
switch (Light_state_G)
{
case RED:
{
Red_light = ON;
Amber_light = OFF;
Green_light = OFF;
if (++Time_in_state == RED_DURATION)
{
Light_state_G = RED_AND_AMBER;
Time_in_state = 0;
}
break;
}
case RED_AND_AMBER:
{
Red_light = ON;
Amber_light = ON;
Green_light = OFF;
if (++Time_in_state == RED_AND_AMBER_DURATION)
{
Light_state_G = GREEN;
Time_in_state = 0;
}
break;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 188

Example: Animatronic dinosaur

Sleeping
Sleeping

Waking
Waking

Attacking
Attacking

Growling
Growling

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
Irregular snoring noises, or slight
movements during this time will add interest for the
audience
...
Eyelids will begin to
flicker
...

• Growling:

Eyes will suddenly open, and the dinosaur will emit a very
loud growl
...

• Attacking:

Rapid ‘random’ movements towards the audience
...


typedef enum {SLEEPING, WAKING, GROWLING, ATTACKING} eDinosaur_State;
/* Times in each of the (four) possible states */
/* (Times are in seconds) */
#define SLEEPING_DURATION 255
#define WAKING_DURATION 60
#define GROWLING_DURATION 40
#define ATTACKING_DURATION 120

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
h"
#include "Dinosaur
...
PONT, 2001-2003
...
J
...


PES I - 191

/*-------------------------------------------------------------*DINOSAUR_Init()
-*-------------------------------------------------------------*/
void DINOSAUR_Init(void)
{
/* Initial dinosaur state */
Dinosaur_state_G = SLEEPING;
}
/*-------------------------------------------------------------*DINOSAUR_Update()
Must be scheduled once per second (from the sEOS ISR)
...
PONT, 2001-2003
...
J
...


PES I - 192

case GROWLING:
{
/* Call relevant function */
DINOSAUR_Growl();
if (++Time_in_state_G == GROWLING_DURATION)
{
Dinosaur_state_G = ATTACKING;
Time_in_state_G = 0;
}
break;
}
case ATTACKING:
{
/* Call relevant function */
DINOSAUR_Perform_Attack_Movements();
if (++Time_in_state_G == ATTACKING_DURATION)
{
Dinosaur_state_G = SLEEPING;
Time_in_state_G = 0;
}
break;
}
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
P1 = (tByte) Dinosaur_state_G;
P2 = Time_in_state_G;
}
/*-------------------------------------------------------------*/
void DINOSAUR_Perform_Waking_Movements(void)
{
/* Demo only
...
*/
P1 = (tByte) Dinosaur_state_G;
P2 = Time_in_state_G;
}
/*-------------------------------------------------------------*/
void DINOSAUR_Perform_Attack_Movements(void)
{
/* Demo only
...
PONT, 2001-2003
...
J
...


PES I - 194

Implementing a Multi-State (Input/Timed) system
• The system will operate in two or more states
...

• Transitions between states may be controlled by the passage

of time, by system inputs or a combination of time and
inputs
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
If, during this time,

no liquid is detected in the outflow tank, then the pump
should be switched off and ‘low water’ warning should be
sounded
...

• After the front door is opened, the correct password must be

entered on the control panel within 30 seconds or the alarm
will sound
...
If, after 50 ms, no

flap movement is detected, it should be concluded that the
flap hydraulics are damaged
...

To meet this type of requirement, we can do two things:
• Keep track of the time in each system state;
• If the time exceeds a pre-determined error value, then we

should move to a different state
...
PONT, 2001-2003
...
J
...


PES I - 196

Example: Controller for a washing machine
Water
Valve

Water
Heater
Start
Switch
Water
Pump
Selector
Dial

Water
Level
Sensor

Washing
Machine
Controller

Drum
Motor

LED
indicators

Temperature
Sensor
Door
lock

Detergent
Hatch

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
The user selects a wash program (e
...
‘Wool’, ‘Cotton’) on
the selector dial
...
The user presses the ‘Start’ switch
...
The door lock is engaged
...
The water valve is opened to allow water into the wash drum
...
If the wash program involves detergent, the detergent hatch is
opened
...

6
...

7
...
When the water reaches the correct
temperature, the water heater is switched off
...
The washer motor is turned on to rotate the drum
...
(The precise
set of movements carried out depends on the wash program
that the user has selected
...

9
...
When the drum
is empty, the pump is switched off
...
PONT, 2001-2003
...
J
...


PES I - 198

The Input / Timed architecture discussed here is by no means unique to
‘white goods’ (such as washing machines)
...
In this case, basic tests (such as ‘WoW’ - ‘Weight
on Wheels’) will be used to determine whether the aircraft is
on the ground or in the air: these tests will be completed
before the operation begins
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
C (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Washer
...
PONT, 2001-2003
...
J
...


PES I - 200

/* ------ Private variables ----------------------------------- */
static eSystem_state System_state_G;
static tWord Time_in_state_G;
static tByte Program_G;
/* Ten different programs are supported
Each one may or may not use detergent */
static tByte Detergent_G[10] = {1,1,1,0,0,1,0,1,1,0};
/* Each one may or may not use hot water */
static tByte Hot_Water_G[10] = {1,1,1,0,0,1,0,1,1,0};
/* --------------------------------------------------------------- */
void WASHER_Init(void)
{
System_state_G = INIT;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 202

case START:
{
/* For demo purposes only */
Debug_port = (tByte) System_state_G;
/* Lock the door */
WASHER_Control_Door_Lock(ON);
/* Start filling the drum */
WASHER_Control_Water_Valve(ON);
/* Release the detergent (if any) */
if (Detergent_G[Program_G] == 1)
{
WASHER_Control_Detergent_Hatch(ON);
}
/* Ready to go to next state */
System_state_G = FILL_DRUM;
Time_in_state_G = 0;
break;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
System_state_G = ERROR;
}
/* Check the water level */
if (WASHER_Read_Water_Level() == 1)
{
/* Drum is full */
/* Does the program require hot water? */
if (Hot_Water_G[Program_G] == 1)
{
WASHER_Control_Water_Heater(ON);
/* Ready to go to next state */
System_state_G = HEAT_WATER;
Time_in_state_G = 0;
}
else
{
/* Using cold water only */
/* Ready to go to next state */
System_state_G = WASH_01;
Time_in_state_G = 0;
}
}
break;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
System_state_G = ERROR;
}
/* Check the water temperature */
if (WASHER_Read_Water_Temperature() == 1)
{
/* Water is at required temperature */
/* Ready to go to next state */
System_state_G = WASH_01;
Time_in_state_G = 0;
}
break;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
case WASH_02:
{
/* For demo purposes only */
Debug_port = (tByte) System_state_G;
break;
}
case ERROR:
{
/* For demo purposes only */
Debug_port = (tByte) System_state_G;
break;
}
}
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
return 0;
}
/* --------------------------------------------------------------- */
bit WASHER_Read_Start_Switch(void)
{
/* Simplified for demo
...
*/
return 1;
}
/* --------------------------------------------------------------- */
bit WASHER_Read_Water_Temperature(void)
{
/* User code here
...
*/
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
Used in
conjunction with an operating system like that presented in
“Embedded C” Chapter 7, this flexible system architecture is in
widespread use in embedded applications
...
PONT, 2001-2003
...
J
...


PES I - 208

Preparation for the next seminar

Please read Chapter 9
before the next seminar

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 210

Seminar 8:
Using the Serial
Interface

Vcc
1
...
PONT, 2001-2003
...
J
...


PES I - 211

Overview of this seminar
This seminar will:
• Discuss the RS-232 data communication standard
• Consider how we can use RS-232 to transfer data to and

from deskbound PCs (and similar devices)
...

• In control applications (sending controller parameters)
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
Similar standards (V
...

The ‘RS-232’ standard includes details of:
• The protocol to be used for data transmission
...

• The connectors to be used to link equipment together
...
Data transfer can be over distances of 15 metres or more
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
That is, it is intended to be
used to send single 8-bit blocks of data
...

• We send the data (8 bits)
...


NOTE: The UART takes care of these details!

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• Both ends of the communication link have an internal clock,

running at the same rate
...

• RS-232 generally operates at one of a (restricted) range of

baud rates
...

• 9600 baud is a very ‘safe’ choice, as it is very widely

supported
...
PONT, 2001-2003
...
J
...


PES I - 215

RS-232 voltage levels
• The threshold levels used by the receiver are +3 V and -3 V

and the lines are inverted
...

• Note that these voltages cannot be obtained directly from the

naked microcontroller port pins: some form of interface
hardware is required
...

Vcc
1
...
1)
To Rx pin ( P3
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
Transmitting each
byte of data, plus stop and start bits, involves the
transmission of 10 bits of information (assuming a single
stop bit is used)
...

• Suppose, for example, we wish to send this information to

the PC:
Current core temperature is 36
...
This will - frequently be
an unacceptably long duration
...

A better solution is to write all data to a buffer in the microcontroller
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
678 degrees

Buffer
Scheduler sends one
character to PC
every 10 ms
(for example)

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• It is also receive-buffered, meaning it can commence

reception of a second byte before a previously received byte
has been read from the receive register
...

• We are primarily interested in Mode 1
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
This register contains the mode selection bits (and
the serial port interrupt bits, TI and RI: not used here)
...

Writing to SBUF loads the transmit register and initiates
transmission
...

/* Read the data from UART
Data = SBUF;

*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• In this mode the baud rate is determined by the overflow rate

of Timer 1 or Timer 2
...


The baud rate is determined by the Timer 1 overflow rate and the
value of SMOD follows:
2
× Frequency
Baud rate (Mode 1) =
SMOD

oscillator

32 × Instructionscycle × (256 − TH 1)

Where:
SMOD

…is the ‘double baud rate’ bit in the PCON register;

Frequencyoscillator

…is the oscillator / resonator frequency;

Instructionscycle

…is the number of machine instructions per oscillator
cycle (e
...
12 or 6)

TH1

…is the reload value for Timer 1

Note that Timer is used in 8-bit auto-reload mode and that interrupt
generation should be disabled
...
PONT, 2001-2003
...
J
...


PES I - 221

Why use 11
...
g
...
0592 MHz crystal oscillator
...
In practice, you can generally work with a
difference in baud rates at both ends of the connection by up to 5%,
but no more
...


Note also that it is generally essential to use some form of crystal
oscillator (rather than a ceramic resonator) when working with
asynchronous serial links (such as RS-232, RS-485, or CAN): the
ceramic resonator is not sufficiently stable for this purpose
...
PONT, 2001-2003
...
J
...


PES I - 222

PC Software
If your desktop computer is running Windows (95, 98, NT, 2000),
then a simple but effective option is the ‘Hyperterminal’ application
which is included with all of these operating systems
...
PONT, 2001-2003
...
J
...


PES I - 223

What about printf()?
We do not generally recommend the use of standard library
function “printf()”, because:
• this function sends data immediately to the UART
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

☺ At the PC end too, RS-232 is ubiquitous: every PC has one or more
RS-232 ports
...

☺ Because of the hardware support, RS-232 generally imposes a low
software load
...

RS-232 has little or no error checking at the hardware level (unlike, for
example, CAN): if you want to be sure that the data you received at the
PC is valid, you need to carry out checks in software
...
PONT, 2001-2003
...
J
...


PES I - 225

Example: Displaying elapsed time on a PC
Vcc
1
...
PONT, 2001-2003
...
J
...


PES I - 226

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
c (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Simple_EOS
...
h"
#include "Elap_232
...
PONT, 2001-2003
...
J
...


PES I - 228

/*-------------------------------------------------------------*Elap_232
...
00)
-------------------------------------------------------Simple library function for keeping track of elapsed time
Demo version to display time on PC screen via RS232 link
...
h"
#include "Elap_232
...
h"
/* ------ Public variable definitions ------------------------- */
tByte Hou_G;
tByte Min_G;
tByte Sec_G;
/* ------ Public variable declarations ------------------------ */
/* See Char_Map
...

-*-------------------------------------------------------------*/
void Elapsed_Time_RS232_Init(void)
{
Hou_G = 0;
Min_G = 0;
Sec_G = 0;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 230

/*-------------------------------------------------------------*PC_LINK_O_Init_T1()
This version uses T1 for baud rate generation
...
PONT, 2001-2003
...
J
...


PES I - 231

/*-------------------------------------------------------------*/
void PC_LINK_O_Update(void)
{
/* Deal with transmit bytes here
...
PONT, 2001-2003
...
J
...


PES I - 232

/*-------------------------------------------------------------*/
void PC_LINK_O_Write_Char_To_Buffer(const char CHARACTER)
{
/* Write to the buffer *only* if there is space
(No error reporting in this simple library
...
*/
return;
}
TI = 0;
SBUF = 0x0d;
}

/* Output CR

*/

Timeout1 = 0;
while ((++Timeout1) && (TI == 0));
if (Timeout1 == 0)
{
/* UART did not respond - error
No error reporting in this simple library
...
PONT, 2001-2003
...
J
...


PES I - 233

sEOS_ISR() interrupt INTERRUPT_Timer_2_Overflow
{
TF2 = 0; /* Must manually reset the T2 flag

*/

/*===== USER CODE - Begin ================================== */
/* Call RS-232 update function every 5ms */
PC_LINK_O_Update();
/* This ISR is called every 5 ms
- only want to update time every second */
if (++Call_count_G == 200)
{
/* Time to update time */
Call_count_G = 0;
/* Call time update function */
Elapsed_Time_RS232_Update();
}
/*===== USER CODE - End ==================================== */
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

In this case, using the menu, the user can determine the state of the
input pins on Port 1 or Port 2:

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 236

void MENU_Perform_Task(char c)
{
PC_LINK_IO_Write_Char_To_Buffer(c); /* Echo the menu option */
PC_LINK_IO_Write_Char_To_Buffer('\n');
/* Perform the task */
switch (c)
{
case 'a':
case 'A':
{
Get_Data_From_Port1();
break;
}
case 'b':
case 'B':
{
Get_Data_From_Port2();
break;
}
}
}
void Get_Data_From_Port1(void)
{
tByte Port1 = Data_Port1;
char String[11] = "\nP1 = XXX\n\n";
String[6] = CHAR_MAP_G[Port1 / 100];
String[7] = CHAR_MAP_G[(Port1 / 10) % 10];
String[8] = CHAR_MAP_G[Port1 % 10];
PC_LINK_IO_Write_String_To_Buffer(String);
}
void Get_Data_From_Port2(void)
{
tByte Port2 = Data_Port2;
char String[11] = "\nP2 = XXX\n\n";
String[6] = CHAR_MAP_G[Port2 / 100];
String[7] = CHAR_MAP_G[(Port2 / 10) % 10];
String[8] = CHAR_MAP_G[Port2 % 10];
PC_LINK_IO_Write_String_To_Buffer(String);
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 238

Conclusions
In this seminar, we have illustrated how the serial interface on the
8051 microcontroller may be used
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 240

Seminar 9:
Case Study:
Intruder Alarm System

Bell box

Door

Window
W

D

Control
panel

W

Statue

W

W

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 242

System Operation
• When initially activated, the system is in ‘Disarmed’ state
...
The alarm does

not sound
...
When a valid password is
entered, the systems enters ‘Arming’ state
...
After 60 seconds, the system enters ‘Armed’ state
...
If a window sensor is tripped, the system enters
‘Intruder’ state
...
The keypad activity is also
monitored: if a correct password is typed in, the system
enters ‘Disarmed’ state
...

The system remains in this state for up to 60 seconds, after
which - by default - it enters Intruder state
...

• In Intruder state, an alarm will sound
...


COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

• Switch reading, as discussed in “Embedded C” Chapter 4, to

process the inputs from the door and window sensors
...
This
feature can be added, if required, without difficulty
...

• A simple ‘keypad’ library, based on a bank of switches
...
This final system would
probably use at least 10 keys: support for additional keys can
be easily added if required
...
This library would
not be necessary in the final system (but it might be useful to
retain it, to support system maintenance)
...
PONT, 2001-2003
...
J
...


PES I - 244

Running the program

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
H (v1
...
C ------------------------------------------- */
#define KEYPAD_PORT P2
sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit

K0
K1
K2
K3
K4
K5
K6
K7

=
=
=
=
=
=
=
=

KEYPAD_PORT^0;
KEYPAD_PORT^1;
KEYPAD_PORT^2;
KEYPAD_PORT^3;
KEYPAD_PORT^4;
KEYPAD_PORT^5;
KEYPAD_PORT^6;
KEYPAD_PORT^7;

/* ------ Intruder
...
C ------------------------------------------ */
/* Pins 3
...
1 used for RS-232 interface */
/*-------------------------------------------------------------*---- END OF FILE ---------------------------------------*-------------------------------------------------------------*/

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
c (v1
...

-*-------------------------------------------------------------*/
#include "Main
...
H"
#include "Simple_EOS
...
h"
#include "Keypad
...
h"
/*
...
PONT, 2001-2003
...
J
...


PES I - 247

/*-------------------------------------------------------------*Intruder
...
00)
-*-------------------------------------------------------------*/

...

/* --------------------------------------------------------------- */
void INTRUDER_Init(void)
{
/* Set the initial system state (DISARMED) */
System_state_G = DISARMED;
/* Set the 'time in state' variable to 0 */
State_call_count_G = 0;
/* Clear the keypad buffer */
KEYPAD_Clear_Buffer();
/* Set the 'New state' flag */
New_state_G = 1;
/* Set the (two) sensor pins to 'read' mode */
Window_sensor_pin = 1;
Sounder_pin = 1;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
*/
if (INTRUDER_Get_Password_G() == 1)
{
System_state_G = ARMING;
New_state_G = 1;
State_call_count_G = 0;
break;
}
break;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
");
New_state_G = 0;
}
/* Remain here for 60 seconds (50 ms tick assumed) */
if (++State_call_count_G > 1200)
{
System_state_G = ARMED;
New_state_G = 1;
State_call_count_G = 0;
break;
}
break;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 251

case DISARMING:
{
if (New_state_G)
{
PC_LINK_O_Write_String_To_Buffer("\nDisarming
...
*/
if (++State_call_count_G > 1200)
{
System_state_G = INTRUDER;
New_state_G = 1;
State_call_count_G = 0;
break;
}
/* Still need to check the window sensors */
if (INTRUDER_Check_Window_Sensors() == 1)
{
/* An intruder detected */
System_state_G = INTRUDER;
New_state_G = 1;
State_call_count_G = 0;
break;
}
/* Finally, check for correct password */
if (INTRUDER_Get_Password_G() == 1)
{
System_state_G = DISARMED;
New_state_G = 1;
State_call_count_G = 0;
break;
}
break;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 253

bit INTRUDER_Get_Password_G(void)
{
signed char Key;
tByte Password_G_count = 0;
tByte i;
/* Update the keypad buffer */
KEYPAD_Update();
/* Are there any new data in the keypad buffer? */
if (KEYPAD_Get_Data_From_Buffer(&Key) == 0)
{
/* No new data - password can't be correct */
return 0;
}
/* If we are here, a key has been pressed */
/* How long since last key was pressed?
Must be pressed within 50 seconds (assume 50 ms 'tick') */
if (State_call_count_G > 1000)
{
/* More than 5 seconds since last key
- restart the input process */
State_call_count_G = 0;
Position_G = 0;
}
if (Position_G == 0)
{
PC_LINK_O_Write_Char_To_Buffer('\n');
}
PC_LINK_O_Write_Char_To_Buffer(Key);
Input_G[Position_G] = Key;

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 255

bit INTRUDER_Check_Window_Sensors(void)
{
/* Just a single window 'sensor' here
- easily extended
...
*/
PC_LINK_O_Write_String_To_Buffer("\nWindow damaged");
return 1;
}
/* Default */
return 0;
}
/* --------------------------------------------------------------- */
bit INTRUDER_Check_Door_Sensor(void)
{
/* Single door sensor (access route) */
if (Door_sensor_pin == 0)
{
/* Someone has opened the door
...
PONT, 2001-2003
...
J
...


PES I - 256

void KEYPAD_Update(void)
{
char Key;
/* Scan keypad here
...
*/
if (KEYPAD_in_waiting_index == KEYPAD_in_read_index)
{
KEYPAD_in_waiting_index = 0;
KEYPAD_in_read_index = 0;
}
/* Load keypad data into buffer */
KEYPAD_recv_buffer[KEYPAD_in_waiting_index] = Key;
if (KEYPAD_in_waiting_index < KEYPAD_RECV_BUFFER_LENGTH)
{
/* Increment without overflowing buffer */
KEYPAD_in_waiting_index++;
}
}
bit KEYPAD_Get_Data_From_Buffer(char* const pKey)
{
/* If there is new data in the buffer */
if (KEYPAD_in_read_index < KEYPAD_in_waiting_index)
{
*pKey = KEYPAD_recv_buffer[KEYPAD_in_read_index];
KEYPAD_in_read_index++;
return 1;
}
return 0;
}

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 258

sEOS_ISR() interrupt INTERRUPT_Timer_2_Overflow
{
TF2 = 0; /* Must manually reset the T2 flag

*/

/*===== USER CODE - Begin ================================== */
/* Call RS-232 update function every 5ms */
PC_LINK_O_Update();
/* This ISR is called every 5 ms
- only want to update intruder every 50 ms
...
PONT, 2001-2003
...
J
...


PES I - 259

Extending and modifying the system
• How would you add a “real” keypad?
(See “Patterns for Time-Triggered Embedded Systems, Chap
...
22)

• How would you add additional nodes?
(See “Patterns for Time-Triggered Embedded Systems, Part F)

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

We’ll consider a final case study in the next seminar
...
PONT, 2001-2003
...
J
...


PES I - 261

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 263

Overview
In this session, we will discuss the design of software to control a
small mobile robot
...
microrobotna
...
PONT, 2001-2003
...
J
...


PES I - 264

What can the robot do?
The robot has IR sensors and transmitters that allow him to detect a
black line on a white surface - and follow it
...
microrobotna
...
PONT, 2001-2003
...
J
...


PES I - 265

The robot brain
Mr Line is controlled by an 8051 microcontroller (an AT89C2051)
...


http://www
...
com

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...


http://www
...
com

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...

Frequency =

1
,
x+y

where x and y are in seconds
...


See: “Patterns for Time-Triggered Embedded Systems”, Chapter 33

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
PONT, 2001-2003
...
J
...


PES I - 269

The resulting code
< We’ll discuss the resulting code in the lecture … >

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
...
le
...
uk/engineering/mjp9/robot
...
PONT, 2001-2003
...
J
...


PES I - 271

Conclusions
That brings us to the end of this course!

COPYRIGHT © MICHAEL J
...
Contains material from:
Pont, M
...
(2002) “Embedded C”, Addison-Wesley
Title: Programming Embedded System I
Description: This course is concerned with the implementation of software (and a small amount of hardware) for embedded systems constructed using a single microcontroller. The processors examined in detail are from the 8051 family (including both ‘Standard’ and ‘Small’ devices). All programming is in the ‘C’ language. By the end of the course, you will be able to: 1. Design software for single-processor embedded applications based on small, industry standard, microcontrollers; 2. Implement the above designs using a modern, high-level programming language (‘C’), and 3. Begin to understand issues of reliability and safety and how software design and programming decisions may have a positive or negative impact in this area.