You are on page 1of 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 onchip. 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 onchip 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 CY LSB P

AC

F0

RS1

RS0

OV

BIT PSW.7 PSW.6 PSW.5 PSW.4

SYMBOL CY AC F0 RS1

FUNCTION Carry flag. Auxilliary Carry flag. (For BCD operations.) Flag 0. (Available to the user for general purposes.) Register bank select control bit 1. Set/cleared by software to determine working register bank. (See Note.) Register bank select control bit 0. Set/cleared by software todetermine working register bank. (See Note.) Overflow flag.

PSW.3 PSW.2

RS0 OV

PSW.1 PSW.0

User-definable flag. Parity flag. Set/cleared by hardware each instruction cycle to 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 Mnemonic Operation Addressing Mode Ind Reg Imm
V V V V V V V V V

Dir
V V V

Exect. Timer uS
1 1 1 1 1 2 1 1 4

Add A,<byte> A=A+<byte> Addc A,<byte> Subb A,<byte> Inc A Inc <byte> Inc DPTR Dec A Dec <byte> Mul AB Div AB A=A+<byte>+C A=A-<byte>-C A=A+1 <byt>=<byt>+1 DPTR=DPTR+1 A=A-1 <byt>=<byt>-1 B:A=BxA

Accumulator Only V V V Data Pointer Only Accumulator Only V V V Accumulator and B Only

A=Int[A/B] B=Mod[A/B]
Dec Adjust

Accumulator and B only Accumulator Only

4
1

DA A

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 Mnemonic
Anl A,<byte> Anl <byte>,A Anl <byte>,#data Orl A,<byte> Orl <byte>,A Orl <byte>,#data

Operation
A=A and <byte> <byte>=<byte>anl A <byte>=<byte>and #data A=A or <byte> <byt>=<byt>orl A <byte>=<byte> or #data A=A xor<byte> <byt>=<byt>xor A <byte>=<byte>xor #data

Addressing Mode Dir


V V V

Exect. Imm
V V V

Ind
V V V

Reg
V V V

Timer uS
1 1 1 1 1 2 1 1 4

Accumulator Only V V V

Data Pointer Only Accumulator Only V V V

Xrl A,<byte>
Xrl<byte>,A Xrl <byte>,#data

Accumulator and B Only

CLR A CPL A RL A RLC A RR A RRC SWAP A

A=00h A= not A Rotate A left 1 bit Rotate A left trough Carry Rotate A right 1 bit Rotate A right trough carry Swap nibbles in A

Accumulator only Accumulator only Accumulator only Accumulator only Accumulator only Accumulator only Accumulator only

1 1 1 1 1 1 1

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 Mnemonic
Mov A,<src> Mov <dest>, <src>

Operation
A=<src>

Dir
V V V

Addressing Mode Ind Reg Imm


V V V V V V V V V

Exect. Timer uS
1 1 1 1 1 2 1 1

Mov <dest>,A <dest>=A <dest>=<src>

Mov DPTR=16 bit DPTR,#data16 immediate const Push <src> Pop <src> Xch A,<byte> Xchd A,@Ri Inc SP Dec SP Acc and <byte> exchange data Acc and @Ri exchange low nibbles V V

Accumulator Only V V

Data Pointer Only Accumulator Only V V

;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 end

; [ 79h ] = A

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 call delay setb P2.7 ;

;turn on 1st 7 segment ;call delay time ;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 0 R/W 0 DB7 0 DB6 0 DB5 1 DB4 DL DB3 N DB2 F DB1 X DB0 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 0 R/W 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 0 DB2 1 DB1 I/D DB0 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 0 R/W 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 1 DB2 D DB1 C DB0 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 0 R/W 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 0 DB2 0 DB1 0 DB0 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 0 S/C 0 0 1 1 R/W 0 R/L 0 1 0 1 DB7 0 DB6 0 DB5 0 DB4 0 DB3 S/C Note Shift cursor position to the left Shift cursor position to the right Shift the entire display to the left Shift the entire display to the right DB2 R/L DB1 X DB0 X

Note : x = Dont care

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 1 Name VSS Ground voltage Function

2 3 4

VCC VEE RS

+5V Contrast voltage Register Select 0 = Instruction Register 1 = Data Register Read/ Write, to choose write or read mode 0 = write mode 1 = read mode Enable 0 = start to lacht data to LCD character 1= disable LSB MSB Back Plane Light Ground voltage

R/W

6 7 8 9 10 11 12 13 14 15 16

E DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 BPL GND

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 (volt) 0

D0 0

D1 0

D2 0

D3 0

D4 0

D5 0

D6 0

D7 0

Des 0

0.02 0.04 0.06 0.08 0.10 0.12 : 5

0 0 0 0 0 0 1

0 0 0 0 0 0 1

0 0 0 0 0 0 1

0 0 0 0 0 0 1

0 0 0 0 0 0 1

0 0 0 1 1 1 1

0 1 1 0 0 1 1

1 0 1 0 1 0 1

1 2 3 4 5 6 : 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 Hundr. 6th Tens 5th Ones 4th 3rd Fraction 2nd 1st

1
Step 1st

0 0 ,

o C

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 Acall delay ;

; P2.1 = 0, displaying hundreds

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 1 0 0 0 0 0 0 1 0 0 0 0 B 0 0 1 0 0 1 C 0 0 0 1 1 0 D Comment Take a step clock wise another step clock wise another step clock wise another step clock wise No step take 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 1 1 0 0 0 0 0 1 1 B 0 1 1 1 0 0 0 0 0 C 0 0 0 1 1 1 0 0 0 D 0 0 0 0 0 1 1 1 0 Comment Take a step clock wise Half a step clock wise The complete full step clock wise another half step clock wise The complete full step clock wise Another half step clock wise The complete full step clock wise another half step clock wise 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

GATE GATE C/T

TIMER 1 C/T M1

M0

GATE

TIMER 0 C/T M1

M0

Gating control when set. Timer/ Counter X is enabled only while INTx pin is high and TRx control pin is set Timer or Counter Selector cleared for Timer operation (input from internal system clock) and set for counter operation (input from Tx input pin)

M1 0 0 1 1

M0 0 1 0 1

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

Timer/ Counter Control ( TCON ) Register MSB TF1 TR1 TF0 TR0 IE1 IT1 IE0 LSB IT0

BIT TCON.7

SYMBOL TF1

FUNCTION Timer 1 overflow flag. Set by hardware on Timer/Counter overflow. Cleared by hardware when processor vector to interrupt routine, or clearing the bit in software. Timer 1 Run control bit . Set/ cleared by software to turn Timer/ Counter on/off Timer 0 overflow flag. Set by hardware on Timer/Counter overflow. Cleared by hardware when processor vector to interrupt routine, or clearing the bit in software. Timer 1 Run control bit . Set/ cleared by software to

TCON.6

TR1

TCON.5 TCON.4

TF0 TR0

TCON.3

IE1

turn Timer/ Counter on/off Interrupt 1 Edge flag. Set by hardware when external interrupt edge detected. Cleared when interrupt processed. Interrupt 1 type control bit. Set/ cleared by software to specefy falling edge/ low level trigerred external interupts Interrupt 0 Edge flag. Set by hardware when external interrupt edge detected. Cleared when interrupt processed. Interrupt 0 type control bit. Set/ cleared by software to specefy falling edge/ low level trigerred external interupts

TCON.2

IT1

TCON.1

IE0

TCON.0

IT0

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 8bit 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 SM0 LSB TI RI

SM1

SM2

REN

TB8

RB8

Where SM0, SM1 specify the serial port mode, as follows SM0 0 0 1 1 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 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 by software to disable reception. The 9th data bit that will be transmitted in Modes 2 and 3. Set or clear by software as desired. In Modes 2 and 3, is the 9th data bit that was received. In Mode 1, it 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 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 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. SM1 0 1 0 1 Mode 0 1 2 3 Description Shif Register 8 bit UART 9 bit UART 9 bit UART Baud Rate fosc/ 12 variable fosc/64 fosc/32 variable

SM2

REN TB8 RB8

TI

RI

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 highpriority 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 EA BIT IE.7 IE.6 IE.5 IE.4 LSB EX0

ES

ET1

EX1 FUNCTION

ET0

SYMBOL EA ES

Disables all interrupts. If EA=0, no interrupt will be acknowledged. If EA=1, each interrupt source is individually enabled or disabled by setting or clearing its enable bit. Enables or disables the Serial Port interrupt. If ES=0,

IE.3 IE.2 IE.1 IE.0

ET1 EX1 ET0 EX0

the Serial Port interrupt is disabled. Enables or disables the Timer 1 Overflow interrupt. If ET1=0, the Timer 1 interrupt is disabled. Enables or disables External Interrupt 1. If EX1=0, External interrupt 1 is disabled. Enables or disables the Timer 0 Overflow interrupt. If ET0=0, the Timer 0 interrupt is disabled. Enables or disables External interrupt 0. If EX0=0, External interrupt 0 is disabled.

Interrupt Priority Register ( IP ) MSB X Note: BIT IP.7 IP.6 IP.5 IP.4 IP.3 IP.2 IP.1 IP.0 X X PS PT1 PX1 PT0 LSB PX0

SYMBOL PS PT1 PX1 PT0 PX0 -

FUNCTION

Defines the Serial Port interrupt priority level. PS=1 programs it to the higher priority level. Defines the Timer 1 interrupt priority level. PT1=1 programs it to the higher priority level. Defines the External Interrupt 1 priority level. PX1=1 programs it to the higher priority level. Enables or disables the Timer 0 interrupt priority level. PT0=1 programs it to the higher priority level. Defines the External Interrupt 0 priority level. PX0=1 programs it to the higher priority level.

Source IE0 TF0 IE1 TF1

Vector Address 0003H 000BH 0013H 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: again2: again1: again: MOV MOV MOV INC CJNE INC CJNE INC CJNE RET R7,#00H R6,#00H R5,#00H R5 R5,#50H,again R6 R6,#50H,again1 R7 R7,#50H,again2

; 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 highpriority 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 EA BIT IE.7 IE.6 IE.5 IE.4 IE.3 LSB EX0

ES

ET1

EX1 FUNCTION

ET0

SYMBOL EA ES ET1

Disables all interrupts. If EA=0, no interrupt will be acknowledged. If EA=1, each interrupt source is individually enabled or disabled by setting or clearing its enable bit. 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 ET1=0, the Timer 1 interrupt is disabled.

IE.2 IE.1 IE.0

EX1 ET0 EX0

Enables or disables External Interrupt 1. If EX1=0, External interrupt 1 is disabled. Enables or disables the Timer 0 Overflow interrupt. If ET0=0, the Timer 0 interrupt is disabled. Enables or disables External interrupt 0. If EX0=0, External interrupt 0 is disabled.

Interrupt Priority Register ( IP ) MSB X Note: BIT IP.7 IP.6 IP.5 IP.4 IP.3 IP.2 IP.1 IP.0 X X PS PT1 PX1 PT0 LSB PX0

SYMBOL PS PT1 PX1 PT0 PX0 -

FUNCTION

Defines the Serial Port interrupt priority level. PS=1 programs it to the higher priority level. Defines the Timer 1 interrupt priority level. PT1=1 programs it to the higher priority level. Defines the External Interrupt 1 priority level. PX1=1 programs it to the higher priority level. Enables or disables the Timer 0 interrupt priority level. PT0=1 programs it to the higher priority level. Defines the External Interrupt 0 priority level. PX0=1 programs it to the higher priority level.

Source IE0 TF0 IE1 TF1 RI + TI

Vector Address 0003H 000BH 0013H 001BH 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-topoint 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 TH2=0xFF TL2=0xFD RCAP2H=0xFF RCAP2L=0xFD ES = 1 EA = 1 TR2 = 1 while(1)

; /* RCLK = 1; TCLK=1; */ ; /* init value */ ; /* init value */ ; /* reload value, 115200 Bds at 11.059MHz */ ; /* reload value, 115200 Bds at 11.059MHz */ ; /* Enable serial interrupt */ ; /* Enable global interrupt */ ; /* Timer 2 run */ ; /* 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. */ }

You might also like