Browse by

Part 1: Introduction to 8051 microcontrollers

written by Ibrahim KAMAL - 4 Comments

This tutorial is specially tailored to electronics and robotics hobbyists that have already realized some simple electronics projects and want to go a step further and start using microcontrollers in their projects, more precisely the 89S52 microcontroller. This first part introduce the main aspects and characteristics of the 89S52, providing to the absolute beginners a base of knowledge, which will help them to understand more advanced issues in the next part of the tutorial.

Introduction to micro-controllers
A micro-controller can be compared to a small stand alone computer, it is a very powerful device, which is capable of executing a series of pre-programmed tasks and interacting with other hardware devices. Being packed in a tiny integrated circuit (IC) whose size and weight is usually negligible, it is becoming the perfect controller for robots or any machines requiring some kind of intelligent automation. A single microcontroller can be sufficient to control a small mobile robot, an automatic washer machine or a security system. Any microcontroller contains a memory to store the program to be executed, and a number of input/output lines that can be used to interact with other devices, like reading the state of a sensor or controlling a motor. Nowadays, microcontrollers are so cheap and easily available that it is common to use them instead of simple logic circuits like counters for the sole purpose of gaining some design flexibility and saving some space. Some machines and robots will even rely on a multitude of microcontrollers, each one dedicated to a certain task. Most recent microcontrollers are „In System Programmable‟, meaning that you can modify the program being executed, without removing the microcontroller from its place. Today, microcontrollers are an indispensable tool for the robotics hobbyist as well as for the engineer. Starting in this field can be a little difficult, because you usually can‟t understand how everything works inside that integrated circuit, so you have to study the system gradually, a small part at a time, until you can figure out the whole image and understand how the system works.

The 8051 micro-controller architecture
The 8051 is the name of a big family of microcontrollers. The device which we are going to use along this tutorial is the „AT89S52„ which is a typical 8051 microcontroller manufactured by Atmel™. Note that this part doesn‟t aim to explain the functioning of the different components of a 89S52 microcontroller, but rather to give you a general idea of the organization of the chip and the available features, which shall be explained in detail along this tutorial. The block diagram provided by Atmel™ in their datasheet showing the architecture the 89S52 device can seem very complicated, and since we are going to use the C high level language to program it, a simpler architecture can be represented as the figure 1.2.A.

figure 1.2.A

This figures shows the main features and components that the designer can interact with. You can notice that the 89S52 has four different ports, each one having eight Input/output lines providing a total of 32 I/O lines. Those ports can be used to output DATA and orders do other devices, or to read the state of a sensor, or a switch. Most of the ports of the 89S52 have „dual function‟ meaning that they can be used for two different functions: the fist one is to perform input/output operations and the second one is used to implement special features of the microcontroller like counting external pulses, interrupting the execution of the program according to external events, performing serial data transfer or connecting the chip to a computer to update the software. Each port has eight pins, and will be treated from the software point of view as an 8-bit variable called „register‟, each bit being connected to a different Input/Output pin. You can also notice two different memory types: RAM and EEPROM. Shortly, RAM is used to store variable during program execution, while the EEPROM memory is used to store the program itself, that‟s why it is often referred to as the „program memory‟. The memory organization will b e discussed in detail later. The special features of the 89S52 microcontroller are grouped in the blue box at the bottom of figure 1.2.A. At this stage of the tutorial, it is just important to note that the 89S52 incorporates hardware circuits that can be used to prevent the processor from executing various repetitive tasks and save processing power for

more complex calculations. Those simple tasks can be counting the number of external pulses on a pin, or generating precise timing sequences. It is clear that the CPU (Central Processing Unit) is the heart of the microcontrollers, It is the CPU that will Read the program from the FLASH memory and execute it by interacting with the different peripherals discussed above.

figure 1.2.B

Figure 1.2.B shows the pin configuration of the 89S52, where the function of each pin is written next to it, and, if it exists, the dual function is written between brackets. The pins are written in the same order as in the block diagram offigure 1.2.A, except for the VCC and GND pins which I usually note at the top and the bottom of any device. Note that the pin that have dual functions, can still be used normally as an input/output pin. Unless you program uses their dual functions, All the 32 I/O pins of the microcontroller are configured as input/output pins. Most of the function of the pins of the 89S52 microcontroller will be discussed in detail, except for the pins required to control an external memory, which are the pins number 29, 30 and 31. Since we are not going to use any external memory, pins 29 and 30 will be ignored through all the tutorial, and pin 31 (EA) always connected to VCC (5 Volts) to enable the micro-controller to use the internal on chip memory rather than an external one (connecting the pin 31 to ground would indicate to the microcontroller that an external memory is to be used instead of the internal one).

you can compare an EEPROM to the Hard-Disk of a desktop computer from a general point of view. is divided into to main parts. as writing general purpose data
. In order to use bigger values. which contains 256 registers. and the SFR part. also called FLASH memory is a more elaborated ROM (Read Only Memory) which is the memory where the program being executed is stored. various register can be used simultaneously.B
A programmer that would use the assembly language. capable of storing values ranging from 0 to 255. While an EEPROM. it has basically the same purpose of the RAM in a desktop computer. The address is noted in Hexadecimal format as this notation simplifies digital logic calculations for the designers. which is to store some data required during the execution time of different programs. the GPR part. like in any digital system.
figure 1. SFRs can be used to control Input/Output lines. Figure 1. In the 8051 family of microcontrollers for example. The EEPROM term stands for Electronically Erasable and Programmable Read Only Memory.A
As you shall see. 00 corresponds to the first location and FF which is equal to 256 corresponds to the last location. GPR stands for „General Purpose Register‟ and are the registers that you can use to store any data during the execution of your program. to retrieve data transmitted through the serial port of a desktop computer.3. SFRs (Special function Register) are registers used to control the functioning of the microcontroller and to assist the processor through the various operations being executed. Figure 1. Even if that‟s not exactly t rue.B shows the memory organization of the 256 registers of the RAM of the 89S52 microcontroller. memory is organized in Registers. most registers are 8-bit register. or to configure one of the on-chip counters and timers.Ashows a typical 8-bit registers.Memory organization
A RAM stands for Random Access Memory.3. Each register is composed of a number of bits (usually eight) where the data can be stored.3. the RAM memory of the 89S52.
figure 1. In microcontrollers. In a memory each register has a specific address which is used by the processor to read and write from specific memory location. have to take this memory organization into consideration while choosing the locations where his variables are stored. Which is the basic unit of construction of a memory.3. For example. where the notation D0 to D7 stands for the 8 DATA bits of the register.

the clock can be fixed to different value by connecting a crystal to the pins 18 and 19. Those pulses will cadence all the events happening inside a microcontroller. In the 89S52 microcontroller. if the CPU is waiting for some result of mathematical operation from the ALU (Arithmetic and Logic Unit).into special function registers could prevent the microcontroller from working correctly. this part will be totally handled by the compiler. then you work on the programming while taking in consideration the
. those pulses will also assure the synchronization of the events between various components inside the microcontroller.
Life cycle of a micro-controller project
Before passing to the next part of the tutorial.5.5. The synchronization of those two devices is maintained because they share the same clock.A. without a precise clock. The maximum operating frequency of the AT89S52 is 33 Mhz. it will be known – according to very specific protocol – when and where the resulting data will be delivered to the CPU.A
As you can see in figure 1. or any other device that relies on time measurements. it would be impossible to build a „ Real Time System„. its imperative to imagine how it can be implemented from the hardware point of view. but since we will use the C language using the KEIL IDE (integrated development environment). It can be deduced that the precision of the timing of a microcontroller depends on the frequency of its clock. however other manufacturers like philips built similar 8051 microcontrollers that can run at frequencies up to 120 Mhz. For example.
Clock concept
The clock concept is found in all modern digital electronics. is important to have a general idea of the steps that are followed to realize a project. it is a simple circuit that will generate pulses of electricity at a very specific frequency. In other words. before passing to the programming phase. from the very beginning when you get an idea to the very end when you finalize your project. after you settle on the choice of your project in the „brain storming‟ part. because programming is much more flexible than the hardware design. The clock has another very important role which is to enable the microcontroller to count timing. Those crystals are sold with the frequency written on them in Mega Hertz.
figure 1. you start by designing the hardware.

Even if you‟re not very familiar with the C language. simply because perfect machines or inventions do not exist. reads the HEX file generated by the compiler. This machine language is basically just zero‟s and one‟s and is written in Hexadecimal format.Leave a reply
If not simpler. that why they are called HEX files. so there is always some room for little changes and updates. resulting in a first prototype. you can transfer it to the microcontroller mounted on the board that you realized already. and sends it to the „program memory‟ of the microcontroller. tacking in account the famous rule that states that any project never works the first time. The hardware design includes all the aspects of the electronic connections between other devices. The main difference is all about the limitations of the processor of the 89S52 microcontroller as compared to modern computers. even if you decide that it is functioning correctly. the version of the C programming language used for the microcontroller environment is not very different than standard C when working on mathematical operations.eventual constraints imposed by the hardware design. or organizing your code.
From the C program to the machine language
The C source code is very high level language. at least it does not work as you expected! Your project will always stay in the prototyping cycle.
. correct eventual errors and enhance its performance.
Part 2: C programming for 8051 using KEIL IDE
written by Ibrahim KAMAL . meaning that it is far from being at the base level of the machine language that can be executed b y a processor. The prototype will be used to test your project. this tutorial will introduce all the basic programming techniques that will be used along this tutorial. etc… After you‟re done with a first version of your program. It will also show you how to use the KEIL IDE. like the compatibility of the voltage levels. The transfer of the code is done using a special device called „burner‟ or „programmer‟ that connect to the computer. or the required number of pins.

figure 2.1.A

There are several types of HEX files; we are going to produce machine code in the INTEL HEX-80 format, since this is the output of the KEIL IDE that we are going to use. Figure 2.1.A shows that to convert a C program to machine language, it takes several steps depending on the tool you are using, however, the main idea is to produce a HEX file at th e end. This HEX file will be then used by the „burner‟ to write every byte of data at the appropriate place in the EEPROM of the 89S52.

Variables and constants
Variables
One of the most basic concepts of programming is to handle variables. knowing the exact type and size of a variable is a very important issue for microcontroller programmers, because the RAM is usually limited is size. There are two main design considerations to be taken in account when choosing the variables types: the occupied space in ram and the processing speed. Logically, a variable that occupies a big number of registers in RAM will be more slowly processed than a small variable that fits on a single register. For you to chose the right variable type for each one of your applications, you will have to refer to the following table:

Data Type bit signed char unsigned char signed int unsigned int signed long unsigned long float

Bits 1 8 8 16 16 32 32 32

Bytes – 1 1 2 2 4 4 4

Value Range 0 to 1 -128 to +127 0 to 255 -32768 to +32767 0 to 65535 -2147483648 to 2147483647 0 to 4294967295 ±1.175494E-38 to ±3.402823E+38

This table shows the number of bits and bytes occupied by each types of variables, noting that each byte will fit into a register. You will notice that most variables can be either „signed‟ or unsigned „unsigned‟, and the major difference between the two types is the range, but both will occupy the same exact space in memory.

The names of the variables shown in the table are the same that are going to be used in the program for variables declarations. Note that in C programming language, any variable have to be declared to be used. Declaring a variable, will attribute a specific location in the RAM or FLASH memory to that variable. The size of that location will depend on the type of the variable that have been declared. To understand the difference between those types, consider the following example source code where we start by declaring three „unsigned char‟ variables, and one „signed char‟ and then perform some simple operations:

In that program the values of „c‟ will be equal to ‟155′! and not „-100′ as you though, because the variable „c‟ is an unsigned type, and when a the value to be stored in a variable is bigger than the maximum value range of this variable, it overflows and rolls back to the other limit. Back to our example, the program is trying to store „-100′ in „c‟, but since „c‟ is unsigned, its range of values is from ‟0 to 255′ so, trying to store a value below zero, will cause the the variable to overflow, and the compiler will subtract the „ -100′ from the other limit plus 1, from ‟255 + 1′ giving ‟156′. We add 1 to the range because the overflow and roll back operation from 0 to 255 counts for the subtraction of one bit. On the other hand, the value of „d‟ will be equal to „ -100′ as expected, because it is a „signed‟ variable. Generally, we try to avoid storing value that are out of range, because sometime, even if the compiler doesn‟t halt on that error, the results can be sometimes totally un expected. Note that in the C programming language, any code line is ended with a semi colon „;‟, except for the lines ending with brackets „{„ „}‟. Like in any programming language, the concept of a variables „array‟ can also be used for microcontrollers programming. an array is like a table or a group of variables of the same type, each one can be called by a specific number, for example an array can be declared this way:

char display[10];

This will create a group of 10 variables. Each one of them is accessible by its number, example:

Where „display[1]„ will be equal to ‟40′. Note that „display‟ contains 10 different variables, numbered from 0 to 9. In that previous example, according to the variable declaration, there is not such variable location as „display[10]„, and using it will cause an error in the compiler.

Constants
Sometimes, you want to store a very large amount of constant values, that wouldn‟t fit in the RAM or simply would take too much space. you can store this DATA in the FLASH memory reserved for the code, but it wont be editable, once the program is burned on your chip. The advantage of this technique is that it can be used to store a huge amount of variables, noting that the FLASH memory of the 89S52 is 8K bytes, 32 times bigger than the RAM memory. It is, however, your responsibility to distribute this memory between your program and your DATA. To specify that a variable is to be stored in the FLASH memory, we use exactly the same variable types names but we add the prefix „code‟ before it. Example:

code unsigned char message[500];

This line would cause this huge array to be stored in the FLASH memory. This can be interesting for displaying messages on an LCD screen. To access the pins and the ports through programming, there are a number of pre-defined variables (defined in the header file, as you shall see later) that dramatically simplifies that task. There are four ports, Port 0 to Port 3, each one of them can be accessed using the char variables P0, P1, P2 and P3 respectively. In those char types variables, each one of the 8 bits represents a pin on the port. Additionally, you can access a single pin of a port using the bit type variables PX_0 to PX_7, where X takes a value between 0 and 3, depending on the port being accessed. For example P1_3 is the pin number 3 of port 1. You can also define your own names, using the „#define‟ directive. Note that this is compiler directive, meaning that the compiler will use this directive to read and understand the code, but it is not a statement or command that can be translated to machine language. For example, you could define the following:

#define LED1 P1_0

With the definition above, the compiler will replace every occurrence of LED1 by P1_0. This makes your code much more easier to read, especially when the new names you give make more sense.

each time you write led_on_time. you cannot write something like:
led_on_time = 100.
Mathematical & logic operations
Now that you know how to declare variables. You can then perform all kind of mathematical operations. Note that this is not a variable and accordingly. the following expression in totally invalid:
5 = b. you only change it‟s value once.' -‟. is the „=‟ operator which is used to store the content of the expression at its right.'*‟ and „/‟. You can also use brackets „( )‟ when needed. counters and interrupts. it is time to know how to handle them in your program using mathematical and logic operations.
The utility of using defined constants. For example the following code will store the value of „b‟ into „a‟ :
a = b.
Mathematical operations
The most basic concept about mathematical operations in programming languages.
And subsequently. to control input/output operations and other features of the microcontroller like timers. that‟s for sure apart from the fact that a word like led_on_time is much more comprehensive than simply „184„! Along this tutorial you will see how port names. and special function registers are used exactly as variables. you cannot change a constant's value in code. or some constant variables that are re-used many times within the code: With a predefined constant. into the variable at its left. trying to store the content of „b‟ in it will cause an error. Example:
. //That's wrong.You could also define a numeric constant value like this:
#define led_on_time 184
Then. using the operators „+‟. and it‟s applied to the whole code. it will be replaced by 184.
Since 5 in a constant. appears when you want to adjust some delays in your code.

For example a Cosine function takes an angle in radians whose value is a float number between -65535 and 65535 and it will return a float value as a result. float sqrt (float val).h‟ file itself. you will be able to use more advanced functions in your equations like Sin. float exp (float val).h‟ header file. from this line you can deduce that the „cos‟ function returns a float data type. float sin (float val). int abs (int val). and you can read the line: extern float cos (float val). Return an the absolute value of a int variable. you have to know the type of variables that those functions take as parameter and return as a result. Cos and Tan trigonometric functions. (the parameter is always between brackets. the following table shows a short description of those functions:
Function char cabs (char val). you can easily know how to deal with the rest of the functions of the math header file. float log (float val). long labs (long val). the cosine function.).
. and takes as a parameter a float too.
To be able to successfully use those functions in your programs. like all the others is declared in the top of the math header file. Return an the absolute value of a float variable. float fabs (float val). Using the same technique. float log10 (float val). They all take angles measured in radians whose value have to be between -65535 and 65535. Returns the square root of a float variable.
If you include „math. You can usually know those data types from the „math. Return an the absolute value of a long variable.a =(5*b)+((a/b)*(a+b)). for example. float cos (float val). absolute values and logarithmic calculations like in the following example:
a =(c*cos(b))+sin(b). Returns the value of the Euler number „e‟ to the power of val Returns the natural logarithm of val Returns the common logarithm of val A set of standard trigonometric functions. float tan (float
Description Return an the absolute value of a char variable.

Returns x to the power y.4. float asin (float val). float floor (float val). float cosh (float val). Example: ceil(4. using the following operators:
Operator ! ~ & |
Description NOT (bit level) Example: P1_0 = !P1_0. float ceil (float val). float sinh (float val). Those logic operators can be used in many ways to merge different bits of different registers together. using the signs of both x and ytodetermine the quadrant of the angle and return a number ranging from -pi to pi. For example: fmod(15. whose 8 bits represents the 8 I/O pins of Port 1. float x). float tanh (float val).Function val). it‟s easier to look at the bits of a variable (which is composed of one or more register). Calculates the smallest integer that is bigger than val.
Logical operations
Description
This function calculates the arc tan of the ratio y / x. float atan2 (float y.
You can also perform logic operations with variables. It is required in that example to clear the four lower bits of that register without changing the state of the four other which may be used by other equipment. float pow (float x. For example. float y). NOT (byte level) Example: P1 = ~P1. float y). consider the variable „P1′. like AND.0) = 3. a NOT operation will invert all the bit of a register.3) = 5. This can be done using logical operators according to the following code:
. float fmod (float x. Calculates the largest integer that is smaller than val. AND OR
Note that those logic operation are performed on the bit level of the registers.8) = 4. Returns the remainder of x / y. OR and NOT operations. float acos (float val). For example. float atan (float val). and hence stored in an 8 -bit register. Actually P1 is an SFR.0. Example: ceil(4. which is of type „char‟. To understand the effect of such operation on registers.

Here. is to to set some of its bits to 1 without affecting the others. as you shall see in the next section. The last types of logic operation studied in this tutorial is the shifting. Recalling the two following relat ions: 1 0 OR OR X X = = 1 X
(where „X‟ can be any binary value) You can deduce that the first and last pins of P1 will be turned on. Recalling the two following relations: 1 0 AND AND X X = = X 0
(where „X‟ can be any binary value) You can deduce that the four higher bits of P1 will remain unchanged. for example. which is ‟10000001′ in binary. By the way. while the four lower bits will be cleared to 0. the value of P1 is ANDed with the variable 0xF0. Those are just a few example of the manipulations that can be done to registers using logical operators. note that you could also perform the same operation using a decimal variable instead of a hexadecimal one. which in the binary base is ‟11110000′. without affecting the state of the other pins of port 1. this can be done using the following two operators:
Operator >> <<
Description Shift to the right Shift to the left
.
A similar types of operations that can be performed on a port. without affecting the other. the following code will have exactly the same effect than the previous one (because 240 = F0 in HEX):
P1 = P1 & 240. //Adding '0x' before a number indicates that it is a hexadecimal one
Here. the following source code can be used:
P1 = P1 | 0x81. Logic operators can also be used to define very specific conditions. It can be useful the shift the bit of a register the right or to the left in various situations. to set the first and last bit of P1. P1 is ORed with the value 0×81.P1 = P1 & 0xF0. For example.

in binary P1 = 1000 0000
You can clearly notice that the content of P1 have been shifted 8 steps to the left. in binary. code to be executed .. for example:
P1 = 0x01... The expression can be any combination of mathematical and logical expressions. All the above situation describe an indispensable aspect of programming: „conditions‟. all the code between those two brackets will be executed if and only if the expression is valid. to differentiate between different situations. according to the following syntax. The „expression‟ is the condition that shall be valid for the „code block‟ to be executed. or to direct the flow of the code depending on some criteria. In other words.. In other words.
Conditions and loops
In most programs. }
.
if (expression) { ... P1 = 0000 0001 P1 = (P1 << 7) // After that operation. the code block is all delimited by the two brackets „{„ and „}‟. this feature allows to execute a block of code only under certain conditions. and otherwise execute another code block or continue with the flow of the program.. it is required at a certain time. }
It is important to see how the code is organized in this part. code to be executed . // After that operation. to make decision according to specific input.The syntax is is quite intuitive. as you can see in the following example:
if ( (P1 == 0) & (a <= 128) ){ .. The most famous way to do that is to use the „if‟ statement.

this error wont generate any alert from the compiler and is very hard to identify in a big program. Otherwise it is clear that in that previous example.... would cause the the compiler to store 0 in P1.Notice the use of the two equal signs (==) between two variables or constants.. the code block is only executed if both the two expressions are true. }else if(expression_3) { . }else{ . In C language.. it can save you lot of debugging time. writing this expression with only one equal sign.. Here is a list of all the operators you can use to write an expression describing a certain condition:
Operator == <. >= !=
Description Equal to Smaller than... This issue is a source of logical error for many beginners in C language. > <=. code block 1 . Observe the following example source code:
if (expression_1) { .. Smaller than or equal to. bigger than... Not equal to
The „If‟ code block can get a little more sophisticated by introducing the „else‟ and „else if‟ statement.. code block 3 .
. }else if(expression_2) { . this means that you are asking whether P1 equals 0 or not.. code block 2 .. bigger than or equal to. so pay attention.

The code will keep looping as long as the condition „i<10′ is true.code block 4 . loops are usually restricted to certain number of loops like in the „for‟ code block or restricted to a certain condition like the „while‟ block.. There are four different code blocks. code block
. However you can chose not to have and „else‟ block at all if you want. BUT you can only have one „else‟ block. each time with the counting variable „i‟ increasing by 1 according to the statement „i++‟. There are some other alternatives to the „if…else‟ code block. which is a highly controllable and configurable loop. Usually the counting value „i‟ is reused in the body of the loop. Another very important tool in the programming languages is the loop. each one with its corresponding condition.. Let‟s start with the „for‟ code block. but also have some limitations and restrictions like the „Select…case‟ code block.i<10..step){ . that c an provide faster execution speeds. which makes the particularity of this loop. For now.i++){
P0 = i.condition. The last code block will only be executed if none of the previous expression is valid. it is enough to understand the „if…else‟ code block. Note that you can have as many „else if‟ blocks as you ne ed. consider the following example source code:
for(i=0. In C language like in many others. which is completely logical.. whose performance is quite fair and have a wide range of applications. only one shall be executed if and only if the corresponding condition is true. }
Here. The „for‟ loop functioning can be recapitulated by the following syntax:
for(start.
}
Here the code between the the two brackets „{„ „}‟ will be be executed a certain number of times.

The condition is the expression that is is to remain true for the loop to continue..
Functions
Functions are way of organizing your code. by grouping relatively small parts of code to be reused many times in the same program. return value //optional . A new function can be created according to the following syntax:
Function_name(parameter_1.
. or to make it an infinite loop. }
Here there is only one parameter to be defined.. that is equivalent to the previous method:
while(i < 10){ P0 = i. the code will keep looping.. reducing its size. Parameter_3){ . step is the increase or decrease of the counting variable. the syntax of this one is simpler than the previous one. as you shall see later on along this tutorial. and increasing its overall performance.. function body . as long as this conditions is satisfied. Both techniques are commonly used in microcontroller programs.. The second type of loop that we are going to study is the „while‟ loop. Then.. it can be any statement that changes its value.. }
Where start represents the start value assigned to the count value before the loop begins. which is the condition to keep this loop alive. it is the responsibility of the programmer to design the software carefully to provide an exit for that loop. as you can observe in the following example source code. whether by an addition or subtraction.. which is „i < 10′ in our example.. i = i +1. Parameter_2. Finally.

for(i=0.
this line of code would cause the program to pause for approximately one second on a 12 MHz clock on a 8051 microcontroller. is a function that will calculate the angle in radian of a given angle in degrees. Usually the „return‟ command is used at the end of the function. consider the following function:
delay(unsigned int y){ unsigned int i. } }
In this last piece of code a function named „delay‟ is created. The number of parameters of the function can be more than the three parameters of the examples above.i<y. The function‟s body is usually a sub program that implies the parameters to produce the required result. like the cos() function. A function like this can be called from anywhere in the program according to the following syntax:
delay(30000). A very common use of functions without return value is to create delays in a software. as all the trigonometric functions that are included by default take angles in radians.i++){ . w hich will output the value next to it. through the „return‟ command.}
This is the general form of a function. the function will repeat a loop for a couple hundreds or thousand of times to generate precise delays in a program. some functions will also generate an output. as it can be zero. This function can be as the following:
deg_to_rad(float deg){ float rad. with an unsigned integer „y‟ as a parameter. all depends on the type and use of the function.
. A common example of a function with a return value. and implying a locally defined unsigned int „i‟.

18). Variables declarations More precisely.rad = (deg * 3.18° Another important note about functions in the „main‟ function. or when a microcontroller circuit is turned ON.. }
Organization of a C program
All C programs have this common organization scheme. root square calculations or numbers approximations.
Where angle should be already defined as a float. and is written like this:
main(){ . or to include mathematical functions like trigonometric functions. sometimes it‟s not. Any C program must contain a function named „main‟ which is the place where the program‟s execution will start. It can be called in your program according to this syntax:
angle = deg_to_rad(102. it is imperative for this category of programming that this organization scheme be followed in order to be able to develop your applications successfully. header files (. Variables declared in this place
. code of the main functions . }
This function named „deg_to_rad‟ will take as a parameter an angle in degrees and output an angle in radians. however. Any application can be divided into the following parts.. more precisely.h) are included into your source code. for microcontrollers. those headers files can be system headers to declare the name of SFRs.. and where will be stored the value returned by the function. contain your own functions that would be shared by various programs. which is the angle in radians equivalent to 102. it were the execution will start after a reset operation. Header files can also 2. sometimes it‟s followed.. this part is dedicated to „Global Variables‟ declarations. retrun rad. to define new constants. The „main‟ function has no parameters. noting that is should be written in this order: 1. Headers Includes and constants definitions
In this part.14)/180.

i++){. and its from here that all the other functions are called and executed. counters. Initialization The particularity of this part is that it is executed only one time when the microcontroller was just subjected to a „RESET‟ or when power is just switched ON.can be used anywhere in the code. whose values will be lost each time you switch from a function to another. but for now it is important to concentrate on the programming to summarize the notions discussed above. In other word s. Usually this part is the core of any program.
4.
3. Those functions can be simple ones that can be called from another place in your program.i<y. This particularity makes it the perfect place in a program to initialize the values of some constants. Actually it is the source code of the example project that we are going to construct in the next part of the tutorial.} }
main(){ while(1){
. Usually in microcontroller programs. unless your are running short of RAM memory and want to save some space. for(i=0. as they can be called from an „interrupt vector‟. then the processor continue executing the rest of the program but never executes this part again. but they consume more memory space. or to define the mode of operation of the timers. variables are declared as global variables instead of local variables. Infinite loop An infinite loop in a microcontroller program is what is going to keep it alive. Functions’ body Here you group all your functions. exactly like a heart have to be always beating for a person to live. interrupts. and other features of the microcontroller. so we use local variables.
Simple C program for 89S52
Here is a very simple but complete example program to blink a LED. global variables as easier to use and implement than local variables. because a processor have to be allays running for the system to function.
#include <REGX52.h>
delay(unsigned int y){ unsigned int i.h> #include <math. To summarize.
5. the sub-programs to be executed when an interrupt occurs is also written in this place.

this tutorial uses KEIL C51 uVision 3 with the C51 compiler v8. with an infinite loop (the condition for that loop to remain will always be satisfied as it is ‟1′). which is simple a function to create a delay controlled via the parameter „y‟. Then comes the main function. Most versions share merely the same interface. P1_0 = 1.keil. delay(30000). like the 89S52 which we are going to use along this tutorial. P1_0 = 0. follow the following steps:

Open Keil and start a new project:
. To create a project. write and test the previous example source code.delay(30000). a function named „delay‟ is created. the pin number 0 of port 1 is constantly turned ON and OFF with a delay of approximately one second.
Using the KEIL environment
KEIL uVision is the name of a software dedicated to the development and testing of a family of microcontrollers based on 8051 technology. A simple circuit can be constructed and a LED can be connected to the pin P1_0 to see how software and hardware adjustments can affect the behavior of you circuits. As you will see in the next part. Inside that loop. You can can download an evaluation version of KEIL at their website: http://www. } }
After including basic headers for the SFR definitions of the 8952 microcontroller (REGX52.h) and for mathematical functions (math.05a.com/c51/.h).

8. where you will be asked to select a device for Target „Target 1′:
. chose a name and click save. The following window will appear.A

You will prompted to chose a name for your new project. Create a separate folder where all the files of your project will be stored.2.


Click File. New.8.
. Leave the two upper check boxes unchecked and click OK.B

From the list at the left.figure 2. You will notice that a brief description of the device appears on the right. The box named „Text1′ is where your code should be written later. then under ATMEL. seek for the brand name ATMEL. and something similar to the following window should appear. The AT89S52 will be called your „Target device‟. select AT89S52. You will be asked whether to „copy standard 8051 startup code„ click No. which is the final destination of your source code.

c‟. Then you have to add this file to your project work space at the left as shown in the following screen shot:
.8.figure 2. and click save. You can name is „code.C

Now you have to click „File. Save as‟ and chose a file name for your source code ending with the letter „.c‟ for example.

. and correct eventual syntax errors. chose the file that you just saved. Options for target ‘target 1′. this step is called „rebuild all targets‟ and has this icon: . then under the „output„ tab.D

After right-clicking on „source group 1„.figure 2.c‟ and add it to the source group. then you will be prompted to browse the file to add to „source group 1′. make sure it is turned ON. by checking the box „generate HEX file„. In KEIL IDE.8. eventually „code. you have to compile your source code.c‟ then before t esting your source code. click on „Add files to group…„. You will notice that the file is added to the project tree at the left.

You can then start to write the source code in the window titled „code. by right-clicking on target 1.

In some versions of this software you have to turn ON manually the option to generate HEX files. This step is very important as the HEX file is the compiled output of your project that is going to be transferred to the micro-controller.

this step is called Debugging. but also to check the FLASH memory occupied by the program (code = 49) as well as the registers occupied in the RAM (data = 9). some new icons will appear. like the run icon circled in the following figure:
. like in most development environment.figure 2. After clicking on the debug icon. and has this icon: . If after rebuilding the targets. In KEIL. the „output window‟ shows that there is 0 error. then you are ready to test the performance of your code.E

You can use the output window to track eventual syntax errors. you will notice that some part of the user interface will change.8.

Port 1′.
to follow the execution step by step. when you‟re finished with the debugging. but clicking on „peripherals.
which allows you
) and you can simulate a reset by clicking on

You can also control the execution of the program using the following icons: programming interface by clicking again on the debug button ( ). you can always return to the
There are many other features to discover in the KEIL IDE. Then.
. In our example.figure 2. You can always stop the execution of the program by clicking on the stop button ( the „reset‟ button . I/O ports. and the more important of them will be presented along the rest of this tutorial. you can see the behavior of the pin 0 or port one.F

You can click on the „Run‟ icon and the execution of the program will start. You will easily discover them in first couple hours of practice.8.

we are going to use our ISP connector. Along all the tutorial. You will notice along this tutorial how this will affect our choices when it comes to connect I/O devices to the ports. The microcontroller reads the state of a pin through the Pin value line. Then we are going to apply this theory on simple experimental projects.
I/O port detailed structure
It is important to have some basic notions about the structure of an I/O port in the 8051 architecture. and writes through the latch value line. because there is no any risk of short-circuit due to the presence of a resistor. the I/O ports configuration and mechanism of the 8051 can be confusing. we are going to study the basic structure and configuration of I/O ports. the two possible outcomes are both unharmful for the microcontroller. If you imagine the behavior of the simple circuit in figure 3. due to the fact that a pin acts as an output pin as well as an input pin in the same time. regardless of the latch value that was set by the processor in the first place. or 0V by connecting the pin directly to the GND through the transistor.
. we are going to transfer programs to the microcontroller. to experiment with the different I/O features of the micro-controller. using a LED and switch.1.Part 3: Basic Input/Output Operations
written by Ibrahim KAMAL . The latch value is the value that the microcontroller tries to output on the pin. providing 5V through the pull-up resistor.A. and the PIN value line will easily follow the value imposed by the external connection. you‟ll notice that the I/O pin should follow the voltage of the Latch value.A
Figure 3. is the actual logic state of the pin. using an ISP (In System Programmer). This can be easily verified by connecting the pin to 0V or to 5V. The first thing you have to notice.1. When the pin is pulled high by the pull-up resistor. you can build one here.Leave a reply
In this third part of the 89s52 tutorial. while the pin value. If you don‟t have one. At this point of the tutorial.A shows the internal diagram of a single I/O pin of port 1.1. the pin can output 5V but can also be used as an input pin. is that there are two different direction for the data flow from the microcontroller‟s processor and the external pin: The Latch value and the Pin value.
figure 3. Actually.

a short circuit will occur and some damage may be made to the micro-controller‟s port or to the external device connected to that pin. generated by the compiler. and the pin value will follow the value imposed by the device connected to it (switch. sensor. where the latch value would be low.i<y. To summarize. causing the pin to provide 0V. Even if some ports like P3 and P0 can have a slightly different internal composition than P1.} }
main(){ while(1){ delay(30000). for(i=0. If you plan to use the pin as an output pin. now we are going to transfer the HEX file corresponding to that code on the 89s52 microcontroller. P1_0 = 0.h> #include <math. to use a PIN as an input pin. The code for blinking a LED is as follow:
#include <REGX52.i++){. you have to output ’1′. then just output the required value without taking any of this in consideration. an external device tries to raise the pin‟s voltage to 5V.Now imagine the opposite configuration. If in this situation.h>
delay(unsigned int y){ unsigned int i. due to the dual functions they assure.
Simple output project: Blinking a led
A first simple project to experiment with the output operations is to blink a LED. in the 8051 architecture. etc…). originally from a C code.
. Let us recall that the HEX file is a machine language file. understanding the structure and functioning of port 1 as described above is fairly enough to use all the ports for basic I/O operations. Assuming you have successfully written and compiled the code as explained in the previous part of the tutorial. being directly connected to GND through the transistor.

According to the fact that we are going to use an ISP programmer. Then. A connector is added by default to allow easy in system programming. you have connect pin 31 (EA) to 5V.2. you have to connect a standard reset circuitry on pin 9 composed of the 10 Kohm resistor R2 and the 10 uF capacitor C3. as you can see in the schematic. as you can see in figure 3.delay(30000). By providing 5V on the EA pin.
. You can also add a switch to short-circuit pin 9 (RST) and 5V giving you the ability to reset the microcontroller by pressing on the switch (the processor resets in a high level is provided on the RST pin for more than 2 machine cycles).A below.A). Note that there are other ways to connect the LED. The EA pin is an active low‟ pin that ind icate the presence of an external memory. Activating this pin by providing 0V on it will tell the internal processor to use external memories and ignore the internal built-in memory of the chip.0 through a 220 ohm resistor R1. Any other connection scheme would involve the internal resistor of the port. but now that you understand the internal structure of the port. P1_0 = 1. At last. you can easily deduce that this is the only way to connect the LED so that the current is fully controlled by the external resistor R 1. First you have to provide a clean (noiseless) 5V power supply. The easiest and most efficient way to do this is to add a crystal resonator and two decoupling capacitors of approximately 30 pF (see the crystal X1 and the capacitors C1 and C2 on figure 3. which is „uncontrollable‟. Those were the minimum connections to be made for the microcontroller to be functional and able to operate correctly.2. For our simple output project. its functionality is deactivated and the processor uses the internal memories (RAM and FLASH). the hardware have to be constructed. a LED is connected to P1. Then you have provide a mean of regulating or generating the clock of the processor. by connecting the Vcc pin (40) to 5V and the GND pin (20) to 0V. } }
Before transferring the HEX file to the target micro-controller.

2. a picture of the implementation of this simple project on a bread board is provided to help you visualize the hardware part of the project:
.figure 3.A
In order get rid of any confusion.

. At this stage. the reset functionality of the ISP cable was used instead. but i preferred to stress on capability of the 8051 architecture to share input and output pins on the same port. as described in the ISP page. you should see the LED blinking as soon as the programming (transfer) is finished. You can experiment with different delay in the code to change the blinking frequency. recalling the internal structure of a pin. The schematic below (figure 3. You can eventually use any other available programming hardware and/or software.3) shows how a switch is added on another pin of Port 1. and without a pull up resistor.figure 3. you can finally connect your ISP programmer. and preventing any eventual short circuits if the port is not well configured. making use of the internal pull up resistor. generating a new hex file (replacing the old one) and retransfer the freshly generated HEX file to the micro-controller.
Simple Input/Output project
The most simple input operation you can implement to the previous project is a push button. Don‟t forget that for any change to take place. We could have connected the switch on another port. and transfer it to the micro-controller. to control the LED. browse the HEX file for programming the FLASH. you have to rebuild your source code. and also the most adapted to the 8051 architecture. If all your connections are correct.2. you‟ll notice that this is the simplest way to connect a switch. launch the ISPprog software. Notice how the switch is connected to ground.B
Note that the reset switch and R/C filter are not present on this breadboard.

there are many possible solutions. The first one I propose is the simplest one: a software that turns on the LED as long as the push button is pressed and turn it off otherwise and whose source code would be as the following:
#include <REGX52.figure 3.h> #include <math.
. that the hardware is finalized.3
Now. To control a led.h>
delay(unsigned int y){ unsigned int i. an adequate software have to be designed and written to assure the correct functioning of the system.

} }
main(){ P1_3 = 1. //Set up P1_3 as input pin
. //Setup P1_3 as input pin while(1){ if(P1_3 == 0){ P1_0 = 0.h> #include <math. then turn it off automatically. //Turn OFF the LED } } }
The other solution I propose is a software that turns ON the LED for a couple of seconds each time the switch is pressed.for(i=0. //Global Variables
void main(){ P1_3 = 1. //Turn ON the LED }else{ P1_0 = 1.h>
unsigned long time.i++){. ON_time.i<y. The source code would be as the following:
#include <REGX52.

Exercise:
To conclude this part of the tutorial. build a software that would allow you to toggle the state of a led on simple button press. while the „ON_time‟ is used to store the fixed time period which the LED should stay ON after the push button is released. } if (P1_3 == 0){ time = 0. required to generate dozens of seconds delays. to prevent eventual overflow. so that they can manage relatively huge numbers. and the whole process can start again. depending on its initial state “
. as it is not needed anymore. A press on the button to turn the LED ON or OFF. P1_0 = 0. You can try on your own to figure out other ways of optimizing the control of a LED or a number of LEDs. i suggest this simple exercise: “Using the same schematic (figure 3.3).ON_time = 100000. and as soon as the elapsed time reaches the required „ON_time‟. } } } // if the switch is pressed. while(1){ if (time < ON_time){ time++. Two variables are defined „time‟ and „ON_time‟. }else{ P1_0 = 1. // reset 'time' to 0 // Turn OFF the LED // start or continue counting //Turn ON the LED
The source code above may need some explanation: First you can notice that there is no „delay‟ function. The variable „time‟ will be used to count the elapsed time (in number of code cycles). Then those two variables as constantly compared. and the „time‟ counting stops. the led switches off. A push on the button would set the „time‟ back to 0. they are both „usigned long‟ type.

figure 4. Those features are principally the timers. to give the programmer more options. because it have a couple of extra functionality.Leave a reply
Most microcontrollers come with a set of „ADD-ONs‟ called peripherals. and it is one of the easiest to learn on the market. counters.1
The serial port.1 below shows a simplified diagram of the main peripherals present in the 89S52 and their interaction with the CPU and with the external I/O pins. We use the expression “Timer/Counter” because this unit can be a counter when it counts external pulses on it‟s corresponding pin. Analog to digital converters. You can notice that there are three timers/Counters. that does not behave like the two others. PWM generators. and communication buses like UART. but never the less. to enhance the functioning of the microcontroller. With the UART provided in the 89S52 you can easily communicate with a serial port equipped computer. the available features are adequate to a wide range of applications.Part 4: Interrupts. This last
. and it can be a timer when it counts the pulses provided by the main clock oscillator of the microcontroller. Timer/Counter two is a special counter. SPI or I2C. interrupts.
Introduction to 89S52 Peripherals
Figure 4. using a UART (Universal Asynchronous Receive Transmit) protocol can be used in a wide range of communication applications. timers and counters
written by Ibrahim KAMAL . The 89S52 is not the most equipped microcontroller in terms of peripherals. and to increase the overall performance of the controller. as well as communicate with another microcontroller.

interruption is a mean of stopping the flow of a program. it is extremely simple to set those bits.2 and the other to P3. As you noticed in figure 4. Through this tutorial.
The rest of the bits of IE register are used for other interrupt sources like the 3 timers overflow (ETx) and the serial interface (ES). the bit EA (Enable ALL) must be set to 1. to execute a small program called „interrupt routine‟. For that purpose there are two External Interrupt sources (INT0 and INT1). If all the peripherals described above can generate interrupt signals in the CPU according to some specific events.A
The first register you have to configure (by turning On or Off the right bits) is the IE register . Most of those SFRs are shared by other peripherals as you shall see in the rest of the tutorial.2.1. then.
External Interrupts
Let‟s start with the simplest peripheral which is the external interrupt.3. The UART and the Timer/Counter 2 shall be discussed in separate tutorials. and can be easily implemented with two 89S52 microcontrollers to build a very powerful multi-processor controllers. you have enable each one of the interrupts to be used with its individual enable bit. shown in figure 4.application.A. is quite interesting. there are two external interrupt sources. EX1 = 1. and it is used to allow different perip herals to cause software interruption.2. and to keep this tutorial a quick and straight forward one. Using the C programming language under KEIL.

The IE register
figure 4. it can be useful to generate an interrupt signal from an external device. To use any of the interrupts. In case you don‟t know. For the external interrupts. simply by using their name as any global variables.
. They are configured using a number of SFRs (Special Function Registers). that may be a sensor or a Digital to Analog converter. one connected to the pin P3. which can be used to cause interruptions on external events (a pin changing its state from 0 to 1 or vice-versa). EX0 = 1. as a response to a certain event. the two bits EX0 and EX1 are used for External Interrupt 0 and External Interrupt 1. called Multi-processor communication. For simplicity. IE stands for „Interrupt Enable‟. Using the following syntax:
EA = 1. This was a presentation of the available peripheral features in a 89S52 microcontroller. we are going to study how to setup and use external interrupts and the two standard timers (T0 and T1). in the 89S52.

an interruption will keep reoccurring as long as P3. External Interrupt 0 is set in „Falling Edge‟ mode. We are going to build a simple digital low pass filter.3 is set to 0. and most programmers tends to use external interrupts trigger ed by a falling edge (transition from 1 to 0).3 External interrupt caused by a low level signal on P3. like in the following example:
IT0 = 1. Since we will be using External Interrupt 0.2/P3.
// Include standard headers #include <REGX52.h>
.2. the external interrupt resets the counter. If the counter reaches a pre-calibrated value. and the signal is not taken in account. The bits IT0/IT1 are used to configure the type of signal on the corresponding pins (P3.3) that generated an interrupt according to the following table:
IT0/IT1 = 1 IT0/IT1 = 0
External interrupt caused by a falling edge signal on P3. and the clean.

Example Program Here is an example program to demonstrate the External Interrupt peripheral feature of the 89s52.3
If IT0 or IT1 is set to 0. This mode isn‟t easy to mange. if the signal bounces between 0 and 1 before the counter reaches the pre-defined value. IT1 = 1.0. then the signal is considered to be stable. the signal to be checked for noise and sampled is imperatively connected to pin P3.2.2. Again. this register is „bit addressable‟ meaning you can set or clear each bit individually using their names. Since the noise is interpreted by digital devices as a succession of high and low levels. and can be sampled.h> #include <math. any „high to low‟ level transition is easily detected in the „Falling edge‟ mode.2/P3.B. filtered output signal is to be generated on P1. shown in figure 4. you have to set the bits IT0 and IT1 in the TCON register.B
Similarly.2/P3. otherwise. and is used to check for noise on a signal and reset a counter in case noise is detected.2 or P3.
The TCON register
figure 4.

{ P1_0 = P3_2.if (counter < time_constant) // Count until the pre-defined time_constant { counter++. }
if (counter == time_constant) // if the counter was not interrupted by any noise. try to build a program that decodes the pulses coming from an incremental encoder to determine an absolute position. // output the valid signal on P1_0 } } }

Exercise: To make sure you‟ve correctly assimilated the functioning of the external interrupts.
.

On the other hand. or by testing it directly on your breadboard. and that the description applies to both of them. you can seek for help in th e forums. and the other for timer/counter 1. The timer is a very interesting peripheral. during counterclockwise rotation. which are fixed with time. hence. and update the position of the encoder at each falling edge. one of them for timer/counter 0. It can be used in two distinct modes:

Timer: Counting internal clock pulses. I’ll often use the notation 1/0 adjacent to a register name. In other words. during clockwise rotation. whose resolution depends on the frequency of the main CPU clock (note that CPU clock equals the crystal frequency over 12).C. build a program to decode the signals coming from an incremental encoder.
.2.
Timer/Counter
For this part. This mechanism can be used to detect the „quantity‟ of rotation in number of pulses as well as direction of the rotation Using this method. shifted by 90 degrees (or by a quarter of a period). You will need only one External interruption. the falling edges of signal A will occur at the same time with respect to the signal B. we can say that it is very precise timer.2. that is imperatively present in every microcontroller. which means that there are two of that register.figure 4. You can try your source code by simulating it in KEIL IDE. as you can see in figure 4. the falling edges of signal A will always occur while signal B is at a low level.C
Incremental encoder are rotational encoder that generate two square waves. The main idea of operation is that for a same direction of rotation. IF you can’t find the solution. the falling edge of signal will always occur while signal B is at high level.

set it to 1 to enable the timer to count.

The IE register First.
Sure. like any other peripheral. or any device that provide pulses. example:
ET0 = 1. 0 to stop counting. 0 to stop counting. a set of SFR are used. whose number would be of some interest. a Timer/Counter can ask for an interruption of the program.2. as you saw before. so you can set its bit using its names.

The TCON register The TCON register is also shared between more than one peripherals. More precisely. set it to 1 to enable the timer to count. the CPU of a microcontroller could provide the required timing or counting. most of them have already been seen at the top of this tutorial. which can be provided by a rotational encoder. The following table shows the names and definitions of the concerned bits of the IR register (you can always take a look at the complete IE register in figure 4. external interrupts. you have to Enable the corresponding interrupts.
Counter: Counting external pulses (on the corresponding I/O pin). used by the processor. but writing 1′s to the corresponding bits in the IE register. the interruption will occur at the same time the counting register will be reinitialized to its initial value.
As the IE register. Overflow interrupt flag. The following table shows the names and definitions of the concerned bits of the TCON register (available in figure 4. Timer/counter 0 RUN bit. allowing it to allocate maximum processing power for more complex calculations. like we did before.2. but the timer/counter peripheral relieves the CPU from that redundant and repetitive task. Timer/counter 1 RUN bit. an IR-barrier sensor. So to control the behavior of the timers/counters. as simply as it seems.A):
EA ET2 ET1 ET0
Enable All interrupts Enable Timer 2 interrupts (will not be treated in this tutorial) Enable Timer 1 interrupts Enable Timer 0 interrupts
You can access those special bits by their names. Example:
TR0 = 1. which – if enabled – occurs when the counting registers of the Timer/Counter are full and overflow.B):
TF1 TR1 TF0 TR0
Overflow interrupt flag. So. used by the processor. TCON is also bit-addressable. It can be used to configure timers or.

The TMOD register
.

If used as timer. Both TH0/1 and TL0/1 are used. For normal operation clear this bit to 0.C. each group being used to configure the mode of operation of one of the two timers.C
For the a given Timer/Counter. pulses from the processor are only divided by 12. counting the main oscillator frequency divided by 12. let us agree and make it clear that the register IS NOT BITADDRESSABLE. If used as counter. an interrupt will occur upon overflow. but the maximum frequency that can be
. TL stands for timer LOW. If an interrupt is enabled. forming a 16 bit timer/counter.2. external pulses are only divided by 32. So. by coding those bits into a decimal or hexadecimal number. as you can see in figure 4. counting external events on P3_4/P3_5. If an interrupt is enabled. cleared to 0 to use it as timer.
M1 M0 Mode   0 0 0      0 1 1   
Description Only TH0/1 is used. Note that this feature involves both a timer and an external
interrupt. and the timer 1/0 will stop counting
G when External Interrupt 1/0 pin is low (set to 0 V).
M1 Timer MODE: Those two last bits combine as 2 bit word that defines the mode of operation. 
Timer/counter modes of operation Each timer/counter has two SFR called TL0 and TH0 (for timer/counter0) and TL1 and TH1 (for timer/counter 1). Timer/counter will count up from the value initially stored in TH0/1 to 255. external pulses are not divided.
figure 4.
C/T‟
Set to 1 to use the timer/counter 1/0 as a Counter.2. set it to 1. TH stands for TH. The result is the main oscillator frequency divided by 384. It you‟re responsibility to write the code to manage the operation of th ose two peripherals.Before explaining the TMOD register. an interrupt will occur upon overflow. and then overflow back to 0. Timer/counter will count up from the 16 bit value initially stored in TH0/1 and TL0/1 to 65535. as you shall see later. and is used to store the lower bits of the number being counted by the timer/counter. the corresponding bits of TMOD can be defined as in the following table:
Gate signal. forming an 8bit timer/counter. If used as timer. meaning you have to write the 8 bits of the register in a single instruction. defined M0 as the table below. and is used to store the higher bits of the number being counted by the timer/counter. pulses from the processor are divided by 32 (after being divided by 12). the TMOD register can be divided into two similar set of bits. and then overflow back to 0.
If you want to use the timers to capture external events‟s length. If used as counter.

counter and interrupts. the software for that controller would be like the following:
// Include standard headers #include <REGX52. or turns too fast.
setup_peripherals(){
. since they offer a wide range of possible customization. If an interrupt is enabled.h> #include <math. an interrupt will occur upon overflow.
1
1
Timer modes 1 and 2 are the most used in 8051 microcontroller projects. external pulses are not divided. a simple project is proposed. A motor is being operated by an outdated motor controller. and that we are using a 24MHz crystal oscillator. Timer/counter will count up from the 8 bit value initially stored in TL0/1 and to 255. and then overflow.2 (External interrupt 0). setting the value of TH0/1 in TL0/1. that the system can be stopped by a high level signal on P1_0. by stopping the whole system in case the motor heats up too much. We need to write the code to stop the motor incase it heats up or in case it reached 10 000 r.
Exercise project
To conclude this tutorial.m. Consider the following problem. This is called the auto-reload function. If used as timer.5 (Timer/Counter 1). A temperature sensor is already set up and give a low signal 0 when the temperature is too high. and an optical encoder output a pulse for each revolution of the motor. pulses from the processor are only divided by 12. TH0/1 is used to hold the value to be restored in TL upon overflow. the encoder is connected to P3. forming an 8 bit timer/counter. We want to add some security to the system. to help you assimilate the functioning of the timers. but the maximum frequency that can be accurately counted equals the oscillator frequency divided by 24.h> #define limit 12 #define stop_signal P1_0
unsigned char sub_counter. Considering that the temperature sensor is connected to P3.p. If used as counter. This mode is beyond the scope of this tutorial.   1 0 2    3  TL0/1 is used for counting.accurately counted equals the oscillator frequency divided by 24.

while(1){ // Do nothing. TL1 = 0. }
void main(){ stop_signal = 0.//Stop the motor stop_signal = 1. the whole program is carried out by interrupts! } }
You should be able to understand and calculate all the choices of timings in that source code. // the motor runs normally setup_peripherals(). TH1 = 0. see this project: Contact less digital tachometer. For more information about RPM measurements. } } }
over_heat_alarm () interrupt 0{ stop_signal = 1. especially the values related with the timer 0 that have to be executed at a very precise time.
.

Contact less tachometer principle of operation
. giving faulty readings.h Ni-Cd battery provides months of regular use of this device before it needs to be recharged. is that it can very accurately measure the rotational speed of a shaft without even touching it. what makes this device special. A 600 mA. This device is built on an AT89S52 (or AT89C52) microcontroller.
Key Features
    
Measures up to 99 000 RPM Instantaneous measurement Automatic DATA Hold Function LCD display Ni-Cad Rechargeable battery Important: this tachometer uses a proximity sensor. and/or how to operate them. This is very interesting when making direct contact with the rotating shaft is not an option or will reduce the velocity of the shaft.99 000 RPM Contact-Less Digital Tachometer
written by Ibrahim KAMAL .29 Comments
This article describes how to build a contact -less tachometer (device used to count the revolutions per minute of a rotating shaft) using a 8051 microcontroller and a proximity sensor.
As the name implies. please refer to this article first. an alpha-numeric LCD module and and a proximity sensor to detect the rotation of the shaft whose speed is being measured. In case you don’t know how to make a proximity sensors.

The idea behind most digital counting device.
Instantaneous measurement algorithm
To be able to deduce an RPM reading in less than second. then multiply this value by 60 to get the number of pulses per minute. please refer tothis tutorial about building a frequency meter. (like the AT89C52 used in this project) and they can be easily configured through programming. C2 and C3) and calculate the average numbers of pulses per fifth second. The counter is connected i such a way to count pulses coming from the proximity sensor. but in the same time. where a counter and a timer are used.
. The main difference between this tutorial about tachometer and frequency meters. and thus. Counter and timers are part of the internal features of a micro-controller. we don‟t want to wait a whole minute before getting a correct reading. Those pulses will be fed to the microcontroller and counted. a simple algorithm have been developed. shows how the timer and the counter are used for this task. Thus we need some additional processing to predict the number of revolutions per minute in less than a second. is a micro-controller. while the timer is used to precisely feed the counted value to the microcontroller every filth of a second. The only purpose of calculating an average reading is that it will allow to get more stable reading and prevent display flickering. then multiply this value by 5. the counted pluses will come from proximity sensor. is that we need the reading in pulses per minutes (to count revolutions per minutes). to get the number of pulses per second. which will detect any reflective element passing infront of it. frequency meters and tachometers. will give an output pulse for each and every rotation of the shaft. as show in the picture. and deduce the frequency of those pulse. In the case of this tachometer. To understand how a micro controller counts pulses. and reset the counter to 0. while constantly refining the reading‟s accuracy. The schematic below (figure 1). that elaborates the process of frequency counting. used to count the pulses coming from a sensor or any other electronic device. The microcontroller can now take an average of the last 3 readings (saved in C 1. which represents the measured RPM.

The micro controller board:
. C2 and C3 are used to store the last three reading. process them and display the result on the LCD display.
figure 1
The electronic Circuits
This device is composed of two electronic circuits: the Sensor. and the microcontroller board.C1. which is a slightly modified proximity sensor. which analyses pulses coming from the sensor.

which includes the reset circuitry along with the crystal resonator that generates the clock pulses required.Circuit explanation:
The LCD connections in the green shading is a standard for most of alpha numeric LCDs. The part in the blue shading is also standard in any 8051 microcontroller circuit.
. The LCD protocol can seem complicated to some of you. and an article should be released soon to explain it. the only feature I added is to be able to control the back light via the 80c52 micro controller.

and constantly updates the reading on the LCD. but we don‟t need to
. and the proximity sensor. the device measures the RPM of the shaft under test. which will be discussed later. we need to turn the IR emissions on or off. or 16 bit register according to the configuration of the timer T0. when the switch is released. When the switch is pressed. The switch SW 1. shown in the upper yellow circle. which will feed the pulses to be counted.4 of the microcontroller. The wire connection P1. regulates a 9V rechargeable Ni-CD battery and also provides a very simple battery monitor. with a green and a red LED. 13. When the switch is pressed again the old reading is replaced by the new one. this schematics misses tow important items to be called a tachometer: The C code loaded into the microcontroller. the last reading is held unchanged on the display. because in this specific application. showing whether the battery need to be recharged or not.
The modified IR proximity sensor
This schematic show the slight modification over the one proposed in this tutorial. is connected to the pin 3. which is the fact that the emitter LED uses a current limiting resistor of a higher value.The power supply. to allow it to be turned on for a long period of time. this pin has a dual function which is to count incoming pulses and increment a 8. which is connected to the output of the sensor. shaded in light red. as long as the device stays on. As you may have noticed. is used to enable/disable the measurement or the counting process.

figure 2. is the output of the sensor. The CTRL line. as well as the other lines concerning the sensor. but is more useful in the prototyping phase…
The software
Here are only small relevant parts of the full C program. and the OUT line. that was loaded into the microcontroller after being compiled to a HEX file. modular designs cost more. For examples. is to allow better performance sensors. P2. The reason for separating the sensor from the main board. Those part of the code were selected as the ones that emphasize the main purpose of a microcontroller in such an application. or even other types of sensors to be connected to the device. In general. here is a simple diagram (figure 2. The full code is available in the Project folder. Comments in green explains the program. is an input coming from the microcontroller ( at the wire connection: P4).inject high currents to reach high ranges… I recommend the reading of this article that fully covers all the aspects of this sensor. P3 and P4 goes in the main board.
.A) showing how they are connected together. You will have to refer to the above schematics to see where P1. turning the IR emissions ON and OFF. which is fed to the microcontroller ( at the wire connection: P1). downloadable at the bottom of this article .A
This picture also shows what is meant by the connection of the sensor to the main board. After analyzing both the main board holding the microcontroller and the sensor. function dealing with the LCD operation are not included in this description.

an old floppy disk drive case is used.
Download
IKALOGIC-KB-99000-RPM-CONTACT-LESS-DIGITAL-TACHOMETER
[Note: I use ExpressPCB(FREEWARE) to design the schematics and the PCB]
In System Programming (ISP) for ATMEL chips
written by Ibrahim KAMAL . you must have some basic microcontroller and C language skills.6 Comments
. Here.
The housing of the tachometer
For the housing. where the tachometer and the battery fits perfectly. those few pictures are worth a thousands words.} } }
To understand the functioning of this source code. The variable scale is used to control the rate at which the tachometer reads and resets the counter.

which consists of sending the data byte by byte (using eight independent lines for the data. and another bunch of lines for the address. frequencies or any other values that you would intend to find by trial and error.6 and P1. ISP is a way to serially program your microcontroller. or you‟re familiar with it.
How does ISP works?
Normally. where data is shifted in bit by bit though.
MOSI (data input) line. when adjusting some delays. MISO (data output) line is used for reading and for code verification. Sometimes. On the other hand ISP is performed using only four lines. Here is ISP Programming sequence as described in ATMEL datasheets: “The Code memory array can be programmed using the serial ISP interface while RST is pulled to VCC. your program start running and those three pins. otherwise if RST is low (0V). without removing the chip from your board. data is transferred through two lines only. the flash memory of an ATMEL microcontroller is programmed using a parallel interface. a process that would otherwise take too much time. The RST (used to activate the serial Programming) pin. After RST is set high. Whether you‟re just starting in the ATMEL microcontrollers. with a clock cycle between each bit and the next (on the SCK (clock input) line). the Programming Enable instruction needs to be executed first before other operations can be executed. are used normally as P1. the control word and clock input). while it resides in its place. and literally. P1. which is normally used to reset the device. as in a I2C interface.7. in other words. it is only used to output the code from the FLASH memory of the microcontroller.If you didn‟t guess it from the title. MOSI (input) and MISO (output). a Chip Erase operation is required. Before a reprogramming sequence can occur. MISO and SCK) to be used for ISP simply by setting RST to HIGH (5V). ISP (In System Programming) will provide you a simple and affordable home made solution to program and debug your microcontroller based project. The Chip Erase operation turns the content of every memory location in the Code array into FFH. ISP can become very useful.. The serial interface consists of pins SCK. Either an external system clock can be
.5. is also used to enable the three pins (MOSI.

The maximum serial clock (SCK) frequency should be less than 1/16 of the crystal frequency. as i am using a ready made software that will handle the transfer protocol. Now that you know some theory about the ISP.nz Important note:
.avrfreaks.net.“ This is as deep as i got in the ISP process. the maximum SCK frequency is 2 MHz. Some more detailed information about the ISP functioning can be found at www. and it is compatible with the software/cable proposed at www.8052. it maybe the simplest circuit that will find in this web site!
The circuit
This circuit is a modification from an original deign of Jerry Meng.aec-electronics. As you will soon discover.com and at www.supplied at pin XTAL1 or a crystal needs to be connected across pins XTAL1 and XTAL2.But this is all you need to know to build and use this extra simple programming device. you should be ready to build the hardware interface.co. With a 33 MHz oscillator clock.

is the four AND gates. and thus cannot be welded. and I did build the programmer with a 74LS08 IC. The circuit almost talks for itself. and the whole circuit is mounted inside the the connector plastic box.P4 have to be connected respectively to P1.The schematic above indicates a 74LS08 IC.
The PCB and the housing
I used an old parallel printer cable. but luckily. the pins P1.P2. will give you a better performance and allow you to use a longer cable. a buffer is a device that will isolate two circuits). it‟s the orange wire in the shown picture at the left)
. Then. or even better a 74HCT08 IC would be much safer.P3.
Note than PINs 14 to 25 of the parallel port are on the Components side of the board.7 and RST in the microcontroller. J1 is the connection to the computer parallel port. A glance at this pictures may be enough to understand how the PCB is mounted and welded to the parallel port connector. (you can notice it. using a 74HC08.6. some precision have to be taken in account when producing the PCB. P1. to protect the parallel port (Shortly. P1. from all those pins we only need the Ground (0V) (pins 18 to 25). the only part that may need some explanation.. simply through a single jumper wire. However. which were all connected to the board. Connecting both two inputs of the AND gates as shown makes it act like a buffer.5. Finally. To achieve this.

Here is a shot of some other ISP programmers I made for some of my friends. Also notice in the microcontroller end of the cable..
. which could cause some damage the the buffer circuit. I wont give more details about this part. but i found the High Brightness LED to be cooler than what i‟ve imagined. i‟ll leave it to your imaginations! The important thing is to solder the cable to a secure connector instead of leaving the wires free to touch each others.
Here is a shot of the device in action.Below is another overall view of the device before being encapsulated. which is simple the female connector of standard pin header. the picture may not be as clear as in reality.

reviewer and a friend – suggested. in general. As Mr Sarma – a regular visitor. Well. so all the standard connection for the microcontroller to run properly are to be made. ISP is made to program the microcontroller while it resides in its place. here are some examples showing how to connect the programmer to different types of microcontrollers:

Connecting the programmer to an AT89S52
.Connecting the programmer to the micro controller
Many visitors were confused on how to connect this programmer to the microcontroller.

You don‟t need to add a crystal resonator.
Connecting the programmer to an ATMEGA16L Note that with the ATMEGA AVR family. making it ready to use simply by connecting the 5V and GND supply rails.
. as those chips contains an internal resonator.

The programmer software
.

Some time the signature
. in most of cases. and two on single sided PCBs. and send it – with respect to the very specific ISP transfer protocol – to the microcontroller. once chosen. I thank him for sharing his work. quoted is Khizer Naeem little story: “I was working on the isp programmer for more than three weeks after i get it working. you will notice that it matches the circuit on this page. one on bread board two on vero boards. I have made five attempts of making the isp programmer given on your site.
User contributions
Khizer Naeem
Khizer Naeem. The software I am proposing was designed to be compatible with a multitude of ISP programming cables. All of these were having the sam e problem. and chose the „AEC ISP‟ cable pinout. a student from International Islamic University of Islamabad. If you have more than one parallel port (never seen this a lot. I have learned a lot of things and would like to bring in your kind notice. shares his experience in building the ISP programmer found on this page. The link to download the software is at the end of this article. His various trials and hard work paid out when he figured out a way of enhancing this ISP programmer. They didn‟t worked the most of the time. The only thing you need to do is to go through „Setup‟.) chose the one to which the programmer is connected. all the difference is the pins used on the parallel port to perform the data transfer..This is the piece of software that will take the HEX file generated by whatever compiler you are using.like they worked 1:100 attempts to program the microcontroller.

sometimes good. when i struck up with an idea that brought me back to life in the programmer business.3 m. and used high quality network cable to connect the programmer to a PC‟s prallel port. Doing this trick. He used a cable as long as 1. “ This cable is rated to 550Mhz to provide additional performance and bandwidth over and above the basic requirements for data
. a electronics hobbyist among us at Ikalogic. “No response from the microcontroller”. I came back to life and all of my programmers that won‟t work previously started working (Now i am having a dozen of working programmer LOLs) “
Eddie Wandy
Eddie Wandy. This is not enough! You must also ground your circuit with the aluminum cover of the socket which is attached internally to the foil of the parallel cable. I usually used the DB-25 Right angle PCB mount socket. I am talking about the cover that surrounds the pins of the male DB-25 socket. Working some times and failing most of the time! I was about to give up and even arranged the few bucks to purchase a branded universal programmer. along with his creative touch… He used USB power supply to power the programmer. I tried shortening the cable and even i made a isp programmer in which the ZIF socket was mounted on the parallel port side board (no cable LOL)
PCB Khizer Naeem
I then tried making the Asim khan‟s ISP programmer. its result were worst. I always common grounded the 18~25 pin of the parallel port with my circuit. Some time the Writing works and the Verifying fails and most of the times writing fails.I then build the Asim khan‟s SPI stand alone programmer the problem was same.was faulty.com build his programmer based on the data provided on this page.

Make sure the cable is no longer than 50 cm (though i made it work with a 1meter cable.) long cables tend to increase noise interference especially with TTL devices. this is – without a doubt – caused by a damaged chip. if the solutions above didn‟ t work. ” says Eddie Wandy.communication. not rubber. which was written by any other programmer .. Try more than one device. If you can read a hex file.
. Post your question in the form below. as they could be programmed through the parallel programmer and functioned correctly. 2. I had two AT89S52 which which had their ISP port damaged somehow.3 meters)
If the programmer doesn’t work
Now if your programmer doesn‟t work. 4. but you CANNOT Write another HEX file using the ISP programmer. don‟t panic and check the following: 1. this RJ45 UTP Tech. but wouldn‟t let me to program them through ISP. cable cant be cut easily like others communication cable.
His configuration is the following:
    
12 MHz Crystal (oscillator)
22n F ceramic cap (decoupling) 220 µf 16vdc (to refilter and stablelize power supply came from USB port) outcoming 5Vdc power supply from USB port I change regular LPT cable with RJ45 network cable (1... its more heavy duty because the copper inside covered by PVC. 3.