Project Weekly Progress Report

Project Title:

Microcontroller Implementation of a Small Robot Arm Controller

Week of: April 11th, 2000

Engineers:

Megan Bern and Ritesh Patel

Advisor’s Signature: _________________

Grade: _______

=================================================================

Objective:

For the week of April 11th, 2000, the objectives were to improve the P controller and continue with the menu system.

Progress:

The P controller code was investigated and several bugs were found. There was a problem with the multiplication of (7/4) of the filtered position signal. The number that was being multiplied by 7/4 was actually the initial position of the robot arm, which was zero degrees. The four cases for the summer were also rewritten. The code was then ran again.

The robot arm did not respond as desired. The signal driving the robot arm was saturating. The open loop path of the P controller was checked to see if there were any problems. This was done by disconnecting the feedback signal from the system. The robot arm moved with the joystick for a 360° range. This indicates that the open loop path of the P controller was working correctly.

The feedback path was then checked. This was done by disconnecting the signal that drives the robot arm from the system. The feedback signal was then evaluated at the point where it is feed into the summer as the robot arm was manually moved around in a 360° circle. The feedback signal was as predicted. When the robot arm was at 0° , the feedback signal measured as 0V. As the robot arm was moved from 0° to 180° , the feedback signal moved from 0V to approximately 4.45V. This was also the response of the feedback signal when the robot arm was moved from 0° to -180° . This is expected due to the 2’s compliment of negative signals.

This means that there must be a problem with the summer of the P controller. This will be further investigated next week.

 

 

 

 

The menu system was also improved. The input branch of the menu system was expanded. This is shown in bold in the code that is attached to this report. The joystick section of the input branch has already been implemented. The user input command signals were the next to implement. After the user chooses to input their own signal, the following prompt will be displayed:

1 = Positive Degree

2 = Negative Degree

The microcontroller will only accept a 1 or 2. If a 1 is accepted the following prompt will be displayed:

1=10 2=20 3=30 4=40

5=50 0=other

The microcontroller will only accept a 1, 2, 3, 4, 5, or 0. If a 1-5 is entered, the robot arm will move to the degree of choice. If a 0 is accepted the following prompt will be displayed:

 

6=60 7=70

8=80 9=90

The microcontroller will only accept a 6, 7, 8, or 9. The robot arm will then move to the degree of choice.

If a 2 is accepted from the input signal prompt, the following prompt will be displayed:

-1=10 -2=20 -3=30

-4=40 -5=50 0=other

The microcontroller will only accept a 1, 2, 3, 4, 5, or 0. If a 1-5 is entered, the robot arm will move to the degree of choice. If a 0 is accepted the following prompt will be displayed:

-6=60 -7=70

-8=80 -9=90

The microcontroller will only accept a 6, 7, 8, or 9. The robot arm will then move to the degree of choice.

To actually move the robot arm to a specified position degree can be done by finding what voltage level of the robot arm corresponds to the desired degree of position. The desired voltage level is converted into a hexadecimal number. This hexadecimal number is then placed into the program for the specified degree of position. These value cannot be determined until we have completed the P controller and measure the voltage that corresponds to the desired degree of position.

 

 

 

 

 

;Ritesh Patel & Megan Bern

;Program1

;01/25/00

;generates 100Hz square wave

;A/D and D/A conversion

;Digital Filter [Yn=.25Rn + .25(Rn-1)+.50(Yn-1)]

;include(mod515)

$INCLUDE(mod515.a51)

;include(digital)

$INCLUDE(digital.a51)

STARD EQU 8000H ;start address for program

ORG stard

JMP SETUP

;Interrupt Jump Table

org stard+2BH ;TF2 + EXF2 interrupt

AJMP TMR2SRV ;Jump to timer 1 interrupt

;-----------------------------------------------------------------

TMR2SRV: ;timer 2 service every 5 ms

MOV a,#2 ;load ACC for channel 2

CALL ADCIN ;call converter subroutine

;value in ACC

MOV a,joy ;MOVE JOYSTICK CONDITION INTO a

JZ around2 ;Jump if zero

MOV a,#1 ;load ACC for channel 1

CALL ADCIN2 ;CALL CONVERTER SUBROUTINE

;VALUE IN acc

AJMP AROUND3 ;jump to call d/a out

around2: MOV A,isig ;move input signal condition into a

JNZ INPSIGA ;jump if user is choosing input position

JZ around1 ;jump around if user is not choosing input signal

INPSIGA: CALL INPSIG ;jump to input signal routine

AROUND3: CALL da_out ;write to D/A converter, Chn 2

around1: MOV a,Tmr_Half ;0.05 second timer move to acc

JZ around ;jump if zero

DEC a ;decrement acc

MOV Tmr_Half,a ;move acc to half second timer

around:

CPL p4.1 ;generate pulse

CLR TF2 ;clear interrupt flag

RETI

; ADCIN subroutine.

; Return ACC with the 8 bit A/D conversion from the channel selected by ACC.

; Grabs current robot arm position after P-to-A/D hardware.

ADCIN:

ANL A,#00000111B ; ONLY 8 CHANNELS

ANL ADCON,#11000000B ; MODE FOR A/D CONVERSION: SINGLE

ORL ADCON,A ; "OR" IN THE CHANNEL

MOV DAPR,#0 ; START CONV W/NO REF VOLTAGE

JB BSY,$ ; LOOP TILL CONVERTED

MOV acc,ADDAT ; ACC = CONVERSION

;LOOP is the code for the digital filter yn=0.25rn+0.25r(n-1)+0.50y(n-1).

LOOP: ;calculate 0.25Rn

mov IPAD,a

CLR C

MOV IP_1,IPAD ;MOVE Rn INTO Rn-1

MOV IPAD,a ;MOVE Rn INTO a

MOV b,#4h ;MOVE 4 INTO b

DIV ab ;DIVIDE Rn BY 4

MOV R7,b ;MOVE REMAINDER 1 INTO R7

MOV R2,a ;MOVE Rn(1/4) INTO R2

;calculate 0.25Rn-1

MOV a,IP_1 ;MOVE Rn-1 INTO a

MOV b,#4h ;MOVE 4 INTO b

DIV ab ;DIVIDE Rn-1 BY 4

MOV R3,a ;MOVE Rn-1(1/4) INTO R3

MOV a,b ;MOVE REMAINDER 2 INTO a

ADD a,R7 ;ADD REMAINDER 1 TO REMAINDER 2

CLR C ;CLEAR CARRY FLAG

MOV R7,a ;MOVE SUM OF REMAINDERS 1 AND 2 INTO R7

;calculate 0.50Yn-1

MOV OP_1,OP ;MOVE Yn INTO Yn-1

MOV a,OP_1 ;MOVE Yn-1 INTO a

MOV b,#2h ;MOVE 2 INTO b

DIV ab ;DIVIDE Yn-1 BY 2

MOV R4,a ;MOVE Yn-1(1/2) INTO R4

MOV a,b ;MOVE REMAINDER 3 INTO a

MOV b,#2h ;MOVE 2 INTO b

MUL ab ;MULTIPLY REMAINDER 3 BY 2

CLR C

ADD a,R7 ;ADD (2)REMAINDER 3 TO REMAINDERS 1 AND 2

MOV b,#4h ;MOVE 4 INTO b

DIV ab ;DIVIDE TOTAL REMAINDERS BY 4

;calculate Yn

CLR C ;CLEAR CARRY FLAG

ADD a,R2 ;ADD (1/4)Rn TO REMAINDERS

CLR C ;CLEAR CARRY FLAG

ADD a,R3 ;ADD (1/4)Rn-1 TO REMAINDERS AND (1/4)Rn

CLR C ;CLEAR CARRY FLAG

ADD a,R4 ;ADD (1/2)Yn-1 TO REMAINDERS, (1/4)Rn, AND (1/4)Rn-1

MOV R5,a ;MOVE TOTAL, Yn, INTO R5

MOV a,b ;MOVE REMAINDER OF TOTAL REMAINDERS INTO a

CLR C ;CLEAR CARRY FLAG

SUBB a,#2 ;SUBTRACT 2 FROM REMAINDER OF REMAINDERS

JC HERE ;JUMP HERE IF REMAINDER IS LESS THAN 0.5

JZ THERE ;JUMP THERE IF REMAINDER IS 0.5

JMP THERE ;JUMP THERE IF REMAINDER IS GREATER THAN 0.5

THERE: MOV a,R5 ;MOVE Yn INTO a

CLR C ;CLEAR CARRY FLAG

ADD a,#1 ;ADD 1 TO Yn

MOV OP,a ;MOVE TOTAL, Yn, INTO CURRENT OUTPUT

LJMP MULT ;Jump to MULT

HERE: CLR C ;CLEAR CARRY FLAG

MOV a,R5 ;MOVE Yn INTO a

MOV OP,a ;MOVE TOTAL, Yn, INTO CURRENT OUTPUT

LJMP MULT

 

;THIS FUNCTION SUBTRACTS 80H FROM Yn and saves it in R6. IT IS DIVIDED BY 30 AND SAVED IN MEMORY.

;It is also multiplied by 7/4 and added to the previous value saved in memory.

;subtracts 80h from Current output and keeps track of sign.

MULT: MOV a,OP

MOV b,#80h ;MOVE 80H INTO B

CLR C ;CLEAR CARRY

SUBB a,b ;SUBTRACT OP-80H

JNC MULTA ;JUMP TO MULT IF OP-80H IS POSITIVE NUMBER OR ZERO

CLR C ;CLEAR CARRY FLAG

MOV negf,#1h ;MOVE 1 INTO RAM LOCATION negf

CPL a ;COMPLIMENT (OP-80H)

MOV b,#1h ;MOVE 1 INTO b

CLR C ;CLEAR CARRY FLAG

ADD a,b ;ADD (OP-80H)'+1

MULTA: ;divides value by 30 and saves in R2.

MOV R6,a ;MOVE OP-80H OR (OP-80H)'+1 INTO R6

MOV b,#1Eh ;MOVE 30 INTO b

DIV ab ;DIVIDE OP-80H BY 30

MOV R2,a ;MOVE (OP-80H)/30 INTO R2

MOV a,b ;MOVE REMAINDER INTO a

CLR C ;CLEAR CARY FLAG

SUBB a,#0Eh ;SUBTRACT 14 FROM REMAINDER

JZ MULT2 ;JUMP IF ZERO

JC MULT2 ;JUMP IF NEGATIVE

MULT1: MOV a,R2 ;MOVE (OP-80H)/30 INTO a

CLR C ;CLEAR CARRY FLAG

ADD a,#1h ;ADD 1 TO (OP-80H)/30

MOV R2,a ;MOVE (OP-80H)/30 INTO R2

MULT2: ;divides value by 4 and saves in R3.

MOV a,R6 ;MOVE (OP-80) OR (OP-80H)'+1 INTO a

MOV b,#4h ;MOVE 4 INTO b

DIV ab ;DIVIDE (OP-80H)/4

MOV R3,a ;MOVE (OP-80H)/4 INTO R3

MOV a,b ;MOVE REMAINDER INTO a

CLR C ;CLEAR CARRY FLAG

SUBB a,#1h ;SUBTRACT 1 FROM REMAINDER

JZ MULT3A ;JUMP IS ZERO

JC MULT3A ;JUMP IF NEGATIVE

MULT3: MOV a,R3 ;MOVE (OP-80H)/4 INTO a

CLR C ;CLEAR CARRY FLAG

ADD a,#1h ;ADD 1 TO (OP-80H)/4

MOV R3,a ;MOVE (OP-80H)/4 INTO R3

AJMP MULT4 ;JUMP TO MULT4

MULT3A: MOV a,R3 ;MOVE (OP-80H)/4 INTO a

MULT4: ;multiplies value by 7 and then adds value to (op-80h)/30

MOV b,#7h ;MOVE 7 INTO b

CLR C ;CLEAR CARRY FLAG

MUL ab ;MULTIPLY (OP-80H)/4 BY 7

MOV b,R2 ;MOVE (OP-80H)/30 INTO b

CLR C ;CLEAR CARRY

ADD a,b ;ADD [(7(OP-80H)/4)+((OP-80H)/30)]

MOV R2,a ;MOV [(7(OP-80H)/4)+((OP-80H)/30)] INTO R2

CALL da_out1

RET

;THIS GRABS THE CURRENT JOYSTICK LOCATION.

ADCIN2: ANL A,#00000111B ; ONLY 8 CHANNELS

ANL ADCON,#11000000B ; MODE FOR A/D CONVERSION: SINGLE

ORL ADCON,A ; "OR" IN THE CHANNEL

MOV DAPR,#0 ; START CONV W/NO REF VOLTAGE

JB BSY,$ ; LOOP TILL CONVERTED

MOV acc,ADDAT ; ACC = CONVERSION

LJMP REM3

;THIS FUNCTION CHECKS TO SEE WHAT POSITION THE USER WOULD LIKE THE ROBOT ARM TO MOVE TO AND ACCEPTS

;THAT POSITION AS THE INPUT SIGNAL.

INPSIG: MOV a,isig

CJNE a,#1h,DEG20

MOV a,#86h

LJMP REM3

DEG20: CJNE a,#2h,DEG30

MOV a,#8Dh

LJMP REM3

DEG30: CJNE a,#3h,DEG40

MOV a,#94h

LJMP REM3

DEG40: CJNE a,#4h,DEG50

MOV a,#9Bh

LJMP REM3

DEG50: CJNE a,#5h,DEG60

MOV a,#0A2h

LJMP REM3

DEG60: CJNE a,#6h,DEG70

MOV a,#0A9h

LJMP REM3

DEG70: CJNE a,#7h,DEG80

MOV a,#0B0h

LJMP REM3

DEG80: CJNE a,#8h,DEG90

MOV a,#0B8h

LJMP REM3

DEG90: CJNE a,#9h,DEGN10

MOV a,#0BFh

LJMP REM3

DEGN10: CJNE a,#11h,DEGN20

MOV a,#78h

LJMP REM3

DEGN20: CJNE a,#12h,DEGN30

MOV a,#71h

LJMP REM3

DEGN30: CJNE a,#13h,DEGN40

MOV a,#6Ah

LJMP REM3

DEGN40: CJNE a,#14h,DEGN50

MOV a,#63h

LJMP REM3

DEGN50: CJNE a,#15h,DEGN60

MOV a,#5Ch

LJMP REM3

DEGN60: CJNE a,#16h,DEGN70

MOV a,#55h

LJMP REM3

DEGN70: CJNE a,#17h,DEGN80

MOV a,#4Eh

LJMP REM3

DEGN80: CJNE a,#18h,DEGN90

MOV a,#47h

LJMP REM3

DEGN90: CJNE a,#19h,INPSIGB

MOV a,#40h

LJMP REM3

INPSIGB: LJMP INPSIG

;THIS FUNCTION SUBTRACTS 80 FROM THE INPUT AND THEN PERFORMS THE SUMMATION OF THE P CONTROLLER.

REM3: ;subtracts 80h from the input signal. checks to see if neg or pos.

;keeps track of sign.

MOV b,#80h ;MOVE 80H INTO b

CLR C ;clear carry flag

SUBB a,b ;SUBTRACT (INPUT-80H)

JNC REM3A ;JUMP IF (INPUT-80H) IS NOT A NEGATIVE NUMBER

MOV negi,#1h ;MOVE 1 INTO RAM LOCATION negi

CPL a ;COMPLIMENT (INPUT-80H)

MOV b,#1h ;MOVE 1 INTO b

CLR C ;clear carry flag

ADD a,b ;ADD (INPUT-80H)'+1

 

REM3A: ;ckecks to see if input is neg or pos.

MOV R4,a ;MOVE (INPUT-80H) OR (INPUT-80H)'+1 INTO R4

MOV a,negi ;MOVE INPUT CONDITION INTO a

JZ REM3B ;JUMP IF INPUT SIGNAL POSITIVE

;input is neg and checks to see if feedback is neg or pos.

MOV a,negf ;MOVE FEEDBACK CONDITION INTO a

JZ STOP ;JUMP IF FEEDBACK CONDITION IS POSITIVE

;input and feedback are both neg. subtracts input from feedback.

MOV a,R2 ;MOVE {[7((OP-80H)'+1)/4]+[(OP-80H)'+1/30]} INTO a

MOV b,R4 ;MOVE (INPUT-80H)'+1 INTO b

CLR C ;clear carry flag

SUBB a,b ;SUBTRACT {[7((OP-80H)'+1)/4]+[((OP-80H)'+1)/30]} - [(INPUT-80H)'+1]

MOV negi,#0 ;RESET negi TO ZERO

MOV negf,#0 ;RESET negf TO ZERO

MOV b,#80h ;MOVE 80H INTO b

CLR C

ADD a,b ;ADD {{[7((OP-80H)'+1)/4]+[(OP-80H)'+1/30]} - [(INPUT-80H)'+1]} + 80H

RET

REM3B: ;input is pos and ckecks to see if feedback is neg or pos.

MOV a,negf ;MOVE FEEDBACK CONDITION INTO a

JNZ STOP1 ;JUMP IF FEEDBACK CONDITION IS NEGATIIVE

;input and feedback are both pos. subtracts feedback from input signal.

MOV a,R4 ;MOVE (INPUT-80H) INTO a

MOV b,R2 ;MOVE [7(OP-80H)/4 + (OP-80H)/3] INTO b

CLR C

SUBB a,b ;SUBTRACT {(INPUT-80H) - [7(OP-80H)/4 + (OP-80H)/3]}

MOV negi,#0 ;RESET negi TO ZERO

MOV negf,#0 ;RESET negf TO ZERO

MOV b,#80h ;MOVE 80H INTO b

CLR C

ADD a,b ;ADD {(INPUT-80H) - [7(OP-80H)/4 + (OP-80H)/3]} + 80H

RET

STOP: ;input is neg and feedback is pos.

MOV b,R2 ;MOVE {[7((OP-80H)'+1)/4]+[(OP-80H)'+1/30]} INTO a

MOV a,#0h ;MOVE 0H INTO a

CLR C

SUBB a,b ;SUBTRACT 0H - {[7((OP-80H)'+1)/4]+[(OP-80H)'+1/30]}

MOV b,R4 ;MOVE (INPUT-80H)'+1 INTO b

CLR C

SUBB a,b ;SUBTRACT 0H - {[7((OP-80H)'+1)/4]+[(OP-80H)'+1/30]} - [(INPUT-80H)'+1]

MOV negi,#0 ;RESET negi TO ZERO

MOV negf,#0 ;RESET negf TO ZERO

MOV b,#80h ;MOVE 80H INTO b

CLR C

ADD a,b ;ADD {0H - {[7((OP-80H)'+1)/4]+[(OP-80H)'+1/30]} - [(INPUT-80H)'+1]} +

;80H

RET

STOP1: ;input is pos and feedback is neg.

MOV a,R4 ;MOVE (INPUT-80H) INTO a

MOV b,R2 ;MOVE [7(OP-80H)/4 + (OP-80H)/3] INTO b

CLR C ;clear carry flag

ADD a,b ;SUBTRACT {(INPUT-80H) - [7(OP-80H)/4 + (OP-80H)/3]}

MOV negi,#0 ;RESET negi TO ZERO

MOV negf,#0 ;RESET negf TO ZERO

MOV b,#80h ;MOVE 80H INTO b

CLR C

ADD a,b ;ADD {(INPUT-80H) - [7(OP-80H)/4 + (OP-80H)/3]} + 80H

RET

 

 

; da_out subrountine

; write value in ACC to D/A channel specified below

da_out: MOV P2,#DA_0 ; point to D/A channel 2

MOVX @R1,a ; write data

RET

da_out1: MOV P2,#DA_2

MOVX @R1,a

RET

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

;

; Intialization Code

;

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

SETUP:

MOV IEN0,#0 ;Disable ALL INTS

MOV SP,#70H ;Initialize STACK

SETB P5.5 ;Do a reset

CLR P5.5 ;bring it low

SETB P5.0 ;make A16 of 128K Ram, high

SETB P5.2 ;disable EEPROM

CLR P5.1 ;new port 5.1 for D/A

;END 80535 Stuff

MOV R0,#7FH ;CLEAR 128 BYTES OF RAM

clr_ram: MOV @R0,#0

DJNZ R0,clr_ram

SETB T2CON.0 ; timer 2: 16 bit operation

SETB T2CON.4 ; and auto-reload mode

MOV TH2,#0EDH ; load timer 2 registers

MOV TL2,#0E4H

MOV CRCH,#0EDH ; load capture registers

MOV CRCL,#0E4H ; timer 2

SETB ET2 ;enable timer 2 ovf int

SETB EAL ; enable all interrupts

Digital:

MOV IPAD,#0 ;Initialize IPAD

MOV IP_1,#0 ;Initialize IP_1

MOV OP,#0 ;Initialize OP

MOV OP_1,#0 ;Initialize OP_1

MOV Tmr_Half,#10 ;Initialize Half second timer to 10

MOV joy,#0 ;INITIALIZE JOYSTICK CONSITION TO ZERO

MOV negi,#0 ;Initialize input condition to zero

MOV negf,#0 ;Initialize feedback condition to zero

MOV isig,#0 ;Initialize input signal condition to zero

Call LCDINIT ; initialize LCD

;THIS FUNCTION CREATES THE MAIN MENU SYSTEM ON THE LCD.

main:

MOV DPTR,#lcddata ; initialize pointer

MOV R0,#0 ; initialize character count

dislop: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#40,dislop ; finished?, then loop

looplcd: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next1 ;Key 1 pressed

MOV joy,#0h

MOV isig,#0h

JMP INPUT1 ;jump if equal

next1: CJNE A,#32h,looplcd ;compare to 2 and if not equal jump

JMP OUTPUT1 ;if equal jump to output

INPUT1: MOV DPTR,#lcddata1 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop1: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop1

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#34,dislop1 ; finished?, then loop

looplcd1: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next2 ;Key 1 pressed

MOV joy,#1h ;set joystick condition to 1

MOV isig,#0h

JMP main

next2: CJNE A,#32h,looplcd1 ;compare to 2 and if not equal jump

MOV joy,#0h ;set joystick condition to zero

MOV isig,#1h

MOV DPTR,#lcd1 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop6: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop6

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#41,dislop6 ; finished?, then loop

looplcd6: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next7 ;Key 1 pressed

JMP posdeg

next7: CJNE A,#32h,looplcd6 ;compare to 2 and if not equal jump

JMP negdeg

posdeg: MOV DPTR,#lcd2 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop7: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop7

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#34,dislop7 ; finished?, then loop

looplcd7: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next8 ;Key 1 pressed

MOV isig,#1h

LJMP main

next8: CJNE A,#32h,next9 ;compare to 2 and if not equal jump

MOV isig,#2h

LJMP main

next9: CJNE A,#33H,next10

MOV isig,#3h

LJMP main

next10: CJNE A,#34H,next11

MOV isig,#4h

LJMP main

next11: CJNE A,#35H,next12

MOV isig,#5h

LJMP main

next12: CJNE A,#30H,looplcd7

otherdeg: MOV DPTR,#lcd3 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop8: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop8

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#21,dislop8 ; finished?, then loop

looplcd8: CALL KEYIN1 ;call keypad subroutine

CJNE A,#36h,next13 ;Key 1 pressed

MOV isig,#6h

LJMP main

next13: CJNE A,#37h,next14 ;compare to 2 and if not equal jump

MOV isig,#7h

LJMP main

next14: CJNE A,#38H,next15

MOV isig,#8h

LJMP main

next15: CJNE A,#39H,looplcd8

MOV isig,#9h

LJMP main

negdeg: MOV DPTR,#lcd4 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop9: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop9

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#39,dislop9 ; finished?, then loop

looplcd9: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next16 ;Key 1 pressed

MOV isig,#11h

LJMP main

next16: CJNE A,#32h,next17 ;compare to 2 and if not equal jump

MOV isig,#12h

LJMP main

next17: CJNE A,#33H,next18

MOV isig,#13h

LJMP main

next18: CJNE A,#34H,next19

MOV isig,#14h

LJMP main

next19: CJNE A,#35H,next20

MOV isig,#15h

LJMP main

next20: CJNE A,#30H,looplcd9

otherdeg1: MOV DPTR,#lcd5 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop10: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop10

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#25,dislop10 ; finished?, then loop

looplcd10: CALL KEYIN1 ;call keypad subroutine

CJNE A,#36h,next21 ;Key 1 pressed

MOV isig,#16h

LJMP main

next21: CJNE A,#37h,next22 ;compare to 2 and if not equal jump

MOV isig,#17h

LJMP main

next22: CJNE A,#38H,next23

MOV isig,#18h

LJMP main

next23: CJNE A,#39H,looplcd10

MOV isig,#19h

JMP main

lcd1: db 1ah,31h,20h,3dh,20h,50h,6fh,73h,69h,74h,69h,76h,65h

db 20h,44h,65h,67h,72h,65h,65h

db 0ah,0dh,32h,20h,3dh,20h,4eh,65h,67h,61h,74h,69h

db 76h,65h,20h,44h,65h,67h,72h,65h,65h

RET

lcd2: db 1ah,31h,3dh,31h,30h,20h,32h,3dh,32h,30h,20h,33h,3dh

db 33h,30h,20h,34h,3dh,34h,30h,0ah,0dh,35h,3dh,35h,30h

db 20h,4fh,3dh,4fh,74h,68h,65h,72h

RET

lcd3: db 1ah,36h,3dh,36h,30h,20h,37h,3dh,37h,30h,0ah,0dh

db 38h,3dh,38h,30h,20h,39h,3dh,39h,30h

RET

lcd4: db 1ah,31h,3dh,2dh,31h,30h,20h,32h,3dh,2dh,32h,30h,20h

db 33h,3dh,2dh,33h,30h,0ah,0dh,34h,3dh,2dh,34h,30h,20h

db 35h,3dh,2dh,35h,30h,20h,4fh,3dh,4fh,74h,68h,65h,72h

RET

lcd5: db 1ah,36h,3dh,2dh,36h,30h,20h,37h,3dh,2dh,37h,30h,0ah

db 0dh,38h,3dh,2dh,38h,30h,20h,39h,3dh,2dh,39h,30h

RET

lcddata1: db 1ah,50h,72h,65h,73h,73h,20h,31h,20h,6fh,72h,20h,32h

db 0ah,0dh,31h,3dh,4ah,4fh,59h,53h,54h,49h,43h,4bh,20h

db 32h,3dh,49h,4eh,53h,49h,47h,20h

RET

lcddata: db 1ah,50h,72h,65h,73h,73h,20h,31h,20h,6fh,72h,20h

db 32h,0ah,0dh,31h,3dh,49h,6eh,20h,32h,3dh

db 4fh,75h,74h,20h,46h,6fh,72h,20h,4dh,65h,6eh,75h,73h

RET

KEYIN1: JNB IE1,KEYIN1 ; LOOP TILL KEY PRESSED

clr ie1

PUSH DPH

PUSH DPL ; SAVE DPTR

MOV DPTR,#KEYTABL ; POINT TO TRANSLATE TABLE

MOV P2,#KEYSEL ; POINT TO KEYPAD PORT

MOVX A,@R1 ; GET KEY FROM PORT

ANL A,#11111B ; ONLY 5 BITS

MOVC A,@A+DPTR ; TRANSLATE TO KEY FROM TABLE

POP DPL

POP DPH

RET

KEYTABL: DB '123C456D789EA0BF'

OUTPUT1: MOV DPTR,#output2 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop2: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop2

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#40,dislop2 ; finished?, then loop

 

looplcd2: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next3 ;Key 1 pressed

JMP error

next3: CJNE A,#32h,looplcd2 ;compare to 2 and if not equal jump

JMP other

error: JMP main

other: MOV DPTR,#output3 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop3: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop3

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#40,dislop3 ; finished?, then loop

looplcd3: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next4 ;Key 1 pressed

JMP final

next4: CJNE A,#32h,looplcd3 ;compare to 2 and if not equal jump

JMP other1

final: JMP main

other1: MOV DPTR,#output4 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop4: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop4

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#42,dislop4 ; finished?, then loop

looplcd4: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next5 ;Key 1 pressed

JMP filtered

next5: CJNE A,#32h,looplcd4 ;compare to 2 and if not equal jump

JMP other2

filtered: JMP main

other2: MOV DPTR,#output5 ; initialize pointer

MOV R0,#0 ; initialize character count

dislop5: MOV a,Tmr_Half ;move half second timer to acc

JNZ dislop5

MOV Tmr_Half,#10 ;move 100(dec)in to half second timer

MOV A,R0 ; copy to A

MOVC A,@A+DPTR

Call LCDOUT

INC R0

CJNE R0,#41,dislop5 ; finished?, then loop

looplcd5: CALL KEYIN1 ;call keypad subroutine

CJNE A,#31h,next6 ;Key 1 pressed

JMP command

next6: CJNE A,#32h,looplcd5 ;compare to 2 and if not equal jump

JMP other3

command: JMP main

other3: JMP main

output6: JMP output6

output2: db 1ah,50h,72h,65h,73h,73h,20h,31h,20h,46h,6fh,72h,20h

db 45h,72h,72h,6fh,72h,20h,0ah,0dh,6fh,72h

db 20h,32h,20h,46h,6fh,72h,20h,4fh,74h,68h,65h,72h,20h,53h

db 69h,67h,73h

RET

output3: db 1ah,50h,72h,65h,73h,73h,20h,31h,20h,46h,6fh,72h,20h

db 4fh,75h,74h,70h,75h,74h,0ah,0dh,6fh,72h,20h,32h,20h

db 46h,6fh,72h,20h,4fh,74h,68h,65h,72h,20h,53h,69h,67h,73h

RET

output4: db 1ah,50h,72h,65h,73h,73h,20h,31h,20h,46h,6fh,72h,20h,46h

db 69h,6ch,74h,65h,72h,65h,64h,0ah,0dh,50h,6fh,73h,20h

db 6fh,72h,20h,32h,20h,4fh,74h,68h,65h,72h,20h,53h,69h,67h,73h

RET

output5: db 1ah,50h,72h,65h,73h,73h,20h,31h,20h,46h,6fh,72h,20h,43h

db 6fh,6dh,6dh,61h,6eh,64h,0ah,0dh,6fh,72h,20h,32h,20h,46h

db 6fh,72h,20h,4fh,74h,68h,65h,72h,20h,53h,69h,67h,73h

RET

 

$include(lcddrv3.a51) ; LCD subrountines

escflag equ psw.5 ;LCD equate

END