Top Banner
Embedded Systems Basics of Embedded Systems : An embedded system is a computer system designed for specific control functions within a larger system, often with real-time computing constraints. It is embedded as part of a complete device often including hardware and mechanical parts. By contrast, a general-purpose computer, such as a personal computer (PC), is designed to be flexible and to meet a wide range of end-user needs. Embedded systems control many devices in common use today. Embedded systems contain processing cores that are typically either microcontrollers or digital signal processors (DSP). The key characteristic, however, is being dedicated to handle a particular task. Since the embedded system is dedicated to specific tasks, design engineers can optimize it to reduce the size and cost of the product and increase the reliability and performance. Some embedded systems are mass-produced, benefiting from economies of scale. Embedded systems range from portable devices such as digital watches and MP3 players, to large stationary installations like traffic lights, factory controllers, or the systems controlling nuclear power plants. Complexity varies from low, with a single microcontroller chip, to very high with multiple units, peripherals and networks mounted inside a large chassis or enclosure. Characteristics of Embedded Systems: 1. These are designed to do some specific task, rather than be a general-purpose computer for multiple tasks. Some have real time performance constraints that must be met, such as safety and usability; others may have low or no performance requirements, allowing the system hardware to be simplified to reduce costs. 2. They are not always standalone devices. Many of themconsist of small, computerized parts within a larger device that serves a more general purpose. Eg: the Gibson Robot Guitar features an embedded system for tuning the strings, but the overall purpose of the Robot Guitar is, of course, to play music. Similarly, an embedded system in an automobile provides a specific function as a subsystem of the car itself. 3. The program instructions written for embedded systems are referred to as firmware, and are stored in read-only memory or Flash memory chips. They run with limited computer hardware resources: little memory, small or non- existent keyboard or screen.
26
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Introduction To Embedded Systems

Embedded Systems

Basics of Embedded Systems :

An embedded system is a computer system designed for specific control functions within a

larger system, often with real-time computing constraints. It is embedded as part of a complete

device often including hardware and mechanical parts. By contrast, a general-purpose computer,

such as a personal computer (PC), is designed to be flexible and to meet a wide range of end-user

needs. Embedded systems control many devices in common use today.

Embedded systems contain processing cores that are typically either microcontrollers or digital signal processors (DSP). The key characteristic, however, is being dedicated to handle a particular task. Since the embedded system is dedicated to specific tasks, design engineers can optimize it to reduce the size and cost of the product and increase the reliability and performance. Some embedded systems are mass-produced, benefiting from economies of scale.

Embedded systems range from portable devices such as digital watches and MP3 players, to large stationary installations like traffic lights, factory controllers, or the systems controlling nuclear power plants. Complexity varies from low, with a single microcontroller chip, to very high with multiple units, peripherals and networks mounted inside a large chassis or enclosure.

Characteristics of Embedded Systems:

1. These are designed to do some specific task, rather than be a general-purpose computer for multiple tasks. Some have real time performance constraints that must be met, such as safety and usability; others may have low or no performance requirements, allowing the system hardware to be simplified to reduce costs.

2. They are not always standalone devices. Many of themconsist of small, computerized parts within a larger device that serves a more general purpose. Eg: the Gibson Robot Guitar features an embedded system for tuning the strings, but the overall purpose of the Robot Guitar is, of course, to play music. Similarly, an embedded system in an automobile provides a specific function as a subsystem of the car itself.

3. The program instructions written for embedded systems are referred to as firmware, and are stored in read-only memory or Flash memory chips. They run with limited computer hardware resources: little memory, small or non-existent keyboard or screen.

Page 2: Introduction To Embedded Systems

Microprocessor Vs. Microcontroller:

Microprocessor is an IC which has only the CPU inside them i.e. only the processing powers such as Intel’s Pentium 1,2,3,4, core 2 duo, i3, i5 etc. These microprocessors don’t have RAM, ROM, and other peripheral on the chip. A system designer has to add them externally to make them functional. Application of microprocessor includes Desktop PC’s, Laptops, notepads etc. But this is not the case with Microcontrollers. Microcontroller has a CPU, in addition with a fixed amount of RAM, ROM and other peripherals all embedded on a single chip. At times it is also termed as a mini computer or a computer on a single chip. Today different manufacturers produce microcontrollers with a wide range of features available in different versions. Some manufacturers are ATMEL, Microchip, TI, Freescale, Philips, Motorola etc. Microcontrollers are designed to perform specific tasks. Specific means applications where the relationship of input and output is defined. Depending on the input, some processing needs to be done and output is delivered. For example, keyboards, mouse, washing machine, digicam, pendrive, remote, microwave, cars, bikes, telephone, mobiles, watches, etc. Since the applications are very specific, they need small resources like RAM, ROM, I/O ports etc and hence can be embedded on a single chip. This in turn reduces the size and the cost. Microprocessor find applications where tasks are unspecific like developing software, games, websites, photo editing, creating documents etc. In such cases the relationship between input and output is not defined. They need high amount of resources like RAM, ROM, I/O ports etc. The clock speed of the Microprocessor is quite high as compared to the microcontroller. Whereas the microcontrollers operate from a few MHz to 30 to 50 MHz, today’s microprocessor operate above 1GHz as they perform complex tasks. Comparing microcontroller and microprocessor in terms of cost is not justified. Undoubtedly a microcontroller is far cheaper than a microprocessor. However microcontroller cannot be used in place of microprocessor and using a microprocessor is not advised in place of a microcontroller as it makes the application quite costly. Microprocessor cannot be used stand alone. They need other peripherals like RAM, ROM, buffer, I/O ports etc and hence a system designed around a microprocessor is quite costly.

Microcontroller:

A microcontroller (sometimes abbreviated µC, uC or MCU) is a small computer on a single integrated

circuit containing a processor core, memory, and programmable input/output peripherals. Program

memory in the form of NOR flash or OTP ROM is also often included on chip, as well as a typically

small amount of RAM. Microcontrollers are designed for embedded applications, in contrast to

the microprocessors used in personal computers or other general purpose applications.

Microcontrollers are used in automatically controlled products and devices, such as automobile engine control systems, implantable medical devices, remote controls, office machines, appliances, power tools, toys and other embedded systems. By reducing the size and cost compared to a design that uses a separate microprocessor, memory, and input/output devices, microcontrollers make it economical to digitally control even more devices and processes. Mixed signal microcontrollers are common, integrating analog components needed to control non-digital electronic systems.

Some microcontrollers may use four-bit words and operate at clock rate frequencies as low as 4 kHz, for low power consumption (milliwatts or microwatts). They will generally have the ability to retain functionality while waiting for an event such as a button press or other interrupt; power consumption while sleeping (CPU clock and most peripherals off) may be just nanowatts, making many of them well suited for long lasting battery applications. Other microcontrollers may serve performance-critical roles, where they may need to act more like a digital signal processor (DSP), with higher clock speeds and power consumption.

Page 3: Introduction To Embedded Systems

Various Microcontrollers till date:

� ARM core processors (many vendors)

� includes ARM9, ARM Cortex-A8, Sitara ARM Microprocessor

� Atmel AVR (8-bit), AVR32 (32-bit), and AT91SAM (32-bit)

� Cypress Semiconductor's M8C Core used in their PSoC (Programmable System-on-Chip)

� Freescale ColdFire (32-bit) and S08 (8-bit)

� Freescale 68HC11 (8-bit)

� Intel 8051

� Infineon: 8, 16, 32 Bit microcontrollers

� MIPS

� Microchip Technology PIC, (8-bit PIC16, PIC18, 16-bit dsPIC33 / PIC24), (32-bit PIC32)

� NXP Semiconductors LPC1000, LPC2000, LPC3000, LPC4000 (32-bit), LPC900, LPC700 (8-bit)

� Parallax Propeller

� PowerPC ISE

� Rabbit 2000 (8-bit)

� Renesas RX, V850, Hitachi H8, Hitachi SuperH (32-bit), M16C (16-bit), RL78, R8C, 78K0/78K0R (8-bit)

� Silicon Laboratories Pipelined 8-bit 8051 Microcontrollers and mixed-signal ARM-based 32-bit microcontrollers

� STMicroelectronics STM8 (8-bit), ST10 (16-bit) and STM32 (32-bit)

� Texas Instruments TI MSP430 (16-bit)

� Toshiba TLCS-870 (8-bit/16-bit).

Many others exist, some of which are used in very narrow range of applications or are more like applications processors than microcontrollers. The microcontroller market is extremely fragmented, with numerous vendors, technologies, and markets. Note that many vendors sell or have sold multiple architectures.

CLASSIFICATION OF MICROCONTROLLERS:

Page 4: Introduction To Embedded Systems

RISC Vs CISC ARCHITECTURE: The simplest way to examine the advantages and disadvantages of RISC architecture is by contrasting it with it's predecessor: CISC (Complex Instruction Set Computers) architecture.

Multiplying Two Numbers in Memory On the right is a diagram representing the storage scheme for a generic computer. The main memory is divided into locations numbered from (row) 1: (column) 1 to (row) 6: (column) 4. The execution unit is responsible for carrying out all computations. However, the execution unit can only operate on data that has been loaded into one of the six registers (A, B, C, D, E, or F). Let's say we want to find the product of two numbers - one stored in location 2:3 and another stored in location 5:2 - and then store the product back in the location 2:3.

The CISC Approach The primary goal of CISC architecture is to complete a task in as few lines of assembly as possible. This is achieved by building processor hardware that is capable of understanding and executing a series of operations. For this particular task, a CISC processor would come prepared with a specific instruction (we'll call it "MULT"). When executed, this instruction loads the two values into separate registers, multiplies the operands in the execution unit, and then stores the product in the appropriate register. Thus, the entire task of multiplying two numbers can be completed with one instruction:

MULT 2:3, 5:2

MULT is what is known as a "complex instruction." It operates directly on the computer's memory banks and does not require the programmer to explicitly call any loading or storing functions. It closely resembles a command in a higher level language. For instance, if we let "a" represent the value of 2:3 and "b" represent the value of 5:2, then this command is identical to the C statement "a = a * b."

One of the primary advantages of this system is that the compiler has to do very little work to translate a high-level language statement into assembly. Because the length of the code is relatively short, very little RAM is required to store instructions. The emphasis is put on building complex instructions directly into the hardware.

The RISC Approach RISC processors only use simple instructions that can be executed within one clock cycle. Thus, the "MULT" command described above could be divided into three separate commands: "LOAD," which moves data from the memory bank to a register, "PROD," which finds the product of two operands located within the registers, and "STORE," which moves data from a register to the memory banks. In order to perform the exact series of steps described in the CISC approach, a programmer would need to code four lines of assembly:

LOAD A, 2:3 LOAD B, 5:2 PROD A, B STORE 2:3, A

At first, this may seem like a much less efficient way of completing the operation. Because there are more lines of code, more RAM is needed to store the assembly level instructions. The compiler must also perform more

work to convert a high-level language statement into code of this form.

CISC RISC

Emphasis on hardware Emphasis on software

Includes multi-clock

complex instructions Single-clock,

reduced instruction only

Page 5: Introduction To Embedded Systems

However, the RISC strategy also brings some very important advantages. Because each instruction requires only one clock cycle to execute, the entire program will execute in approximately the same amount of time as the multi-cycle "MULT" command. These RISC "reduced instructions" require less transistors of hardware space than the complex

instructions, leaving more room for general purpose registers. Because all of the instructions execute in a uniform amount of time (i.e. one clock), pipelining is possible.

Separating the "LOAD" and "STORE" instructions actually reduces the amount of work that the computer must perform. After a CISC-style "MULT" command is executed, the processor automatically erases the registers. If one of the operands needs to be used for another computation, the processor must re-load the data from the memory bank into a register. In RISC, the operand will remain in the register until another value is loaded in its place.

The Performance Equation The following equation is commonly used for expressing a computer's performance ability:

The CISC approach attempts to minimize the number of instructions per program, sacrificing the number of cycles per instruction. RISC does the opposite, reducing the cycles per instruction at the cost of the number of instructions per program.

RISC Roadblocks Despite the advantages of RISC based processing, RISC chips took over a decade to gain a foothold in the commercial world. This was largely due to a lack of software support.

Although Apple's Power Macintosh line featured RISC-based chips and Windows NT was RISC compatible, Windows 3.1 and Windows 95 were designed with CISC processors in mind. Many companies were unwilling to take a chance with the emerging RISC technology. Without commercial interest, processor developers were unable to manufacture RISC chips in large enough volumes to make their price competitive.

Another major setback was the presence of Intel. Although their CISC chips were becoming increasingly unwieldy and difficult to develop, Intel had the resources to plow through development and produce powerful processors. Although RISC chips might surpass Intel's efforts in specific areas, the differences were not great enough to persuade buyers to change technologies.

The Overall RISC Advantage Today, the Intel x86 is arguable the only chip which retains CISC architecture. This is primarily due to advancements in other areas of computer technology. The price of RAM has decreased dramatically. In 1977, 1MB of DRAM cost about $5,000. By 1994, the same amount of memory cost only $6 (when adjusted for inflation). Compiler technology has also become more sophisticated, so that the RISC use of RAM and emphasis on software has become ideal.

Memory-to-memory:

"LOAD" and "STORE"

incorporated in instructions

Register to register:

"LOAD" and "STORE"

are independent instructions

Small code sizes,

high cycles per second Low cycles per second,

large code sizes

Transistors used for storing

complex instructions Spends more transistors

on memory registers

Page 6: Introduction To Embedded Systems

Types Of RAM & ROM:

Types of RAM

The RAM family includes two important memory devices: static RAM (SRAM) and dynamic RAM (DRAM). The primary difference between them is the lifetime of the data they store. SRAM retains its contents as long as electrical power is applied to the chip. If the power is turned off or lost temporarily, its contents will be lost forever. DRAM, on the other hand, has an extremely short data lifetime-typically about four milliseconds. This is true even when power is applied constantly.

In short, SRAM has all the properties of the memory you think of when you hear the word RAM. Compared to that, DRAM seems kind of useless. By itself, it is. However, a simple piece of hardware called a DRAM controller can be used to make DRAM behave more like SRAM. The job of the DRAM controller is to periodically refresh the data stored in the DRAM. By refreshing the data before it expires, the contents of memory can be kept alive for as long as they are needed. So DRAM is as useful as SRAM after all.

When deciding which type of RAM to use, a system designer must consider access time and cost. SRAM devices offer extremely fast access times (approximately four times faster than DRAM) but are much more expensive to produce. Generally, SRAM is used only where access speed is extremely important. A lower cost-per-byte makes DRAM attractive whenever large amounts of RAM are required. Many embedded systems include both types: a small block of SRAM (a few kilobytes) along a critical data path and a much larger block of DRAM (perhaps even Megabytes) for everything else.

Types of ROM

Memories in the ROM family are distinguished by the methods used to write new data to them (usually called programming), and the number of times they can be rewritten. This classification reflects the evolution of ROM devices from hardwired to programmable to erasable-and-programmable. A common feature of all these devices is their ability to retain data and programs forever, even during a power failure.

The very first ROMs were hardwired devices that contained a preprogrammed set of data or instructions. The contents of the ROM had to be specified before chip production, so the actual data could be used to arrange the transistors inside the chip. Hardwired memories are still used, though they are now called masked ROMs to distinguish them from other types of ROM. The primary advantage of a masked ROM is its low production cost. Unfortunately, the cost is low only when large quantities of the same ROM are required.

One step up from the masked ROM is the PROM (programmable ROM), which is purchased in an unprogrammed state. If you were to look at the contents of an unprogrammed PROM, you would see that the data is made up entirely of 1's. The process of writing your data to the PROM involves a special piece of equipment called a device programmer. The device programmer writes data to the device one word at a time by applying an electrical charge to the input pins of the chip. Once a PROM has been programmed in this way, its contents can never be changed. If the code or data stored in the PROM must be changed, the current device must be discarded. As a result, PROMs are also known as one-time programmable (OTP) devices.

An EPROM (erasable-and-programmable ROM) is programmed in exactly the same manner as a PROM. However, EPROMs can be erased and reprogrammed repeatedly. To erase an EPROM, you simply expose the device to a strong source of ultraviolet light. (A window in the top of the device allows the light to reach the silicon.) By doing this, you essentially reset the entire chip to its initial--unprogrammed--state. Though more expensive than PROMs, their ability to be reprogrammed makes EPROMs an essential part of the software development and testing process.

Page 7: Introduction To Embedded Systems

Hybrids

As memory technology has matured in recent years, the line between RAM and ROM has blurred. Now, several types of memory combine features of both. These devices do not belong to either group and can be collectively referred to as hybrid memory devices. Hybrid memories can be read and written as desired, like RAM, but maintain their contents without electrical power, just like ROM. Two of the hybrid devices, EEPROMand flash, are descendants of ROM devices. These are typically used to store code.

EEPROMs are electrically-erasable-and-programmable. Internally, they are similar to EPROMs, but the erase operation is accomplished electrically, rather than by exposure to ultraviolet light. Any byte within an EEPROM may be erased and rewritten. Once written, the new data will remain in the device forever--or at least until it is electrically erased. The primary tradeoff for this improved functionality is higher cost, though write cycles are also significantly longer than writes to a RAM. So you wouldn't want to use an EEPROM for your main system memory.

Flash memory combines the best features of the memory devices described thus far. Flash memory devices are high density, low cost, nonvolatile, fast (to read, but not to write), and electrically reprogrammable. These advantages are overwhelming and, as a direct result, the use of flash memory has increased dramatically in embedded systems. From a software viewpoint, flash and EEPROM technologies are very similar. The major difference is that flash devices can only be erased one sector at a time, not byte-by-byte. Typical sector sizes are in the range 256 bytes to 16KB. Despite this disadvantage, flash is much more popular than EEPROM and is rapidly displacing many of the ROM devices as well.

The third member of the hybrid memory class is NVRAM (non-volatile RAM). Nonvolatility is also a characteristic of the ROM and hybrid memories discussed previously. However, an NVRAM is physically very different from those devices. An NVRAM is usually just an SRAM with a battery backup. When the power is turned on, the NVRAM operates just like any other SRAM. When the power is turned off, the NVRAM draws just enough power from the battery to retain its data. NVRAM is fairly common in embedded systems. However, it is expensive--even more expensive than SRAM, because of the battery--so its applications are typically limited to the storage of a few hundred bytes of system-critical information that can't be stored in any better way.

Table 1 summarizes the features of each type of memory discussed here, but keep in mind that different memory types serve different purposes. Each memory type has its strengths and weaknesses. Side-by-side comparisons are not always effective.

Type Volatile? Writeable? Erase

Size

Max Erase

Cycles Cost (per Byte) Speed

SRAM Yes Yes Byte Unlimited Expensive Fast

DRAM Yes Yes Byte Unlimited Moderate Moderate

Masked

ROM No No n/a n/a Inexpensive Fast

PROM No Once, with a device

programmer n/a n/a Moderate Fast

EPROM No Yes, with a device

programmer

Entire

Chip

Limited (consult

datasheet) Moderate Fast

Page 8: Introduction To Embedded Systems

EEPROM No Yes Byte Limited (consult

datasheet) Expensive

Fast to read, slow to

erase/write

Flash No Yes Sector Limited (consult

datasheet) Moderate

Fast to read, slow to

erase/write

NVRAM No Yes Byte Unlimited Expensive (SRAM

+ battery) Fast

Table 1. Characteristics of the various memory types

When working with microcontrollers, many of the tasks usually consist of controlling the peripherals that are connected to the device, respectively programming the subsystems that are contained in the controller (which by itself communicate with the circuitry connected to the controller).

The AVR series of microcontrollers offers two different ways to perform this task:

· There's a separate I/O address space available that can be addressed with specific I/O instructions that are applicable to some or all of the I/O address space (in, out, sbi etc.), known as I/O mapping.

· The entire I/O address space is also made available as memory-mapped I/O, i. e. it can be accessed using all the MCU instructions that are applicable to normal data memory. The I/O register space is mapped into the data memory address space with an offset of 0x20 since the bottom of this space is reserved for direct access to the MCU registers. (Actual SRAM is available only behind the I/O register area, starting at either address 0x60, or 0x100 depending on the device.).

This is why there are two sets of addresses in the AVR data sheets. The first address is using I/O mapping and the second address in brackets is the memory mapped approach.

Registers

Registers are special storages with 8 bits capacity and they look like this:

7 6 5 4 3 2 1 0

Note the numeration of these bits: the least significant bit starts with zero (20 = 1).

A register can either store numbers from 0 to 255 (positive number, no negative values), or numbers from -128 to

+127 (whole number with a sign bit in bit 7), or a value representing an ASCII-coded character (e.g. 'A'), or just

eight single bits that do not have something to do with each other (e.g. for eight single flags used to signal eight

different yes/no decisions).

The special character of registers, compared to other storage sites, is that

• they can be used directly in assembler commands,

• operations with their content require only a single command word,

• they are connected directly to the central processing unit called the accumulator,

Page 9: Introduction To Embedded Systems

• they are source and target for calculations. There are 32 registers in an AVR. They are originally named r0 to r31. However certain instructions will not work in

registers r0 to r15 e.g. ldi will only work on registers r16 to r31.

About Keil Software

About the Keil Compiler

Keil Software publishes one of the most complete development tool suites for 8051 software, which is used throughout industry. For

development of C code, their Developer's Kit product includes their C51 compiler, as well as an integrated 8051 simulator for debugging.

The C programming language was designed for computers, though, and not embedded systems. It does not support direct access to registers,

nor does it allow for the reading and setting of single bits, two very important requirements for 8051 software. In addition, most software

developers are accustomed to writing programs that will by executed by an operating system, which provides system calls the program may use

to access the hardware. However, much code for the 8051 is written for direct use on the processor, without an operating system. To support

this, the Keil compiler has added several extensions to the C language to replace what might have normally been implemented in a system call,

such as the connecting of interrupt handlers.

The purpose is to further explain the limitations of the Keil compiler, the modifications it has made to the C language, and how to account for

these in developing software for the 8051 micro controller.

Keil Limitations

There are several very important limitations in the evaluation version of Keil's Developer's Kit that users need be aware of when writing

software for the 8051.

Object code must be less than 2 Kbytes

The compiler will compile any-sized source code file, but the final object code may not exceed 2 Kbytes. If it does, the linker will refuse to create

a final binary executable (or HEX file) from it. Along the same lines, the debugger will refuse any files that are over 2Kbytes, even if they were

compiled using a different software package.

Program code starts at address 0x4000

All C code compiled and linked using the Keil tools will begin at address 0x4000 in code memory. Such code may not be programmed into

devices with less than 16Kbytes of Read-Only Memory. Code written in assembly may circumvent this limitation by using the "origin" keyword

to set the start to address 0x0000. No such work-around exists for C programs, though. However, the integrated debugger in the evaluation

software may still be used for testing code. Once tested, the code may be compiled by the full version of the Keil software, or by another

compiler that supports the C extensions used by Keil.

C Modifications

The Keil C compiler has made some modifications to an otherwise ANSI-compliant implementation of the C programming language. These

modifications were made solely to facilitate the use of a higher-level language like C for writing programs on micro controllers.

Variable Types

The Keil C compiler supports most C variable types and adds several of its own.

Standard Types

Page 10: Introduction To Embedded Systems

The evaluation version of the Keil C compiler supports the standard ANSI C variable types, with the exception of the floating-point types. These

types are summarized below.

Type Bits Bytes Range

Char 8 1 -128 to +127

unsigned char 8 1 0 to 255

enum 16 2 -32,768 to +32,767

short 16 2 -32,768 to +32,767

unsigned short 16 2 0 to 65,535

int 16 2 -32,768 to +32,767

unsigned int 16 2 0 to 65,535

long 32 4 -2,147,483,648 to +2,147,483,647

unsigned long 32 4 0 to 4,294,697,295

In addition to these variable types, the compiler also supports the struct and union data structures, as well as type redefinition using typedef.

Keil Types

To support a micro controller and embedded systems applications, Keil added several new types to their compiler. These are summarized in the

table below

Type Bits Bytes Range

Bit 1 0 0 to 1

Sbit 1 0 0 to 1

Sfr 8 1 0 to 255

sf16 16 2 0 to 65,535

Of these, only the bit type works as a standard variable would. The other three have special behavior that a programmer must be aware of.

bit

This is a data type that gets allocated out of the 8051's bit-addressable on-chip RAM. Like other data types, it may be declared as either a

variable. However, unlike standard C types, if may not be used as a pointer. An example of its usage follows.

/* declare two bit variables - the compiler will decide which */

/* addresses they are at. Initialize them to 0 and 1. */

bit testbit1 = 0;

bit testbit2 = 1;

/* set testbit1 to the value in testbit2 */

Page 11: Introduction To Embedded Systems

testbit1 = testbit2;

/* clear testbit2 */

testbit2 = 0;

/* testbit1 is now a 1, and testbit2 is now a 0 */

/* Note that the assignment of testbit2 to testbit1 only copied */

/* the contents of testbit2 into testbit1. It did *not* change */

/* the location of testbit1 to be the same as testbit2. */

sbit, sfr, and sf16

These are special types for accessing 1-bit, 8-bit, and 16-bit special function registers. Because there is no way to indirectly address registers in

the 8051, addresses for these variables must be declared outsite of functions within the code. Only the data addressed by the variable may be

manipulated in the code. An example follows:

/* create an sbit variable that points to pin 0 of port 1 */

/* note that this is done outside of any functions! */

sbit P10 = 0x90;

/* now the functions may be written to use this location */

void main (void)

{

/* forever loop, toggling pin 0 of port 1 */

while (1==1)

{

P10 = !P10;

delay (500); /* wait 500 microseconds */

}

}

Conveniently, the standard special function registers are all defined in the reg51.h file that any developer may include into their source file.

Only registers unique to the particular 8051-derivative being used for the project need have these variable declared, such as registers and bits

related to a second on-chip serial port

Keil Variable Extensions

In writing applications for a typical computer, the operating system handles manages memory on behalf of the programs, eliminating their need

to know about the memory structure of the hardware. Even more important, most computers having a unified memory space, with the code

and data sharing the same RAM. This is not true with the 8051, which has separate memory spaces for code, on-chip data, and external data.

To accommodate for this when writing C code, Keil added extensions to variable declarations to specify which memory space the variable is

allocated from, or points to. The most important of these for student programmers are summarized in the following table.

Page 12: Introduction To Embedded Systems

Extension Memory Type Related ASM

Data Directly-addressable data memory (data memory addresses 0x00-0x7F) MOV A, 07Fh

Idata Indirectly-addressable data memory (data memory addresses 0x00-0xFF) MOV R0, #080h , MOV A, R0

Xdata External data memory MOVX @DPTR

Code Program memory MOVC @A+DPTR

These extensions may be used as part of the variable type in declaration or casting by placing the extension after the type, as in the example

below. If the memory type extension is not specified, the compiler will decide which memory type to use automatically, based on the memory

model (SMALL, COMPACT, or LARGE, as specified in the project properties in Keil).

/* This is a function that will calculate and return a checksum of */

/* a range of addresses in code memory, using a simple algorithm */

/* that simply adds each consecutive byte together. This could be */

/* useful for verifying if the code in ROM got corrupted (like if */

/* the Flash device were wearing out). */

unsigned int checksum (unsigned int start, unsigned int end)

{

/* first, declare pointers to the start and end of */

/* the range in code memory. */

unsigned int code *codeptr, *codeend;

/* now declare the variable the checksum will be */

/* calculated in. Because direct-addressable data */

/* is faster to access than indirect, and this */

/* variable will be accessed frequently, we will */

/* declare it in data memory (instead of idata). */

/* In reality, if left unspecified, the compiler */

/* would probably leave it in the accumulator for */

/* even faster access, but that would defeat the */

/* point of this example. */

unsigned int data checksum = 0;

/* Initialize the codestart and codeend pointers to */

Page 13: Introduction To Embedded Systems

/* the addresses passed into the function as params. */

/* because start and end are passed in as values, */

/* not pointers, they must be cast to the correct */

/* pointer type */

codeptr = (unsigned int code *)start;

codeend = (unsigned int code *)end;

/* Now perform the checksum calculation, looping */

/* until the end of the range is reached. */

while (codeptr <= codeend)

{

checksum = checksum + (unsigned int data)*codeptr;

codeptr++; /* go to the next address */

}

return (checksum);

}

Keil Function Extensions

As in most other C compilers, functions may be declared in one of two fashions:

unsigned int functionname (unsigned int var)

{

....

return (var);

} functionname (var)

unsigned int var

{

....

return (var);

}

Most modern programmers use the first syntax, as do the examples in this document.

Page 14: Introduction To Embedded Systems

Keil provides two important extensions to the standard function declaration to allow for the creation of interrupt handlers and reentrant

functions.

interrupt

In writing applications for a typical computer, the operating system provides system calls for setting a function, declared in the standard

manner, as the handler for an interrupt. However, in writing code for an 8051 without an operating system, such a system would not be

possible using solely C code. To eliminate this problem, the Keil compiler implements a function extension that explicitly declares a function as

an interrupt handler. The extension is interrupt, and it must be followed by an integer specifying which interrupt the handler is for. For

example:

/* This is a function that will be called whenever a serial */

/* interrupt occurs. Note that before this will work, interrupts */

/* must be enabled. See the interrupt example in the appendix. */

void serial_int (void) interrupt 4

{

...

}

In the example, a function called serial_int is set as the handler for interrupt 4, which is the serial port interrupt. The number is calculated by

subtracting 3 from the interrupt vector address and dividing by 8. The five standard interrupts for the 8051 are as follows:

Interrupt Flag Vector Address

Reset - 0000

External 0 IE0 0003h

Timer 0 TF0 000Bh

External 1 IE1 0013h

Timer 1 TF1 001Bh

Serial RI/TI 0023h

Other interrupts are dependent on the implementation in the particular 8051-derivative being used in the project, but may be calculated in the

same manor using the vector addresses specified by the manufacturer.

using

Since the processor only save the current program counter before executing an interrupt handler, the handler can potentially damage any data

that was in the registers prior to the interrupt. This in turn would corrupt the program once the processor goes back to where it left off. To

avoid this, the Keil compiler determines which registers will be used by the interrupt handler function, pushes them out to the stack, executes

the handler, and then restores the registers from the stack, before returning to the interrupted code. However, this incurs extra time, especially

if a lot of registers will be used. It is preferred that as little time be spent in interrupts as possible. To decrease this time, Keil provides an

optional extension, using, to the interrupt extension that tells the compiler to simple change to a new register bank prior to executing the

handler, instead of pushing the registers to the stack.

/* This is a function that will be called whenever a serial */

/* interrupt occurs. Prior to executing the handler, the */

Page 15: Introduction To Embedded Systems

/* processor will switch to register bank 1

void serial_int (void) interrupt 4 using 1

{

...

}

In the 8051, interrupts have two possible priorities: high and lo. If, during the processing of an interrupt, another interrupt of the same priority

occurs, the processor will continue processing the first interrupt. The second interrupt will only be processed after the first has finished.

However, if an interrupt of a higher priority arrives, the first (low priority) interrupt will itself be interrupted, and not resume until the higher

priority interrupt has finished. Because of this, all interrupts of the same priority may use the same register bank.

The using extension should be used when quick execution time is of high importance, or when other functions are called from the interrupt

handler, as it would otherwise push all of the registers on to the stack prior to calling the function, incurring more time penalties.

Reentrant

Similar to the case described for interrupts above, it is possible for a single function to be interrupted by itself. For example, in the middle of

normal execution of the function, the interrupt occurs, and that interrupt makes a call to the same function. While the interrupt handler will

save the registers before entering this function, no protective measures are taken from overwriting the contents of local variables allocated in

data memory. When the interrupt is serviced and control is passed back to normal execution, the corrupted data in those variables could ruin

the entire program.

The general term for a function that may be called more than once simultaneously is "reentrant." Accordingly, the reentrant extension may be

used in a function declaration to force the compiler to maintain a separate data area in memory for each instance of the function. While safe,

this does have the potential to use large area of the rather limited data memory. An example of such a function follows.

/* Because this function may be called from both the main program */

/* and an interrupt handler, it is declared as reentrant to */

/* protect its local variables. */

int somefunction (int param) reentrant

{

...

return (param);

}

/* The handler for External interrupt 0, which uses somefunction() */

void external0_int (void) interrupt 0

{

...

somefunction(0);

Page 16: Introduction To Embedded Systems

}

/* the main program function, which also calls somefunction() */

void main (void)

{

while (1==1)

{

...

somefunction();

}

}

Apart from knowing Keil Software for programming a Microcontroller we have pre-defined functions and usage of variables for interfacing LEDs, switches and LCDs.

LOOPS IN C:

Loops are used to repeat one statement or set statements more than one time. Most real programs contain some construct that loops within the program, performing repetitive actions on a stream of data or a region of memory. There are several ways to loop in C.

For Loop For loop is a counter loop. The for loop allows automatic initialization of instrumentation of a counter variable. The general form is for (initialization; condition; increment/decrement) { statements block } If the statement block is only one statement, the braces are not necessary. Although the for allows a number of variations, generally the initialization is used to set a counter variable to its starting value. The condition is generally a relational statement that checks the counter variable against a termination value, and the increment increments (or decrements) the counter value. The loop repeats until the condition becomes false. Example Main(){ int i; for(i = 0; i < count; i++) { printf(“%d\n”,i); } }

Page 17: Introduction To Embedded Systems

While Loop The while loop repeats a statement until the test at the top proves false. The while loop has the general form: while(condition) { statement block } The while tests its condition at the top of the loops. Therefore, if the condition is false to begin with, the loop will not execute at all. The condition may be any expression. An example of a while follows. It reads characters until end-of-file is encountered. Example main(){ int t = 0; while(t<=10) { printf(“%d\n”,t); t=t+1; } }

do-while loop This is very similar to the while loop except that the test occurs at the end of the loop body. This guarantees that the loop is executed at least once before continuing. Such a setup is frequently used where data is to be read. The test then verifies the data, and loops back to read again if it was unacceptable. void main(void){ int val; do { printf("Enter 1 to continue and 0 to exit :"); scanf("%d\n", &val); } while (val!= 1 && val!= 0) }

SWITCH BOUNCING & DEBOUNCING:

Switch debounce and switch bounce are two different things.

Switch Bounce happens when you close a mechanical switch. When you close a switch it

tends to literally bounce upon the metal contact which connects the circuit.

It's almost like dropping a basketball. The basketball will hit then ground (analogous to a

closed switch) then bounce back up (analogous to a open switch) then bounce back down,

then up, then down, etc... until it permanently stays on the ground (permanently closed).

Usually switches take a few microseconds to a few milliseconds to completely close. What

this means in terms of digital logic is that as the switch physically bounces your logic can

switch back and forth low-to-high-to-low-etc... until your switch settles down.

Switch Debounce is the process of getting rid of switch bounce. One solution to get rid of

switch bounce is given above by dlgoff

Page 18: Introduction To Embedded Systems

Set and forget

Figure 1 shows the classic debounce circuit. Two cross-coupled NAND gates form a simple Set-Reset (SR) latch.

The design requires a double throw switch. Two pull-up resistors generate a logic one for the gates; the switch pulls

one of the inputs to ground.

Figure 1: The SR debouncer

The SR latch is a rather funky beast, as confusing to non-EEs as recursion is to, well, just about everyone.

With the switch in the position shown the upper gate's output will be a one, regardless of the value of the other input.

That and the one created by the bottom pull-up resistor drives the lower NAND to a zero, which races around back

into the other gate. If the switch moves between contacts and is for a while suspended in the nether region between

terminals, the latch maintains its state because of the looped-back zero from the bottom gate.

The switch moves a rather long way between contacts. It may bounce around a bit, but will never bang all the way

back to the other contact. Thus, the latch's output is guaranteed bounce-free.

The circuit suggests an alternative approach, a software version of the same idea. Why not skip the NAND pair and

run the two contacts, with pull-ups, directly to input pins on the CPU? Sure, the computer will see plenty of

bounciness, but write a trivial bit of code that detects any assertion of either pole, which means the switch is in that

position, as follows:

if(switch_hi())state=ON;

if(switch_lo())state=OFF;

The functions switch_hi and switch_lo each read one of the two poles. Other functions in the program examine

variable stateto determine the switch's position. This saves two gates but costs one extra input pin on the processor.

It's the simplest—and most reliable—debounce code possible.

(OK, so I slipped some code in after all).

An RC debouncer

The SR circuit is the most effective of all debouncing approaches but it's rarely used. Double-throw switches are

bulkier and more expensive than the simpler single-pole versions. An awful lot of us use switches that are plated

onto the circuit board, and it's impossible to make double-pole versions of these. So EEs prefer alternative designs

that work with cheap single-pole switches.

Page 19: Introduction To Embedded Systems

Though complex circuits using counters and smart logic satisfy our longing for pure digital solutions to all

problems, from signal processing to divorce, it's easier and cheaper to exploit the peculiar nature of a resistor-

capacitor (RC) network.

Charge or discharge a capacitor through a resistor and you'll find the voltage across the cap rises slowly; it doesn't

snap to a new value like a sweet little logic circuit. Increase the value of either component and the time lag ("time

constant" in EE lingo) increases.

Figure 2 shows a typical RC debouncer. A simple circuit, surely, yet one that hides a surprising amount of

complexity.

Page 20: Introduction To Embedded Systems

8051 Architecture:

Page 21: Introduction To Embedded Systems
Page 22: Introduction To Embedded Systems

LCD :

The most commonly used Character based LCDs are based on Hitachi's HD44780 controller or other which

are compatible with HD44580. In this tutorial, we will discuss about character based LCDs, their interfacing with

various microcontrollers, various interfaces (8-bit/4-bit), programming, special stuff and tricks you can do with these

simple looking LCDs which can give a new look to your application.

The most commonly used LCDs found in the market today are 1 Line, 2 Line or 4 Line LCDs which have

only 1 controller and support at most of 80 charachers, whereas LCDs supporting more than 80 characters make use

of 2 HD44780 controllers.

Most LCDs with 1 controller has 14 Pins and LCDs with 2 controller has 16 Pins (two pins are extra in

both for back-light LED connections). Pin description is shown in the table below.

Pin No. Name Description

Pin no. 1 VSS Power supply (GND)

Pin no. 2 VCC Power supply (+5V)

Pin no. 3 VEE Contrast adjust

Pin no. 4 RS 0 = Instruction input

1 = Data input

Pin no. 5 R/W 0 = Write to LCD module

1 = Read from LCD module

Pin no. 6 EN Enable signal

Pin no. 7 D0 Data bus line 0 (LSB)

Pin no. 8 D1 Data bus line 1

Pin no. 9 D2 Data bus line 2

Pin no. 10 D3 Data bus line 3

Pin no. 11 D4 Data bus line 4

Page 23: Introduction To Embedded Systems

Pin no. 12 D5 Data bus line 5

Pin no. 13 D6 Data bus line 6

Pin no. 14 D7 Data bus line 7 (MSB)

Table 1: Character LCD pins with 1 Controller

Pin No. Name Description

Pin no. 1 D7 Data bus line 7 (MSB)

Pin no. 2 D6 Data bus line 6

Pin no. 3 D5 Data bus line 5

Pin no. 4 D4 Data bus line 4

Pin no. 5 D3 Data bus line 3

Pin no. 6 D2 Data bus line 2

Pin no. 7 D1 Data bus line 1

Pin no. 8 D0 Data bus line 0 (LSB)

Pin no. 9 EN1 Enable signal for row 0 and 1 (1stcontroller)

Pin no. 10 R/W 0 = Write to LCD module

1 = Read from LCD module

Pin no. 11 RS 0 = Instruction input

1 = Data input

Pin no. 12 VEE Contrast adjust

Pin no. 13 VSS Power supply (GND)

Pin no. 14 VCC Power supply (+5V)

Pin no. 15 EN2 Enable signal for row 2 and 3 (2ndcontroller)

Pin no. 16 NC Not Connected

Table 2: Character LCD pins with 2 Controller

Page 24: Introduction To Embedded Systems

LCD interfacing with Microcontrollers tutorial - LCD Commands and Insturctions

►Commands and Instruction set

Only the instruction register (IR) and the data register (DR) of the LCD can be controlled by the MCU. Before starting the internal operation of the LCD, control information is temporarily stored into these registers to allow interfacing with various

MCUs, which operate at different speeds, or various peripheral control devices. The internal operation of the LCD is determined by signals sent from the MCU. These signals, which include register selection signal (RS), read/write signal (R/W), and the data bus (DB0 to DB7), make up the LCD instructions (Table 3). There are four categories of instructions that:

• Designate LCD functions, such as display format, data length, etc.

• Set internal RAM addresses

• Perform data transfer with internal RAM

• Perform miscellaneous functions

Page 25: Introduction To Embedded Systems

Table 3: Command and Instruction set for LCD type HD44780

Although looking at the table you can make your own commands and test them. Below is a breif list of useful commands which are used frequently while working on the LCD.

No. Instruction Hex Decimal

1 Function Set: 8-bit, 1 Line, 5x7 Dots 0x30 48

2 Function Set: 8-bit, 2 Line, 5x7 Dots 0x38 56

3 Function Set: 4-bit, 1 Line, 5x7 Dots 0x20 32

4 Function Set: 4-bit, 2 Line, 5x7 Dots 0x28 40

Page 26: Introduction To Embedded Systems

5 Entry Mode 0x06 6

6 Display off Cursor off (clearing display without clearing DDRAM content)

0x08 8

7 Display on Cursor on 0x0E 14

8 Display on Cursor off 0x0C 12

9 Display on Cursor blinking 0x0F 15

10 Shift entire display left 0x18 24

12 Shift entire display right 0x1C 30

13 Move cursor left by one character 0x10 16

14 Move cursor right by one character 0x14 20

15 Clear Display (also clear DDRAM content) 0x01 1

16 Set DDRAM address or coursor position on display

0x80+add* 128+add*

17 Set CGRAM address or set pointer to CGRAM location

0x40+add** 64+add**

Table 4: Frequently used commands and instructions for LCD

* DDRAM address given in LCD basics section see Figure 2,3,4

** CGRAM address from 0x00 to 0x3F, 0x00 to 0x07 for char1 and so on..

The table above will help you while writing programs for LCD. But after you are done testing with the table 4, i recommend

you to use table 3 to get more grip on working with LCD and trying your own commands. In the next section of the tutorial

we will see the initialization with some of the coding examples in C as well as assembly.