Sunteți pe pagina 1din 150

8051 Asembler i C programiranje

Skinuto sa www.mytutorialcafe.com by Jovica Jovanovic jojzi@yahoo.com

www.jovica.co.sr
1. Microcontroller MCS-51 Architecture
1.1. Memory Organization

All 80C51 devices have separate address spaces for program and data memory,
as shown in Figures 1.1.1 and 1.1.2. The logical separation of program and data
memory allows the data memory to be accessed by 8-bit addresses, which can
be quickly stored and manipulated by an 8-bit CPU. Nevertheless, 16-bit data
memory addresses can also be generated through the DPTR register. Program
memory (ROM, EPROM) can only be read, not written to. There can be up to 64k
bytes of program memory. In the 89s51, the lowest 4k bytes of program are on-
chip. In the ROMless versions, all program memory is external. The read strobe
for external program memory is the PSEN (program store enable).

Figure 1.1.1 89s51 Block Diagram

Data Memory (RAM) occupies a separate address space from Program Memory.
In the 80C51, the lowest 128 bytes of data memory are on-chip. Up to 64k bytes
of external RAM can be addressed in the external Data Memory space. In the
ROMless version, the lowest 128 bytes are on-chip. The CPU generates read
and write signals, RD and WR, as needed during external Data
Memory accesses. External Program Memory and external Data Memory may be
combined if desired by applying the RD and PSEN signals to the inputs of an
AND gate and using the output of the gate as the read strobe to the external
Program/Data memory.

Program Memory
Figure 1.1.4 shows a map of the lower part of the Program Memory. After reset,
the CPU begins execution from location 0000H. As shown in Figure 1.1.4, each
interrupt is assigned a fixed location in Program Memory. The interrupt causes
the CPU to jump to that location, where it commences execution of the service
routine. External Interrupt 0, for example, is assigned to location 0003H. If
External Interrupt 0 is going to be used, its service routine must begin at location
0003H. If the interrupt is not going to be used, its service location is available as
general purpose Program Memory.

Figure 1.1.2. Memory Program Structure

Figure 1.1.3. Interrupt Location


Data Memory
The right half of Figure 1.4 shows the internal and external Data Memory spaces
available to the 80C51 user.The CPU generates RD and WR signals as needed
during external RAM accesses. Internal Data Memory is mapped in Figure1.5.
The memory space is shown divided into three blocks, which are generally
referred to as the Lower 128, the Upper 128, and SFR space.

Figure 1.1.4. Memory Data Structure

Internal Data Memory addresses are always one byte wide, which implies an
address space of only 256 bytes. However, the addressing modes for internal
RAM can in fact accommodate 384 bytes, using a simple trick. Direct addresses
higher than 7FH access one memory space, and indirect addresses higher than
7FH access a different memory space. Thus Figure 1.1.5. shows the Upper 128
and SFR space occupying the same block of addresses, 80H through FFH,
although they are physically separate entities.
Figure 1.5. Internal Data Memory

The Lower 128 bytes of RAM are present in all 80C51 devices as mapped in
Figure 1.1.6. The lowest 32 bytes are grouped into 4 banks of 8 registers.
Program instructions call out these registers as R0 through R7. Two bits in the
Program Status Word (PSW) select which register bank is in use. This allows
more efficient use of code space, since register instructions are shorter than
instructions that use direct addressing.

Figure 1.1.6. Lower 128 bytes of internal RAM

All of the bytes in the Lower 128 can be accessed by either direct or indirect
addressing. The Upper 128 (Figure 1.1.7) can only be accessed by indirect
addressing.

Figure 1.1.7.Upper 128 Bytes of Internal RAM

1.2. Special Function Register

A Map of the on-chip memory area called the Special Function Register (SFR)
space is shown in Figure 1.2.1. Note that in the SFRs not all of the addresses are
occupied. Unoccupied addresses are not implemented on the chip. Read
accesses to these addresses will in general return random data, and write
accesses will have no effect. User software should not write 1s to these
unimplemented locations, since they may be used in other 80C51 Family
derivative products to invoke new features. The functions of the SFRs are
described in the text that follows.
Figure 1.2.1. MCS-51 SFR Memory Map

Accumulator
ACC is the Accumulator register. The mnemonics for Accumulator-Specific
instructions, however, refer to the Accumulator simply as A.

B Register
The B register is used during multiply and divide operations. For other
instructions it can be treated as another scratch pad register.

Program Status Word


The PSW register contains program status information as detailed in Tabel 1.2.1

Stack Pointer
The Stack Pointer register is 8 bits wide. It is incremented before data is stored
during PUSH and CALL executions. While the stack may reside anywhere in on-
chip RAM, the Stack Pointer is initialized to 07H after a reset. This causes the
stack to begin at locations 08H.

Data Pointer
The Data Pointer (DPTR) consists of a high byte (DPH) and a low byte (DPL). Its
intended function is to hold a 16-bit address. It may be manipulated as a 16-bit
register or as two independent 8-bit registers.
Ports 0 to 3
P0, P1, P2, and P3 are the SFR latches of Ports 0, 1, 2, and 3, respectively.
Writing a one to a bit of a port SFR (P0, P1, P2, or P3) causes the corresponding
port output pin to switch high. Writing a zero causes the port output pin to switch
low. When used as an input, the external state of a port pin will be held in the
port SFR (i.e., if the external state of a pin is low, the corresponding port SFR bit
will contain a 0; if it is high, the bit will contain a 1).

Serial Data Buffer


The Serial Buffer is actually two separate registers, a transmit buffer and a
receive buffer. When data is moved to SBUF, it goes to the transmit buffer and is
held for serial transmission. (Moving a byte to SBUF is what initiates the
transmission.) When data is moved from SBUF, it comes from the receive buffer.

Timer Registers
Register pairs (TH0, TL0), and (TH1, TL1) are the 16-bit Counting registers for
Timer/Counters 0 and 1, respectively.

Control Register
Special Function Registers IP, IE, TMOD, TCON, SCON, and PCON contain
control and status bits for the interrupt system, the Timer/Counters, and the serial
port. They are described in later sections.

Table 1.2.1 Program Status Word

MSB LSB
CY AC F0 RS1 RS0 OV - P

BIT SYMBOL FUNCTION


PSW.7 CY Carry flag.
PSW.6 AC Auxilliary Carry flag. (For BCD operations.)
PSW.5 F0 Flag 0. (Available to the user for general purposes.)
Register bank select control bit 1.
PSW.4 RS1 Set/cleared by software to determine working register
bank. (See Note.)
Register bank select control bit 0.
PSW.3 RS0 Set/cleared by software todetermine working register
bank. (See Note.)
PSW.2 OV Overflow flag.
PSW.1 - User-definable flag.
Parity flag.
Set/cleared by hardware each instruction cycle to
PSW.0 P
indicate an odd/even number of one bits in the
Accumulator, i.e., even parity.

Program Status Word


The Program Status Word (PSW) contains several status bits that reflect the
current state of the CPU. The PSW, shown in Figure 10, resides in the SFR
space. It contains the Carry bit, the Auxiliary Carry (for BCD operations), the two
register bank select bits, the Overflow flag, a Parity bit, and two user-definable
status flags. The Carry bit, other than serving the function of a Carry bit in
arithmetic operations, also serves as the Accumulator for a number of Boolean
operations. The bits RS0 and RS1 are used to select one of the four register
banks shown in Figure 1.7. A number of instructions refer to these RAM locations
as R0 through R7. The selection of which of the four is being referred to is made
on the basis of the RS0 and RS1 at execution time.

The Parity bit reflects the number of 1s in the Accumulator: P = 1 if the


Accumulator contains an odd number of 1s, and P = 0 if the Accumulator
contains an even number of 1s. Thus the number of 1s in the Accumulator plus P
is always even. Two bits in the PSW are uncommitted and may be used as
general purpose status flags.

1.3. Addressing

The addressing modes in the 80C51 instruction set are as follows:


An "addressing mode" refers to how you are addressing a given memory
location. In summary, the addressing modes are as follows, with an example of
each:

Immediate Addressing MOV A,#20h


Direct Addressing MOV A,30h
Indirect Addressing MOV A,@R0
External Direct MOVX A,@DPTR
Code Indirect MOVC A,@A+DPTR

Immediate Addressing

Immediate addressing is so-named because the value to be stored in memory


immediately follows the operation code in memory. That is to say, the instruction
itself dictates what value will be stored in memory.
For example, the instruction:
;Lesson 1.3.1
;===========================================
;This instruction uses Immediate Addressing because the
;Accumulator will be loaded with the value that immediately
;follows in this case 20 (hexidecimal).
;===========================================
org 0h
start:MOV A,#20h; put constant 20 into Acc
end

;Lesson 1.3.2
org 0h
Start:MOV A, #0h;
MOV A,#11h;
MOV B,#27h;
end
;
;Lesson 1.3.3
Org 0h
Start:MOV 70h,#0h; put constant 0 into RAM 70h
MOV 71h,#1h;
MOV 72h,#2h;
end
;
;Lesson 1.3.4
Org 0h
Start:MOV DPTR,#1234h;put constant 1234 into DPTR
end
;
;Lesson 1.3.5
Org 0h
Start:MOV PSW,#0; Select register bank 0
MOV R0,#0; put 0 into register 0
MOV R1,#1; put 1 into register 1
MOV R2,#2; put 2 into register 2
MOV R3,#3; put 3 into register 3
MOV R4,#4; put 4 into register 4
MOV R5,#5; put 5 into register 5
MOV R6,#6; put 6 into register 6
MOV R7,#7; put 7 into register 7
end
;
;Lesson 1.3.6
org 0h
Start:MOV PSW,#8; Select register bank 1
MOV R0,#0; put 0 into register 0
MOV R1,#1; put 1 into register 1
MOV R2,#2; put 2 into register 2
MOV R3,#3; put 3 into register 3
MOV R4,#4; put 4 into register 4
MOV R5,#5; put 5 into register 5
MOV R6,#6; put 6 into register 6
MOV R7,#7; put 7 into register 7
end
Immediate addressing is very fast since the value to be loaded is included in the
instruction. However, since the value to be loaded is fixed at compile-time it is not
very flexible.

Direct Addressing

Direct addressing is so-named because the value to be stored in memory is


obtained by directly retrieving it from another memory location. For example:

;Lesson 1.3.7
;============================================
;This This instruction will read the data out of Internal
;RAM address 30 (hexidecimal) and store it in the
;Accumulator.
;============================================
;
org 0h
Start:MOV A,30h;
end
;
;Lesson 1.3.8
Org 0h
Start:Mov 70h,#1;put constant 1 into RAM 70h
Mov A, 70h;copy RAM 70 content into Acc
Mov A,#0 ;put constant 0 into Acc
Mov 90h,A ;copy Acc content into RAM 90h
end
;
;Lesson 1.3.9
Inbyte equ 70h
Port1 equ 90h
Org 0h
Start: Mov Inbyte,#3;put constant 3 into RAM 70h
Mov A,Inbyte ;copy RAM 70h content into Acc
Mov A,#0 ;Clear accumulator
Mov Port1,A ;copy Acc content into RAM 90h
end
;
Percobaan 2.5.3:
Org 0h
Mov DPTR,#Character
Start:Mov A, #0
Inc DPTR
Movc A, @A+DPTR
Mov R0,A
Sjmp Start
Character:
DB 0,1,2,3,4,5,6,7,8,9

Direct addressing is generally fast since, although the value to be loaded isnt
included in the instruction, it is quickly accessable since it is stored in the 8051s
Internal RAM. It is also much more flexible than Immediate Addressing since the
value to be loaded is whatever is found at the given address--which may be
variable. Also, it is important to note that when using direct addressing any
instruction which refers to an address between 00h and 7Fh is referring to
Internal Memory. Any instruction which refers to an address between 80h and
FFh is referring to the SFR control registers that control the 8051 microcontroller
itself. The obvious question that may arise is, "If direct addressing an address
from 80h through FFh refers to SFRs, how can I access the upper 128 bytes of
Internal RAM that are available on the 8052?" The answer is: You cant access
them using direct addressing. As stated, if you directly refer to an address of 80h
through FFh you will be referring to an SFR. However, you may access the
8052s upper 128 bytes of RAM by using the next addressing mode, "indirect
addressing."

Indirect Addressing

Indirect addressing is a very powerful addressing mode which in many cases


provides an exceptional level of flexibility. Indirect addressing is also the only way
to access the extra 128 bytes of Internal RAM found on an 8052.

Indirect addressing appears as follows:

MOV A,@R0

This instruction causes the 8051 to analyze the value of the R0 register. The
8051 will then load the accumulator with the value from Internal RAM which is
found at the address indicated by R0.
For example, lets say R0 holds the value 40h and Internal RAM address 40h
holds the value 67h. When the above instruction is executed the 8051 will check
the value of R0. Since R0 holds 40h the 8051 will get the value out of Internal
RAM address 40h (which holds 67h) and store it in the Accumulator. Thus, the
Accumulator ends up holding 67h. Indirect addressing always refers to Internal
RAM; it never refers to an SFR. Thus, in a prior example we mentioned that SFR
99h can be used to write a value to the serial port. Thus one may think that the
following would be a valid solution to write the value 1 to the serial port:

MOV R0,#99h ;
MOV @R0,#01h;

This is not valid. Since indirect addressing always refers to Internal RAM these
two instructions would write the value 01h to Internal RAM address 99h on an
8052. On an 8051 these two instructions would produce an undefined result
since the 8051 only has 128 bytes of Internal RAM.

;Percobaan 2.5.1:
Org 0h
Start:Mov PSW, #0 ; choose register bank 0
Mov R0, #78h; put constant 78h into R0
Mov @R0, #1 ; put contanta 1 into 78h
end
;
;Percobaan 2.5.2:
Org 0h
Start:Mov PSW,#0; pilih register bank 1
Mov R0,90h; copy RAM 90h content into R0
Mov @R0,#1; put constant 1 into 90h
End
;

External Direct

External Memory is accessed using a suite of instructions which use what I call
"External Direct" addressing. I call it this because it appears to be direct
addressing, but it is used to access external memory rather than internal
memory.There are only two commands that use External Direct addressing
mode:

MOVX A,@DPTR
MOVX @DPTR,A

As you can see, both commands utilize DPTR. In these instructions, DPTR must
first be loaded with the address of external memory that you wish to read or
write. Once DPTR holds the correct external memory address, the first command
will move the contents of that external memory address into the Accumulator.
The second command will do the opposite: it will allow you to write the value of
the Accumulator to the external memory address pointed to by DPTR.

External Indirect

External memory can also be accessed using a form of indirect addressing which
I call External Indirect addressing. This form of addressing is usually only used in
relatively small projects that have a very small amount of external RAM. An
example of this addressing mode is:

MOVX @R0,A

Once again, the value of R0 is first read and the value of the Accumulator is
written to that address in External RAM. Since the value of @R0 can only be 00h
through FFh the project would effectively be limited to 256 bytes of External
RAM. There are relatively simple hardware/software tricks that can be
implemented to access more than 256 bytes of memory using External Indirect
addressing; however, it is usually easier to use External Direct addressing if your
project has more than 256 bytes of External RAM.
1.4. Instruction Set
Arithmetic Instructions
The menu of arithmetic instructions is listed in Table 1.4.1 The table indicates the
addressing modes that can be used with each instruction to access the <byte>
operand.
For example, the ADD A,<byte> instruction can be written as:

ADD a, 7FH (direct addressing)


ADD A, @R0 (indirect addressing)
ADD a, R7 (register addressing)
ADD A, #127 (immediate constant)

The MUL AB instruction multiplies the Accumulator by the data in the B register
and puts the 16-bit product into the concatenated B and Accumulator registers.

The DIV AB instruction divides the Accumulator by the data in the B register and
leaves the 8-bit quotient in the Accumulator, and the 8-bit remainder in the B
register.

Table 1.4.1. MCS-51 Arithmetic Instruction

Addressing Mode Exect.


Mnemonic Operation
Dir Ind Reg Imm Timer uS
Add A,<byte> A=A+<byte> V V V V 1
Addc
A=A+<byte>+C V V V V 1
A,<byte>
Subb
A=A-<byte>-C V V V V 1
A,<byte>
Inc A A=A+1 Accumulator Only 1
Inc <byte> <byt>=<byt>+1 V V V 1
Inc DPTR DPTR=DPTR+1 Data Pointer Only 2
Dec A A=A-1 Accumulator Only 1
Dec <byte> <byt>=<byt>-1 V V V 1
Mul AB B:A=BxA Accumulator and B Only 4
A=Int[A/B]
Div AB Accumulator and B only 4
B=Mod[A/B]
DA A Dec Adjust Accumulator Only 1

Logical Instructions
Table 1.4.2 shows the list of 80C51 logical instructions. The instructions that
perform Boolean operations (AND, OR, Exclusive OR, NOT) on bytes perform
the operation on a bit-by-bit basis. That is, if the Accumulator contains
00110101B and byte contains 01010011B, then:

Table 1.4.2. MCS-51 Logical Instructions

Addressing Mode Exect.


Mnemonic Operation
Dir Ind Reg Imm Timer uS
Anl A,<byte> A=A and <byte> V V V V 1
Anl <byte>,A <byte>=<byte>anl A V V V V 1
<byte>=<byte>and
Anl <byte>,#data V V V V 1
#data
Orl A,<byte> A=A or <byte> Accumulator Only 1
Orl <byte>,A <byt>=<byt>orl A V V V 1
<byte>=<byte> or
Orl <byte>,#data Data Pointer Only 2
#data
Xrl A,<byte> A=A xor<byte> Accumulator Only 1
Xrl<byte>,A <byt>=<byt>xor A V V V 1
<byte>=<byte>xor
Xrl <byte>,#data Accumulator and B Only 4
#data
CLR A A=00h Accumulator only 1
CPL A A= not A Accumulator only 1
RL A Rotate A left 1 bit Accumulator only 1
Rotate A left
RLC A Accumulator only 1
trough Carry
Rotate A right 1
RR A Accumulator only 1
bit
Rotate A right
RRC Accumulator only 1
trough carry
Swap nibbles in
SWAP A Accumulator only 1
A

Data Transfer
Internal RAM
Table 3 shows the menu of instructions that are available for moving data around
within the internal memory spaces, and the addressing modes that can be used
with each one. With a 12MHz clock, all of these instructions execute in either 1 or
2ms. The MOV <dest>, <src> instruction allows data to be transferred between
any two internal RAM or SFR locations without going through the Accumulator.
Remember, the Upper 128 bytes of data RAM can be accessed only by indirect
addressing, and SFR space only by direct addressing.The Data Transfer
instructions include a 16-bit MOV that can be used to initialize the Data Pointer
(DPTR) for look-up tables in Program Memory, or for 16-bit external Data
Memory accesses.

Table 1.4.3. MCS-51 Data Transfer Instruction

Addressing Mode Exect.


Mnemonic Operation
Dir Ind Reg Imm Timer uS
Mov A,<src> A=<src> V V V V 1
Mov <dest>,A <dest>=A V V V V 1
Mov <dest>,
<dest>=<src> V V V V 1
<src>
Mov DPTR=16 bit
Accumulator Only 1
DPTR,#data16 immediate const
Push <src> Inc SP V V V 1
Pop <src> Dec SP Data Pointer Only 2
Acc and <byte>
Xch A,<byte> Accumulator Only 1
exchange data
Acc and @Ri
Xchd A,@Ri exchange low V V V 1
nibbles

;Lesson 1.4.1.

Org 0h
Start:Mov A,#1 ; put 1 into the accumulator
ADD A,#2 ; add the constant 2 to Accumulator (1+2)
Mov 78h,#3 ; put 3 into internal RAM 78h
ADD A, 78h ; add Acc and RAM 78h content
Mov R0, #79h; put 79 into R0
Mov @R0, #4 ; put 4 into RAM 79h
ADD A,@R0 ; add Acc and RAM 79h content
Mov R5, #5 ; put 5 into R5
ADD A,R5 ; add Acc and R5
end

;Lesson 1.4.2.

Org 0h
Start:Mov 78h,#34h ; [ 78h ] = 34h
Mov 79h,#12h ; [ 79h ] =12h
Mov 7Ah,#0EFh; [ 7Ah ] = EFh
Mov 7Bh,#12h ; [ 7Bh ] = 12h
Mov A,78h ; A = [ 78h ]
Add A,7Ah ; A = A + [ 78h ]
Mov 78h,A ; [ 78h ] = A
Mov A,79h ; A = [ 79h ]
ADDC A,7Bh ; A = A + [ 7Bh ] + C
Mov 79h,A ; [ 79h ] = A
end

2.1. L E D
2.1.1 Making a LED Blink

The first step is to build a simple circuit. At this point you should be familiar with
the parts used. (1 resistors, and 1 LED). This design is intended for use with an
Atmel 89s51 but also posible for others family 8051. Most microcontrollers can
handle the current required to turn an LED on and off but. In this lesson we're
going to make a LED Blink continously.

Step 1st
Build the circuit as shown in figure 2.1.1 As you seen on figure 2.1.1 P0.0 is
connected to LED's katode. Remember, that all we want to do with this lesson is
make a LED blink.

Figure 2.1.1 Diagram Skematik LED Blink

Step 2nd
In this step, you must tipe the assembly program to make the LED blink, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp211.zip )

org 0h
start: Clr P0.0 ; send '0' to P0.0
call delay; call delay time
Setb P0.0 ; send '1' to P0.0
call delay; call delay time
sjmp start; loooooop forever to start
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with LED1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( LED1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the LED ( of course if your cable connection and your
program are corrected ).

2.1.2. More LED Blink

Congratulation, you have succeded with make a LED blink. Now lets improve
your skill by making more LED blink ( 8 LED ). In this lesson, we will make four
LED blink change reversed.

Step 1st
Build the circuit as shown in figure 2.1.2. As you seen on figure 2.1.2. P0.0
trough P0.7 is connected to LED's katode each. Remember, that all we want to
do with this lesson is make four LED blink change reversed.
Figure 2.1.2. Diagram Skematik LED Blink

Step 2nd
In this step, you must tipe the assembly program to make four LED blink, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp212.zip )

org 0h
start: mov P0,#11110000b; Turn on LED on P0.0 - P0.3
call delay ; call delay time
mov P0,#00001111b; Turn on LED on P3.4 - P0.7
call delay; call delay time
sjmp start; loooooop forever to start
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with LED2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( LED2.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the LED ( of course if your cable connection and your
program are corrected ).

2.1.3. Running LED

Congratulation, you have succeded with make more LED to blink. Now lets
improve your skill by making running LED ( 8 LED ). In this lesson, you'll turn on
one LED in sequence for 8 LED.

Step 1st
Build the circuit as shown in figure 2.1.3. As you seen on figure 2.1.3. P0.0
trough P0.7 is connected to LED's katode each. Remember, that all we want to
do with this lesson is make these LED to run.

Figure 2.1.3. Diagram Skematik Running LED

Step 2nd
In this step, you must tipe the assembly program to make four LED blink, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp213.zip )

org 0h
start: mov P0,#11111110b; Turn on LED on P0.0
call delay ; call delay time
mov P0,#11111101b; Turn on LED on P0.1
call delay ; call delay time
mov P0,#11111011b; Turn on LED on P0.2
call delay ; call delay time
mov P0,#11110111b; Turn on LED on P0.3
call delay ; call delay time
mov P0,#11101111b; Turn on LED on P0.4
call delay ; call delay time
mov P0,#11011111b; Turn on LED on P0.5
call delay ; call delay time
mov P0,#10111111b; Turn on LED on P0.6
call delay ; call delay time
mov P0,#01111111b; Turn on LED on P3.7
call delay ; call delay time
sjmp start ; loooooop forever to start
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with LED3.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( LED3.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the LED ( of course if your cable connection and your
program are corrected ).

2.2.2. Running LED Right or Left when you' re push the button

In this lesson, we will command the LED to run right or left by swichting the
button, for example run the LED to the right when pushing swicht on P2.0 and
run the LED to the left when pushing swicht on P2.1.
Figure 2.2.2. Diagram Skematik Input Data

Step 1st
Build the circuit as shown in figure 2.2.2. As you seen on figure 2.2.2. P2.0
trough P2.7 is connected to swicht push button each and LED's Katode is
connected to P0.0 trough P0.7. Remember, that all we want to do with this
lesson is make a LED start running to the left or right, by pushing the button P2.0
or P2.1.

Step 2nd
In this step, you must tipe the assembly program to make your LED on when you
push the swicht, we assume that you have already known the editor, we used
MIDE-51 to edit the program. ( Download File : exp222.zip )
org 0h
CekP20: JB P2.0,CekP21 ; checking P2.0 while get push
call RLeft ; if so, call Rotate Left subrutine
sjmp CekP20 ; jump forever to CekP20
CekP21: JB P2.1,CekP20 ; checking P2.1 while get push
call RRight ; if so, call Rotate Right
sjmp CekP20 ; jump forever to CekP2.0
;===============================================
;this subroutine is used to move LED to the left.
;================================================
RLeft: mov A,#11111110b;send data to Acc
RLeft1: mov P0,A ;send data to P0
call delay ;call delay time
JB P2.0,RLeft2 ;checking P2.0 while get push
sjmp EndRLeft ;if so, finish Rotate Left
RLeft2: RL A
sjmp RLeft1
EndRLeft:
ret
;
;=================================================
;this subroutine is used to move LED to the right.
;=================================================
RRight: mov A,#01111111b
RRight1:mov P0,A
call delay
JB P2.0,RRight2
sjmp EndRRight
RRight2:RL A
sjmp RRight1
EndRRight:
ret
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with SW2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( SW2.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the LED ( of course if your cable connection and your
program are corrected ).
2.3. 7 Segment
The 7 segment display is found in many displays such as microwaves or fancy
toaster ovens and occasionally in non cooking devices. It is just 7 LEDs that have
been combined into one case to make a convenient device for displaying
numbers and some letters. The display is shown on the left. The pinout of the
display is on the right.

Figure 2.3. 7 Segmen

2.3.1. Writing a character to single 7 Segmen

This version is a common anode version. That means that the positive leg of
each LED is connected to a common point. Each LED has a negative leg that is
connected to one of the pins of the device. To make it work you need to connect
pin common to 5 volts trough driver transistor. Then to make each segment light
up, connect the ground pin for that led to ground. A resistor is required to limit the
current. Rather than using a resistor from each LED to ground, you can just use
one resistor from Vcc to pin 3 to limit the current.
Figure 2.3.1. Driving 7 Segmen common anoda

Step 1st
Build the circuit as shown in figure 2.3.1. As you seen on figure 2.3.1. P2.0 is
connected to driver transistor, and each pin of 7 segmen is connected to P0.0
trough P0.6. Remember, that all we want to do with this lesson is write a number
1 to 7 segmen.

Step 2nd
In this step, you must tipe the assembly program to make your 7 segmen shown
a number on 7 segmen, we assume that you have already known the editor, we
used MIDE-51 to edit the program.

org 0h
start: mov P2,#11111001b; send high logic to a and b segmen
clr P0.0 ; send current to 7 segment
sjmp start ; jump forever
end

Step 3rd
Safe your assembly program above, and name it with 7seg1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( 7seg1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the 7 segmen( of course if your cable connection and
your program are corrected ).
2.3.2. Writing multi number to single 7 Segmen consecutively

Step 1st
Build the circuit as shown in figure 2.3.2. As you seen on figure 2.3.2. P2.0 is
connected to driver transistor, and each pin of 7 segmen is connected to P0.0
trough P0.6. Remember, that all we want to do with this lesson is write multi
number ( 1-2-3-1-2-3 and so on ) to 7 segmen as consecutively.

Step 2nd
In this step, you must tipe the assembly program to make your 7 segmen shown
a number on 7 segmen, we assume that you have already known the editor, we
used MIDE-51 to edit the program. ( Download File : exp232.zip )

org 0h
start: mov P2,#11111001b; send high logic to a and b segmen
clr P0.0 ; send current to 7 segment
call delay ; call delay time
mov P2,#10111011b; send high logic to a,b,d,e,g seg.
clr P2.0 ; send current to 7 segment
call delay ; call delay time
mov P2,#01110000b; send high logic to a,b,c,d,g seg.
clr P2.0 ; send current to 7 segment
call delay ;call delay time
sjmp start ; jump forever
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with 7seg2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( 7seg2.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the 7 segmen( of course if your cable connection and
your program are corrected ).

2.3.3. Writing multi number to single 7 Segmen consecutively

As what you have been worked out in lesson 2.3.2, in this lesson you should
write some number ( 0,1,2,3,4,5,6,7,8,9 ) to 7 Segmen. Of course it's very simple
one, you are just copy and paste for couple time, and editing for the data.

2.3.4. Writing multi character to single 7 Segmen consecutively

As what you have been worked out in lesson 2.3.3, in this lesson you should
write some character ( A,b,C,d,E,F,G,H,I,J ) to 7 Segmen. Of course it's very
simple one, you are just copy and paste for couple time, and editing.

2.3.5. Writing multi character on 8 x 7 segmen

In this lesson, we are going to drive more 7 segmen, in this way you can write
eight character or number on multi 7 segmen. We used a multiplexing methode
to transfer data for driver transistor consequtively.

Figure 2.3.5. Driving on Multi 7 Segmen

Step 1st
Build the circuit as shown in figure 2.3.5. As you seen on figure 2.3.5. P2.0
trough P2.7 is connected to driver transistor, and all eight 7 segment is
connected to P0.0 trough P0.6 parallelly. Remember, that all we want to do with
this lesson is write multi number ( 1-2-3-4-5-6-7-8 ) to 1st, 2nd, 3rd, 4th, 5th, 6th,
7th and 8th 7 segmen each.

Step 2nd
In this step, you must tipe the assembly program to make your 7 segmen shown
some number on 7 segmen, we assume that you have already known the editor,
we used MIDE-51 to edit the program. ( Download File asm : exp235.zip
,Download Complete Circuit File : Sevensegmen.PDF )

org 0h
start: mov P0,#11111001b;write a number '1'
clr P2.7 ;turn on 1st 7 segment
call delay ;call delay time
setb P2.7 ;turn off 1st 7 segment
;
mov P0,#11011011b;write a number '2'
clr P2.6 ;turn on 2nd 7 segment
call delay ;call delay time
setb P2.6 ;turn off 2nd 7 segment
;
mov P0,#10110000b;write a number '3'
clr P2.5 ;turn on 3rd 7 segment
call delay ;call delay time
setb P2.5 ;turn off 3rd 7 segment
;
mov P0,#10011001b;write a number '4'
clr P2.4 ;turn on 4th 7 segment
call delay ;call delay time
setb P2.4 ;turn off 4th 7 segment
;
mov P0,#10010010b;write a number '5'
clr P2.3 ;turn on 5th 7 segment
call delay ;call delay time
setb P2.3 ;turn off 5th 7 segment
;
mov P0,#10000010b;write a number '6'
clr P2.2 ;turn on 2nd 7 segment
call delay ;call delay time
setb P2.2 ;turn off 2nd 7 segment
;
mov P0,#11111000b;write a number '7'
clr P2.1 ;turn on 7th 7 segment
call delay ;call delay time
setb P2.1 ;turn off 7th 7 segment
;
mov P0,#10000000b;write a number '8'
clr P2.0 ;turn on 8th 7 segment
call delay ;call delay time
setb P2.0 ;turn off 8th 7 segment
sjmp start ;jump forever
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with 7seg3.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.
Step 4th
Download your hex file ( 7seg3.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the 7 segmen( of course if your cable connection and
your program are corrected ).

2.3.6. Writing multi character on 8 x 7 segmen

In this lesson, we are going to drive more 7 segmen, in this way you can write
eight character or number on multi 7 segmen. We used a multiplexing methode
to transfer data for driver transistor consequtively.

Figure 2.3.5. Driving on Multi 7 Segmen

Step 1st
Build the circuit as shown in figure 2.3.5. As you seen on figure 2.3.5. P2.0
trough P2.7 is connected to driver transistor, and all eight 7 segment is
connected to P0.0 trough P0.6 parallelly. Remember, that all we want to do with
this lesson is write multi number ( 1-2-3-4-5-6-7-8 ) to 1st, 2nd, 3rd, 4th, 5th, 6th,
7th and 8th 7 segmen each.

Step 2nd
In this step, you must tipe the assembly program to make your 7 segmen shown
some number on 7 segmen, we assume that you have already known the editor,
we used MIDE-51 to edit the program. ( Download File : exp236.zip ,
Download Complete Circuit File : Sevensegmen.PDF )

org 0h
start: mov P0,#11111001b;write a number '1'
clr P2.7 ;turn on 1st 7 segment
call delay ;call delay time
setb P2.7 ;turn off 1st 7 segment
;
mov P0,#11011011b;write a number '2'
clr P2.6 ;turn on 2nd 7 segment
call delay ;call delay time
setb P2.6 ;turn off 2nd 7 segment
;
mov P0,#10110000b;write a number '3'
clr P2.5 ;turn on 3rd 7 segment
call delay ;call delay time
setb P2.5 ;turn off 3rd 7 segment
;
mov P0,#10011001b;write a number '4'
clr P2.4 ;turn on 4th 7 segment
call delay ;call delay time
setb P2.4 ;turn off 4th 7 segment
;
mov P0,#10010010b;write a number '5'
clr P2.3 ;turn on 5th 7 segment
call delay ;call delay time
setb P2.3 ;turn off 5th 7 segment
;
mov P0,#10000010b;write a number '6'
clr P2.2 ;turn on 2nd 7 segment
call delay ;call delay time
setb P2.2 ;turn off 2nd 7 segment
;
mov P0,#11111000b;write a number '7'
clr P2.1 ;turn on 7th 7 segment
call delay ;call delay time
setb P2.1 ;turn off 7th 7 segment
;
mov P0,#10000000b;write a number '8'
clr P2.0 ;turn on 8th 7 segment
call delay ;call delay time
setb P2.0 ;turn off 8th 7 segment
sjmp start ;jump forever
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with 7seg4.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( 7seg4.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the 7 segmen( of course if your cable connection and
your program are corrected ).

2.3.7. Writing multi character on 8 x 7 segment

In this lesson, we are going to drive more 7 segmen, in this way you can write
eight character on 8 x 7 segmen. We used a multiplexing methode to transfer
data for driver transistor consequtively. Another mothode to take the data tobe
transfer to 8 x 7 segment is by used look up table, as shown in listing program
below.

Step 1st
Build the circuit as shown in figure 2.3.5. As you seen on figure 2.3.5. P2.0
trough P2.7 is connected to driver transistor, and all eight 7 segment is
connected to P0.0 trough P0.6 parallelly. Remember, that all we want to do with
this lesson is write multi character ( A-b-C-d-E-F-g-h ) to 1st, 2nd, 3rd, 4th, 5th,
6th, 7th and 8th 7 segmen each.

Step 2nd
In this step, you must tipe the assembly program to make your 7 segmen shown
some number on 7 segmen, we assume that you have already known the editor,
we used MIDE-51 to edit the program. ( Download File : exp237.zip ,
Download Complete Circuit File : Sevensegmen.PDF )

org 0h
start: mov dptr, #word ;get dptr address
mov R6,#8 ;save number of character
mov R1,#01111111b;drive for 8th 7 segment
Again: clr A ;clear A, A= 0
movc A,@A+dptr ;take data from look up table
inc dptr ;inc address
mov P0,A ;write character to P0
mov A,R1 ;transfer data R1 -> A
mov P2,A ;send data A to P2
rr A ;rotate right data A
mov R1,A ;saving data A -> R1
call delay ;call delay time
mov P0,#11111111b;
djnz R6,Again ;decrement number character
sjmp start ;jump forever
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
;
word: DB 00111111b, 01000111b, 00001000b, 00000011b
DB 01000110b, 01000000b, 01001000b, 00111111b
end

Step 3rd
Safe your assembly program above, and name it with 7seg5.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( 7seg5.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the 7 segmen( of course if your cable connection and
your program are corrected ).

2.3.8. Moving Display

In this lesson, we are going to drive 8 x7 segmen, in this way you can write eight
character on multi 7 segmen. We used a multiplexing methode to transfer data
for driver transistor consequtively.

Figure 2.3.5. Driving on Multi 7 Segmen

Step 1st
Build the circuit as shown in figure 2.3.5. As you seen on figure 2.3.5. P2.0
trough P2.7 is connected to driver transistor, and all eight 7 segment is
connected to P0.0 trough P0.6 parallelly. Remember, that all we want to do with
this lesson is to write ( k-O-n-P-U-t-E-r ) to 1st, 2nd, 3rd, 4th, 5th, 6th, 7th and 8th
7 segmen each sifting the word to the left.

Step 2nd
In this step, you must tipe the assembly program to make your 7 segmen shown
some number on 7 segmen, we assume that you have already known the editor,
we used MIDE-51 to edit the program. ( Download File asm : exp238.zip
,Download Complete Circuit File : Sevensegmen.PDF )

org 0h
Begin: mov r1,#150
start1: mov dptr,#word1
mov r5,#8
mov r2,#01111111b
again1: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again1
djnz r1,start1
mov r1,#150
start2: mov dptr,#word2
mov r5,#8
mov r2,#01111111b
again2: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again2
djnz r1,start2
mov r1,#150
start3: mov dptr,#word3
mov r5,#8
mov r2,#01111111b
again3: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again3
djnz r1,start3
mov r1,#150
start4: mov dptr,#word4
mov r5,#8
mov r2,#01111111b
again4: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again4
djnz r1,start4
mov r1,#150
start5: mov dptr,#word5
mov r5,#8
mov r2,#01111111b
again5: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again5
djnz r1,start5
mov r1,#150
start6: mov dptr,#word6
mov r5,#8
mov r2,#01111111b
again6: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again6
djnz r1,start6
mov r1,#150
start7: mov dptr,#word7
mov r5,#8
mov r2,#01111111b
again7: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again7
djnz r1,start7
mov r1,#150
start8: mov dptr,#word8
mov r5,#8
mov r2,#01111111b
again8: clr A
movc A,@A+dptr
inc dptr
mov p2,A
mov A,r2
mov p3,A
rr A
mov r2,A
acall delay
mov p2,#11111111b
djnz r5,again8
djnz r1,start8
ljmp begin
;
delay: mov r3,#10
delay1: mov r4,#10
djnz r4,$
djnz r3,delay1
ret
;
word1: db 10001010b,11000000b,11001000b,10001100b
db 11000001b,10000111b,10000110b,11001110b
word2: db 11000000b,11001000b,10001100b,11000001b
db 10000111b,10000110b,11001110b,10001010b
word3: db 11001000b,10001100b,11000001b,10000111b
db 10000110b,11001110b,10001010b,11000000b
word4: db 10001100b,11000001b,10000111b,10000110b
db 11001110b,10001010b,11000000b,11001000b
word5: db 11000001b,10000111b,10000110b,11001110b
db 10001010b,11000000b,11001000b,10001100b
word6: db 10000111b,10000110b,11001110b,10001010b
db 11000000b,11001000b,10001100b,11000001b
word7: db 10000110b,11001110b,10001010b,11000000b
db 11001000b,10001100b,11000001b,10000111b
word8: db 11001110b,10001010b,11000000b,11001000b
db 10001100b,11000001b,10000111b,10000110b
end
end

Step 3rd
Safe your assembly program above, and name it with *.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( *.hex ) into the microcontroller by using Microcontroller
ATMEL ISP software, see the instruction.After download this hex file you'll see
the action of the 7 segmen( of course if your cable connection and your program
are corrected ).

Figure 2.4.2. Pin connection betwen LCD Character to microcontroller

( Download Complete Circuit File : LCDCharacter.PDF )

Initializing LCD Character

Function Set
Sets the interface data lenght, the number of lines, and character font

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0 0 0 1 DL N F X X
Note : X = Don't care
DL : Sets interface data lenght.
DL = 1, Data is sent or received in 8 bit lenght
( DB7 - DB0 )
DL = 0, Data is sent or received in 4 bit lenght
( DB7 - DB4 )
When the 4 bit lenght is selected, data must be sent
or recived twice.

Entry Mode Set


Sets the increment/ Decrement and Shift modes to the desired settigs

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0 0 0 0 0 0 1 I/D S
I/D : Increment/ Decrement the DDRAM address by 1 when a
character code is writen into or read from the DDRAM
I/D = "0", Decrement
I/D = "1", Increment
S : Shift the entire display either to the right or to
left.
S = 1, shift to right or left depent on I/D
S = 0, display does not shift

Display On/ Off Cursor


Controls the display ON/OFF status, cursor ON/OFF and Cursor Blink function

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0 0 0 0 0 1 D C B
D : Controlling display
D = 1, Display is ON
D = 0, Display is OFF
In this case display data remains in the DDRAM. It can
be displayed immediately by setting D = 1.
C : Display cursor
C = 1, Cursor is Displayed
C = 0, Cursor does not display
B : The character indicated by the cursor blinks when B=1

Clear Display
The execution of clear display instruction sets entry mode to increment mode

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0 0 0 0 0 0 0 0 1

Cursor of Display Sift


Shifts the cursor position or display to the right or left without writing or reading
display data. This function is used to corect or search for the display

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0 0 0 0 0 S/C R/L X X
Note : x = Dont care
S/C R/L Note
0 0 Shift cursor position to the left
0 1 Shift cursor position to the right
1 0 Shift the entire display to the left
1 1 Shift the entire display to the right
INITIALIZING THE LCD

Before you may really use the LCD, you must initialize and configure it. This is
accomplished by sending a number of initialization instructions to the LCD.

The first instruction we send must tell the LCD whether we'll be communicating
with it with an 8-bit or 4-bit data bus. We also select a 5x8 dot character font.
These two options are selected by sending the command 38h to the LCD as a
command. As you will recall from the last section, we mentioned that the RS line
must be low if we are sending a command to the LCD. Thus, to send this 38h
command to the LCD we must execute the following 8051 instructions:

Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret

Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret

The write_inst routine that we just wrote will send the


instruction to pick the address or initializing.

Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret

The write_data routine that we just wrote will send the character in the
accumulator to the LCD which will, in turn, display it. Thus to display text on the
LCD all we need to do is load the data in R1 to P0 that already connected to DB7
- DB0. Pretty easy, huh?
EXAMPLE :

writing " WELCOME TO " to LCD Character. Now that we have all the
component subroutines written, writing the classic "WELCOME TO" program--
which displays the text "WELCOME TO " on the LCD is a relatively trivial matter.
Consider

call init_LCD
mov R1,#80h
call write_inst
mov R1,#'W'
call write_data
mov R1,#'E'
call write_data
mov R1,#'L'
call write_data
mov R1,#'C'
call write_data
mov R1,#'O'
call write_data
mov R1,#'M'
call write_data
mov R1,#'E'
call write_data
mov R1,#''
call write_data
mov R1,#'T'
call write_data
mov R1,#'O'
call write_data

The above program, should when executed, initiated LCD, choose address
DDRAM, and display WELCOME TO upper left hand corner the display.

CURSOR POSITIONING

The lcd module contains a certain amount of memory which is assigned to the
display. All the text we write to the LCD module is stored in this memory, and the
LCD module subsequently reads this memory to display the text on the LCD
module itself. This memory can be represented with the following "memory map":

Figure 2.12. Memori Map LCD Module

In the above memory map, the area shaded in blue is the visible display. As you
can see, it measures 16 characters per line by 2 lines. The numbers in each box
is the memory address that corresponds to that screen position.
Thus, the first character in the upper left-hanad corner is at address 00h. The
following character position (character #2 on the first line) is address 01h, etc.
This continues until we reach the 16th character of the first line which is at
address 0Fh.

However, the first character of line 2, as shown in the memory map, is at address
40h. This means if we write a character to the last position of the first line and
then write a second character, the second character will not appear on the
second line. That is because the second character will effectively be written to
address 10h--but the second line begins at address 40h.

Thus we need to send a command to the LCD that tells it to position the cursor
on the second line. The "Set Cursor Position" instruction is 80h. To this we must
add the address of the location where we wish to position the cursor. In our
example, we said we wanted to display "World" on the second line on the tenth
character position.

Referring again to the memory map, we see that the tenth character position of
the second line is address 4Ah. Thus, before writing the word "WELCOME TO"
to the LCD, we must send a "Set Cursor Position" instruction--the value of this
command will be 80h (the instruction code to position the cursor) plus the
address 00h. 80h + 00h = 80h. Thus sending the command 80h to the LCD will
position the cursor on the firs line at the first DDRAM.

2.4. LCD Character 2 x 16


The LCD Module can easily be used with an 8051 microcontroller such as the
AT89s51. The LCD Module comes with a 16 pin connector. This can be plugged
into connector 16 pin. The pins on the 16 pin connector of the LCD Module are
defined below.

Figure 2.4.1 LCD Character 2 x 16 Module

PIN Name Function


1 VSS Ground voltage
2 VCC +5V
3 VEE Contrast voltage
Register Select
4 RS 0 = Instruction Register
1 = Data Register
Read/ Write, to choose write or read mode
5 R/W 0 = write mode
1 = read mode
Enable
6 E 0 = start to lacht data to LCD character
1= disable
7 DB0 LSB
8 DB1 -
9 DB2 -
10 DB3 -
11 DB4 -
12 DB5 -
13 DB6 -
14 DB7 MSB
15 BPL Back Plane Light
16 GND Ground voltage

LCD Character Background

The LCD Character standard requires 3 control lines as well as either 4 or 8 I/O
lines for the data bus. The user may select whether the LCD is to operate with a
4-bit data bus or an 8-bit data bus. If a 4-bit data bus is used the LCD will require
a total of 7 data lines (3 control lines plus the 4 lines for the data bus). If an 8-bit
data bus is used the LCD will require a total of 11 data lines (3 control lines plus
the 8 lines for the data bus).

The three control lines are referred to as EN, RS, and RW.

The EN line is called "Enable." This control line is used to tell the LCD that you
are sending it data. To send data to the LCD, your program should make sure
this line is low (0) and then set the other two control lines and/or put data on the
data bus. When the other lines are completely ready, bring EN high (1) and wait
for the minimum amount of time required by the LCD datasheet (this varies from
LCD to LCD), and end by bringing it low (0) again.
The RS line is the "Register Select" line. When RS is low (0), the data is to be
treated as a command or special instruction (such as clear screen, position
cursor, etc.). When RS is high (1), the data being sent is text data which sould be
displayed on the screen. For example, to display the letter "T" on the screen you
would set RS high.

The RW line is the "Read/Write" control line. When RW is low (0), the information
on the data bus is being written to the LCD. When RW is high (1), the program is
effectively querying (or reading) the LCD. Only one instruction ("Get LCD status")
is a read command. All others are write commands--so RW will almost always be
low.

Finally, the data bus consists of 4 or 8 lines (depending on the mode of operation
selected by the user). In the case of an 8-bit data bus, the lines are referred to as
DB0, DB1, DB2, DB3, DB4, DB5, DB6, and DB7.

An Example Hardware Configuration


As we've mentioned, the LCD requires either 8 or 11 I/O lines to communicate
with. For the sake of this tutorial, we are going to use an 8-bit data bus--so we'll
be using 11 of the 8051's I/O pins to interface with the LCD.

2.4.1. Writing "Hello World" to LCD Character in the Upper Left firs
Line.

In this lesson, you can try to write word " Hello World " in first line of LCD
Character.

Step 1st
Build the circuit as shown in figure 2.11. As you seen on figure 2.11. P0.0 trough
P0.7 is connected to DB0 - DB7,and P2.0- P2.1. is connected to RS and EN
each. Remember, that all we want to do with this lesson is write " Hello World ",
in the first line of LCD Character

Step 2nd
In this step, you must tipe the assembly program to make your LCD Character
shown the word, we assume that you have already known the editor, we used
MIDE-51 to edit the program. ( Download File asm : exp241.zip , Download
Complete Circuit File : LCDCharacter.PDF )

org 0h
start: call init_LCD
mov R1,#80h
call write_inst
mov R1,#'H'
call write_data
mov R1,#'e'
call write_data
mov R1,#'l'
call write_data
mov R1,#'l'
call write_data
mov R1,#'o'
call write_data
mov R1,#' '
call write_data
mov R1,#'W'
call write_data
mov R1,#'o'
call write_data
mov R1,#'r'
call write_data
mov R1,#'l'
call write_data
mov R1,#'d'
call write_data
EndChar:
sjmp Endchar

Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
delay: mov R0,#0
delay1:mov R7,#0fh
djnz R7,$
djnz R0,delay1
ret
;
end

Step 3rd
Safe your assembly program above, and name it with lcd1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( lcd1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of the 7 segmen( of course if your cable connection and
your program are corrected ).

2.4.2. Writing "Hello World" to LCD Character in the lower left


second line.
Try to do it this lesson with your own idea, OK

2.4.3. Writing a word by using look up table

The difference about this lesson with previus is how the data come from. By
using look up table dinamically we can cange the caracter more easily.

Step 1st
Build the circuit as shown in figure 2.11. As you seen on figure 2.11. P0.0 trough
P0.7 is connected to DB0 - DB7,and P2.0- P2.1. is connected to RS and EN
each. Remember, that all we want to do with this lesson is write " Hello World ",
in the first line of LCD Character

Step 2nd
In this step, you must tipe the assembly program to make your LCD Character
shown the word, we assume that you have already known the editor, we used
MIDE-51 to edit the program. ( Download File asm : exp243.zip ,Download
Complete Circuit File : LCDCharacter.PDF ))

org 0h
call init_LCD
start: call write_char
sjmp start
;
write_char:
mov dptr,#word1 ;DPTR = [ address word1 ]
mov r3,#16 ;R3=16,number character to be display
mov r1,#80h ;R1=80h,address DDRAM start position
acall write_inst
;
write1:clr a ;A=0
movc a,@a+dptr ; A = [A+ DPTR]
mov r1,A ; R1 = A
inc dptr ; DPTR = DPTR +1
acall write_data;
djnz r3,write1 ; R3 = R3-1,
ret
;
Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
delay: mov R0,#0
delay1:mov R7,#0fh
djnz R7,$
djnz R0,delay1
ret
;
word1: DB ' Welcome Home '; here is the data to be look up
;
end

Step 3rd
Safe your assembly program above, and name it with lcd3.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( lcd3.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of LCD Character 2 x16 ( of course if your cable
connection and your program are corrected ).

2.4.4. Moving Character on LCD


This lesson is learn how to make you word on LCD moving arround, actualy it's
just a simple case, by executing sift right or left instruction. see table cursor of
display sift

Step 1st
Build the circuit as shown in figure 2.11. As you seen on figure 2.11. P0.0 trough
P0.7 is connected to DB0 - DB7,and P2.0- P2.1. is connected to RS and EN
each. Remember, that all we want to do with this lesson is write " Hello World ",
in the first line of LCD Character

Step 2nd
In this step, you must tipe the assembly program to make your LCD Character
shown the word, we assume that you have already known the editor, we used
MIDE-51 to edit the program. ( Download File asm : exp244.zip , Download
Complete Circuit File : LCDCharacter.PDF ))

org 0h
call init_LCD
start: call write_char; writing a word
;
mov R2,#10 ; number data tobe sift
siftR: call sift2right
djnz R2,siftR ; counting down number data
;
mov R2,#10
siftL: call sift2right
djnz R2,siftR
sjmp start
;
write_char:
mov dptr,#word1 ;DPTR = [ address word1 ]
mov r3,#16 ;R3=16,number character to be display
mov r1,#80h ;R1=80h,address DDRAM start position
acall write_inst
;
write1:clr a ;A=0
movc a,@a+dptr ; A = [A+ DPTR]
mov r1,A ; R1 = A
inc dptr ; DPTR = DPTR +1
acall write_data;
djnz r3,write1 ; R3 = R3-1,
ret
;
Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
sift2left:
mov R1,#00011011b ;R1 = sift2left
call write_inst
call ldelay
ret
;
sift2Right:
mov R1,#00011111b ;R1 = sift2right
call write_inst
call ldelay
ret
;
delay: mov R0,#0
delay1:mov R7,#0fh
djnz R7,$
djnz R0,delay1
ret
;
Ldelay:mov R6,#030h
Ld1: call delay
djnz R6,Ld1
ret
;
word1: DB ' Welcome Home '; here is the data to be look up
;
end
2.5. Analog to Digital Converter

The easiest way to do analog to digital conversion is to use an IC such as the


ADC0804 that does the work for you. The analog voltage is applied to pin 6 and
the result is available at pins 11 through 18. We will connect pin 1 and 2 (Chip
Select and Read) to ground so that the chip is always enabled. (If you wanted to
use more than one ADC you could use this pin to control which chip is currently
enabled).
Connect pin 7 (Vin - ) to ground. The ADC0804 includes an internal oscillator
which requires an external capacitor and resistor to operate. Connect the 150 pF
capacitor from pin 4 (CLOCK IN) to ground and the 10k ohm resistor from pin 4
to pin 19 (CLOCK R). ( Download Complete Circuit File : ADC.pdf )

Figure 2.5.1 Typical connection of free running mode

For example:
The input range of ADC is 0 - 5 volt
then we must setting Vref = 0.5 Vin maximum or = 2.5 volt
because this ADC0804 is 8 bit then
V resolution = 5/255 = 0.02 volt
this is mean that ADC will respon each 0,02V increasing

Vin
D0 D1 D2 D3 D4 D5 D6 D7 Des
(volt)
0 0 0 0 0 0 0 0 0 0
0.02 0 0 0 0 0 0 0 1 1
0.04 0 0 0 0 0 0 1 0 2
0.06 0 0 0 0 0 0 1 1 3
0.08 0 0 0 0 0 1 0 0 4
0.10 0 0 0 0 0 1 0 1 5
0.12 0 0 0 0 0 1 1 0 6
: :
5 1 1 1 1 1 1 1 1 255

Stage 1)
to operate this ADC, we use a free running mode, by connecting WR to INT

Stage 2)
When the conversion process is complete, pin 5 (Interrupt) will go low and this
signal is used to convert ADC again.

Stage 3)
Next we read the values into the 89s51 Port 0.

The assembly program will be:

Org 0h

start: mov A,P0 ; saving data ADC to Accumulator


sjmp start
end

2.5.1. Displaying data ADC 0804 in LCD Character as a Decimal

In this lesson will be learn how to display data ADC on LCD Character, for a
simple task that we assume ADC have input ranges 0 - 5 volt, and then will
display data as desimal that must be 3 digit 0 - 255.
Figure 2.5.1. Display data ADC to LCD Character as decimal

Step 1st
Build the circuit as shown in figure 2.5.1. As you seen on figure 2.5.1. P0.0
trough P0.7 is connected to DB0 - DB7 ADC0804, and P2.0- P2.7. is connected
to D0 - D7, and P3.0, P3.1. is connected to RS and EN each. Remember, that all
we want to do with this lesson is write data ADC, in the first line of LCD
Character

Step 2nd
In this step, you must tipe the assembly program to make your LCD Character
shown the data, we assume that you have already known the editor, we used
MIDE-51 to edit the program. ( Download File asm : exp251.zip, Download
Complete Circuit File : ADC.pdf )

org 0h
call init_LCD
start: call ADC
call Bin2Dec
call Write2LCD
sjmp start
;
;=================================================
;this subroutine is used to take data from ADC and
;keep to Accumulator
;=================================================
ADC: mov A,P0
nop
nop
ret
;
;========================================================
;this subroutine is used print out data decimal to LCD
;character 2 x16 on address DDRAM 0C9 0CA 0CB each for
;hundreds, tens, and ones
;========================================================
Write2LCD:
mov r1,#0c9h
call write_inst
mov a,hundreds
add a,#30h
mov r1,a
call write_data
;
mov r1,#0cah
call write_inst
mov a,tens
add a,#30h
mov r1,a
call write_data
;
mov r1,#0cbh
call write_inst
mov a,ones
add a,#30h
mov r1,a
call write_data
ret
;
;========================================================
;this subroutine is used to convert binary data from ADC
;become decimal 3 digit
;========================================================
Bin2Dec:
mov b,#100d
div ab
mov hundreds,a
mov a,b
mov b,#10d
div ab
mov tens,a
mov ones,b
ret
;
write_char:
mov dptr,#word1 ;DPTR = [ address word1 ]
mov r3,#16 ;R3=16,number character to be display
mov r1,#80h ;R1=80h,address DDRAM start position
acall write_inst
;
write1:clr a ;A=0
movc a,@a+dptr ; A = [A+ DPTR]
mov r1,A ; R1 = A
inc dptr ; DPTR = DPTR +1
acall write_data;
djnz r3,write1 ; R3 = R3-1,
ret
;
Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
delay: mov R0,#0
delay1:mov R2,#0fh
djnz R2,$
djnz R0,delay1
ret
;
word1: DB ' Data ADC0804 '
;
end

Step 3rd
Safe your assembly program above, and name it with adc1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( adc1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of ADC ( of course if your cable connection and your
program are corrected

2.5.2. Displaying data ADC 0804 in 8x7 Segmen as a Decimal

In this lesson will be learn how to display data ADC on 8 x 7 segmen, for a
simple task, we assume ADC have input ranges 0 - 5 volt, and then will display
data as desimal that must be 3 digit 0 - 255, and each digit would be placed on
3rd, 2nd and 1st 7 segmen.

Figure 2.5.2. Connecting ADC and display to 7 segmen

Step 1st
Build the circuit as shown in figure 2.5.2. As you seen on figure 2.5.2. P3.0
trough P3.7 is connected to DB0 - DB7 ADC0804, and P2.0- P2.7. is connected
to transistor driver, and P3.0 trough P3.7. is connected to 7 Segmen. Remember,
that all we want to do with this lesson is write data ADC, to 8 x 7 Segmen.

Step 2nd
In this step, you must tipe the assembly program to make your 8 x 7 Segmen
shown the data, we assume that you have already known the editor, we used
MIDE-51 to edit the program. ( Download File asm : exp252.zip, Download
Complete Circuit File : ADC.pdf)

org 0h
hundreds equ 30h
tens equ 31h
ones equ 32h
start: call ADC
call Bin2Dec
call Display2SevenSegmen
sjmp start
;
;=================================================
;this subroutine is used to take data from ADC and
;keep to Accumulator
;=================================================
ADC: mov A,P0
nop
nop
ret
;
;========================================================
;this subroutine is used to convert binary data from ADC
;become decimal 3 digit
;========================================================
Bin2Dec:
mov b,#100d
div ab
mov hundreds,a
mov a,b
mov b,#10d
div ab
mov tens,a
mov ones,b
ret
;===============================================
;this subroutine is used to convert data ADC to
;8 x 7 segmen
;===============================================
Display2SevenSegmen:
Mov P2,#11111111b
mov A, Hundreds
mov DPTR,#Data7segmen
movc A,@A+DPTR
mov P0,A
clr P2.5
call delay
;
mov A,tens
mov DPTR,#Data7segmen
movc A,@A+DPTR
setb P1.5
mov P0,A
clr P2.6
call delay
;
mov A,ones
mov DPTR,#Data7segmen
movc A,@A+DPTR
setb P1.6
mov P0,A
clr P2.7
call delay
ret
;
delay: mov R0,#0
delay1:mov R2,#0fh
djnz R2,$
djnz R0,delay1
ret
;
Data7segmen:
db 11000000b,11111001b,10100100b,10110000b,10011001b
db 10010010b,10000010b,11111000b,10000000b,10010000b
end

Step 3rd
Safe your assembly program above, and name it with adc2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file into the microcontroller by using Microcontroller ATMEL
ISP software, see the instruction.After download this hex file you'll see the action
of ADC ( of course if your cable connection and your program are corrected )

2.5.3. Simulating to Display Temperature by Using Look Up Table

WHAT IS THE LOOK UP TABLE ?

Why do we need a look up tabel ? Look up tabel is just couple data that safe in
ROM and it's used to manipulate data. So we can avoid a very confusing prosess
of math. In this case we are going to display temperature with three digit and one
digit after point.

Temp = DataADC * 100/ 255 oC.

Note : DataADC is data that came from ADC, and have range 0-255, in this
simple task, we assume that we use temperature range from 0 - 100 oC, so you
just divide 100 by 255 as you look in table below.
After you made the tabel by using Microsoft Exell, now you should write down the
data int the look up table:

fraction :
db 0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6,0,4
db 8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8,2,6
db 0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6,0
db 4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8,2
db 6,0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6
db 0,4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8
db 2,6,0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2
db 6,0,4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4
db 8,2,6,0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6
db 0,4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8,2,6,0
;
Ones :
db 0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8,9,9
db 9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9,9
db 0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8,9
db 9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9
db 9,0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8,9
db 9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8
db 9,9,0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8
db 9,9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8
db 8,9,9,0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8
db 9,9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9,9,0
;
Tens :
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
db 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
db 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
db 4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
db 5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
db 6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
db 7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
db 8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0
;
Hundreds :
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1

our plan is display the data as look like this for example:

8th 7th 6th 5th 4th 3rd 2nd 1st


Hundr. Tens Ones Fraction

1 0 0 , 0 o C
Step 1st
Build the circuit as shown in figure 2.5.2. As you seen on figure 2.5.2. P3.0
trough P3.7 is connected to DB0 - DB7 ADC0804, and P2.0- P2.7. is connected
to transistor driver, and P3.0 trough P3.7. is connected to 7 Segmen. Remember,
that all we want to do with this lesson is write data ADC, to 8 x 7 Segmen.

Step 2nd
In this step, you must tipe the assembly program to make your LCD Character
shown the data, we assume that you have already known the editor, we used
MIDE-51 to edit the program. ( Download File asm : exp253.zip, Download
Complete Circuit File : ADC.pdf)

org 0h
hundreds_100 equ 30h
tens_10 equ 31h
ones_1 equ 32h
dataadc equ 33h
start: call ADC
call Bin2Dec
call Display2SevenSegmen
sjmp start
;
;=================================================
;this subroutine is used to take data from ADC and
;keep to Accumulator
;=================================================
ADC: mov A,P0
nop
nop
ret
;
;========================================================
;this subroutine is used to convert binary data from ADC
;become decimal 3 digit
;========================================================
Bin2Dec:
mov b,#100d
div ab
mov hundreds_100,a
mov a,b
mov b,#10d
div ab
mov tens_10,a
mov ones_1,b
ret
;===============================================
;this subroutine is used to convert data ADC to
;8 x 7 segmen
;===============================================
Display2sevensegmen:
mov P2,#11111111b ; P1 = 11111111b
mov DPTR,#hundreds ; DPTR = [hundreds ]
mov A,DataADC ; A = [DataADC]
movc A,@A+DPTR ; A = [A+DPTR]
mov DPTR,#Data7segmen; DPTR = [Data7Segmen]
movc A,@A+DPTR ; A = [A+DPTR]
mov P0,A ; P0 = A
clr P2.1 ; P2.1 = 0, displaying hundreds
Acall delay
;
mov DPTR,#tens ; DPTR = [ tens ]
mov A,DataADC ; A = [DataADC]
movc A,@A+DPTR ; A = [A+DPTR]
mov DPTR,#Data7segmen; DPTR = [Data7Segmen]
movc A,@A+DPTR ; A = [A+DPTR]
setb P2.1 ; P2.1 = 1
mov P0,A ; P0 = A
clr P2.2 ; P2.2 = 0, displaying hundreds
Acall delay
;
mov DPTR,#ones ; DPTR = [ ones]
mov A,DataADC ; A = DataADC
movc A,@A+DPTR ; A =[ A+DPTR]
mov DPTR,#Data7segmen; DPTR = [Data7Segmen]
movc A,@A+DPTR ; A = [A+DPTR]
setb P2.2 ; P2.2 = 1
mov P0,A ; P0 = A
clr P2.3 ; P2.3 = 0, displaying ones
Acall delay
;
setb P2.3
mov P0,#11111011b
clr P2.4 ; P2.4 = 0, displaying coma
Acall delay
;
mov DPTR,#fraction
mov A,DataADC
movc A,@A+DPTR
mov DPTR,#Data7segmen
movc A,@A+DPTR
setb P2.4
mov P0,A
clr P2.5 ; P2.5 = 0, displaying fraction
Acall delay
ret
;
setb P2.5
mov P0,#10100011b
clr P2.6 ; P2.6 = 0, displaying o
Acall delay
;
setb P2.6
mov P0,#11000011b
clr P2.7 ; P2.7 = 0, displaying C
Acall delay
;
delay: mov R0,#0
delay1:mov R2,#0fh
djnz R2,$
djnz R0,delay1
ret
;
fraction :
db 0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6,0,4
db 8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8,2,6
db 0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6,0
db 4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8,2
db 6,0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6
db 0,4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8
db 2,6,0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2
db 6,0,4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4
db 8,2,6,0,4,8,2,6,0,4,7,1,5,9,3,7,1,5,9,3,7,1,5,8,2,6
db 0,4,8,2,6,0,4,8,2,5,9,3,7,1,5,9,3,7,1,5,9,3,6,0,4,8,2,6,0
;
Ones :
db 0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8,9,9
db 9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9,9
db 0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8,9
db 9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9
db 9,0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8,9
db 9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8
db 9,9,0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8
db 9,9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8
db 8,9,9,0,0,0,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,7,7,7,8,8
db 9,9,9,0,0,1,1,1,2,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9,9,0
;
Tens :
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
db 2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
db 3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
db 4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
db 5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
db 6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
db 7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
db 8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0
;
Hundreds :
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
;
data7segmen:
db 11000000b,11111001b,10100100b,10110000b,10011001b
db 10010010b,10000010b,11111000b,10000000b,10010000b
end

Step 3rd
Safe your assembly program above, and name it with adc4.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( adc4.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of ADC ( of course if your cable connection and your
program are corrected

2.6. Build Digital to Analog Converter Using 0808

The first task this week is to build a simple D/A convertor and evaluate its
performance. You will be using a DAC0808 (DAC0808 datasheet).Your design
should take 8 bits from the microcontroller (use the 8 8bits on Port 0 of the
AT89s51 as the input to the D/A convertor). The D/A output should range from 0
to 5 volts. The lower 8 bits from the AT89s51 should go into the 8 bits from the
DAC0808. Note: I expect you to try to get the device to work by reading the
datasheet and trying to understand it, if you have trouble you should come see
me, but I expect you to have fairly specific questions that indicate you have put
some thought into the problem.

Figure 2.6.1. Pin Configuration DAC0808

Things to consider with the this design:

Figure 2.6.1 from page 4 of the DAC0808 datasheet is a good place to start your
design.
The pins are labeled A1 through A8, but note that A1 is the Most Significant Bit,
and A8 is the Least Significant Bit (the opposite of the normal convention).
Ground the two least significant bits.
The D/A convertor has an output current, instead of an output voltage. The
output pin should stay at about 0 volts. The op-amp on the "Typical Application"
on the datasheet converts the current to a voltage. How does it do this?
The output current from pin 4 ranges between 0 (when the inputs are all 0) to
Imax*255/256 when all the inputs are 1. The current, Imax, is determined by the
current into pin 14 (which is at 0 volts). Note: Since we are using 8 bits, the
maximum value is Imax*255/256.
You'll need to modify the circuit given in the datasheet to get a full scale range of
0 to 5 volts. Again, our output will be just under 5 volts. The output of the D/A
convertor takes some time to settle. You may need to take this in consideration
when planning the timing of the A/D conversion in later sections of this lab.
Check the DAC0808 datasheet for specs. The code below shows an easy way to
send 8 bits to the output of the microcontrollerr. You should probably test your
code without the D/A convertor separately to ensure that the microcontroller is
behaving as you expect. ( Download Complete Circuit File : DAC0808.pdf

Figure 2.6.2. Typical Application DAC0808

Where, Rf = Feedback Resistor of Current to Voltage


Converter circuit
2.6.1. Simple Experiment to Generate a Voltage from DAC

In this lesson we are like to design, how to generate a voltage 2 volt from
DAC0808. There is something you must to do is to calculate the konstanta K, as
you have learned in previous lesson.

Step 1st
Build the circuit as shown in figure 2.6.2 As you seen on figure 2.6.2. P0.0 trough
P0.7 is connected to A8 - A1.
or example, we assumes that the Vref = 5 volt, R14 = 5 k, and Rf = 5k

K = Vref/ R14;
= 5/5k
= 1 mA
If, we put logic high into A1 through A8 then we have:
Io = 1 mA x 0.99
= 1 mA
So,Vo = Io x Rf
= 1 mA x 5k
= 5 volt
Voltage Resolution = 5/255 = 0.02 volt

If you like to send a 2 volt out from your DAC, than you
must write down this decimal
= 2/0.02
= 100 decimal

Step 2nd
In this step, you must tipe the assembly program to make a voltage from your
DAC, we assume that you have already known the editor, we used MIDE-51 to
edit the program. ( Download Complete Circuit File : DAC0808.pdf )

org 0h
start: mov A,#100
mov P0,A
sjmp start

Step 3rd
Safe your assembly program above, and name it with dac1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( dac1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of DAC ( of course if your cable connection and your
program are corrected
2.6.2. Generating a Stair Step Voltage from DAC

In this lesson we are like to design, how to generate stair step voltage from 0volt
trough 5 volt, with resolution 1 volt each step. There is something you must to do
is to calculate the konstanta K, as you have learned in previous lesson.

Step 1st
Build the circuit as shown in figure 2.6.2. As you seen on figure 2.6.2. P0.0
trough P0.7 is connected to A8 - A1.
or example, we assumes that the Vref = 5 volt, R14 = 5 k, and Rf = 5k

K = Vref/ R14;
= 5/5k
= 1 mA
If, we put logic high into A1 through A8 then we have:
Io = 1 mA x 0.99
= 1 mA
So,Vo = Io x Rf
= 1 mA x 5k
= 5 volt
Voltage Resolution = 5/255 = 0.02 volt

* Voltage 0 volt
= 0/ 0.02
= 0 decimal
* Voltage 1 volt
= 1/0.02
= 50 decimal
* Voltage 2 volt
= 2/0.02
= 100 decimal
* Voltage 3 volt
= 3/0.02
= 150 decimal
* Voltage 4 volt
= 4/0.02
= 200 decimal
* Voltage 5 volt
= 5/0.02
= 255 decimal

Step 2nd
In this step, you must tipe the assembly program to make a voltage from your
DAC, we assume that you have already known the editor, we used MIDE-51 to
edit the program. ( Download File asm : exp262.zip, Download Complete
Circuit File : DAC0808.pdf )

org 0h
start: mov A,#0
mov P0,A
call delay
;
mov A,#50
mov P0,A
call delay
;
mov A,#100
mov P0,A
call delay
;
mov A,#150
mov P0,A
call delay
;
mov A,#200
mov P0,A
call delay
;
mov A,#255
mov P0,A
call delay
;
sjmp start
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
end

Step 3rd
Safe your assembly program above, and name it with dac2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file into the microcontroller by using Microcontroller ATMEL
ISP software, see the instruction.After download this hex file you'll see the action
of DAC ( of course if your cable connection and your program are corrected )

2.6.3. Generating a Stair Step Voltage by Using Look Up Table

In this lesson we are like to design, how to generate stair step voltage from 0volt
trough 5 volt, with resolution 0.5 volt each step. There is something you must to
do is to calculate the konstanta K, as you have learned in previous lesson.

Step 1st
Build the circuit as shown in figure 2.6.2 As you seen on figure 2.6.2. P0.0 trough
P0.7 is connected to A8 - A1.
For example, we assumes that the Vref = 5 volt, R14 = 5 k, and Rf = 5k

K = Vref/ R14;
= 5/5k
= 1 mA
If, we put logic high into A1 through A8 then we have:
Io = 1 mA x 0.99
= 1 mA
So,Vo = Io x Rf
= 1 mA x 5k
= 5 volt
Voltage Resolution = 5/255 = 0.0196 volt

* Voltage 0 volt
= 0/ 0.0196
= 0 decimal
* Voltage 0.5 volt
= 0.5/0.0196
= 25 decimal
* Voltage 1 volt
= 1/0.0196
= 51 decimal
* Voltage 1.5 volt
= 1.5/0.0196
= 76 decimal
:
:
* Voltage 5 volt
= 5/0.0196
= 255 decimal

Step 2nd
In this step, you must tipe the assembly program to make a voltage from your
DAC, we assume that you have already known the editor, we used MIDE-51 to
edit the program. ( Download File : exp263.zip , Download Complete Circuit
File : DAC0808.pdf)

org 0h
mov DPTR,#DataDAC
start: clr A
movc A,@ A+DPTR
mov P0,A
inc DPTR
call delay
sjmp start
;
delay: mov R0,#0
delay1:mov R2,#0fh
djnz R2,$
djnz R0,delay1
ret
;
DataDAC:
DB 0,25,51,76,102,127,153,178,204,229,255
end

Step 3rd
Safe your assembly program above, and name it with dac3.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file into the microcontroller by using Microcontroller ATMEL
ISP software, see the instruction.After download this hex file you'll see the action
of DAC ( of course if your cable connection and your program are corrected )

f.4. Generating a Sine Wave Voltage by Using Look Up Table

In this lesson we are like to design, how to generate sine wave voltage from 0volt
trough 5 volt, with resolution 0.1 volt each step. There is something you must to
do is to calculate the konstanta K, as you have learned in previous lesson. For
this lesson you must to do by your self, something that gives you a clue is:

Figure 2.6.3. Sine wave voltage 0 - 5 volt

2.7. Driving Stepper Motor

General Theory of Stepper Motors

An ordinary DC motor will turn around and around as long as power is supplied.
No intelligent circuitry is required to drive such a motor, unless you want to slow it
down or reverse direction - just apply power and it spins. A stepper motor is very
different. If you just feed it power, it will stay where it is. In order to make the
motor move, you have to feed it a changing signal. This is best illustrated by
thinking of a magnetic compass with electromagnets around it:
Figure 2.7.1 Motor Stepper

The drawing on the bottom shows power applied to the N electromagnet, drawing
the compass toward it. On the right, power is instead applied to the E
electromagnet, and the needle has rotated toward that side.

Figure 2.7.2. Basic Stepper Motor

Just four electromagnets would give coarse jumpy motion. Now imagine a similar
arrangement with 100 electromagnets around the compass. By energizing each
electromagnet in sequence, the needle takes 100 steps around the circle. But
driving 100 individual electromagnets would require complex electronics. We
fake it:
Figure 2.7.3. Basic Motor Stepper with more electromagnet

In these drawing, the circled letters represent electromagnets. All the magnets
with the same letter are wired together. When you energize that circuit, all of the
electromagnets torn on at once. On the left, there are 8 magnets, but only 4
circuits. Sequencing through the four circuits gives half of a rotation. One more
run through the sequence completes the rotation. This setup requires that both
ends of the compass needle be north-seeking. On the right, the same 4 circuits
energize 16 magnets. This setup requires 16 steps (4 repetitions of a 4-step
cycle) to complete one rotation.

On the right, the same 4 circuits energize 16 magnets. This setup requires 16
steps (4 repetitions of a 4-step cycle) to complete one rotation. In actual practice,
just four control wires can provide just about as many steps as you might want.
One of the characteristics of a given stepper motor is the number of steps
necessary to make a complete circle, usually expressed as number of degrees
per step.

Table 2.7.1. Full Step Mode

A B C D Comment
1 0 0 0 Take a step clock wise
0 1 0 0 another step clock wise
0 0 1 0 another step clock wise
0 0 0 1 another step clock wise
0 0 0 1 No step take
0 0 1 0 Take a step back

More Complex Drive


As we have seen, it is very easy to drive a stepper motor, by simply turning one
electromagnet fully on at a time. But there are other ways to drive a stepper
motor.

Half Steps
By turning on two coils at once, the motor will take a position between the two
steps.

Figure 2.7.4. Half step mode

Table 2.7.2. Half Step Mode

A B C D Comment
1 0 0 0 Take a step clock wise
1 1 0 0 Half a step clock wise
0 1 0 0 The complete full step clock wise
0 1 1 0 another half step clock wise
0 0 1 0 The complete full step clock wise
0 0 1 1 Another half step clock wise
0 0 0 1 The complete full step clock wise
1 0 0 1 another half step clock wise
1 0 0 0 Start position

2.7.1. Get to run your stepper motor

A basic example of stepper motor driver is shown in figure 2.7.1.1 Notice the
separate voltages for logic and for the stepper motor. Usually the motor will
require a different voltage than the logic portion of the system. Typically logic
voltage is +5 Vdc and the stepper motor voltage can range from +5 Vdc up to
about +48 Vdc. The driver is also an "open collector" driver, wherein it takes its
outputs to GND to activate the motor's windings.
Figure 2.7.1.1 Driving motor stepper

Step 1st
Build the circuit as shown in figure 2.7.1.1. As you seen on figure 2.7.1.1. P0.4
trough P0.7 is connected to driver motor stepper. Remember, that all we want to
do with this lesson is write data to stepper motor.

Step 2nd
In this step, you must tipe the assembly program to make your stepper motor
run, we assume that you have already known the editor, we used MIDE-51 to
edit the program. ( Download File : exp271.zip , Download Complete Circuit
File : StepperMotor.PDF ))

org 0h
start: mov P0,#11101111b; Turn on driver 1
call delay ; call delay time
mov P0,#11011111b; Turn on driver 2
call delay ; call delay time
mov P0,#10111111b; Turn on driver 3
call delay ; call delay time
mov P0,#01111111b; Turn on driver 4
call delay ; call delay time
sjmp start
;
delay: mov R0,#0
delay1:mov R2,#0fh
djnz R2,$
djnz R0,delay1
ret
end

Step 3rd
Safe your assembly program above, and name it with stepper1.asm (for
example) Compile the program that you have been save by using MIDE-51, see
the software instruction.

Step 4th
Download your hex file ( stepper1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Stepper Motor ( of course if your cable connection and
your program are corrected ).

2.7.2. Directing your step wise with push button

The other way to drive step wise of motor stepper is by using a swicht push
button, for example, in this lesson we can try to rotate stepper motor in clockwise
if we push the button and counter clockwise if we do not push the button.

Figure 2.7.2.1. Driving motor stepper wise step with swicht push button

Step 1st
Build the circuit as shown in figure 2.7.2.1. As you seen on figure 2.7.2.1. P0.4
trough P0.7 is connected to driver motor stepper and one push button is
connected to P2.0. Remember, that all we want to do with this lesson is to drive
clock wise or counter clock wise of motor stepper with push button.

Step 2nd
In this step, you must tipe the assembly program to make your stepper motor
run, we assume that you have already known the editor, we used MIDE-51 to
edit the program. ( Download File : exp272.zip , Download Complete Circuit
File : StepperMotor.PDF )

org 0h
start: jb P2.0,CW
call StepCCW
sjmp start
CW: call StepCW
sjmp start
;
StepCW:
mov P0,#11101111b; Turn on driver 1
call delay ; call delay time
mov P0,#11011111b; Turn on driver 2
call delay ; call delay time
mov P0,#10111111b; Turn on driver 3
call delay ; call delay time
mov P0,#01111111b; Turn on driver 4
call delay ; call delay time
ret
;
StepCCW:
mov P0,#01111111b; Turn on driver 1
call delay ; call delay time
mov P0,#10111111b; Turn on driver 2
call delay ; call delay time
mov P0,#11011111b; Turn on driver 3
call delay ; call delay time
mov P0,#11101111b; Turn on driver 4
call delay ; call delay time
ret
;
delay: mov R0,#0
delay1:mov R2,#0fh
djnz R2,$
djnz R0,delay1
ret
end

Step 3rd
Safe your assembly program above, and name it with stepper2.asm (for
example) Compile the program that you have been save by using MIDE-51, see
the software instruction.

Step 4th
Download your hex file ( stepper2.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Stepper Motor ( of course if your cable connection and
your program are corrected ).

2.g.3. Directing your step wise with push button

With refers to lesson 2.g.2., in this lesson you can try how to drive stepper motor
with two swicht, that's mean you can direct step wise with two push button, and
each push button controls one direction as shown in figure 2.23.
Figure 2.23. Driver stepper motor stepper wise with two push button

2.8. K E Y P A D 4 x 4

Keypads are often used as a primary input device for embedded


microcontrollers. The keypads actually consist of a number of switches,
connected in a row/column arrangement as shown in Fig 2.8.1.

In order for the microcontroller to scan the keypad, it outputs a nibble to force
one (only one) of the columns low and then reads the rows to see if any buttons
in that column have been pressed. The rows are pulled up by the internal weak
pull-ups in the 8051 ports. Consequently, as long as no buttons are pressed, the
microcontroller sees a logic high on each of the pins attached to the keypad
rows. The nibble driven onto the columns always contains only a single 0. The
only way the microcontroller can find a 0 on any row pin is for the keypad button
to be pressed that connects the column set to 0 to a row. The controller knows
which column is at a 0-level and which row reads 0, allowing it to determine
which key is pressed. For the keypad, the pins from left to right are: R1, R2, R3,
R4, C1, C2, C3, C4.

Figure 2.8.1. Keypad 4 X 4 Connection


The Algorithm

Matrix-type keypads consist of a rectangular array of momentary push button.


Each row and each column of push buttons is connected to a common rail.
Suppose a four by four array of push button are used. A four by four array is
often used to input hexadecimal numbers. There are four comun rails and four
row rails. Each pushbutton has two terminals, one connected to its column rail
and the other to its row rail. The row and column rails are connected to the
microcontroller ports. The columns are driven low by output port. The rows are
then read into the input ports. If no key is pressed, the rows read 1. When a row
is detected to be 0, it indicates that a key in that row is pressed. the task now is
to detect which key of the row is actually pressed. The microcontroller loops
through each column, driving only one column low at a time as it inspects the
row.The microcontroller needs to poll the rows to see if a key is pressed. Only
when the column in which the pressed key resides is driven low is the row rail
grounded, and thus the voltage is low. The rows and columns are
interchangeable, that is, the rows may be driven low as the columns are read by
the input ports.

2.8.1. Display Keypad Data to LED

In this lesson we are like to design, how to scan keypad 4 x 4, and then display it
to LED.

Figure 2.8.2. Keypad connection and display to LED

Step 1st
Build the circuit as shown in figure 2.8.2. As you seen on figure 2.2.8. P3.0
trough P3.7 is connected to keypad 4 x 4 and to drive LEDs, it's connected to
P2.0 trough P2.7.
Step 2nd
In this step, you must tipe the assembly program to scan your keypad data, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp281.zip , Download Complete Circuit File :
Keypad4x4.pdf )

;In this lesson we'll scan keypad and get data out to LED
;and convert it into binary data
row1 bit P2.4
row2 bit P2.5
row3 bit P2.6
row4 bit P2.7
col1 bit P2.0
col2 bit P2.1
col3 bit P2.2
col4 bit P2.3
;
keydata equ 70h
keybounc equ 71h
keyport equ P2
org 0h
start: call keypad4x4 ;calling subroutine keypad4x4
Mov A,keydata ;A = keydata
Cjne A,#0FFh,send ;
sjmp start ;LOOPING FOREVER
send: CPL A ;A = NOT A
Mov P0,A ;P0 = A
Sjmp start ;LOOPING FOREVER PART 2
;
delay: mov R0,#0
delay1:mov R2,#50
djnz R2,$
djnz R0,delay1
ret
;
;====================================
; subroutine scan keypad 4x4
;====================================
Keypad4x4:
mov keybounc,#50 ;keybounc = 50
mov keyport,#0FFh ;keyport=P2= FF
clr col1 ;col1= P3.0 = 0
Detect:jb row1,key1 ;jump to key1 if row1=1
djnz keybounc,Detect
mov keydata,#00h ;Keydata =00h
ret
;
key1: jb row2,key2 ;jump to Key2 if row2=1
djnz keybounc,key1
mov keydata,#04h ;Keydata = 04h
ret
;
key2: jb row3,key3 ; idem
djnz keybounc,key2
mov keydata,#08h
ret
;
key3: jb row4,key4 ; idem
djnz keybounc,key3
mov keydata,#0Ch
ret
;
key4: setb col1
clr col2
jb row1,key5
djnz keybounc,key4
mov keydata,#01h
ret
;
key5: jb row2,key6
djnz keybounc,key5
mov keydata,#05h
ret
;
key6: jb row3,key7
djnz keybounc,key6
mov keydata,#09h
ret
;
key7: jb row4,key8
djnz keybounc,key7
mov keydata,#0Dh
ret
;
key8: setb col2
clr col3
jb row1,key9
djnz keybounc,key8
mov keydata,#02h
ret
;
key9: jb row2,keyA
djnz keybounc,key9
mov keydata,#06h
ret
;
keyA: jb row3,keyB
djnz keybounc,keyA
mov keydata,#0Ah
ret
;
keyB: jb row4,keyC
djnz keybounc,keyB
mov keydata,#0Eh
ret
;
keyC: setb col3
clr col4
jb row1,keyD
djnz keybounc,keyC
mov keydata,#03h
ret
;
keyD: jb row2,keyE
djnz keybounc,keyD
mov keydata,#07h
ret
;
keyE: jb row3,keyF
djnz keybounc,keyE
mov keydata,#0Bh
ret
;
keyF: jb row4,Nokey
djnz keybounc,keyF
mov keydata,#0Fh
ret
Nokey:mov keydata,#0FFh
ret
;================================
;The end of Keypad 4x4 subroutine
;================================
end

Step 3rd
Safe your assembly program above, and name it with key1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( key1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Keypad 4 x 4( of course if your cable connection and
your program are corrected )

2.8.2. Display Keypad 4 x 4 with LCD Character 2 x16

After doing lesson 2.8.1. you can see that how easy to scan keypad and read
data out to LED. In this lesson it's look like lesson 2.8.2. but the data will read out
with LCD Character 2 x16.
Figure 2.8.3.Keypad Connection to Microcontroller

Step 1st
Build the circuit as shown in figure 2.8.3. As you seen on figure 2.8.2 P3.0 trough
P3.7 is connected to keypad 4 x 4 and LCD Character 2x16 to read keypad data,
connected to P0.0 trough P0.7., P2.0 and P2.1 connected to RS and EN each.

Step 2nd
In this step, you must tipe the assembly program to scan your keypad data, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp282.zip , Download Complete Circuit File :
Keypad4x4.pdf)

;the following experiment is used to scan


;keypad 4x4 and result of scan will be released
;to LCD Character
row1 bit P2.4
row2 bit P2.5
row3 bit P2.6
row4 bit P2.7
col1 bit P2.0
col2 bit P2.1
col3 bit P2.2
col4 bit P2.3
;
keydata equ 70h
keybounc equ 71h
keyport equ P2
org 0h
start: call keypad4x4 ;calling subroutine keypad4x4
Mov A,keydata ;A = keydata
Cjne A,#0FFh,WrLCD;
sjmp start ;LOOPING FOREVER PART 1
;
WrLCD: Mov R1,#80h ;Pick DDRAM 1st row and 1st col
call write_inst
Mov R1,A
call write_data ;write data
Sjmp start ;LOOPING FOREVER PART 2
;
Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
delay: mov R0,#0
delay1:mov R2,#50
djnz R2,$
djnz R0,delay1
ret
;
;====================================
; subroutine scan keypad 4x4
;====================================
Keypad4x4:
mov keybounc,#50 ;keybounc = 50
mov keyport,#0FFh ;keyport=P2= FF
clr col1 ;col1= P3.0 = 0
Detect:jb row1,key1 ;jump to Key1 if row1=1
djnz keybounc,Detect
mov keydata,#00h ;Keydata =00h
ret
;
key1: jb row2,key2 ;jump to key2 if row2=1
djnz keybounc,key1
mov keydata,#04h ;Keydata = 04h
ret
;
key2: jb row3,key3 ; idem
djnz keybounc,key2
mov keydata,#08h
ret
;
key3: jb row4,key4 ; idem
djnz keybounc,key3
mov keydata,#0Ch
ret
;
key4: setb col1
clr col2
jb row1,key5
djnz keybounc,key4
mov keydata,#01h
ret
;
key5: jb row2,key6
djnz keybounc,key5
mov keydata,#05h
ret
;
key6: jb row3,key7
djnz keybounc,key6
mov keydata,#09h
ret
;
key7: jb row4,key8
djnz keybounc,key7
mov keydata,#0Dh
ret
;
key8: setb col2
clr col3
jb row1,key9
djnz keybounc,key8
mov keydata,#02h
ret
;
key9: jb row2,keyA
djnz keybounc,key9
mov keydata,#06h
ret
;
keyA: jb row3,keyB
djnz keybounc,keyA
mov keydata,#0Ah
ret
;
keyB: jb row4,keyC
djnz keybounc,keyB
mov keydata,#0Eh
ret
;
keyC: setb col3
clr col4
jb row1,keyD
djnz keybounc,keyC
mov keydata,#03h
ret
;
keyD: jb row2,keyE
djnz keybounc,keyD
mov keydata,#07h
ret
;
keyE: jb row3,keyF
djnz keybounc,keyE
mov keydata,#0Bh
ret
;
keyF: jb row4,Nokey
djnz keybounc,keyF
mov keydata,#0Fh
ret
Nokey:mov keydata,#0FFh
ret
;================================
;The end of Keypad 4x4 subroutine
;================================
end

Step 3rd
Safe your assembly program above, and name it with key2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( key2.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Keypad 4 x 4 ( of course if your cable connection and
your program are corrected )

2.8.3. Display Keypad 4 x 4 with 8x7 Seven Segmen

Continuing your sucsess, will try your knowledge with more complex experiment
by read out the keypad 4 x 4 data with 8x7 Seven Segmen.
Figure 2.8.4.Keypad Connection to Microcontroller with 8x7 segmen

Step 1st
Build the circuit as shown in figure 2.8.4. As you seen on figure 2.8.4 P3.0 trough
P3.7 is connected to keypad 4 x 4 and 8 x 7 Segmen to read keypad data,
connected to P0.0 trough P0.7., P2.0 and P2.1 connected to RS and EN each.

Step 2nd
In this step, you must tipe the assembly program to scan your keypad data, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File asm : exp283.zip , Download Complete Circuit File
: Keypad4x4.pdf)

;the following experiment is used to scan


;keypad 4x4 and result of scan will be released
;to Display 7 Segmen
row1 bit P2.4
row2 bit P2.5
row3 bit P2.6
row4 bit P2.7
col1 bit P2.0
col2 bit P2.1
col3 bit P2.2
col4 bit P2.3
;
keydata equ 70h
keybounc equ 71h
keyport equ P2
org 0h
start: call keypad4x4 ;calling subrutine keypad4x4
Mov A,keydata ;A = keydata
Cjne A,#0FFh,Wr7Seg;
sjmp start ;LOOPING FOREVER PART 1
;
Wr7Seg:
;================================================
;I left the assembly instruction for you to learn
;=================================================
;
delay: mov R0,#0
delay1:mov R2,#50
djnz R2,$
djnz R0,delay1
ret
;
;====================================
; subroutine scan keypad 4x4
;====================================
Keypad4x4:
mov keybounc,#50 ;keybounc = 50
mov keyport,#0FFh ;keyport=P2= FF
clr col1 ;col1= P3.0 = 0
Detect:jb row1,key1 ;jump to Key1 if row=1
djnz keybounc,Detect
mov keydata,#00h ;Keydata =00h
ret
;
key1: jb row2,key2 ;jump to key2 if row2=1
djnz keybounc,key1
mov keydata,#04h ;Keydata = 04h
ret
;
key2: jb row3,key3 ; idem
djnz keybounc,key2
mov keydata,#08h
ret
;
key3: jb row4,key4 ; idem
djnz keybounc,key3
mov keydata,#0Ch
ret
;
key4: setb col1
clr col2
jb row1,key5
djnz keybounc,key4
mov keydata,#01h
ret
;
key5: jb row2,key6
djnz keybounc,key5
mov keydata,#05h
ret
;
key6: jb row3,key7
djnz keybounc,key6
mov keydata,#09h
ret
;
key7: jb row4,key8
djnz keybounc,key7
mov keydata,#0Dh
ret
;
key8: setb col2
clr col3
jb row1,key9
djnz keybounc,key8
mov keydata,#02h
ret
;
key9: jb row2,keyA
djnz keybounc,key9
mov keydata,#06h
ret
;
keyA: jb row3,keyB
djnz keybounc,keyA
mov keydata,#0Ah
ret
;
keyB: jb row4,keyC
djnz keybounc,keyB
mov keydata,#0Eh
ret
;
keyC: setb col3
clr col4
jb row1,keyD
djnz keybounc,keyC
mov keydata,#03h
ret
;
keyD: jb row2,keyE
djnz keybounc,keyD
mov keydata,#07h
ret
;
keyE: jb row3,keyF
djnz keybounc,keyE
mov keydata,#0Bh
ret
;
keyF: jb row4,Nokey
djnz keybounc,keyF
mov keydata,#0Fh
ret
Nokey:mov keydata,#0FFh
ret
;================================
;The end of Keypad 4x4 subroutine
;================================
end

Step 3rd
Safe your assembly program above, and name it with key3.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( key3.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Keypad 4 x 4 ( of course if your cable connection and
your program are corrected )

3. Timer/ Counter

The MCS-51 has two 16 bit Timer/ Counter register. Timer 0 and Timer 1. Both
can be configured to operate either as timers or event counters ( see figure 3.1. ).
In the Timer function, the register is incremented every mechine cycle.

Figure 3.1. Diagram block Timer/ Counter Operation

As shown in figure 3.1., microcontroller can be used as timer or counter as you


need. The question is, what you have to do, so the microcontroller will act as
timer or counter. See left and right swicht on diagram blog. Microcontroller will
act as timer when swicht position on upper and microcontroller will act as counter
when swicht position on lower by controlling C/T bit on TMOD register. The right
swicht position is depent on BIT GATE ( Register TMOD ), TR1 ( Register TCON
) dan INT1.

Timer/ Counter Mode Control ( TMOD ) Register


TIMER 1 TIMER 0
GATE C/T M1 M0 GATE C/T M1 M0

Gating control when set. Timer/ Counter X is enabled only


GATE
while INTx pin is high and TRx control pin is set
Timer or Counter Selector cleared for Timer operation (input
C/T from internal system clock) and set for counter operation
(input from Tx input pin)

M1 M0 Operating
0 0 8048 Timer, TLx serves as 5 bit prescaler
16 bit Timer/Counter THx and TLx are cascaded, there is
0 1
no prescaler
8 bit auto reaload Timer/ Counter THx holds a value which
1 0
is tobe reloaded into TLx each time it overflows
(Timer 0) TL0 is an 8 bit Timer/ Counter controlled by the
1 1 standard timer 0 control bits
(Timer 1) Timer/ Counter 1 stopped

Timer/ Counter Control ( TCON ) Register

MSB LSB
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

BIT SYMBOL FUNCTION


Timer 1 overflow flag. Set by hardware on
Timer/Counter overflow. Cleared by hardware when
TCON.7 TF1
processor vector to interrupt routine, or clearing the bit
in software.
Timer 1 Run control bit . Set/ cleared by software to
TCON.6 TR1
turn Timer/ Counter on/off
Timer 0 overflow flag. Set by hardware on
Timer/Counter overflow. Cleared by hardware when
TCON.5 TF0
processor vector to interrupt routine, or clearing the bit
in software.
TCON.4 TR0 Timer 1 Run control bit . Set/ cleared by software to
turn Timer/ Counter on/off
Interrupt 1 Edge flag. Set by hardware when external
TCON.3 IE1 interrupt edge detected. Cleared when interrupt
processed.
Interrupt 1 type control bit. Set/ cleared by software to
TCON.2 IT1 specefy falling edge/ low level trigerred external
interupts
Interrupt 0 Edge flag. Set by hardware when external
TCON.1 IE0 interrupt edge detected. Cleared when interrupt
processed.
Interrupt 0 type control bit. Set/ cleared by software to
TCON.0 IT0 specefy falling edge/ low level trigerred external
interupts

3.1. Timer/ Counter Mode 0 : 13 bit Counter

Putting either Timer into Mode 0 makes it look like an 8048 Timer, which is an 8-
bit Counter with a divide-by-32 prescaler. Figure 7 shows the Mode 0 operation
as it applies to Timer 1. In this mode, the Timer register is configured as a 13-bit
register. As the count rolls over from all 1s to all 0s, it sets the Timer interrupt flag
TF1. The counted input is enabled to the Timer when TR1 = 1 and either GATE =
0 or INT1 = 1. (Setting GATE = 1 allows the Timer to be controlled by external
input INT1, to facilitate pulse width measurements). TR1 is a control bit in the
Special Function Register TCON (Figure 8). GATE is in TMOD.

Figure 3.1. Timer/Counter Mode 0: 13-Bit Counter


The 13-bit register consists of all 8 bits of TH1 and the lower 5 bits of TL1. The
upper 3 bits of TL1 are indeterminate and should be ignored. Setting the run flag
(TR1) does not clear the registers. Mode 0 operation is the same for the Timer 0
as for Timer 1. Substitute TR0, TF0, and INT0 for the corresponding Timer 1
signals in Figure 7. There are two different GATE bits, one for Timer 1 (TMOD.7)
and one for Timer 0 (TMOD.3).

3.1.1 Generate pulse by using Timer 1 in mode 0

By using Timer function, we can design a pulse generator and outputs data to
port. as you see on figure 3.3.1., with frequency 1 Hz

Step 1st
Build the circuit as shown in figure 3.1.1. As you seen on figure 3.1.1. P0.0 is
connected to LED. Remember, that all we want to do with this lesson is generate
a pulse with frequency 1 Hz

Step 2nd
In this step, you must tipe the assembly program to make your Timer get action,
we assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp311.zip )

Figure 3.1.1. A pulse generator from timer function


Figure 3.1.2. Pulse Periode 1 second

This program initialized counter/timer 1 to be a timer operating in mode 0, that is


a 13 bit timer. When the timer overflows, the hardware sets the flag TF1. The
program spends most of its time checking whether the timer overflow flag TF0 is
set. Note that in this mode, with a 12 MHz crystal frequency, the timer overflows
every 8192 microseconds.
In this experiment, to generate interruption every 1000 micro second, then :
8192 - 5000 = 3192d or 0C78h
Interruption will come out every 5000 x 1 microsecond = 0,005 second.
R0 is implemented as a software counter, Register R0 is incremented every
Timer 0 overflows. If Register R7 detected with value 100 then port P0.0 will
output data with Ton = 0,005 x 100 second = 0,5 second.

Org 0h
Start: Setb P0.0 ;P0.0 = 1
call Delay ;call delay time
Clr P0.0 ;P0.0 = 0
Sjmp Start ;Looping Forever
;
Delay: Mov R0,#0 ;R0 = 0
Mov TMOD,#00000000b ;mode 1, Timer 1
Load: Mov TH1, #00Ch ;TH1 = D8h
Mov TL1, #078h ; TL1 = F0h
Setb TR1 ; TR1 = 1, Start Running
OFlow: JNB TF1, OFlow ; jump to OFlow if TF1 =0
Inc R0 ; R0 = R0+1
CJNE R0,#100,Load;
Ret
;
End

Step 3rd
Safe your assembly program above, and name it with timer1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( timer1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Timer( of course if your cable connection and your
program are corrected ).

3.2. Timer/ Counter Mode 1 : 16 bit Counter

Mode 1 is the same as Mode 0, except that the Timer register is being run with
all 16 bits.
Figure 3.2. Timer/Counter Mode 1: 16-Bit Counter

3.2.1. Generate pulse by using Timer 1 mode 1

By using Timer function, we can design a pulse generator and outputs data to
port. as you see on figure 3.3.1., with frequency 1 Hz

Step 1st
Build the circuit as shown in figure 3.2.1. As you seen on figure 3.2.1. P0.0 is
connected to LED. Remember, that all we want to do with this lesson is generate
a pulse with frequency 1 Hz

Step 2nd
In this step, you must tipe the assembly program to make your Timer get action,
we assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp32.zip )
Figure 3.2.1. A pulse generator from timer function

Figure 3.2.2. Pulse Periode 1 second

Note that in this mode, with a 12 MHz crystal frequency, the timer overflows
every 65,536 microseconds.
In this experiment, to generate interruption every 1000 micro second, then :
65536 - 10000 = 55536 d or D8F0h
Interruption will come out every 1000 x 1 microsecond = 0.01 second.
R0 is implemented as a software counter, Register R0 is incremented every
Timer 0 overflows. If Register R7 detected with value 50 then port P0.0 will
output data with Ton = 0,01 x 50 second = 0,5 second.

Org 0h
Start: Setb P0.0 ;P0.0 = 1
call Delay ;call delay time
Clr P0.0 ;P0.0 = 0
Sjmp Start ;Looping Forever
;
Delay: Mov R0,#0 ;R0 = 0
Mov TMOD,#00010000b ;mode 1, Timer 1
Load: Mov TH1, #0D8h ;TH1 = D8h
Mov TL1, #0F0h ; TL1 = F0h
Setb TR1 ; TR1 = 1, Start Running
OFlow: JNB TF1, OFlow ; jump to OFlow if TF1 =0
Inc R0 ; R0 = R0+1
CJNE R0,#50,Load;
Ret
;
End

Step 3rd
Safe your assembly program above, and name it with timer2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( timer2.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Timer( of course if your cable connection and your
program are corrected ).

3.3. Timer/ Counter Mode 2 : 8 bit Auto Reload

Mode 2 configures the Timer register as an 8-bit Counter (TL1) with automatic
reload, as shown in Figure 9. Overflow from TL1 not only sets TF1, but also
reloads TL1 with the contents of TH1, which is preset by software. The reload
leaves TH1 unchanged.

Figure 3.3. Timer/Counter Mode 1: 16-Bit Counter

Mode 2 operation is the same for Timer/Counter 0.

3.4. Timer/ Counter Mode 3 : Two 8 bit counter


Timer 1 in Mode 3 simply holds its count. The effect is the same as setting
TR1=0.

Figure 3.4. 1. Timer/ Counter 1 mode 3

Timer 0 in Mode 3 establishes TL0 and TH0 as two separate counters. The logic
for Mode 3 on Timer 0 is shown in Figure 10. TL0 uses the Timer 0 control bits:
C/T, GATE, TR0, INT0, and TF0. TH0 is locked into a timer function (counting
machine cycles) and takes over the use of TR1 and TF1 from Timer 1. Thus,
TH0 now controls the Timer 1 interrupt.
Mode 3 is provided for applications requiring an extra 8-bit timer on the counter.
With Timer 0 in Mode 3, an 80C51 can look like it has three Timer/Counters.
When Timer 0 is in Mode 3, Timer 1 can be turned on and off by switching it out
of and into its own Mode 3, or can still be used by the serial port as a baud rate
generator, or in fact, in any application not requiring an interrupt.

3.4.1. Timer/ Counter acts as Counter Mode 3 with output LED

A simple way to detect wheater the counter counting or not is by using 8 LED as
output of P0.0 trough P0.7.
Figure 3.4.1. Get data counter out to LED

Step 1st
Build the circuit as shown in figure 3.4.1. As you seen on figure 3.4.1. P0.0
trough P0.7 is connected to LED. Remember, that all we want to do with this
lesson is count the pulse and display to LED

Step 2nd
In this step, you must tipe the assembly program to make your Timer get action,
we assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp341.zip )

org 0h
Start: Mov TMOD,#01110000b ; mode 3 counter 8 bit timer 1
Setb TR1 ; TR1 = 1, start counting
Get: Mov A, TL1 ; A = TL1
CPL A
Mov P1, A ; P1 = A
Sjmp Get ; Looping Forever
End

Step 3rd
Safe your assembly program above, and name it with timer3.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( timer3.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Timer( of course if your cable connection and your
program are corrected ).

Serial Port Control ( SCON ) Register

MSB LSB
SM0 SM1 SM2 REN TB8 RB8 TI RI

Where SM0, SM1 specify the serial port mode, as follows

SM0 SM1 Mode Description Baud Rate


0 0 0 Shif Register fosc/ 12
0 1 1 8 bit UART variable
1 0 2 9 bit UART fosc/64 fosc/32
1 1 3 9 bit UART variable

Note:
Enables the multiprocessor communication feature in Modes 2 and
3. In Mode 2 or 3, if SM2 is set to 1, then Rl will not be activated if
SM2 the received 9th data bit (RB8) is 0. In Mode 1, if SM2=1 then RI will
not be activated if a valid stop bit was not received. In Mode 0, SM2
should be 0.
Enables serial reception. Set by software to enable reception. Clear
REN
by software to disable reception.
The 9th data bit that will be transmitted in Modes 2 and 3. Set or
TB8
clear by software as desired.
In Modes 2 and 3, is the 9th data bit that was received. In Mode 1, it
RB8 SM2=0, RB8 is the stop bit that was received. In Mode 0,
RB8 is not used.
Transmit interrupt flag. Set by hardware at the end of the 8th bit time
TI in Mode 0, or at the beginning of the stop bit in the other modes, in
any serial transmission. Must be cleared by software.
Receive interrupt flag. Set by hardware at the end of the 8th bit time
RI in Mode 0, or halfway through the stop bit time in the other modes, in
any serial reception (except see SM2). Must be cleared by software.

3.4.2. Timer/ Counter acts as Counter Mode 3 with output LCD Char.
In this lesson will do, the experiment more complicated with LCD character to
see number of pulse into timer 1.

Figure 3.4.2. Get data counter out to LED

Step 1st
Build the circuit as shown in figure 3.4.2. As you seen on figure 3.4.2. P0.0
trough P0.7 is connected to LCD Character . Remember, that all we want to do
with this lesson is count the pulse and display to LCD Character 2 x 16

Step 2nd
In this step, you must tipe the assembly program to make your Timer get action,
we assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp342.zip )

Hundreds equ 70h


Tens equ 71h
ones equ 72h
;
Org 0h
setb p3.1
Start: Mov TMOD,#01110000b
setb tr1
call init_lcd
call printword
get: mov a,tl1

call Convert
call PrintChar
sjmp Get
;
Convert:
mov b,#100d
div ab
mov Hundreds,a
mov a,b
mov b,#10d
div ab
mov Tens,a
mov Ones,b
ret
;
PrintChar:
mov r1,#0c9h
acall write_inst
mov a,Hundreds
add a,#30h
mov r1,a
acall write_data
mov r1,#0cah
acall write_inst
mov a,Tens
add a,#30h
mov r1,a
acall write_data
mov r1,#0cbh
acall write_inst
mov a,Ones
add a,#30h
mov r1,a
acall write_data
ret
;
printword:
mov dptr,#myword
mov r3,#8
mov r1,#0c0h
call write_inst
CountW:clr a
movc a,@a+dptr
mov r1,A
inc dptr
acall write_data
djnz r3,CountW
ret
;
Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
;
delay: mov R0,#0
delay1:mov R7,#0fh
djnz R7,$
djnz R0,delay1
ret
myWord:
DB 'Data counter :'
end

Step 3rd
Safe your assembly program above, and name it with timer4.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.
Step 4th
Download your hex file ( timer4.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Timer( of course if your cable connection and your
program are corrected ).

4. Standard Serial Interface


The serial port is full duplex, meaning it can transmit and receive simultaneously.
It is also receive-buffered, meaning it can commence reception of a second byte
before a previously received byte has been read from the register. (However, if
the first byte still hasnt been read by the time reception of the second byte is
complete, one of the bytes will be lost.) The serial port receive and transmit
registers are both accessed at Special Function Register SBUF. Writing to SBUF
loads the transmit register, and reading SBUF accesses a physically separate
receive register.

Figure 4.1. Standard serial communication

The serial port can operate in 4 modes:

Mode 0:
Serial data enters and exits through RxD. TxD outputs the shift clock. 8 bits are
transmitted/received (LSB first). The baud rate is fixed at 1/12 the oscillator
frequency.
Mode 1:
10 bits are transmitted (through TxD) or received (through RxD): a start bit (0), 8
data bits (LSB first), and a stop bit (1). On receive, the stop bit goes into RB8 in
Special Function Register SCON. The baud rate is variable.

Mode 2:
11 bits are transmitted (through TxD) or received (through RxD): start bit (0), 8
data bits (LSB first), a programmable 9th data bit, and a stop bit (1). On Transmit,
the 9th data bit (TB8 in SCON) can be assigned the value of 0 or 1. Or, for
example, the parity bit (P, in the PSW) could be moved into TB8. On receive, the
9th data bit goes into RB8 in Special Function Register SCON, while the stop bit
is ignored. The baud rate is programmable to either 1/32 or 1/64 the oscillator
frequency.

Mode 3:
11 bits are transmitted (through TxD) or received (through RxD): a start bit (0), 8
data bits (LSB first), a programmable 9th data bit, and a stop bit (1). In fact,
Mode 3 is the same as Mode 2 in all respects except baud rate. The baud rate in
Mode 3 is variable.

In all four modes, transmission is initiated by any instruction that uses SBUF as a
destination register. Reception is initiated in Mode 0 by the condition RI = 0 and
REN = 1. Reception is initiated in the other modes by the incoming start bit if
REN = 1.

Serial Port Control Register


The serial port control and status register is the Special Function Register SCON,
shown in Figure 11. This register contains not only the mode selection bits, but
also the 9th data bit for transmit and receive (TB8 and RB8), and the serial port
interrupt bits (TI and RI).

Baud Rates
The baud rate in Mode 0 is fixed: Mode 0 Baud Rate = Oscillator Frequency / 12.
The baud rate in Mode 2 depends on the value of bit SMOD in Special Function
Register PCON. If SMOD = 0 (which is the value on reset), the baud rate is 1/64
the oscillator frequency. If SMOD = 1, the baud rate is 1/32 the oscillator
frequency. Baud Rate mode 2:

,
In the 80C51, the baud rates in Modes 1 and 3 are determined by the Timer 1
overflow rate.

Using Timer 1 to Generate Baud Rates


When Timer 1 is used as the baud rate generator, the baud rates in Modes 1 and
3 are determined by the Timer 1 overflow rate and the value of SMOD as follows:
Baud Rate Mode 1,3

The Timer 1 interrupt should be disabled in this application. The Timer itself can
be configured for either timer or counter operation, and in any of its 3 running
modes. In the most typical applications, it is configured for timer operation, in
the auto-reload mode (high nibble of TMOD = 0010B). In that case the baud rate
is given by the formula: Baud Rate Mode 1,3

One can achieve very low baud rates with Timer 1 by leaving the Timer 1
interrupt enabled, and configuring the Timer to run as a 16-bit timer (high nibble
of TMOD = 0001B), and using the Timer 1 interrupt to do a 16-bit software
reload. Figure 12 lists various commonly used baud rates and how they can be
obtained from Timer 1.

5.1. Interrupt

The 80C51 provides 5 interrupt sources. These are shown in Figure 17. The
External Interrupts INT0 and INT1 can each be either level-activated or
transition-activated, depending on bits IT0 and IT1 in Register TCON. The flags
that actually generate these interrupts are bits IE0 and IE1 in TCON. When an
external interrupt is generated, the flag that generated it is cleared by the
hardware when the service routine is vectored to only if the interrupt was
transition-activated. If the interrupt was level-activated, then the external
requesting source is what controls the request flag, rather than the on-chip
hardware.

The Timer 0 and Timer 1 Interrupts are generated by TF0 and TF1, which are set
by a rollover in their respective Timer/Counter registers (except see Timer 0 in
Mode 3). When a timer interrupt is generated, the flag that generated it is cleared
by the on-chip hardware when the service routine is vectored to.

The Serial Port Interrupt is generated by the logical OR of RI and TI. Neither of
these flags is cleared by hardware when the service routine is vectored to. In
fact, the service routine will normally have to determine whether it was RI or TI
that generated the interrupt, and the bit will have to be cleared in software.

All of the bits that generate interrupts can be set or cleared by software, with the
same result as though it had been set or cleared by hardware. That is, interrupts
can be generated or pending interrupts can be canceled in software.
Each of these interrupt sources can be individually enabled or disabled by setting
or clearing a bit in Special Function Register IE (Figure 18). IE also contains a
global disable bit, EA, which disables all interrupts at once.

Priority Level Structure


Each interrupt source can also be individually programmed to one of two priority
levels by setting or clearing a bit in Special Function

Register IP (Figure 19). A low-priority interrupt can itself be interrupted by a high-


priority interrupt, but not by another low-priority interrupt. A high-priority interrupt
cant be interrupted by any other interrupt source.

If two request of different priority levels are received simultaneously, the request
of higher priority level is serviced. If requests of the same priority level are
received simultaneously, an internal polling sequence determines which request
is serviced. Thus within each priority level there is a second priority structure
determined by the polling sequence as follows:

Source Priority Within Level


1. IE0 (highest)
2. TF0
3. IE1
4. TF1
5. RI+TI (lowest)

Note that the priority within level structure is only used to resolve simultaneous
requests of the same priority level. The IP register contains a number of
unimplemented bits. IP.7, IP.6, and IP.5 are reserved in the 80C51. User
software should not write 1s to these positions, since they may be used in other
8051 Family products.

Interrupt Enable Registe ( IE )

MSB LSB
EA X X ES ET1 EX1 ET0 EX0

BIT SYMBOL FUNCTION


Disables all interrupts. If EA=0, no interrupt will be
acknowledged. If EA=1, each interrupt source is
IE.7 EA
individually enabled or disabled by setting or clearing its
enable bit.
IE.6 - -
IE.5 - -
IE.4 ES Enables or disables the Serial Port interrupt. If ES=0,
the Serial Port interrupt is disabled.
Enables or disables the Timer 1 Overflow interrupt. If
IE.3 ET1
ET1=0, the Timer 1 interrupt is disabled.
Enables or disables External Interrupt 1. If EX1=0,
IE.2 EX1
External interrupt 1 is disabled.
Enables or disables the Timer 0 Overflow interrupt. If
IE.1 ET0
ET0=0, the Timer 0 interrupt is disabled.
Enables or disables External interrupt 0. If EX0=0,
IE.0 EX0
External interrupt 0 is disabled.

Interrupt Priority Register ( IP )

MSB LSB
X X X PS PT1 PX1 PT0 PX0

Note:
BIT SYMBOL FUNCTION
IP.7 - -
IP.6 - -
IP.5 - -
Defines the Serial Port interrupt priority level. PS=1
IP.4 PS
programs it to the higher priority level.
Defines the Timer 1 interrupt priority level. PT1=1
IP.3 PT1
programs it to the higher priority level.
Defines the External Interrupt 1 priority level. PX1=1
IP.2 PX1
programs it to the higher priority level.
Enables or disables the Timer 0 interrupt priority level.
IP.1 PT0
PT0=1 programs it to the higher priority level.
Defines the External Interrupt 0 priority level. PX0=1
IP.0 PX0
programs it to the higher priority level.

Source Vector Address


IE0 0003H
TF0 000BH
IE1 0013H
TF1 001BH
RI + TI 0023H

4.1. Basic Turn LED On-Off Serially- RS232 Serial

This experimen is a basic thing you shoul to know, how to convert data serial to
parallel, in this case you may need Basic serial RS232 Communication to learn.

Figure 4.1. Turn On and Off LED


Step 1st
Build the circuit as shown in figure 4.1. As you seen on figure 4.1. Remember,
that all we want to do with this lesson is send data out trough PC serially, to turn
off and on LED.

Step 2nd
In this step, you must tipe the assembly program to make your serial working, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File asm and hex : testingLED.zip )

org 0h
nop
call initserial
gets: call inchar
mov P2,a
sjmp gets
;
initserial:
mov scon,#52h
mov tmod,#20h
mov th1,#-13
setb tr1
ret
;
inchar:
detect: jnb ri,detect;
clr ri
mov a,sbuf
ret
;
End

To get the data from microcontroller serially, computer must run the program to
get data from port communication RS232, in this experiment I have been used
Delphi programming: ( Download File Delphi : testingLED.zip )

(a)
(b)
Figure 4.2. Delphi Programming to Turn off and On

var
Form1: TForm1;
data,status:byte;
const
base = $3f8;{base address port serial}
lcr = 3; {line control register}
dll = 0; {divisor lacht low byte}
dlh = 1; {divisor lacht high byte}
lsr = 5; {line status register}

Procedure Initserial;
begin
asm
mov dx,base+lcr; {address line control register}
mov al,$80 ; {10000000b = access bit divisor lacht}
out dx,al
;
mov dx,base+dll; {address divisor lacht low byte}
mov al,$30 ; {DLLB = 30h}
out dx,al
;
mov dx,base+dlh; {address divisor lacht high byte}
mov al,$00 ; {DLLH = 00h}
out dx,al
; {In this case Port Serial have}
; { baud rate = 2400 bps}
mov dx,base+lcr;{address line control register}
mov al,$03 ; {00000011b =}
out dx,al ; {bit 7=0, access to Rx buffer & Tx
; {bit 6=0, set break disable
; {bit 5-4-3=000, no parity
; {bit 2=0, one stop bit
; {bit 1-0=11,data lenght 8 bit}
end;
end;

Procedure Send_Data_Serial;
begin
asm
mov dx,base
mov al,data
out dx,al
end
end;

procedure TForm1.FormCreate(Sender: TObject);


begin
Initserial;
end;

procedure TForm1.Button1Click(Sender: TObject);


begin
repeat
asm
mov dx,base+lsr ; {address line status register }
in al,dx
and al,$20 ; {00100000b =not masking bit 5}
mov status,al ; {bit5=Empty Transmitting holding reg}
end;
until status = $20;{If ETHR = 1 then data ready tobe send }
data:=0;
Send_Data_Serial;
end;

procedure TForm1.Button2Click(Sender: TObject);


begin
repeat
asm
mov dx,base+lsr; {address line status register }
in al,dx
and al,$20 ; {00100000b =not masking bit 5}
mov status,al ; {bit5=Empty Transmitting holding reg}
end;
until status = $20; { If ETHR = 1 then data ready tobe send}
data:=1;
Send_Data_Serial;
end;

;{do the same instruction for 2, 4, 6, 8, 16, 32, 64, 128 }

procedure TForm1.Button10Click(Sender: TObject);


begin
repeat
asm
mov dx,base+lsr ; {address line status register }
in al,dx
and al,$20 ; {00100000b =not masking bit 5}
mov status,al ; {bit5=Empty Transmitting holding reg}
end;
until status = $20; { If ETHR = 1 then data ready tobe send }
data:=255;
Send_Data_Serial;
end;
Step 3rd
Safe your assembly program above, Compile the program that you have been
save by using MIDE-51, see the software instruction.

Step 4th
Download your hex file (testingLED.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of serial transmition( of course if your cable connection
and your program are corrected ).

4.2. Controlling Rotation of LED Serially - RS232 Serial

Standart communication using serial data RS232 is very efective way to minimize
cable connection. This experiment will be done to arrange the rotation direction
of LED by using DELPHI Programming and conducted serially.

Figure 4.1. Sending Command to LED

Step 1st
Build the circuit as shown in figure 4.1. As you seen on figure 4.1. Remember,
that all we want to do with this lesson is send data out trough PC serially, to
direct LED rotation.

Step 2nd
In this step, you must tipe the assembly program to make your serial working, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File asm and hex : rotateRL.zip, Download Complete
Circuit File : SerialLED.PDF )

org 0h
nop
call initserial
gets:call inchar
cjne a,#1,rotR
sjmp rotL
sjmp gets
;
rotR:mov P2,#11111110b;
call delay
mov P2,#11111101b;
call delay ;
mov P2,#11111011b;
call delay ;
mov P2,#11110111b;
call delay ;
mov P2,#11101111b;
call delay ;
mov P2,#11011111b;
call delay ;
mov P2,#10111111b;
call delay ;
mov P2,#01111111b;
call delay ;
sjmp gets
;
rotL:mov P2,#01111111b;
call delay
mov P2,#10111111b;
call delay ;
mov P2,#11011111b;
call delay ;
mov P2,#11101111b;
call delay ;
mov P2,#11110111b;
call delay ;
mov P2,#11111011b;
call delay ;
mov P2,#11111101b;
call delay ;
mov P2,#11111110b;
call delay ;
sjmp gets
;
initserial:
mov scon,#52h ;serial mode 1 configuration
mov tmod,#20h ; Baud rate 2400 BPS
mov th1,#-13
setb tr1
ret
;
inchar:
detect: jnb ri,detect;detecting do data have been accepted or not yet.
clr ri
mov a,sbuf
ret
;

delay:
MOV R7,#00H
again2: MOV R6,#00H
again1: MOV R5,#00H
again: INC R5
CJNE R5,#50H,again
INC R6
CJNE R6,#50H,again1
INC R7
CJNE R7,#50H,again2
RET

;
End

To get the data from microcontroller serially, computer must run the program to
get data from port communication RS232, in this experiment I have been used
Delphi programming: ( Download File Delphi : rotateLED.zip )

(a)

(b)
Figure 4.2. Delphi Programming for Left or Right Rotate

var
Form1: TForm1;
data,status:byte;
const
base = $3f8;{base address port serial}
lcr = 3; {line control register}
dll = 0; {divisor lacht low byte}
dlh = 1; {divisor lacht high byte}
lsr = 5; {line status register}

Procedure Initserial;
begin
asm
mov dx,base+lcr; {address line control register}
mov al,$80 ; {10000000b = access bit divisor lacht}
out dx,al
;
mov dx,base+dll; {address divisor lacht low byte}
mov al,$30 ; {DLLB = 30h}
out dx,al
;
mov dx,base+dlh; {address divisor lacht high byte}
mov al,$00 ; {DLLH = 00h}
out dx,al
; {In this case Port Serial have}
; { baud rate = 2400 bps}
mov dx,base+lcr;{address line control register}
mov al,$03 ; {00000011b =}
out dx,al ; {bit 7=0, access to Rx buffer & Tx
; {bit 6=0, set break disable
; {bit 5-4-3=000, no parity
; {bit 2=0, one stop bit
; {bit 1-0=11,data lenght 8 bit}
end;
end;

Procedure Send_Data_Serial;
begin
asm
mov dx,base
mov al,data
out dx,al
end
end;

procedure TForm1.FormCreate(Sender: TObject);


begin
Initserial;
end;

procedure TForm1.Button1Click(Sender: TObject);


begin
repeat
asm
mov dx,base+lsr ; {address line status register }
in al,dx
and al,$20 ; {00100000b =not masking bit 5}
mov status,al ; {bit5=Empty Transmitting holding reg}
end;
until status = $20; { If ETHR = 1 then data ready tobe send }
data:=0;
Send_Data_Serial;
end;

procedure TForm1.Button2Click(Sender: TObject);


begin
repeat
asm
mov dx,base+lsr; {address line status register }
in al,dx
and al,$20 ; {00100000b =not masking bit 5}
mov status,al ; {bit5=Empty Transmitting holding reg}
end;
until status = $20; { If ETHR = 1 then data ready tobe send}
data:=1;
Send_Data_Serial;
end;

Step 3rd
Safe your assembly program above, Compile the program that you have been
save by using MIDE-51, see the software instruction.

Step 4th
Download your hex file (rotateRL.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of serial transmition( of course if your cable connection
and your program are corrected ).

4.3. Taking data of DIP Swicht serially.- Serial RS232

Communication standart using serial data RS232 is very efective way to


minimize cable connection. This experiment, will be done by intake of data of DIP
Swicht serially with using serial data communications RS232.
Figure 4.1. Sending data DIP swicht serially to PC

Step 1st
Build the circuit as shown in figure 4.1. As you seen on figure 4.1. Remember,
that all we want to do with this lesson is take data DIP SW trough PC serially.

Step 2nd
In this step, you must tipe the assembly program to make your serial working, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File asm and hex : dip_sw.zip, Download File
Complete Circuit File : SerialDipSW)

org 0h
nop
call initserial
gets: call inchar
mov P2,a
sjmp gets
;
initserial:
mov scon,#52h
mov tmod,#20h
mov th1,#-13
setb tr1
ret
;
inchar:
detect: jnb ri,detect;
clr ri
mov a,sbuf
ret
;
End

To get the data from microcontroller serially, computer must run the program to
get data from port communication RS232, in this experiment I have been used
Delphi programming: ( Download File Delphi : dipsw.zip )

(a)

(b)
Figure 4.2. Delphi Programming Display Data DIP SW

var
Form1: TForm1;
data,status:byte;
const
base = $3f8;{base address port serial}
lcr = 3; {line control register}
dll = 0; {divisor lacht low byte}
dlh = 1; {divisor lacht high byte}
lsr = 5; {line status register}

Procedure Initserial;
begin
asm
mov dx,base+lcr; {address line control register}
mov al,$80 ; {10000000b = access bit divisor lacht}
out dx,al
;
mov dx,base+dll; {address divisor lacht low byte}
mov al,$30 ; {DLLB = 30h}
out dx,al
;
mov dx,base+dlh; {address divisor lacht high byte}
mov al,$00 ; {DLLH = 00h}
out dx,al
; {In this case Port Serial have}
; { baud rate = 2400 bps}
mov dx,base+lcr;{address line control register}
mov al,$03 ; {00000011b =}
out dx,al ; {bit 7=0, access to Rx buffer & Tx
; {bit 6=0, set break disable
; {bit 5-4-3=000, no parity
; {bit 2=0, one stop bit
; {bit 1-0=11,data lenght 8 bit}
end;
end;
;
Procedure Receive_Data_Serial;
begin
asm
mov dx,base
in al,dx
mov data,al
end
end;
;
procedure TForm1.FormCreate(Sender: TObject);
begin
Initserial;
end;

procedure TForm1.Button1Click(Sender: TObject);


begin
initserial;
timer1.enabled:=true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Repeat
asm
mov dx,base+lsr; { address line status register }
in al,dx
and al,$01 ; {LSR = 00000001b, deteksi bit 0}
mov status,al ; {bit 0 = data ready}
end;
until status = $01 ;{ jika bit 0 = 1 then data ready}
Receive_Data_Serial;
edit1.text:=inttostr(data);
end;

Step 3rd
Safe your assembly program above, Compile the program that you have been
save by using MIDE-51, see the software instruction.
Step 4th
Download your hex file (dip_sw.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of serial transmition( of course if your cable connection
and your program are corrected ).

4.4. Send ADC data to PC serially - RS 232

This experiment is very good for the process of data acquisition for the process
of measurement of long distance serially. You should learn more about Serial
communication RS232.

Figure 4.1. Sending ADC data serially to PC

Step 1st
Build the circuit as shown in figure 4.1. As you seen on figure 4.1. Remember,
that all we want to do with this lesson is send out ADC data to PC serially.

Step 2nd
In this step, you must tipe the assembly program to make your serial working, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp41.zip , Download Complete Circuit File :
SerialADC.PDF )

org 0h
call initserial
;
start: mov a,p2; ambil data dari adc
call Sendout
sjmp start
;
Sendout:
detect: jnb ti,detect;
clr ti ;
mov sbuf,a ;
ret
;
initserial:
mov scon,#52h;initialize serial mode 1
mov tmod,#20h;timer1 mode 2
mov th1,#0F3h;Reload value for baud rate 2400
setb tr1
ret
end

To get the data from microcontroller serially, computer must run the program to
get data from port communication RS232, in this experiment I have been used
Delphi programming: ( Download Delphi File : adcserial.zip )

Figure 4.2. Delphi Programming Display Data ADC

unit serial1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
data,status:byte;
const
base = $3f8;{base address port serial}
lcr = 3; {line control register}
dll = 0; {divisor lacht low byte}
dlh = 1; {divisor lacht high byte}
lsr = 5; {line status register}
implementation
{$R *.DFM}
Procedure Initserial;
begin
asm
mov dx,base+lcr; {address line control register}
mov al,$80 ; {10000000b = access bit divisor lacht}
out dx,al
;
mov dx,base+dll; {address divisor lacht low byte}
mov al,$30 ; {DLLB = 30h}
out dx,al
;
mov dx,base+dlh; {address divisor lacht high byte}
mov al,$00 ; {DLLH = 00h}
out dx,al
; {Pada saat ini Port serial}
; {memp.baud rate = 2400 bps}
mov dx,base+lcr;{address line control register}
mov al,$03 ; {00000011b =}
out dx,al ; {bit 7=0, access to Rx buffer & Tx
; {bit 6=0, set break disable
; {bit 5-4-3=000, no parity
; {bit 2=0, one stop bit
; {bit 1-0=11,data lenght 8 bit}
end;
end;
Procedure Receive_Data_Serial;
begin
asm
mov dx,base
in al,dx
mov data,al
end
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
initserial;
timer1.enabled:=true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Repeat
asm
mov dx,base+lsr ; { address line status register }
in al,dx
and al,$01 ; {LSR = 00000001b, detects bit 0}
mov status,al ; {bit 0 = data ready}
end;
until status = $01;{ jika bit 0 = 1 then data ready}
Receive_Data_Serial;
edit1.text:=inttostr(data);
end;

end.

Step 3rd
Safe your assembly program above, and name it with exp41.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( exp41.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of serial transmition( of course if your cable connection
and your program are corrected ).

4.5. Writing a char serially from PC to LCD Character 2x16

This experiment will be done for process to print character out to LCD Character,
in this experiment the delivery is just for one character, you need to modify to
write more character. You should learn more about Serial communication RS232.

Figure 4.2. Transmit data serially to LCD Character


Step 1st
Build the circuit as shown in figure 4.2. As you seen on figure 4.2. Remember,
that all we want to do with this lesson transmit.

Step 2nd
In this step, you must tipe the assembly program to make your serial working, we
assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File asm : exp42.zip ,Download Complete Circuit File :
SerialLCD.PDF )

org 0h
call initserial
call init_LCD
;
start: call GetChar
mov r1,#0c0h
acall write_inst
add a,#30h
mov r1,a
acall write_data
sjmp start
;
GetChar:
detect: jnb ri,detect ;
clr ri
mov a,sbuf
ret
;
initserial:
mov scon,#52h;initialize serial mode 1
mov tmod,#20h;timer1 mode 2
mov th1,#0F3h;Reload value for baud rate 2400
setb tr1
ret
;
Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
delay: mov R0,#0
delay1:mov R7,#0fh
djnz R7,$
djnz R0,delay1
ret
end
;

To get the data from microcontroller serially, computer must run the program to
get data from port communication RS232, in this experiment I have been used
Delphi programming: ( Download File Delphi : LCDserial.zip )

Figure 4.3. Delphi Programming Sends Data to LCD Character

unit sendlcd2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Timer1: TTimer;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
data,status:byte;
const
base = $3f8;{base address port serial}
lcr = 3; {line control register}
dll = 0; {divisor lacht low byte}
dlh = 1; {divisor lacht high byte}
lsr = 5; {line status register}
implementation
{$R *.DFM}
Procedure Initserial;
begin
asm
mov dx,base+lcr; {address line control register}
mov al,$80 ; {10000000b = access bit divisor lacht}
out dx,al
;
mov dx,base+dll; {address divisor lacht low byte}
mov al,$30 ; {DLLB = 30h}
out dx,al
;
mov dx,base+dlh; {address divisor lacht high byte}
mov al,$00 ; {DLLH = 00h}
out dx,al
; {Pada saat ini Port serial}
; {memp.baud rate = 2400 bps}
mov dx,base+lcr; {address line control register}
mov al,$03 ; {00000011b =}
out dx,al ; {bit 7=0, access to Rx buffer & Tx
; {bit 6=0, set break disable
; {bit 5-4-3=000, no parity
; {bit 2=0, one stop bit
; {bit 1-0=11,data lenght 8 bit}
end;
end;
Procedure Send_Data_Serial;
begin
asm
mov dx,base
mov al,data
out dx,al
end
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Initserial;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
repeat
asm
mov dx,base+lsr ; {address line status register }
in al,dx
and al,$20 ; {00100000b =not masking bit 5}
mov status,al ; {bit5=Empty Transmitting holding reg}
end;
until status = $20;{If ETHR=1 then data ready tobe send }
data:=strtoint(edit1.text);
Send_Data_Serial;
end;

end.

Step 3rd
Safe your assembly program above, and name it with seri2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( exp42.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of serial transmition( of course if your cable connection
and your program are corrected ).

5.1. Interrupt

The 80C51 provides 5 interrupt sources. These are shown in Figure 17. The
External Interrupts INT0 and INT1 can each be either level-activated or
transition-activated, depending on bits IT0 and IT1 in Register TCON. The flags
that actually generate these interrupts are bits IE0 and IE1 in TCON. When an
external interrupt is generated, the flag that generated it is cleared by the
hardware when the service routine is vectored to only if the interrupt was
transition-activated. If the interrupt was level-activated, then the external
requesting source is what controls the request flag, rather than the on-chip
hardware.

The Timer 0 and Timer 1 Interrupts are generated by TF0 and TF1, which are set
by a rollover in their respective Timer/Counter registers (except see Timer 0 in
Mode 3). When a timer interrupt is generated, the flag that generated it is cleared
by the on-chip hardware when the service routine is vectored to.

The Serial Port Interrupt is generated by the logical OR of RI and TI. Neither of
these flags is cleared by hardware when the service routine is vectored to. In
fact, the service routine will normally have to determine whether it was RI or TI
that generated the interrupt, and the bit will have to be cleared in software.

All of the bits that generate interrupts can be set or cleared by software, with the
same result as though it had been set or cleared by hardware. That is, interrupts
can be generated or pending interrupts can be canceled in software.

Each of these interrupt sources can be individually enabled or disabled by setting


or clearing a bit in Special Function Register IE (Figure 18). IE also contains a
global disable bit, EA, which disables all interrupts at once.
Priority Level Structure
Each interrupt source can also be individually programmed to one of two priority
levels by setting or clearing a bit in Special Function

Register IP (Figure 19). A low-priority interrupt can itself be interrupted by a high-


priority interrupt, but not by another low-priority interrupt. A high-priority interrupt
cant be interrupted by any other interrupt source.

If two request of different priority levels are received simultaneously, the request
of higher priority level is serviced. If requests of the same priority level are
received simultaneously, an internal polling sequence determines which request
is serviced. Thus within each priority level there is a second priority structure
determined by the polling sequence as follows:

Source Priority Within Level


1. IE0 (highest)
2. TF0
3. IE1
4. TF1
5. RI+TI (lowest)

Note that the priority within level structure is only used to resolve simultaneous
requests of the same priority level. The IP register contains a number of
unimplemented bits. IP.7, IP.6, and IP.5 are reserved in the 80C51. User
software should not write 1s to these positions, since they may be used in other
8051 Family products.

Interrupt Enable Registe ( IE )

MSB LSB
EA X X ES ET1 EX1 ET0 EX0

BIT SYMBOL FUNCTION


Disables all interrupts. If EA=0, no interrupt will be
acknowledged. If EA=1, each interrupt source is
IE.7 EA
individually enabled or disabled by setting or clearing its
enable bit.
IE.6 - -
IE.5 - -
Enables or disables the Serial Port interrupt. If ES=0,
IE.4 ES
the Serial Port interrupt is disabled.
Enables or disables the Timer 1 Overflow interrupt. If
IE.3 ET1
ET1=0, the Timer 1 interrupt is disabled.
Enables or disables External Interrupt 1. If EX1=0,
IE.2 EX1
External interrupt 1 is disabled.
Enables or disables the Timer 0 Overflow interrupt. If
IE.1 ET0
ET0=0, the Timer 0 interrupt is disabled.
Enables or disables External interrupt 0. If EX0=0,
IE.0 EX0
External interrupt 0 is disabled.

Interrupt Priority Register ( IP )

MSB LSB
X X X PS PT1 PX1 PT0 PX0

Note:
BIT SYMBOL FUNCTION
IP.7 - -
IP.6 - -
IP.5 - -
Defines the Serial Port interrupt priority level. PS=1
IP.4 PS
programs it to the higher priority level.
Defines the Timer 1 interrupt priority level. PT1=1
IP.3 PT1
programs it to the higher priority level.
Defines the External Interrupt 1 priority level. PX1=1
IP.2 PX1
programs it to the higher priority level.
Enables or disables the Timer 0 interrupt priority level.
IP.1 PT0
PT0=1 programs it to the higher priority level.
Defines the External Interrupt 0 priority level. PX0=1
IP.0 PX0
programs it to the higher priority level.

Source Vector Address


IE0 0003H
TF0 000BH
IE1 0013H
TF1 001BH
RI + TI 0023H

5.2. Timer Interrupt Application


5.2.1. Pulse Generator

The next example implements Timer 0 interrupt for generates pulse generator.
The interrupt generated from Timer 0 overflows TF0. At the begining data
10000000b will be send out to P0, and after 0,05 second data will be
complemented be 01111111 and send out to P0 again.

Figure 5.2.1. Clock generator with Timer 0 interrupt

Step 1st
Build the circuit as shown in figure 5.2.1. As you seen on figure 5.2.1. P0.0 is
connected to Osciloscope. Remember, that all we want to do with this lesson is
generate clock via P0.0 with timer 0 interrupt

Step 2nd
In this step, you must tipe the assembly program to make your Timer get action,
we assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp521.zip )

In this experiment, we use Timer 0 mode 1 with vector address timer 0 interrupt
0BH. Note that in this mode, with a 12 Mhz crystal frequency, the timer over
flows every 65,536 microsecond. To generate interrupt every 50000 microsecond
( 0,05 second ) then 65536-50000=15536 d = 3CB0 h and data tobe loaded TL0
= B0h dan TH0 = 3Ch.

Org 0h
sjmp Start
Org 0bh
Ljmp Interrupt_Timer0
;
Start: mov A,#10000000b
call InitTimer
;
Forever:
mov P0,A
sjmp Forever ;
;
Interrupt_Timer0:
mov tl0,#0b0h
mov th0,#03ch
cpl A
reti
;
InitTimer:
mov TMOD,#00000001b;Timer/Counter 0 as Timer
mov tl0,#0b0h
mov th0,#03ch
setb ET0 ;Enable Timer 0 Interrupt
setb EA ;Enable Master Interrupt
setb TR0 ;Start Running
ret
;
end

Step 3rd
Safe your assembly program above, and name it with int1.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( int1.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Timer 0 Interrupt ( of course if your cable connection
and your program are corrected ).

5.2.2. Digital Clock ( :SS)

The next example implements interrupt Timer 0 as digital clock, in this example
will display second at 8 x7 segmen module ( fist and second 7 segmen ).

Step 1st
Build the circuit as shown in figure 5.2.1. As you seen on figure 5.2.1. P0 and P2
is connected to 8 x 7 Segmen. Remember, that all we want to do with this lesson
displays digital clock as second part only
Figure 5.2.2. Digital clock with timer 0 interrupt

Step 2nd
In this step, you must tipe the assembly program to make your Timer get action,
we assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp522.zip )

Note that in this mode, with a 12 MHz crystal frequency, the timer overflows
every 65,536 microseconds.
In this experiment, to generate interruption every 1000 micro second, then :
65536 - 50000 = 15536 d or 3CB0h ( TL0 = B0h dan TH0 = 3Ch )
Interruption will come out every 50000 x 1 microsecond = 0.05 second.
R0 is implemented as a software counter, Register R0 is incremented every
Timer 0 overflows. If Register R7 detected with value 20 then data will be
incremented

second equ 30h


secondTens equ 31h
secondOnes equ 32h
counter20 equ 33h
;
Org 0h
sjmp Start
Org 0bh
Ljmp Interrupt_Timer0
;
Start: mov P3,#11111111b
mov second,#0
call InitTimer
;
Forever:
call ClockDisplay
sjmp Forever ;
;
Interrupt_Timer0:
mov tl0,#0b0h
mov th0,#03ch
djnz Counter20, EndInterrupt
mov Counter20,#20
call DoClock
EndInterrupt:
reti
;
DoClock:
inc second
mov A,second
cjne A,#60,Update
mov second,#0
Update:mov A,second
mov B,#10
DIV AB
mov SecondTens,A
mov SecondOnes,B
ret
;
ClockDisplay:
Setb P2.7
Mov DPTR,#Decoder7Segmen
mov A,secondOnes
Movc A,@A+DPTR
Mov P0,A
Clr P2.7
call delay
;
Setb P2.7
Mov DPTR,#Decoder7Segmen
mov A,secondTens
Movc A,@A+DPTR
Mov P0,A
Clr P2.6
call delay
ret
;
InitTimer:
mov TMOD,#00000001b
mov tl0,#0b0h
mov th0,#03ch
setb ET0 ;Enable Timer 0 Interrupt
setb EA ;Master Interrupt Enable
setb TR0 ;Clock start running
ret
;
;=============================================
;subroutine delay created to rise delay time
;=============================================
delay: mov R1,#255
del1: mov R2,#255
del2: djnz R2,del2
djnz R1,del1
ret
;========================================
;LOOKUPTABLE
; Decode to Seven Segmen -> g f e d c b a
;========================================
Decoder7Segmen:
DB 11000000b,11111001b,10100100b,10110000b,10011001b
DB 10010010b,10000010b,11111000b,10000000b,10010000b
;
End

Step 3rd
Safe your assembly program above, and name it with int2.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( int2.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Interruption( of course if your cable connection and
your program are corrected ).

5.2.3. Digital Clock with display LCD Character (HH:MM:SS)

The next example implements interrupt Timer 0 as digital clock, in this example
will display hours,minutes, and seconds at LCD Character 2 x 16 module.

Step 1st
Build the circuit as shown in figure 5.2.3. Remember, that all we want to do with
this lesson displays digital clock with display on LCD Character 2 x 16.

Figure 5.2.3. Digital clock with timer 0 interrupt

Step 2nd
In this step, you must tipe the assembly program to make your Timer get action,
we assume that you have already known the editor, we used MIDE-51 to edit the
program. ( Download File : exp523.zip )

Note that in this mode, with a 12 MHz crystal frequency, the timer overflows
every 65,536 microseconds.
In this experiment, to generate interruption every 1000 micro second, then :
65536 - 50000 = 15536 d or 3CB0h ( TL0 = B0h dan TH0 = 3Ch )
Interruption will come out every 50000 x 1 microsecond = 0.05 second.
R0 is implemented as a software counter, Register R0 is incremented every
Timer 0 overflows. If Register R7 detected with value 20 then data will be
incremented

Counter20 equ 70h


second equ 71h
minute equ 72h
hour equ 73h
secondOnes equ 74h
secondTens equ 75h
minuteOnes equ 76h
minuteTens equ 77h
hourOnes equ 78h
hourTens equ 79h
;
org 0h
ljmp start
;=============================
;vektor interrupt TF0 location
;=============================
org 0bh
Ljmp timerinterrupt
;
Start: mov counter20,#20
mov second,#0
mov minute,#0
mov hour,#0
call UpdateDisplay
mov TMOD,#00000001b
mov tl0,#0b0h
mov th0,#03ch
setb ET0
setb EA
setb TR0
call init_lcd
;
;========================================================
;This subroutine will display Digital Clock as HH:MM:SS
;as you have seen, this subroutine execute every time
;========================================================
scandisplay:
mov r1,#8ch
acall write_inst
mov r1,secondones
acall write_data
;
mov r1,#8bh
acall write_inst
mov r1,secondtens
acall write_data
;
mov r1,#89h
acall write_inst
mov r1,minuteones
acall write_data
;
mov r1,#88h
acall write_inst
mov r1,minutetens
acall write_data
;
mov r1,#86h
acall write_inst
mov r1,hourones
acall write_data
;
mov r1,#85h
acall write_inst
mov r1,hourtens
acall write_data
sjmp scandisplay
;
Init_lcd:
mov r1,#00000001b ;Display clear
acall write_inst ;
mov r1,#00111000b ;Function set,
;Data 8 bit,2 line font 5x7
acall write_inst ;
mov r1,#00001100b ;Display on,
;cursor off,cursor blink off
acall write_inst
mov r1,#00000110b ;Entry mode, Set increment
acall write_inst
ret
;
Write_inst:
clr P2.0 ; RS = P2.0 = 0, write mode instruction
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr P2.1 ; EN = 0 = P2.1
ret
;
Write_data:
setb P2.0 ; RS = P2.0 = 1, write mode data
mov P0,R1 ; D7 s/d D0 = P0 = R1
setb P2.1 ; EN = 1 = P2.1
call delay; call delay time
clr p2.1 ; EN = 0 = P2.1
ret
;
delay: mov R0,#0
delay1:mov R7,#0fh
djnz R7,$
djnz R0,delay1
ret
;
;===================================================
;this subroutine will execute every 0,05 second
;after 20 interruption, Digital clock will be updated
;===================================================
timerinterrupt:
mov tl0,#0B0h
mov th0,#03Ch
djnz counter20,EndInterrupt
mov counter20,#20
call DigitalClock
EndInterrupt:
reti
;
;===================================================
;This subroutine below, will process digital clock
;and updates value for second, minute, hour
;===================================================
DigitalClock:
OneSecond:
inc second
mov a,#60
cjne a,second,UpdateDisplay
mov second,#0
;
OneMinute:
inc minute
mov A,#60
cjne A,minute,UpdateDisplay
mov minute,#0
;
OneHour:
inc hour
mov A,#24
cjne A,hour,UpdateDisplay
mov hour,#0
mov minute,#0
mov second,#0
;
UpdateDisplay:
mov a,second
mov b,#10
div ab
mov secondOnes,b
mov secondTens,a
;
mov a,minute
mov b,#10
div ab
mov minuteOnes,b
mov minuteTens,a
;
mov a,hour
mov b,#10
div ab
mov hourOnes,b
mov hourTens,a
;
mov a,#30h
add a,secondOnes
mov secondOnes,a
;
mov a,#30h
add a,secondTens
mov secondTens,a
;
mov a,#30h
add a,minuteOnes
mov minuteOnes,a
;
mov a,#30h
add a,minuteTens
mov minuteTens,a
;
mov a,#30h
add a,hourOnes
mov hourOnes,a
;
mov a,#30h
add a,hourTens
mov hourTens,a
;
ret

End

Step 3rd
Safe your assembly program above, and name it with int3.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( int3.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Interruption( of course if your cable connection and
your program are corrected ).

5.3. External Interrupt


In this experiment External Interrupt 0 is enabled and set up to respond to 1-to-0
transitions. When an Interrupt is received, Buzzer is on, and buzzer is off when
no interrupt recived.

Figure 5.3.1. External Interrupt Application

Step 1st
Build the circuit as shown in figure 5.3.1. As you seen on figure 5.3.1. P0 is
connected to buzzer. Remember, that all we want to do with this lesson is get
buzzer on when interrupt is received.

Step 2nd
In this step, you must tipe the assembly program to make your Interrupt get
action, we assume that you have already known the editor, we used MIDE-51 to
edit the program. ( Download File : exp53.zip )

Org 0000h
Ljmp Start
Org 0003h
Ljmp ExtInterrupt
Start:call InitEkstInterrupt
;
Loop: setb P0.0
Sjmp Loop;
;
ExtInterrupt:
clr P0.0
reti
;
InitEkstInterrupt:
Setb IT0 ;negatif transition
Setb EX0 ;External Interrupt Enable
Setb EA ;Master Interrupt Enable
ret
;
End

Step 3rd
Safe your assembly program above, and name it with int4.asm (for example)
Compile the program that you have been save by using MIDE-51, see the
software instruction.

Step 4th
Download your hex file ( int4.hex ) into the microcontroller by using
Microcontroller ATMEL ISP software, see the instruction.After download this hex
file you'll see the action of Interruption( of course if your cable connection and
your program are corrected ).

Driving 8 LED C Programming 8051


Microcontroller

/************************************************
* example of using WHILE loop construct *
* to drive 8 LEDS connected to port B *
**
* * Compiler : MIDE-51
**
************************************************/
#include < at89s51.h > /* Include 89s51 header file */
char const num[ ] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
void wait (void)
{ ; /* wait function */
}
void main( void )
{
unsigned int i;
unsigned char j;
P0 = 0; /* initialize ZERO to P0 */
while(1){
for( j = 0; j < 8; j++ )
{
P0 = num[ j ];

for ( i = 0; i < 10000; i++ )


{
wait(); /* delay for half second */
}
}
}
}

Makes LED blink every 0.5 second


C Programming 8051
Wichit Sirichote, kswichit@kmitl.ac.th

A basic circuit of the 89C2051 shown here can be made easily using point-to-
point soldering with a universal PCB. Use an ordinary 20-pin socket, do not use a
circle-pin socket. D1 is a small dot LED. U2 can be either 7805 or 78L05. U3 is
optional for correcting any polarity DC adapter. Without the 2051 chip in the
socket, checks the connection, then measures +5V between pin 20 and pin 10.
Test the LED by shorting P1.7 pin to GND.
Test your board with myfirst.c, a simple c program
that makes LED blink every 0.5 second.
/*
* myfirst.c
* First C program for 2051 experiment
* complement P1.7 every 0.5 sec
* Copyright (C) 1999 Wichit Sirichote
* compiled with Dunfield Micro-C for 8051 Release 3.2
*/
#include c:\mc\8051io.h /* include i/o header file */
#include c:\mc\8051reg.h
extern register char cputick;
// cputick was incremented every 10ms
register unsigned char sec100,flag1;
#define n 50
task1(); // functions declarations
task2();
main()
{
flag1 = 0;
sec100 = 0;
serinit(9600); // set timer0 to be 16 bit counter
while(1){
while(cputick == 0)
;
cputick = 0;
task1();
task2();
}
}
task1() // set bit 0 of flag1 every n*10ms
{
sec100++; // increment sec100
if (sec100 >= n)
{sec100 = 0; // clear sec100
flag1 |= 0x01; // set bit 0 of flag1
}
}
task2()
{
if ((flag1 & 0x01) != 0) // execute below if bit 0 of flag1 is set
{
// P1 ^= 0x80; // exclusive or the latch bit 7 with 0x80
asm " CPL P1.7"; // complement P1.7
flag1 &= ~0x01; // clear bit 0 of flag1
}
}

Scanning 7-Segment and Push Button Part 1


8051 C Programming

/********************************************
** Display Two 7 Segmen

** Compiler : MIDE-51
*******************************************/
#include < at89C2051.h > /* Include 89C2051 header file */
char num[ ] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void wait (void) /* wait function */
{;}
void main( void ){
unsigned char cnt, right;
unsigned int i;
P1 = 0; /* ZERO port P1 & port P3 */
P3 = 0;
for( ;; ){
for (right=0;right<3;right++)
{
P3 = right;
for (cnt=0;cnt<10;cnt++)
{
P1 = num[cnt];
for (i = 0; i < 10000; i++)
{
wait(); /* delay for half second */
}
}
}
}
}

Scanning 7-Segment and Push Button Part 2


8051 C Programming
Wichit Sirichote, kswichit@kmitl.ac.th

Since the output buffer of P1 can sink 20mA (each output pin, but maximum IOL
for all outputs was limited at 80mA), thus we can use P1 to drive LED display
directly. As shown in the circuit, Two common-anode 7-segment LEDs are
connected to P1 with 180 Ohms current limiting resistor. Each segment of two
LED are tied in parallel to P1. Q1 and Q2 are activated by logic low of P3.0 and
P3.1, sourcing +5V to common anode pins. P3.4 read logic low if either S1 or S2
was pressed while scanning period have made.
The program demonstrates simple counting down clock.
S1 is used for setting time to 99, S2 for start count down.
/*
* 7-seg.c
* Driving 2-digit 7-segment Common Anode LED & keypad
* Copyright (C) 1999 Wichit Sirichote
* compiled with Dunfield Micro-C for 8051 Release 3.2
* c:\mc\cc51 7-seg -i h=c:\mc m=t
*/
#include c:\mc\8051io.h /* include i/o header file */
#include c:\mc\8051reg.h
extern register char cputick; // cputick was incremented every 10ms
register unsigned char flag1;
unsigned register char sec,digit,buffer[2];
register char key;
char convert[10] = {0x3F,0x0c,0x76,0x5e,0x4d,0x5b,0x7b,0x0e,0x7f,0x5f};
/* my LED's segment pin designation (differs from standard)
b
__
a|__| c
f| | d
--
e
*/
#define setValue 99
main()
{
flag1 = 0;
sec = setValue;
timeToBuffer();
serinit(9600); // set timer0 to be 16 bit counter
while(1){
while(cputick < 10)
scanLED();
// execute the following functions every 100ms
cputick = 0;
timeToBuffer();
keyexe();
countdown();
}
}

scanLED() /* scan 2-digit LED and 2-key switch, if key pressed key= 0-1
else key = -1 */
{
int i;
digit = 0x02; // scan code 00000010
key = -1;
for( i = 0; i < 2; i++) /* 2-DIGIT scanning */
{
P3 = ~digit; /* send complement[digit] */
P1 = ~buffer[i]; /* send complement[segment] */
delay(1); /* delay 1ms */
P1 = 0xff; /* off LED */
if ((P3 & 0x10) == 0) /* if key pressed P3.4 became low */
key = i; /* save key position to key variable */
digit>>=1; /* next digit */
}
}
timeToBuffer() // converts binary data in sec to 7-segment pattern
{
buffer[0] = convert[sec%10];
buffer[1] = convert[sec/10];
}
countdown()
{
if ((flag1 & 0x02) != 0)
sec--;
if (sec == 0 )
flag1 &= ~0x02; // clear run bit
}
keyexe()
{
if (key != -1)
{
switch(key){
case (0): /* key position 0 */
reset(); /* service key 0 */
break;
case (1): /* key position 1 */
run(); /* service key 1 */
}
}
}
reset()
{
sec = setValue; // reload set value
timeToBuffer();
flag1 &= ~0x02; // stop counting down
}
run()
{
if (sec != 0)
flag1 |= 0x02; // start counting down
}

Generate a Square Wave with C Programming

/* ********************************
**
** This is a program to generate a
** square wave without using interrupt
** The frequency of the square wave depends
** upon the frequency of crystal used
** Compiler : MIDE-51
************************************/
#include <8051.h>
bit PinStatus=1;
void Toggle(void)
{
PinStatus = !PinStatus;
P1_1 = PinStatus;
return;
}
void main(void)
{
while (1)
Toggle();
return;
}

Summing Port 0 and Port 1 with C Programming


/************************************
**
** A program to get familer with SDCC
**
** This program will read port 0 and port 1
** and will add the their contents. Then it checks
** whether the result is greater than 127 or not. If it is
** greater than 127 then the addition result would be
** put to port 3 else to port 2.
** Compiler : MIDE-51

*************************************/
#include <8051.h>
void main(void)
{
unsigned char a, b, c;
a=P0;
b=P1;
c=a+b;
if (c<127)
P2=c;
else
P3=c;
return;
}

Driving 5 x 7 Matrix LED with C Programming 8051 Microcontroller

/************************************************
* *example of driving 5 x 7 Matrix LEDs *
**
* * Compiler : MIDE-51
**
************************************************/
#include < at89s51.h > /* Include 89s51 header file here */
char const pat[5]={ 0x3f, 0x02, 0x04, 0x02, 0x3f };
void wait (void)
{ ; /* wait function */
}
void main( void )
{
unsigned char cnt, col;
unsigned int i;
P3 = 0; /* ZERO port_a & port P3 */
P1 = 0;
for( ;; )
{
col = 1;
for (cnt=0;cnt<5;cnt++)
{
for(col = 0;col < 32;col<<=1;)
{
P1 = pat[cnt];
P3 = col;
for (i = 0; i < 10000; i++)
{
wait(); /* delay for half second */
}
}
}
}
}

Serial Communication RS232 UART with Mode 1 Timer 1

/*******************************************************
* Copyright (c) 2004 Atmel.
* This file is an example to use uart with timer1.
* UART will echo a received data.
* This file can be parsed by Doxygen for automatic documentation
* generation.
* Put here the functional description of this file within the software
* architecture of your program.
********************************************************/
/* I N C L U D E S */
#include "8051.h"
char uart_data;
/********************************************************
* FUNCTION_PURPOSE: This file set up uart in mode 1 (8 bits uart) with
* timer 1 in mode 2 (8 bits auto reload timer).
* FUNCTION_INPUTS: void
* FUNCTION_OUTPUTS: void
********************************************************/
void main (void)
{
SCON = 0x50 ;/* uart in mode 1 (8 bit), REN=1 */
TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */
TH1 = 0xFD ; /* 9600 Bds at 11.059MHz */
TL1 = 0xFD ; /* 9600 Bds at 11.059MHz */
ES = 1 ; /* Enable serial interrupt*/
EA = 1 ; /* Enable global interrupt */
TR1 = 1 ; /* Timer 1 run */
while(1) ; /* endless */
}
/*******************************************************
* FUNCTION_PURPOSE: serial interrupt, echo received data.
* FUNCTION_INPUTS: P3.0(RXD) serial input
* FUNCTION_OUTPUTS: P3.1(TXD) serial output
*******************************************************/
void serial_IT(void) interrupt 4
{
if (RI == 1)
{ /* if reception occur */
RI = 0; /* clear reception flag for next reception */
uart_data = SBUF;/* Read receive data */
SBUF = uart_data;/* Send back same data on uart*/
}
else TI = 0 ;/* if emission occur */
} /* clear emission flag for next emission*/

Serial Communication RS232 UART with Mode 1 Timer 1


/**************************************************
* Copyright (c) 2004 Atmel.
* This file is an example to use uart with timer2.
* UART will echo a received data.
* This file can be parsed by Doxygen for automatic documentation
* generation.
* Put here the functional description of this file within the software
* architecture of your program.
***************************************************/
/* @section I N C L U D E S */
#include "8051.h"
char uart_data;
/***************************************************
* FUNCTION_PURPOSE: This file set up uart in mode 1 (8 bits uart) with
* timer 2 in baud rate generator mode.
* FUNCTION_INPUTS: void
* FUNCTION_OUTPUTS: void
***************************************************/
void main (void)
{
SCON = 0x50 ; /* uart in mode 1 (8 bit), REN=1 */
T2CON &= 0xF0; /* EXEN2=0; TR2=0; C/T2#=0; CP/RL2#=0; */
T2CON |= 0x30 ; /* RCLK = 1; TCLK=1; */
TH2=0xFF ; /* init value */
TL2=0xFD ; /* init value */
RCAP2H=0xFF ; /* reload value, 115200 Bds at 11.059MHz */
RCAP2L=0xFD ; /* reload value, 115200 Bds at 11.059MHz */
ES = 1 ; /* Enable serial interrupt */
EA = 1 ; /* Enable global interrupt */
TR2 = 1 ; /* Timer 2 run */
while(1) ; /* endless */
}
/************************************************
* FUNCTION_PURPOSE: serial interrupt, echo received data.
* FUNCTION_INPUTS: P3.0(RXD) serial input
* FUNCTION_OUTPUTS: P3.1(TXD) serial output
*************************************************/
void serial_IT(void) interrupt 4
{
if (RI == 1)
{ /* if reception occur */
RI = 0 ; /* clear reception flag for next reception */
uart_data = SBUF; /* Read receive data */
SBUF = uart_data; /* Send back same data on uart*/
}
else TI = 0 ; /* if emission occur */
} /* clear emission flag for next emission*/

Mode 13 bits Timer Software Gated (not used)

/**************************************************
* Copyright (c) 2004 Atmel.
* Please read file license.txt for copyright notice.
* @brief This file is an example to use timer0 in mode 0.
* Put here the functional description of this file within the software
* architecture of your program.
***************************************************/
/* @section I N C L U D E S */
#include "8051.h"
/**************************************************
* FUNCTION_PURPOSE: This file set up timer 0 in mode 0 (13 bits timer)
* with a software gate.
* The 13-bits register consist of all 8 bits of TH0 and the lower 5 bits
* of TL0. The upper 3 bits of TL0 are undeterminate and are ignored.
* FUNCTION_INPUTS: void
* FUNCTION_OUTPUTS: void
***************************************************/
void main(void)
{
TMOD &= 0xF0; /* Timer 0 mode 0 with software gate */
/* GATE0=0; C/T0#=0; M10=0; M00=0; */
TH0 = 0x00; /* init values */
TL0 = 0x00;
ET0=1; /* enable timer0 interrupt */
EA=1; /* enable interrupts */
TR0=1; /* timer0 run */
while(1); /* endless */
}
/*************************************************
* FUNCTION_PURPOSE: timer0 interrupt
* FUNCTION_INPUTS: void
* FUNCTION_OUTPUTS: P1.0 toggle period = 2 * 8192 cycles
**************************************************/
void it_timer0(void) interrupt 1 /* interrupt address is 0x000b */
{
TF0 = 0; /* reset interrupt flag (already done by hardware)*/
P1_0 = ~ P1_0;/* P1.0 toggle when interrupt. */
}

Mode 13 bits Timer Hardware Gated


/**************************************************
* Copyright (c) 2004 Atmel.
* @brief This file is an example to use timer0 in mode 0.
*
* Put here the functional description of this file within the software
* architecture of your program.
***************************************************/
/* @section I N C L U D E S */
#include "8051.h"
/**************************************************
* FUNCTION_PURPOSE: This file set up timer 0 in mode 0 (13 bits timer)
* with a hardware gate.
* The 13-bits register consist of all 8 bits of TH0 and the lower 5 bits
* of TL0. The upper 3 bits of TL0 are undeterminate and are ignored.
* FUNCTION_INPUTS: P3.2(INT0)=1 : GATE Input
* FUNCTION_OUTPUTS: void
***************************************************/
void main(void)
{
TMOD &= 0xF0; /* Timer 0 mode 0 with hardware gate */
TMOD |= 0x08; /* GATE0=1; C/T0#=0; M10=0; M00=0; */
TH0 = 0x00; /* init values */
TL0 = 0x00;
ET0=1; /* enable timer0 interrupt */
EA=1; /* enable interrupts */
TR0=1; /* timer0 run */
while(1); /* endless */
}
/**
* FUNCTION_PURPOSE: timer0 interrupt
* FUNCTION_INPUTS: void
* FUNCTION_OUTPUTS: P1.0 toggle period = 2 * 8192 cycles
*/
void it_timer0(void) interrupt 1 /* interrupt address is 0x000b */
{
TF0 = 0; /* reset interrupt flag (already done by
hardware)*/
P1_0 = ~ P1_0;/* P1.0 toggle when interrupt. */
}

S-ar putea să vă placă și