Please click on the image in order to see clear view.
The objective of the project is to develop an AT89S51 microcontroller based trainer kit having an onboard ADC with provision for port access [for integrating devices outside to the trainer kit], a 4x4 keypad, LCD display and serial interface with PC.
Task breakdown
- Interfacing ADC with AT89S51
- Interfacing 16x2 LCD with AT89S51
- Interfacing 4x4 keypad with AT89S51
- ADC must get data from outside
- Bridge microcontroller with the PC via COM port (serial) to read/write data to/from the board.
Heart of the System
The software has been written using AT89S51 microcontroller compatible assembly language. The provision for choosing assembly language is, I can directly talk/listen to/from hardware, no wrapping and more handling capability on my own hands. For editing/ compiling/creation of hex file, I have used the MIDE-51 Editor. I have used C# serial port class for pc + microcontroller communication and data exchange. our project required an internal interrupt and an external interrupt in order to functioning the whole system without extra hand, i.e. no re-dumping of hex file into the controller engine.
We didn’t use IC MM74C922 for check bouncing of key press since it will increase the product cost rather we have checked it by software using delay technique.
Project Code
//////////////////////////////////////////
Code that has been used as hex file inside microcontroller
//////////////////////////////////////////
;the following experiment is used to scan
;keypad 4x4 and result of scan will be released
;to LCD Character as normal operation
;an ADC o/p will be available to port when
;external interrupt triggered and serial port data
;fetch using serial port interrupt(internal interrupt)
row1 bit P1.4
row2 bit P1.5
row3 bit P1.6
row4 bit P1.7
col1 bit P1.0
col2 bit P1.1
col3 bit P1.2
col4 bit P1.3
;
keybounc equ 71h
keyport equ P1
org 0h
LJMP start
ORG 0003h ; vector address for interrupt 0
LJMP ISR0 ; jump to start of ISR0
ORG 23h ; vector address serial port interrupt
LJMP ISR_SERIAL
ORG 0100h
start:
MOV IE, #10010001B
SETB IT0
call keypad4x4 ;calling subroutine keypad4x4
Mov A,R7;keydata ;A = keydata
Cjne A,#0FFh,WrLCD;
sjmp start ;LOOPING FOREVER PART 1
;
WrLCD: call Init_lcd
Mov R1,#80h ;Pick DDRAM 1st row and 1st col
call write_inst
Mov R1,A
call write_data ;write data
Ljmp 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 P3.4 ; RS = P3.4 = 0, write mode instruction
mov P2,R1 ; D7 s/d D0 = P2 = R1
setb P3.5 ; EN = 1 = P3.5
call delay; call delay time
clr P3.5 ; EN = 0 = P3.5
ret
;
Write_data:
setb P3.4 ; RS = P3.4 = 1, write mode data
mov P2,R1 ; D7 s/d D0 = P0 = R1
setb P3.5 ; EN = 1 = P3.5
call delay; call delay time
clr p3.5 ; EN = 0 = P3.5
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=P1= FF, inut port
clr col1 ;col1= P1.0 = 0
Detect:jb row1,key1 ;jump to Key1 if row1=1
djnz keybounc,Detect
mov R7,#'0';0h ;Keydata =00h
ret
;
key1: jb row2,key2 ;jump to key2 if row2=1
djnz keybounc,key1
mov R7,#'4';04h ;Keydata = 04h
ret
;
key2: jb row3,key3
djnz keybounc,key2
mov R7,#'8';08h
ret
;
key3: jb row4,key4
djnz keybounc,key3
mov R7,#'c';0Ch
ret
;
key4: setb col1
clr col2
jb row1,key5
djnz keybounc,key4
mov R7,#'1';01h
ret
;
key5: jb row2,key6
djnz keybounc,key5
mov R7,#'5';05h
ret
;
key6: jb row3,key7
djnz keybounc,key6
mov R7,#'9';09h
ret
;
key7: jb row4,key8
djnz keybounc,key7
mov R7,#'d';0Dh
ret
;
key8: setb col2
clr col3
jb row1,key9
djnz keybounc,key8
mov R7,#'2';02h
ret
;
key9: jb row2,keyA
djnz keybounc,key9
mov R7,#'6';06h
ret
;
keyA: jb row3,keyB
djnz keybounc,keyA
mov R7,#'A';0Ah
ret
;
keyB: jb row4,keyC
djnz keybounc,keyB
mov R7,#'E';0Eh
ret
;
keyC: setb col3
clr col4
jb row1,keyD
djnz keybounc,keyC
mov R7,#'3';03h
ret
;
keyD: jb row2,keyE
djnz keybounc,keyD
mov R7,#'7';07h
ret
;
keyE: jb row3,keyF
djnz keybounc,keyE
mov R7,#'B';0Bh
ret
;
keyF: jb row4,Nokey
djnz keybounc,keyF
mov R7,#'F';0Fh
ret
Nokey:mov R7,#0FFh
ret
;================================
;The end of Keypad 4x4 subroutine
;================================
ISR0:
Hundreds equ 30h
tens equ 31h
ones equ 32h
call init_LCD
call ADC
call Bin2Dec
call Write2LCD
RETI
;
;===================================
;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
;===================================;
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
;
word1: DB ' Data ADC0804 '
;end lcd
ISR_SERIAL:
nop
call initserial
call inchar
call init_LCD
call Bin2Dec
call Write2LCD
RETI
;
initserial:
mov scon,#52h
mov tmod,#20h
mov th1,#-13
setb tr1
ret
;
inchar:
detect1: jnb ri,detect1;
clr ri
mov a,sbuf
ret
;
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
Bin2Dec:
mov b,#100d
div ab
mov hundreds,a
mov a,b
mov b,#10d
div ab
mov tens,a
mov ones,b
ret
end
//////////////////////////////////////////Code that has been used in pc side to communicate with microcontroller
//////////////////////////////////////////
using System.IO.Ports;
public void SendByte(byte packet)
{
try
{
SerialPort port = new SerialPort("COM1", 2400, Parity.None, 8,
StopBits.One);
port.Open();
byte[] writeByte = new byte[1];
writeByte[0] = packet;
port.Write(writeByte, 0, 1); // write to port
port.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public void ReadByte()
{
byte byteRead = new byte();
try
{
SerialPort port = new SerialPort("COM1", 2400, Parity.None,
8, StopBits.One);
port.Open();
int byteValue = port.ReadByte(); // read from port
port.Close();
byteRead = Convert.ToByte(byteValue);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
super
ReplyDelete