architecture and programming of 8051 mcu

130
Architecture and programming of 8051 MCU's TOC Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Chapter 6 Chapter 7 Chapter 6 : Examples 6.1 Basic connecting of the microcontroller 6.2 Additional components 6.3 Examples Introduction The purpose of this chapter is to provide basic information about microcontrollers that one needs to know in order to be able to use them successfully in practice. This is why this chapter doesn't contain any super interesting program or device schematic with amazing solutions. Instead, the following examples are better proof that program writing is neither a privilege nor a talent issue, but the ability of simply putting puzzle pieces together using directives. Rest assured that design and development of devices mainly consists of the following method “test-correct-repeat”. Of course, the more you are in it, the more complicated it becomes since the puzzle pieces are put together by both children and first-class architects... 6.1 Basic connecting

Upload: donny-tappy

Post on 29-Sep-2015

70 views

Category:

Documents


8 download

DESCRIPTION

Architecture and Programming of 8051 MCU

TRANSCRIPT

Architecture and programming of 8051 MCU's

TOC Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Chapter 6 Chapter 7Chapter 6 : Examples

6.1 Basic connecting of the microcontroller 6.2 Additional components 6.3 ExamplesIntroduction

The purpose of this chapter is to provide basic information about microcontrollers that one needs to know in order to be able to use them successfully in practice. This is why this chapter doesn't contain any super interesting program or device schematic with amazing solutions. Instead, the following examples are better proof that program writing is neither a privilege nor a talent issue, but the ability of simply putting puzzle pieces together using directives. Rest assured that design and development of devices mainly consists of the following method test-correct-repeat. Of course, the more you are in it, the more complicated it becomes since the puzzle pieces are put together by both children and first-class architects...

6.1 Basic connecting

As seen in the figure above, in order to enable the microcontroller to operate properly it is necessary to provide:

Power supply:

Reset signal: and

Clock signal.

Clearly, it is about very simple circuits, but it does not have to be always like that. If the target device is used for controlling expensive machines or maintaining vital functions, everything gets increasingly complicated. However, this solution is sufficient for the time being...

Power supply

Even though this microcontroller can operate at different power supply voltages, why to test Murphys low?! A 5V DC is most commonly used. The circuit, shown in the figure, uses a cheap integrated three-terminal positive regulator LM7805, and provides high-quality voltage stability and quite enough current to enable the microcontroller and peripheral electronics to operate normally (enough current in this case means 1Amp).

Reset signal

In order that the mucrocontroller can operate properly, a logic 0 (0V) must be applied to the reset pin RS. The push button connecting the reset pin RS to power supply VCC is not necessary. However, it is almost always provided because it enables the microcontroller safe return to normal operating conditions if something goes wrong. 5V is brought to this pin, the microcontroller is reset and program starts execution from the beginning.

Clock signal

Even though the microcontroller has a built-in oscillator, it cannot operate without two external capacitors and quartz crystal which stabilize its operation and determines its frequency (operating speed of the microcontroller).

Of course, it is not always possible to apply this solution so that there are always alternative ones. One of them is to provide clock signal from a special source through invertor. See the figure on the left.

6.2 Additional components

Regardless of the fact that the microcontroller is a product of modern technology, it is of no use without being connected to additional components. Simply put, the appearance of voltage on its pins means nothing if not used for performing certain operations (turn something on/off, shift, display etc.).

Switches and Push buttons

There are no simpler devices than switches and push-buttons. This is the simplest way of detecting appearance of a voltage on the microcontroller input pin.

Nevertheless, it is not so simple in practice... It is about contact bounce- a common problem with m e c h a n i c a l switches. When the contacts strike together, their momentum and elasticity act together to cause bounce. The result is a rapidly pulsed electrical current instead of a clean transition from zero to full current. It mostly occurs due to vibrations, slight rough spots and dirt between contacts. This effect is usually unnoticeable when using these components in everyday life because the bounce happens too quickly. In other words, the whole this process does not last long (a few micro- or miliseconds), but it is long enough to be registered by the microcontroller. When using only a push-button as a pulse counter, errors occur in almost 100% of cases!

The simplest solution to this problem is to connect a simple RC circuit to suppress quick voltage changes. Since the bounce period is not defined, the values of components are not precisely determined. In most cases, it is recomended to use the values shown in figure below.

If complete stability is needed then radical measures should be taken. The output of the circuit, shown in figure (RS flip-flop), will change its logic state only after detecting the first pulse triggered by contact bounce. This solution is expensive (SPDT switch), but effecient, the problem is definitely solved. Since the capacitor is not used, very short pulses can also be registered in this way.

In addition to these hardware solutions, there is also a simple software solution. When a program tests the state of an input pin and detects a change, the check should be done one more time after a certain delay. If the change is confirmed, it means that a switch or push button has changed its position. The advantages of such solution are obvious: it is free of charge, effects of noises are eliminated and it can be applied to the poorer quality contacts as well. Disadvantage is the same as when using RC filter, i.e. pulses shorter than program delay cannot be registered.

Optocoupler

An optocoupler is a device commonly used to galvanically separate microcontrollers electronics from any potentially dangerous current or voltage in its surroundings. Optocouplers usually have one, two or four light sources (LED diodes) on their input while on their output, opposite to diodes, there is the same number of elements sensitive to light (phototransistors, photo-thyristors or photo-triacs). The point is that an optocoupler uses a short optical transmission path to transfer a signal between the elements of circuit, while keeping them electrically isolated. This isolation makes sense only if diodes and photo-sensitive elements are separately powered. In this way, the microcontroller and expensive additional electronics are completely protected from high voltage and noises which are the most common cause of destroying, damaging or unstable operation of electronic devices in practice. The most frequently used optocouplers are those with phototransistors on their outputs. When using the optocoupler with internal base-to-pin 6 connection (there are also optocouplers without it), the base can be left unconnected. An optional connection which lessens the effects of noises by eliminating very short pulses is presented by the broken line in the figure.

Relay

A relays is an electrical switch that opens and closes under control of another electrical circuit. It is therefore connected to ouput pins of the microcontroller and used to turn on/off high-power devices such as motors, transformers, heaters, bulbs, antenna systems etc. These are almost always placed away from the board sensitive components. There are various types of relays but all of them operate in the same way. When a current flows through the coil, the relay is operated by an electromagnet to open or close one or many sets of contacts. Similar to optocouplers, there is no galvanic connection (electrical contact) between input and output circuits. Relays usually demand both higher voltage and current to start operation, but there are also miniature ones which can be activated by a low current directly obtained from a microcontroller pin.

The figure shows the solution specific to the 8051 microcontroller. A darlington transistor is used here to activate relays because of its high current gain. This is not in accordance with rules, but is necessary in the event that logic one activation is applied since the output current is then very low (pin acts as an input).

In order to prevent the appearance of self-induction high voltage, caused by a sudden stop of current flow through the coil, an inverted polarized diode is connected in parallel to the coil. The purpose of this diode is to cut off the voltage peak.

Light-emitting diode (LED)

Light-emitting diodes are elements for light signalization in electronics. They are manufactured in different shapes, colors and sizes. For their low price, low power consumption and simple use, they have almost completely pushed aside other light sources, bulbs at first place. They perform similar to common diodes with the difference that they emit light when current flows through them.

It is important to limit their current, otherwise they will be permanently destroyed. For this reason, a conductor must be connected in parallel to an LED. In order to determine value of this conductor, it is necessary to know diodes voltage drop in forward direction, which depends on what material a diode is made from and what colour it is. Typical values of the most frequently used diodes are shown in table below. As seen, there are three main types of LEDs.Standardones get ful brightness at current of 20mA.Low Currentdiodes get ful brightness at ten times lower current whileSuper Brightdiodes produce more intensive light than Standard ones.

COLORTYPETYPICAL CURRENT ID (MA)MAXIMAL CURRENT IF (MA)VOLTAGE DROP UD (V)

Infrared-30501.4

RedStandard20301.7

RedSuper Bright20301.85

RedLow Current2301.7

Orange-10302.0

GreenLow Current2202.1

Yellow-20302.1

Blue-20304.5

White-25354.4

Since the 8051 microcontroller can provide only low output current and since its pins are configured as outputs when voltage provided on them is 0V, direct connecting to LEDs is performed as shown in figure on the right (Low currentLED, cathode is connected to the output pin).

LED displays

Basically, an LED display is nothing more than several LEDs moulded in the same plastic case. There are many types of displays composed of several dozens of built in diodes which can display different symbols.

Most commonly used is a so called 7-segment display. It is composed of 8 LEDs, 7 segments are arranged as a rectangle for symbol displaying and there is an additional segment for decimal point displaying. In order to simplify connecting, anodes and catodes of all diodes are connected to the common pin so that there are common anode displays and common catode displays, respectively. Segments are marked with the latters from A to G, plus dp, as shown in the figure on the left. On connecting, each diode is treated separtely, which means that each must have its own current limiting resistor.

Displays connected to the microcontroller usually occupy a large number of valuable I/O pins, which can be a big problem especially if it is needed to display multy digit numbers. The problem is more than obvious if, for example, it is needed to display two 6-digit numbers (a simple calculation shows that 96 output pins are needed in this case). The solution to this problem is called MULTIPLEXING. This is how an optical illusion based on the same operating principle as a film camera is made. Only one digit is active at a time, but they change their state so quickly making impression that all digits of a number are simultaneously active.

Here is an explanation on the figure above. First a byte representing units is applied on a microcontroller port and a transistor T1 is activated at the same time. After a while, the transistor T1 is turned off, a byte representing tens is applied on a port and a transistor T2 is activated. This process is being cyclically repeated at high speed for all digits and corresponding transistors.

The fact that the microcontroller is just a kind of miniature computer designed to understand only the language of zeros and ones is fully expressed when displaying any digit. Namely, the microcontroller doesn't know what units, tens or hundreds are, nor what ten digits we are used to look like. Therefore, each number to be displayed must be prepared in the following way:

First of all, a multy digit number must be split into units, tens etc. in a particular subroutine. Then each of these digits must be stored in special bytes. Digits get familiar format by performing masking. In other words, a binary format of each digit is replaced by a different combination of bits in a simple subroutine. For example, the digit 8 (0000 1000) is replaced by the binary number 0111 111 in order to activate all LEDs displaying digit 8. The only diode remaining inactive in this case is reserved for the decimal point. If a microcontroller port is connected to the display in such a way that bit 0 activates segment a, bit 1 activates segment b, bit 2 segment c etc., then the table below shows the mask for each digit.

DIGITS TO DISPLAYDISPLAY SEGMENTS

dpabcdefg

010000001

110011111

210010010

310000110

411001100

510100100

610100000

710001111

810000000

910000100

In addition to digits from 0 to 9, some letters of alphabet - A, C, E, J, F, U, H, L, b, c, d, o, r, t - can also be displayed by performing appropriate masking.If the event that common chatode displays are used all units in the table should be replaced by zeros and vice versa. Additionally, NPN transistors should be used as drivers as well.

Liquid Crystal Displays (LCD)

An LCD display is specifically manufactured to be used with microcontrollers, which means that it cannot be activated by standard IC circuits. It is used for displaying different messages on a miniature liquid crysal display.

The model described here is for its low price and great capabilities most frequently used in practice. It is based on the HD44780 microcontroller (Hitachi) and can display messages in two lines with 16 characters each. It displays all the letters of alphabet, Greek letters, punctuation marks, mathematical symbols etc. In addition, it is possible to display symbols made up by the user. Other useful features include automatic message shift (left and right), cursor appearance, LED backlight etc.

LCD Pins

There are pins along one side of a small printed board. These are used for connecting to the microcontroller. There are in total of 14 pins marked with numbers (16 if it has backlight). Their function is described in the table bellow:

FUNCTIONPIN NUMBERNAMELOGIC STATEDESCRIPTION

Ground1Vss-0V

Power supply2Vdd-+5V

Contrast3Vee-0 - Vdd

Control of operating4RS01D0 D7 are interpreted as commandsD0 D7 are interpreted as data

5R/W01Write data (from controller to LCD)Read data (from LCD to controller)

6E01From 1 to 0Access to LCD disabledNormal operatingData/commands are transferred to LCD

Data / commands7D00/1Bit 0 LSB

8D10/1Bit 1

9D20/1Bit 2

10D30/1Bit 3

11D40/1Bit 4

12D50/1Bit 5

13D60/1Bit 6

14D70/1Bit 7 MSB

LCD screen

An LCD screen consists of two lines each containing 16 characters. Each character consists of 5x8 or 5x11 dot matrix. This book covers the most commonly used display, i.e. the 5x8 character display.

Display contrast depends on the power supply voltage and whether messages are displayed in one or two lines. For this reason, varying voltage 0-Vdd is applied on the pin marked as Vee. Trimmer potentiometer is usually used for that purpose. Some LCD displays have built-in backlight (blue or green LEDs). When used during operation, a current limiting resistor should be serially connected to one of the pins for backlight power supply (similar to LEDs).

If there are no characters displayed or if all of them are dimmed when the display is on, the first thing that should be done is to check the potentiometer for contrast regulation. Is it properly adjusted? The same applies if the mode of operation has been changed (writing in one or two lines).

LCD Memory

The LCD display contains three memory blocks: DDRAM Display Data RAM;

CGRAM Character Generator RAM; and

CGROM Character Generator ROM.

DDRAM Memory

DDRAM memory is used for storing characters to be displayed. The size of this memory is sufficient for storing 80 characters. Some memory locations are directly connected to the characters on display.

It works quite simply: it is sufficient to configure the display so as to increment addresses automatically (shift right) and set the starting address for the message that should be displayed (for example 00 hex).

After that, all characters sent through lines D0-D7 will be displayed in the message format we are used to- from left to right. In this case, displaying starts from the first field of the first line since the address is 00 hex. If more than 16 characters are sent, then all of them will be memorized, but only the first sixteen characters will be visible. In order to display the rest of them, a shift command should be used. Virtually, everything looks as if the LCD display is a window which moves left-right over memory locations containing different characters. This is how the effect of message moving on the screen is made.

If the cursor is on, it appears at the location which is currently addressed. In other words, when a character appears at the cursor position, it will automatically move to the next addressed location.Since this is a sort of RAM memory, data can be written to and read from it, but its contents is irretrievably lost when the power goes off.

CGROM Memory

CGROM memory contains the default chracter map with all characters that can be displayed on the screen. Each character is assigned to one memory location.

The addresses of CGROM memory locations match the characters of ASCII. If the program being currently executed encounters a command send character P to port, then the binary value 0101 0000 appears on the port. This value is the ASCII equivalent to the character P. It is then written to LCD, which results in displaying the symbol from 0101 0000 location of CGROM. In other words, the character P is displayed. This applies to all letters of alphabet (capitals and small), but not to numbers.

As seen on the previous map, addresses of all digits are pushed forward by 48 relative to their values (digit 0 address is 48, digit 1 address is 49, digit 2 address is 50 etc.). Accordingly, in order to display digits correctly, each of them needs to be added a decimal number 48 prior to be sent to LCD.

From their inception till today, computers can recognize only numbers, but not letters. It means that all data a computer swaps with a peripheral device has a binary format, even though the same is recognized by the man as letters (keyboard is an excellent example). Every character matches the unique combination of zeroes and ones. ASCII is character encoding based on the English alphabet. ASCII code specifies correspondance between standard character symbols and their numerical equivalents.

CGRAM memoryApart from standard characters, the LCD display can also display symbols defined by the user itself. It can be any symbol in the size of 5x8 pixels. RAM memory called CGRAM in the size of 64 bytes enables it.

Memory registers are 8 bits wide, but only 5 lower bits are used. Logic one (1) in every register represents a dimmed dot, while 8 locations grouped together represent one character. It is best illustrated in figure below:

Symbols are usually defined at the beginnig of the program by simply writing zeros and ones to registers of CGRAM memory so that they form desired shapes. In order to display them it is sufficient to specify their address. Pay attention to the first coloumn in the CGROM map of characters. It doesn't contain RAM memory addresses, but symbols being discussed here. In this example, display 0 means - display , display 1 means - display etc.

LCD Basic CommandsAll data transferred to LCD through the outputs D0-D7 will be interpreted as a command or a data, which depends on the pin RS logic state:

RS = 1- Bits D0-D7 are addresses of the characters to be displayed. LCD processor addresses one character from the character map and displays it. The DDRAM address specifies the location on which the character is to be displayed. This address is defined before the character is transferred or the address of previously transferred character is automatically incremented.

RS = 0- Bits D0 - D7 are commands which determine the display mode. The commands recognized by the LCD are given in the table below:

COMMANDRSRWD7D6D5D4D3D2D1D0EXECUTION TIME

Clear display00000000011.64mS

Cursor home000000001x1.64mS

Entry mode set00000001I/DS40uS

Display on/off control0000001DUB40uS

Cursor/Display Shift000001D/CR/Lxx40uS

Function set00001DLNFxx40uS

Set CGRAM address0001CGRAM address40uS

Set DDRAM address001DDRAM address40uS

Read BUSY flag (BF)01BFDDRAM address-

Write to CGRAM or DDRAM10D7D6D5D4D3D2D1D040uS

Read from CGRAM or DDRAM11D7D6D5D4D3D2D1D040uS

I/D 1 = Increment (by 1) R/L 1 = Shift right

0 = Decrement (by 1) 0 = Shift left

S 1 = Display shift on DL 1 = 8-bit interface

0 = Display shift off 0 = 4-bit interface

D 1 = Display on N 1 = Display in two lines

0 = Display off 0 = Display in one line

U 1 = Cursor on F 1 = Character format 5x10 dots

0 = Cursor off 0 = Character format 5x7 dots

B 1 = Cursor blink on D/C 1 = Display shift

0 = Cursor blink off 0 = Cursor shift

What is theBusyflag?

Compared to the microcontroller, the LCD is an extremely slow component. Because of this, it was necessary to provide a signal which will, upon command execution, indicate that the display is ready to receive a new data. That signal, called the busy flag, can be read from line D7. When the BF bit is cleared (BF=0), the display is ready to receive a new data.

LCD Connection

Depending on how many lines are used for connecting the LCD to the microcontroller, there are 8-bit and 4-bit LCD modes. The appropriate mode is selected at the beginning of the operation. This process is called initialization. 8-bit LCD mode uses outputs D0-D7 to transfer data in the way explained on the previous page. The main purpose of 4-bit LED mode is to save valuable I/O pins of the microcontroller. Only 4 higher bits (D4-D7) are used for communication, while other may be left unconnected. Each data is sent to the LCD in two steps: four higher bits are sent first (normally through the lines D4-D7), then four lower bits. Initialization enables the LCD to link and interpret received bits correctly. Data is rarely read from the LCD (it is mainly transferred from the microcontroller to LCD) so that it is often possible to save an extra I/O pin by simple connecting R/W pin to ground. Such saving has its price. Messages will be normally displayed, but it will not be possible to read the busy flag since it is not possible to read the display either.

Fortunately, there is a simple solution. After sending a character or a command it is important to give the LCD enough time to do its job. Owing to the fact that execution of the slowest command lasts for approximately 1.64mS, it will be sufficient to wait approximately 2mS for LCD.

LCD Initialization

The LCD is automatically cleared when powered up. It lasts for approximately 15mS. After that, the display is ready for operation. The mode of operation is set by default. It means that:

1. Display is cleared

2. Mode

DL= 1 Communication through 8-bit interface

N= 0 Messages are displayed in one line

F= 0 Character font 5 x 8 dots

3. Display/Cursor on/off

D= 0 Display off

U= 0 Cursor off

B= 0 Cursor blink off

4. Character entry

ID= 1 Displayed addresses are automatically incremented by 1

S= 0 Display shift off

Automatic reset is in most cases performed without any problems. In most cases, but not always! If for any reason the power supply voltage does not reach ful value within 10mS, the display will start to perform completely unpredictably. If the voltage supply unit is not able to meet this condition or if it is needed to provide completely safe operation, the process of initialization is applied. Initialization, among other things, causes a new reset enabling display to operate normally.

Refer to the figure below for the procedure on 8-bit initialization:

It is not a mistake!In this algorithm, the same value is transferred three times in a row.

In case of 4-bit initialization, the procedure is as follows:

6.3 Examples

The schematic below is used in the several following examples:

Apart from components necessary for the operation of the microcontroller such as oscillator with capacitors and the simplest reset circuit, there are also several LEDs and one push button. These are used to indicate the operation of the program.

All LEDs are polarized in such a way that they are activated by driving a microcontroller pin low (logic 0).

LED Blinking

The purpose of this example is not to demonstrate the operation of LEDs, but the operating speed of the microcontroller. Simply put, in order to enable LED blinking to be visible, it is necessary to provide sufficient amount of time to pass between on/off states of LEDs. In this example time delay is provided by executing a subroutine calledDelay. It is a triple loop in which the program remains for approximately 0.5 seconds and decrements values stored in registers R0, R1 or R2. After returning from the subroutine, the pin state is inverted and the same procedure is repeated...

;************************************************************************

;* PROGRAM NAME : Delay.ASM

;* DESCRIPTION: Program turns on/off LED on the pin P1.0

;* Software delay is used (Delay).

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(DELAY.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ;Reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ;Define Stack pointer

MOV P1,#0FFh ;All pins are configured as inputs

LOOP:

CPL P1.0 ;Pin P1.0 state is inverted

LCALL Delay ;Time delay

SJMP LOOP

Delay:

MOV R2,#20 ;500 ms time delay

F02: MOV R1,#50 ;25 ms

F01: MOV R0,#230

DJNZ R0,$

DJNZ R1,F01

DJNZ R2,F02

END ;End of program

Using Watch-dog Timer

This example describes how the watch-dog timer should not operate. The watch-dog timer is properly adjusted (nominal time for counting is 1024mS), but instruction used to reset it is intentionally left out so that this timer always "wins". As a result, the microcontroller is reset (state in registers remains unchanged), program starts execution from the beginning and the number in register R3 is incremented by 1 and then copied to port P1.

LEDs display this number in binary format...

;************************************************************************

;* PROGRAM NAME : WatchDog.ASM

;* DESCRIPTION : After watch-dog reset, program increments number in

;* register R3 and shows it on port P1 in binary format.

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(WATCHDOG.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

WMCON DATA 96H

WDTEN EQU 00000001B ; Watch-dog timer is enabled

PERIOD EQU 11000000B ; Nominal Watch-dog period is set to be 1024ms

;RESET VECTOR

CSEG AT 0

JMP XRESET ; Reset vector

CSEG

ORG 100H

XRESET: ORL WMCON,#PERIOD ; Define Watch-dog period

ORL WMCON,#WDTEN ; Watch-dog timer is enabled

MOV A,R3 ; R3 is moved to port 1

MOV P1,A

INC R3 ; Register R3 is incremented by 1

LAB: SJMP LAB ; Wait for watch-dog reset

END ; End of program

Timer T0 in mode 1

This program spends most of its time in an endless loop waiting for timer T0 to count up a full cycle. When it happens, an interrupt is generated, routineTIM0_ISRis executed and logic zero (0) on port P1 is shifted right by one bit. This is another way of demonstrating the operating speed of the microcontroller since each shift means that counter T0 has counted up 216pulses!

;************************************************************************

;* PROGRAM NAME : Tim0Mod1.ASM

;* DESCRIPTION: Program rotates "0" on port 1. Timer T0 in mode 1 is

;* used

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(TIM0MOD1.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;DECLARATION OF VARIABLES

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 00BH

JMP TIM0_ISR ; Timer T0 reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

MOV TMOD,#01H ; MOD1 is selected

MOV A,#0FFH

MOV P1,#0FFH

SETB TR0 ; Timer T0 is enabled

MOV IE,#082H ; Interrupt enabled

CLR C

LOOP1: SJMP LOOP1 ; Remain here

TIM0_ISR: RRC A ; Rotate accumulator A through Carry flag

MOV P1,A ; Contents of accumulator A is moved to PORT1

RETI ; Return from interrupt

END ; End of program

Timer T0 in Split mode

Similarly to the previous example, the program spends most of its time in a loop called LOOP1. Since 16-bit Timer T0 is split into two 8-bit timers, there are also two interrupt sources.

The first interrupt is generated after timer T0 reset. Routine TIM0_ISR in which logic zero (0) bit on port P1 rotates is executed. Outside looking, it seems that LEDs move.

Another interrupt is generated upon Timer T1 reset. Routine TIM1_ISR in which the bit state DIRECTION inverts is executed. Since this bit determines direction of bit rotation then the moving direction of LED is also changed.If you press a push button T1 at some point, a logic zero (0) on the P3.2 output will disable Timer T1.

;************************************************************************

;* PROGRAM NAME : Split.ASM

;* DESCRIPTION: Timer TL0 rotates bit on port P1, while TL1 determines

;* the rotation direction. Both timers operate in mode

;* 3. Logic zero (0) on output P3.2 disables rotation on port P1.

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(SPLIT.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;DECLARATION OF VARIABLES

BSEG AT 0

;DECLARATION OF BIT-VARIABLES

SEMAPHORE: DBIT 8

DIRECTION BIT SEMAPHORE

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 00BH

JMP TIM0_ISR ; Timer T0 reset vector

ORG 01BH

JMP TIM1_ISR ; Timer T1 reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

MOV TMOD,#00001011B ; Define MOD3

MOV A,#0FFH

MOV P1,#0FFH

MOV R0,#30D

SETB TR0 ; TL0 is turned on

SETB TR1 ; TL1 is turned on

MOV IE,#08AH ; Interrupt enabled

CLR C

CLR DIRECTION ; Rotate to the right

LOOP1: SJMP LOOP1 ; Remain here

TIM0_ISR:

DJNZ R0,LAB3 ; Slow down rotation by 256 times

JB DIRECTION,LAB1

RRC A ; Rotate contents of Accumulator to the right through

; Carry flag

SJMP LAB2

LAB1: RLC A ; Rotate contents of Accumulator to the left through

; Carry flag

LAB2: MOV P1,A ; Contents of Accumulator is moved to port P1

LAB3: RETI ; Return from interrupt

TIM1_ISR:

DJNZ R1,LAB4 ; Slow down direction of rotation by 256 times

DJNZ R2,LAB4 ; When time expires, change rotation direction

CPL SMER

MOV R2,#30D

LAB4: RETI

END ; End of program

Simultaneous use of timers T0 and T1

This program can be considered as continuation of the previous one. They share the same idea, but in this case true timers T0 and T1 are used. In order to demonstrate the operation of both timers on the same port at the same time, timer T0 reset is used to shift logic zero (0) on the port, while Timer T1 reset is used to change rotation direction. This program spends most of its time in the loopLOOP1waiting for an interrupt to be caused by reset. By checking the DIRECTION bit, information on rotation direction of both bits in accumulator as well as of moving port LED is obtained.

;************************************************************************

;* PROGRAM NAME : Tim0Tim1.ASM

;* DESCRIPTION: Timer TO rotates bit on port P1 while Timer1

;* changes rotation direction. Both timers are configured to operate in mode 1.

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(TIM0TIM1.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;DECLARATION OF VARIABLES

BSEG AT 0

;DECLARATION OF BIT-VARIABLES

SEMAPHORE: DBIT 8

DIRECTION BIT SEMAPHORE

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 00BH ; Timer 0 Reset vector

JMP TIM0_ISR

ORG 01BH ; Timer 1 Reset vector

JMP TIM1_ISR

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

MOV TMOD,#11H ; Select MOD1 for both timers

MOV A,#0FFH

MOV P1,#0FFH

MOV R0,#30D ; R0 is initialized

SETB TR0 ; TIMER0 is turned on

SETB TR1 ; TIMER1 is turned on

MOV IE,#08AH ; Timer0 and Timer1 Interrupt enabled

CLR C

CLR DIRECTION ; Rotate to the right

LOOP1: SJMP LOOP1 ; Remain here

TIM0_ISR:

JB DIRECTION,LAB1

RRC A ; Rotate contents of accumulator to the right through

; Carry flag

SJMP LAB2

LAB1: RLC A ; Rotate contents of Accumulator to the left through

; Carry flag

LAB2: MOV P1,A ; Contents of Accumulator is moved to port P1

RETI ; Return from interrupt

TIM1_ISR:

DJNZ R0,LAB3 ; When time expires, change rotation direction

CPL DIRECTION

MOV R0,#30D ; Initialize R0

LAB3:

RETI

END ; End of program

Using Timer T2

This example describes the use of Timer T2 configured to operate inAuto-Reloadmode. In this very case, LEDs are connected to port P3 while the push button used for forced timer reset (T2EX) is connected to the P1.1 pin.

Program execution is similar to the previous examples. When timer ends counting, an interrupt is enabled and subroutineTIM2_ISRis executed, thus rotating a logic zero (0) in accumulator and moving the contents of accumulator to the P3 pin. At last, flags which caused an interrupt are cleared and program returns to the loop LOOP1 where it remains until a new interrupt request arrives...

If push button T2EX is pressed, timer is temporarily reset. This push button resets timer, while push button RESET resets the microcontroller.

;************************************************************************

;* PROGRAM NAME : Timer2.ASM

;* DESCRIPTION: Program rotates log. "0" on port P3. Timer2 determines

;* the speed of rotation and operates in auto-reload mode

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(TIMER2.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;DEFINITION OF VARIABLES

T2MOD DATA 0C9H

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 02BH ; Timer T2 Reset vector

JMP TIM2_ISR

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

MOV A,#0FFH

MOV P3,#0FFH

MOV RCAP2L,#0FH ; Prepare 16-bit auto-reload mode

MOV RCAP2L,#01H

CLR CAP2 ; Enable 16-bit auto-reload mod

SETB EXEN2 ; Pin P1.1 reset is enabled

SETB TR2 ; Enable Timer T2

MOV IE,#0A0H ; Interrupt is enabled

CLR C

LOOP1: SJMP LOOP1 ; Remain here

TIM2_ISR: RRC A ; Rotate contents of Accumulator to the right through

; Carry flag

MOV P3,A ; Move the contents of Accumulator A to PORT3

CLR TF2 ; Clear timer T2 flag TF2

CLR EXF2 ; Clear timer T2 flag EXF2

RETI ; Return from interrupt

END ; End of program

Using External Interrupt

Here is another example of interrupt execution. An external iterrupt is generated when a logic zero (0) is present on pin P3.2 or P3.3. Depending on which input is active, one of two routines will be executed:

A logic zero (0) on the P3.2 pin initiates execution of interrupt routine Isr_Int0, thus incrementing number in register R0 and copying it to port P0. Logic zero on the P3.3 pin initiates execution of subroutine Isr_Int1, number in register R1 is incremented by 1 and then copied to port P1.

In short, each press on push buttons INT0 and INT1 will be counted and immediately shown in binary format on appropriate port (LED which emitts light represents a logic zero (0)).

;************************************************************************

;* PROGRAM NAME : Int.ASM

;* DESCRIPTION : Program counts interrupts INT0 generated by appearance of high-to-low

;* transition signal on pin P3.2 Result appears on port P0. Interrupts INT1 are also

;* counted up at the same time. They are generated byappearing high-to-low transition

;* signal on pin P3. The result appears on port P1.

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(INT.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 003H ; Interrupt routine address for INT0

JMP Isr_Int0

ORG 013H ; Interrupt routine address for INT1

JMP Isr_Int1

ORG 100H

XRESET:

MOV TCON,#00000101B ; Interrupt INT0 is generated by appearing

; high-to-low transition signal on pin P3.2

; Interrupt INT0 is generated by appearing

; high-to-low transition signal on pin P3.3

MOV IE,#10000101B ; Interrupt enabled

MOV R0,#00H ; Counter starting value

MOV R1,#00H

MOV P0,#00H ; Reset port P0

MOV P1,#00H ; Reset port P1

LOOP: SJMP LOOP ; Remain here

Isr_Int0:

INC R0 ; Increment value of interrupt INT0 counter

MOV P0,R0

RETI

Isr_Int1:

INC R1 ; Increment value of interrupt INT1 counter

MOV P1,R1

RETI

END ; End of program

Using LED display

The following examples describe the use of LED displays. Common chatode displays are used here, which means that all built-in LEDs are polarized in such a way that their anodes are connected to the microcontroller pins. Since the common way of thinking is that logic one (1) turns something on and logic zero (0) turns something of, Low Current displays (low power consumption) and their diodes (segments) are connected serially to resistors of relatively high resistance.

In order to save I/O pins, four LED displays are connected to operate in multiplex mode. It means that all segments having the same name are connected to one output port each and only one display is active at a time.

Tranzistors and segmenats on displays are quickly activated, thus making impression that all digits are active simultaneously.

Writing digits on LED display

This program is a kind of warming up exerciese before real work starts. The purpose of this example is to display something on any display. Multiplex mode is not used this time. Instead, digit 3 is displayed on only one of them (first one on the right).

Since the microcontroller does not know how we write number 3, a small subroutine calledDispis used (the microcontroller writes this number as 0000 0011). This subroutine enables all decimal digits (0-9) to be displayed (masked). The principle of operation is simple. A number to be displayed is added to the current address and program jump is executed. Different numbers require different jump length. Precisely determined combination of zeroes and ones appears on each of these new locations (digit 1 mask, digit 2 mask...digit 9 mask). When this combination is transferred to the port, the display shows desired digit.

;************************************************************************

;* PROGRAM NAME : 7Seg1.ASM

;* DESCRIPTION: Program displays number "3" on 7-segment LED display

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(7SEG1.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

MOV P1,#0 ; Turn off all segments on displays

MOV P3,#20h ; Activate display D4

LOOP:

MOV A,#03 ; Send number 3 to display

LCALL Disp ; Perform appropriate masking for the number

MOV P1,A

SJMP LOOP

Disp: ; Subroutine for displaying digits

INC A

MOVC A,@A+PC

RET

DB 3FH ; Digit 0 mask

DB 06H ; Digit 1 mask

DB 5BH ; Digit 2 mask

DB 4FH ; Digit 3 mask

DB 66H ; Digit 4 mask

DB 6DH ; Digit 5 mask

DB 7DH ; Digit 6 mask

DB 07H ; Digit 7 mask

DB 7FH ; Digit 8 mask

DB 6FH ; Digit 9 mask

END ; End of program

Writing and changing digits on LED display

This program is only an extended verson of the previous one. There is only one digit active- the first one on the right, and there is no use of multiplexing. Unlike the previous example, all decimal numbers are displayed (0-9). In order to enable digits to change at reasonable pace, a soubroutine L2 which causes a short time delay is executed prior to each change occurs. Basically, the whole process is very simple and takes place in the main loop called LOOP which looks as follows:

1. R3 is copied to Accumulator and subroutine for masking digits Disp is executed;

2. Accumulator is copied to the port and displayed;

3. The contents of the R3 register is incremented;

4. It is checked whether 10 cycles are counted or not. If it is, register R3 is reset in order to enable counting to start from 0; and

5. Instruction labeled as L2 within subroutine is executed.

;************************************************************************

;* PROGRAM NAME: 7Seg2.ASM

;* DESCRIPTION: Program writes numbers 0-9 on 7-segment LED display

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(7SEG2.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

MOV R3,#0 ; Counter initial value

MOV P1,#0 ; Turn off all display segments

MOV P3,#20h ; Activate display D4

LOOP:

MOV A,R3

LCALL Disp ; Perform appropriate masking for number in

; Accumulator

MOV P1,A

INC R3 ; Increment number in register by 1

CJNE R3,#10,L2 ; Check whether the number 10 is in R3

MOV R3,#0 ; If it is, reset counter

L2:

MOV R2,#20 ; 500 mS time delay

F02: MOV R1,#50 ; 25 mS

F01: MOV R0,#230

DJNZ R0,$

DJNZ R1,F01

DJNZ R2,F02

SJMP LOOP

Disp: ; Subroutine for writing digits

INC A

MOVC A,@A+PC

RET

DB 3FH ; Digit 0 mask

DB 06H ; Digit 1 mask

DB 5BH ; Digit 2 mask

DB 4FH ; Digit 3 mask

DB 66H ; Digit 4 mask

DB 6DH ; Digit 5 mask

DB 7DH ; Digit 6 mask

DB 07H ; Digit 7 mask

DB 7FH ; Digit 8 mask

DB 6FH ; Digit 9 mask

END ; End of program

Writing two-digit number on LED display

It is time for time multiplexing! This is the simplest example which displays the number 23 on two displays in such a way that one of them displays units, while the other displays tens. The most important thing in the program is time synchronization. Otherwise, everything is very simple. Transistor T4 enables display D4 and at the same time a bit combination corresponding to the digit 3 is set on the port. After that, transistor T4 is disabled and the whole process is repeated using transistor T3 and display D3 in order to display digit 2. This procedure must be continuosly repeated in order to make impression that both displays are active at the same time.

;************************************************************************

;* PROGRAM NAME: 7Seg3.ASM

;* DESCRIPTION: Program displays number "23" on 7-segment LED display

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(7SEG3.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

LOOP: MOV P1,#0 ; Turn off all display segments

MOV P3,#20h ; Activate display D4

MOV A,#03 ; Write digit 3 on display D4

LCALL Disp ; Find appropriate mask for that digit

MOV P1,A ; Put the mask on the port

MOV P1,#0 ; Turn off all dislay segments

MOV P3,#10h ; Activate display D3

MOV A,#02 ; Write digit 2 on display D3

LCALL Disp ; Find mask for that digit

MOV P1,A ; Put the mask on the port

SJMP LOOP ; Return to the label LOOP

Disp: ; Subroutine for writing digits

INC A

MOVC A,@A+PC

RET

DB 3FH ; Digit 0 mask

DB 06H ; Digit 1 mask

DB 5BH ; Digit 2 mask

DB 4FH ; Digit 3 mask

DB 66H ; Digit 4 mask

DB 6DH ; Digit 5 mask

DB 7DH ; Digit 6 mask

DB 07H ; Digit 7 mask

DB 7FH ; Digit 8 mask

DB 6FH ; Digit 9 mask

END ; End of program

Using four digit LED display

In this example all four displays, instead of two, are active so that it is possible to write numbers from 0 to 9999. Here, the number 1 234 is displayed. After initialization, the program remains in the loop LOOP where digital multiplexing is performed. The subroutine Disp is used to convert binary numbers into corresponding combinations of bits for the purpose of activating display lighting segments.

;************************************************************************

;* PROGRAM NAME : 7Seg5.ASM

;* DESCRIPTION : Program displays number"1234" on 7-segment LED display

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(7SEG5.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

LOOP: MOV P1,#0 ; Turn off all display segments

MOV P3,#20h ; Activate display D4

MOV A,#04 ; Write digit 4 on display D4

LCALL Disp ; Find mask for that digit

MOV P1,A ; Put the mask on the port

MOV P1,#0 ; Turn off all display segments

MOV P3,#10h ; Activate display D3

MOV A,#03 ; Write digit 3 on display D3

LCALL Disp ; Find mask for that digit

MOV P1,A ; Put the mask on the port

MOV P1,#0 ; Turn off all display segments

MOV P3,#08h ; Activate display D2

MOV A,#02 ; Write digit 2 on display D2

LCALL Disp ; Find mask for that digit

MOV P1,A ; Put the mask on the port

MOV P1,#0 ; Turn off all display segments

MOV P3,#04h ; Activate display D1

MOV A,#01 ; Write digit 1 on display D1

LCALL Disp ; Find mask for that digit

MOV P1,A ; Put the mask on the port

SJMP LOOP ; Return to the lable LOOP

Disp: ; Subroutine for writing digits

INC A

MOVC A,@A+PC

RET

DB 3FH ; Digit 0 mask

DB 06H ; Digit 1 mask

DB 5BH ; Digit 2 mask

DB 4FH ; Digit 3 mask

DB 66H ; Digit 4 mask

DB 6DH ; Digit 5 mask

DB 7DH ; Digit 6 mask

DB 07H ; Digit 7 mask

DB 7FH ; Digit 8 mask

DB 6FH ; Digit 9 mask

END ; End of program

LED display as a two digit counter

Things are getting complicated... In addition to two digit multiplexing, the microcontroller also performs other operations. In this example, contents of registers R2 and R3 are incremented in order to display number counting (97, 98, 99, 00, 01, 02...).

This time, transistors which activate displays remain turned on for 25mS. The soubroutine Delay is in charge of that. Even though digits shift much slower now, it is still not slow enough to make impression of simultaneous operation. After both digits of a number blink for 20 times, the number on displays is incremented by 1 and the whole procedure is repeated.

;************************************************************************

;* PROGRAM NAME : 7Seg4.ASM

;* DESCRIPTION: Program displays numbers 0-99 on 7-segment LED displays

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(7SEG4.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 100H

XRESET: MOV SP,#STACK_START ; Define Stack pointer

MOV R2,#0 ; Counter starting value

MOV R3,#0

MOV R4,#0

LOOP: INC R4 ;Wait for display to be "refreshed" for 100 times

CJNE R4,#20d,LAB1 ;before incrementing the counter

MOV R4,#0

MOV P1,#0 ; Turn off all display segments

INC R2 ; Increment Register containing units by 1

CJNE R2,#10d,LAB1

MOV R2,#0 ; Reset units

INC R3 ; Increment Register with tens by 1

CJNE R3,#10d,LAB1 ;

MOV R3,#0 ; Reset tens

LAB1:

MOV P3,#20h ; Activate display D4

MOV A,R2 ; Copy Register containing units to A

LCALL Disp ; Call mask for that digit

MOV P1,A ; Write units on display D4

LCALL Delay ; 25ms delay

MOV P1,#0 ; Turn off all display segments

MOV P3,#10h ; Activate display D3

MOV A,R3 ; Copy Register contaning tens to A

LCALL Disp ; Call mask for that digit

MOV P1,A ; Write tens on display D3

LCALL Delay ; 25ms delay

SJMP LOOP

Delay:

MOV R1,#50 ; 5 ms delay

F01: MOV R0,#250

DJNZ R0,$

DJNZ R1,F01

RET

Disp: ; Subroutine for displaying digits

INC A

MOVC A,@A+PC

RET

DB 3FH ; Digit 0 mask

DB 06H ; Digit 1 mask

DB 5BH ; Digit 2 mask

DB 4FH ; Digit 3 mask

DB 66H ; Digit 4 mask

DB 6DH ; Digit 5 mask

DB 7DH ; Digit 6 mask

DB 07H ; Digit 7 mask

DB 7FH ; Digit 8 mask

DB 6FH ; Digit 9 mask

END ; End of program

Handling EEPROM

This program writes data to on-chip EEPROM memory. In this case, the data is a hexadecimal number 23 which is to be written to the location with address 00.

To make sure that this number is correctly written, the same location of EEPROM is read 10mS later in order to compare these two numbers. If they match, F will be displayed. Otherwise, E will be displayed on the LED display (Error).

;************************************************************************

;* PROGRAM NAME: EEProm1.ASM

;* DESCRIPTION: Programming EEPROM at address 0000hex and displaying message

;* on LED display.

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(EEPROM1.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

WMCON DATA 96H

EEMEN EQU 00001000B ; Access to internal EEPROM is enabled

EEMWE EQU 00010000B ; Write to EEPROM is enabled

TEMP DATA 030H ; Define Auxiliary register

THE END EQU 071H ; Display "F"

ERROR EQU 033H ; Display "E"

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 100H

XRESET: MOV IE,#00 ; All interrupts are disabled

MOV SP,#STACK_START

MOV DPTR,#0000H ; Choose location address in EEPROM

ORL WMCON,#EEMEN ; Access to EEPROM is enabled

ORL WMCON,#EEMWE ; Write to EEPROM is enabled

MOV TEMP,#23H ; Number written to EEPROM is moved to

MOV A,TEMP ; register TEMP and Accumulator

MOVX @DPTR,A ; Write byte to EEPROM

CALL DELAY ; 10ms delay

MOVX A,@DPTR ; Read the same location and compare to TEMP,

CJNE A,TEMP,ERROR ; If they don't match, jump to label ERROR

MOV A,#KRAJ ; Display F (correct)

MOV P1,A

XRL WMCON,#EEMWE ; Write to EEPROM is disabled

XRL WMCON,#EEMEN ; Access to EEPROM is disabled

LOOP1: SJMP LOOP1 ; Remain here

ERROR: MOV A,#ERROR ; Display E (error)

MOV P1,A

LOOP2: SJMP LOOP2

DELAY: MOV A,#0AH ; Delay

MOV R3,A

LOOP3: NOP

LOOP4: DJNZ B,LOOP4

LOOP5: DJNZ B,LOOP5

DJNZ R3,LOOP3

RET

END ; End of program

Data reception via UART

In order to enable successful UART serial communication, it is necessary to meet specific rules of the RS232 standard. It primarily refers to voltage levels required by this standard. Accordingly, -10V stands for logic one (1) in the message, while +10V stands for logic zero (0). The microcontroller converts accurately data into serial format, but its power supply voltage is only 5V. Since it is not easy to convert 0V into 10V and 5V into -10V, this operation is on both transmit and receive side left to a specialized IC circuit. Here, the MAX232 by MAXIM is used because it is widespread, cheap and reliable.

This example shows how to receive message sent by a PC. Timer T1 generates boud rate. Since the 11.0592 MHz quartz crystal is used here, it is easy to obtain standard baud rate which amouts to 9600 bauds. Each received data is immediately transferred to port P1 pins.

;************************************************************************

;* PROGRAM NAME : UartR.ASM

;* DESCRIPTION: Each data received from PC via UART appears on the port

;* P1.

;*

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(UARTR.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 023H ; Starting address of UART interrupt routine

JMP IR_SER

ORG 100H

XRESET: MOV IE,#00 ; All interrupts are disabled

MOV SP,#STACK_START ; Initialization of Stack pointer

MOV TMOD,#20H ; Timer1 in mode2

MOV TH1,#0FDH ; 9600 baud rate at the frequency of

; 11.0592MHz

MOV SCON,#50H ; Receiving enabled, 8-bit UART

MOV IE,#10010000B ; UART interrupt enabled

CLR TI ; Clear transmit flag

CLR RI ; Clear receive flag

SETB TR1 ; Start Timer1

LOOP: SJMP LOOP ; Remain here

IR_SER: JNB RI,OUTPUT ; If any data is received,

; move it to the port

MOV A,SBUF ; P1

MOV P1,A

CLR RI ; Clear receive flag

OUTPUT RETI

END ; End of program

Data transmission via UART

This program describes how to use UART to transmit data. A sequence of numbers (0-255) is transmitted to a PC at 9600 baud rate. The MAX 232 is used as a voltage regulator.

;************************************************************************

;* PROGRAM NAME : UartS.ASM

;* DESCRIPTION: Sends values 0-255 to PC.

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(UARTS.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;STACK

DSEG AT 03FH

STACK_START: DS 040H

;RESET VECTORS

CSEG AT 0

JMP XRESET ; Reset vector

ORG 100H

XRESET: MOV IE,#00 ; All interrupts are disabled

MOV SP,#STACK_START ; Initialization of Stack pointer

MOV TMOD,#20H ; Timer1 in mode 2

MOV TH1,#0FDH ; 9600 baud rate at the frequency of

; 11.0592MHz

MOV SCON,#40H ; 8-bit UART

CLR TI ; Clear transmit bit

CLR RI ; Clear receive flag

MOV R3,#00H ; Reset caunter

SETB TR1 ; Start Timer 1

START: MOV SBUF,R3 ; Move number from counter to a PC

LOOP1: JNB TI,LOOP1 ; Wait here until byte transmission is

; complete

CLR TI ; Clear transmit bit

INC R3 ; Increment the counter value by 1

CJNE R3,#00H,START ; If 255 bytes are not sent return to the

; label START

LOOP: SJMP LOOP ; Remain here

END ; End of program

Writing message on LCD display

This example uses the most frequently used type of LCD which displays text in two lines with 16 characters each. In order to save I/O ports, only 4 pins are used for communication here. In this way each byte is transmitted in two steps: first higher then lower nible.

LCD needs to be initialized at the beginning of the program. Besides, parts of the program which repeat in the program create special subroutines. All this may seem extremely complicated, but the whole program basically performs several simple operations and displaysMikroelektronika Razvojni sistemi.

*************************************************************************

;* PROGRAM NAME : Lcd.ASM

;* DESCRIPRTION : Program for testing LCD display. 4-bit communication

;* is used. Program does not check BUSY flag but uses program delay

;* between 2 commands. PORT1 is used for connection

;* to the microcontroller.

;************************************************************************

;BASIC DIRECTIVES

$MOD53

$TITLE(LCD.ASM)

$PAGEWIDTH(132)

$DEBUG

$OBJECT

$NOPAGING

;Stack

DSEG AT 0E0h

Stack_Start: DS 020h

Start_address EQU 0000h

;Reset vectors

CSEG AT 0

ORG Start_address

JMP Inic

ORG Start_address+100h

MOV IE,#00 ; All interrupts are disabled

MOV SP,#Stack_Start

Inic: CALL LCD_inic ; Initialize LCD

;*************************************************

;* MAIN PROGRAM

;*************************************************

START: MOV A,#80h ; Next character will appear on the first

CALL LCD_status ; location in the first line of LCD display.

MOV A,#'M' ; Display character M.

CALL LCD_putc ; Call subroutine for character transmission.

MOV A,#'i' ; Display character i.

CALL LCD_putc

MOV A,#'k' ; Display character k.

CALL LCD_putc

MOV A,#'r' ; Display character r.

CALL LCD_putc

MOV A,#'o' ; Display character o.

CALL LCD_putc

MOV A,#'e' ; Display character e.

CALL LCD_putc

MOV A,#'l' ; Display character l.

CALL LCD_putc

MOV A,#'e' ; Display character e.

CALL LCD_putc

MOV A,#'k' ; Display character k.

CALL LCD_putc

MOV A,#'t' ; Display character t.

CALL LCD_putc

MOV A,#'r' ; Display character r.

CALL LCD_putc

MOV A,#'o' ; Display character o.

CALL LCD_putc

MOV A,#'n' ; Display character n.

CALL LCD_putc

MOV A,#'i' ; Display character i.

CALL LCD_putc

MOV A,#'k' ; Display character k.

CALL LCD_putc

MOV A,#'a' ; Display character a.

CALL LCD_putc

MOV A,#0c0h ; Next character will appear on the first

CALL LCD_status ; location in the second line of LCD display.

MOV A,#'R' ; Display character R.

CALL LCD_putc ; Call subroutine for character transmission.

MOV A,#'a' ; Display character a.

CALL LCD_putc

MOV A,#'z' ; Display character z.

CALL LCD_putc

MOV A,#'v' ; Display character v.

CALL LCD_putc

MOV A,#'o' ; Display character o.

CALL LCD_putc

MOV A,#'j' ; Display character j.

CALL LCD_putc

MOV A,#'n' ; Display character n.

CALL LCD_putc

MOV A,#'i' ; Display character i.

CALL LCD_putc

MOV A,#' ' ; Display character .

CALL LCD_putc

MOV A,#'s' ; Display character s.

CALL LCD_putc

MOV A,#'i' ; Display character i.

CALL LCD_putc

MOV A,#'s' ; Display character s.

CALL LCD_putc

MOV A,#'t' ; Display character t.

CALL LCD_putc

MOV A,#'e' ; Display character e.

CALL LCD_putc

MOV A,#'m' ; Display character m.

CALL LCD_putc

MOV A,#'i' ; Display character i.

CALL LCD_putc

MOV R0,#20d ; Wait time (20x10ms)

CALL Delay_10ms ;

MOV DPTR,#LCD_DB ; Clear display

MOV A,#6d ;

CALL LCD_inic_status ;

MOV R0,#10d ; Wait time(10x10ms)

CALL Delay_10ms

JMP START

;*********************************************

;* Subroutine for wait time (T= r0 x 10ms)

;*********************************************

Delay_10ms: MOV R5,00h ; 1+(1+(1+2*r7+2)*r6+2)*r5 approximately

MOV R6,#100d ; (if r7>10)

MOV R7,#100d ; 2*r5*r6*r7

DJNZ R7,$ ; $ indicates current instruction.

DJNZ R6,$-4

DJNZ R5,$-6

RET

;**************************************************************************************

;* SUBROUTINE: LCD_inic

;* DESCRIPTION: Subroutine for LCD initialization.

;*

;* (is used with 4-bit interface, under condition that pins DB4-7 on LCD

;* are connected to pins PX.4-7 on microcontrollers ports, i.e. four higher

;* bits on the port are used).

;*

;* NOTE: It is necessary to define port pins for controlling LCD operation:

;* LCD_enable, LCD_read_write, LCD_reg_select,similar to port for connection to LCD.

;* It is also necessary to define addresses for the first character in each

;* line.

;**************************************************************************************

LCD_enable BIT P1.3 ; Bit for activating pin E on LCD.

LCD_read_write BIT P1.1 ; Bit for activating pin RW on LCD.

LCD_reg_select BIT P1.2 ; Bit for activating pin RS on LCD.

LCD_port SET P1 ; Port for connection to LCD.

Busy BIT P1.7 ; Port pin on which Busy flag appears.

LCD_Start_I_red EQU 00h ; Address of the first message character

; in the first line of LCD display.

LCD_Start_II_red EQU 40h ; Address of the first message character

; in the second line of LCD display.

LCD_DB: DB 00111100b ; 0 -8b, 2/1 lines, 5x10/5x7 format

DB 00101100b ; 1 -4b, 2/1 lines, 5x10/5x7 format

DB 00011000b ; 2 -Display/cursor shift, right/left

DB 00001100b ; 3 -Display ON, cursor OFF, cursor blink off

DB 00000110b ; 4 -Increment mode, display shift off

DB 00000010b ; 5 -Display/cursor home

DB 00000001b ; 6 -Clear display

DB 00001000b ; 7 -Display OFF, cursor OFF, cursor blink off

LCD_inic: ;*****************************************

MOV DPTR,#LCD_DB

MOV A,#00d ; Triple initialization in 8-bit

CALL LCD_inic_status_8 ; mode is performed at the beginning

MOV A,#00d ; (in case of slow increment of

CALL LCD_inic_status_8 ; power supply when the power supply is on

MOV A,#00d

lcall LCD_inic_status_8

MOV A,#1d ; Change from 8-bit into

CALL LCD_inic_status_8 ; 4-bit mode

MOV A,#1d

CALL LCD_inic_status

MOV A,#3d ; As from this point the program executes in

;4-bit mode

CALL LCD_inic_status

MOV A,#6d

CALL LCD_inic_status

MOV A,#4d

CALL LCD_inic_status

RET

LCD_inic_status_8:

;******************************************

PUSH B

MOVC A,@A+DPTR

CLR LCD_reg_select ; RS=0 - Write command

CLR LCD_read_write ; R/W=0 - Write data on LCD

MOV B,LCD_port ; Lower 4 bits from LCD port are memorized

ORL B,#11110000b

ORL A,#00001111b

ANL A,B

MOV LCD_port,A ; Data is moved from A to LCD port

SETB LCD_enable ; high-to-low transition signal

; is generated on the LCD's EN pin

CLR LCD_enable

MOV B,#255d ; Time delay in case of improper reset

DJNZ B,$ ; during initialization

DJNZ B,$

DJNZ B,$

POP B

RET

LCD_inic_status:

;****************************************************************************

MOVC A,@A+DPTR

CALL LCD_status

RET

;****************************************************************************

;* SUBROUTINE: LCD_status

;* DESCRIPTION: Subroutine for defining LCD status.

;****************************************************************************

LCD_status: PUSH B

MOV B,#255d

DJNZ B,$

DJNZ B,$

DJNZ B,$

CLR LCD_reg_select ; RS=O: Command is sent to LCD

CALL LCD_port_out

SWAP A ; Nibles are swapped in accumulator

DJNZ B,$

DJNZ B,$

DJNZ B,$

CLR LCD_reg_select ; RS=0: Command is sent to LCD

CALL LCD_port_out

POP B

RET

;****************************************************************************

;* SUBROUTINE: LCD_putc

;* DESCRIPTION: Sending character to be displayed on LCD.

;****************************************************************************

LCD_putc: PUSH B

MOV B,#255d

DJNZ B,$

SETB LCD_reg_select ; RS=1: Character is sent to LCD

CALL LCD_port_out

SWAP A ; Nibles are swapped in accumulator

DJNZ B,$

SETB LCD_reg_select ; RS=1: Character is sent to LCD

CALL LCD_port_out

POP B

RET

;****************************************************************************

;* SUBROUTINE: LCD_port_out

;* DESCRIPTION: Sending commands or characters on LCD display

;****************************************************************************

LCD_port_out: PUSH ACC

PUSH B

MOV B,LCD_port ; Lower 4 bits of LCD port are memorized

ORL B,#11110000b

ORL A,#00001111b

ANL A,B

MOV LCD_port,A ; Data is copied from A to LCD port

SETB LCD_enable ; high-to-low transition signal

; is generated on the LCD's EN pin

CLR LCD_enable

POP B

POP ACC

RET

END ; End of program

Binary to decimal number conversion

When using LED and LCD displays, it is often necessary to convert numbers from binary to decimal. For example, if some register contains a number in binary format that should be displayed on a three digit LED display it is first necessary to convert it to decimal format. In other words, it is necessary to define what should be displayed on the most right display (units), middle display (tens) and most left display (hundreds).

The subroutine below performs conversion of one byte. Binary number is stored in the accumulator, while digits of that number in decimal format are stored in registers R3, R2 and accumulator (units, tens and hundreds, respectively).

;************************************************************************

;* SUBROUTINE NAME : BinDec.ASM

;* DESCRIPTION : Content of accumulator is converted into three decimal digits

;************************************************************************

BINDEC: MOV B,#10d ; Store decimal number 10 in B

DIV AB ; A:B. Remainder remains in B

MOV R3,B ; Move units to register R3

MOV B,#10d ; Store decimal number 10 in B

DIV AB ; A:B. Remainder remains in B

MOV R2,B ; Move tens to register R2

MOV B,#10d ; Store decimal number 10 in B

DIV AB ; A:B. Remainder remains in B

MOV A,B ; Move hundreds to accumulator

RET ; Return to the main program

previous chapter|table of contents|next chapter

Featured Development Tools

Easy8051 v6 Development System

TheEasy8051 v6is compatible with 14-, 16-, 20-, 28-, 40-pin PLCC44 and PLCC32 MCUs. It comes with an AT89S8253. The board has a USB 2.0 programmer and many peripherals such as COG, port expander, MENU and 4x4 keypads etc. [more info]

mikroProg for 8051

mikroProg for 8051 is supported with mikroC, mikroBasic and mikroPascal compilers for 8051. You may also use mikroProg for 8051 as a standalone programming tool. [more info]

Featured Compilers

mikroBasic PRO for 8051

The8051core combined with modern modules is popular in the past. WithmikroBasicyou can quickly developArchitecture and programming of 8051 MCU's

TOC Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Chapter 6 Chapter 7Chapter 7 : Development systems

7.1 At the end - from the beginning... 7.2 Easy8051A Development system7.1 At the end - from the beginning...

What is always the most difficult thing to do? You have bought the microcontroller, you have learned everything about its circuits and registers, you have a great idea how to apply all your knowledge in practice. But the most difficult thing to do is to start...

How to start working?

A microcontroller is a good-natured genie in the bottle and no extra knowledge is required to use it.

In order to create a device controlled by the microcontroller, it is necessary to provide the simplest PC, program for compiling and simple device to transfer the code from PC to the chip itself.

Even though the whole process is quite logical, there are often some queries, not because it is complicated, but for numerous variations. Lets take a look.

Writing program in assembly language

In order to write a program for the microcontroller, a specialized program in the Windows environment may be used. It may, but it does not have to... When using such a software, there are numerous tools which facilitate the operation (simulator tool comes first), which is an obvious advantage. But there is also another ways to write a program. Basically, text is the only thing that matters. Any program for text processing can be used for this purpose. The point is to write all instructions in such an order they should be executed by the microcontroller, observe the rules of assembly language and write instructions exactly as they are defined. In other words, you just have to follow the program idea. Thats all!

;RESET VECTOR

CSEG AT 0

JMP XRESET ; Reset vector

CSEG

ORG 100H

XRESET: ORL WMCON,#PERIOD ; Define Watch-dog period

ORL WMCON,#WDTEN ; Watch-dog timer is enabled

To enable the compiler to operate successfully, it is necessary that a document containing this program has the extension, .asm in its name, for example: Program asm.

When a specialized program (mplab) is used, this extension will be automatically added. If any other program for text processing (Notepad) is used then the document should be saved and renamed. For example: Program.txt -> Program.asm. This procedure is not necessarily performed. The document may be saved in original format while its text may be copied to the programmer for further use.

Compiling a program

The microcontroller does not undrestand assembly language as such. That is why it is necessary to compile the program into machine language. It is more than simple when a specialized program (mplab) is used because a compiler is a part of the software. Just one click on the appropriate icon solves the problem and a new document with .hex extension appears. It is actually the same program, only compiled into machine language which the microcontroller perfectly understands. Such documentation is commonly named hex code and seemingly represents a meaningless sequence of numbers in hexadecimal number system.

:03000000020100FA1001000075813F

7590FFB29012010D80F97A1479D40

90110003278589EAF3698E8EB25B

A585FEA2569AD96E6D8FED9FAD

AF6DD00000001FF255AFED589EA

F3698E8EB25BA585FEA2569AD96

DAC59700D00000278E6D8FED9FA

DAF6DD00000001FF255AFED8FED

9FADAF6DD000F7590FFB29013278

E6D8FED9FADAF6DD00000001FF2

55AFED589EAF3698E8EB25BA585

FEA2569AD96DAC59D9FADAF6D

D00000001FF255AFED8FED9FADA

F6DD000F7590FFB29013278E6D82

78E6D8FED9FA589EAF3698E8EB2

5BA585FEA2569AD96DAF6DD000