org 0000h
mov sp,#40h
mov r3,#00h
mov r4,#00h
lcall DELAY_20MS ; to give lcd some time to get started
mov a,#38h ; Initialization for LCD
lcall command
lcall DELAY
mov a,#0ch ; Screen on and cursor off, no blink
lcall command
lcall DELAY
mov a,#06h ; shift cursor right
lcall command
lcall DELAY
mov a,#01h ; Clear screen and home cursor
lcall command
lcall DELAY
mov a,#'S' ;Write "SINE WAVE"
lcall display
lcall DELAY
mov a,#'I'
lcall display
lcall DELAY
mov a,#'N'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'W'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'V'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
mov a,#0C0h ; shift cursor to second line
lcall command
lcall DELAY
mov a,#'5' ;Write "50 Hz" on second line
lcall display
lcall DELAY
mov a,#'0'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'H'
lcall display
lcall DELAY
mov a,#'z'
lcall display
lcall DELAY
SINE_50:mov b,#200 ;subroutine for generating 50 Hz sinewave
mov dptr,#SINE_TABLE
L3:clr a
movc a,@a+dptr
mov p2,a
inc dptr
lcall DELAY_42US
djnz b,L3
lcall CHECK_GLOBLE
sjmp SINE_50
SINE_100:mov b,#200 ;subroutine for generating 100 Hz sinewave
mov dptr,#SINE_TABLE
L4:clr a
movc a,@a+dptr
mov p2,a
inc dptr
lcall DELAY_19US
djnz b,L4
lcall CHECK_GLOBLE
sjmp SINE_100
SINE_250:mov b,#200 ;subroutine for generating 250 Hz sinewave
mov dptr,#SINE_TABLE
L5:clr a
movc a,@a+dptr
mov p2,a
inc dptr
lcall DELAY_4US
djnz b,L5
lcall CHECK_GLOBLE
sjmp SINE_250
SINE_500:mov b,#200 ;subroutine for generating 500 Hz sinewave
mov dptr,#SINE_TABLE
L6:clr a
movc a,@a+dptr
mov p2,a
inc dptr
nop
djnz b,L6
lcall CHECK_GLOBLE
sjmp SINE_500
SQURE_50:clr a ;subroutine for generating 50 Hz squrewave
mov p2,a
lcall DELAY_10MS
cpl a
mov p2,a
lcall DELAY_10MS
lcall CHECK_GLOBLE
sjmp SQURE_50
SQURE_100:clr a ;subroutine for generating 100 Hz squrewave
mov p2,a
lcall DELAY_5MS
cpl a
mov p2,a
lcall DELAY_5MS
lcall CHECK_GLOBLE
sjmp SQURE_100
SQURE_250:clr a ;subroutine for generating 250 Hz squrewave
mov p2,a
lcall DELAY_2MS
cpl a
mov p2,a
lcall DELAY_2MS
lcall CHECK_GLOBLE
sjmp SQURE_250
SQURE_500:clr a ;subroutine for generating 500 Hz squrewave
mov p2,a
lcall DELAY_1MS
cpl a
mov p2,a
lcall DELAY_1MS
lcall CHECK_GLOBLE
sjmp SQURE_500
SAWTOOTH_50:clr a ;subroutine for generating 50 Hz
sawtoothwave
L7:mov p2,a
lcall DELAY_27US
inc a
lcall CHECK_GLOBLE
sjmp L7
SAWTOOTH_100:clr a ;subroutine for generating 100 Hz
sawtoothwave
L8:mov p2,a
lcall DELAY_8US
inc a
lcall CHECK_GLOBLE
sjmp L8
SAWTOOTH_250:clr a ;subroutine for generating 250 Hz
sawtoothwave
L9:mov p2,a
lcall DELAY_5US
inc a
cjne a,#200,L9
lcall CHECK_GLOBLE
sjmp SAWTOOTH_250
SAWTOOTH_500:clr a ;subroutine for generating 500 Hz
sawtoothwave
L10:mov p2,a
nop
nop
nop
inc a
cjne a,#250,L10
lcall CHECK_GLOBLE
sjmp SAWTOOTH_500
TRIANGULAR_50:clr a ;subroutine for generating 50 Hz
triangularhwave
L11:mov p2,a
lcall DELAY_15US
inc a
cjne a,#0ffh,L11
L12:dec a
mov p2,a
lcall DELAY_15US
cjne a,#00h,L12
lcall CHECK_GLOBLE
sjmp TRIANGULAR_50
TRIANGULAR_100:clr a ;subroutine for generating 100 Hz
triangularhwave
L13:mov p2,a
lcall DELAY_5US
inc a
cjne a,#0ffh,L13
L14:dec a
mov p2,a
lcall DELAY_5US
cjne a,#00h,L14
lcall CHECK_GLOBLE
sjmp TRIANGULAR_100
TRIANGULAR_250:clr a ;subroutine for generating 250 Hz
triangularhwave
L15:mov p2,a
nop
nop
nop
inc a
cjne a,#0ffh,L15
L16:dec a
mov p2,a
nop
nop
nop
cjne a,#00h,L16
lcall CHECK_GLOBLE
sjmp TRIANGULAR_250
TRIANGULAR_500:clr a ;subroutine for generating 500 Hz
triangularhwave
L17:mov p2,a
inc a
cjne a,#0ffh,L17
L18:dec a
mov p2,a
cjne a,#00h,L18
lcall CHECK_GLOBLE
sjmp TRIANGULAR_500
FREQ_50B:mov r4,#00h ;subroutine to make blink "50 Hz"
mov r7,#10
mov b,#06h
mov a,#0C0h
lcall command
lcall DELAY
M0:mov a,#' ' ;to blank first line
lcall display
lcall DELAY
djnz b,M0
L19:mov a,#0C0h
lcall command
lcall DELAY
mov a,#'5'
lcall display
lcall DELAY
mov a,#'0'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'H'
lcall display
lcall DELAY
mov a,#'z'
lcall display
lcall DELAY
lcall DELAY_01S
lcall CHECK1
dec r7
cjne r7,#00h,L21
ljmp GENERATE
L21:mov a,#0C0h
lcall command
lcall DELAY
mov b,#06h
L22:mov a,#' '
lcall display
lcall DELAY
djnz b,L22
lcall DELAY_01S
ljmp L19
CHECK1:mov p0,#0ffh ;subroutine to check key press position
mov a,p0
cjne a,#7fh,NEXT9
ljmp FREQ_CHECK
NEXT9:cjne a,#0bfh,NEXT10
ljmp WAVE_CHECK
NEXT10:cjne a,#0dfh,NEXT12
inc r4
cjne r4,#04h,next11
mov r4,#00h
NEXT11:ljmp FREQ_CHECK
NEXT12:cjne a,#0efh,NEXT14
dec r4
cjne r4,#0ffh,NEXT13
mov r4,#03h
NEXT13:ljmp FREQ_CHECK
NEXT14:cjne a,#0f7h,NEXT15
ljmp GENERATE
NEXT15:ret
FREQ_100B:mov r4,#01h ;subroutine to make blink "100 Hz"
mov r7,#10
L23:mov a,#0C0h
lcall command
lcall DELAY
mov a,#'1'
lcall display
lcall DELAY
mov a,#'0'
lcall display
lcall DELAY
mov a,#'0'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'H'
lcall display
lcall DELAY
mov a,#'z'
lcall display
lcall DELAY
lcall DELAY_01S
lcall CHECK1
dec r7
cjne r7,#00h,L25
ljmp GENERATE
L25:mov a,#0C0h
lcall command
lcall DELAY
mov b,#06h
L26:mov a,#' '
lcall display
lcall DELAY
djnz b,L26
lcall DELAY_01S
ljmp L23
FREQ_250B:mov r4,#02h ;subroutine to make blink "250 Hz"
mov r7,#10
L27:mov a,#0C0h
lcall command
lcall DELAY
mov a,#'2'
lcall display
lcall DELAY
mov a,#'5'
lcall display
lcall DELAY
mov a,#'0'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'H'
lcall display
lcall DELAY
mov a,#'z'
lcall display
lcall DELAY
lcall DELAY_01S
lcall CHECK1
dec r7
cjne r7,#00h,L29
ljmp GENERATE
L29:mov a,#0C0h
lcall command
lcall DELAY
mov b,#06h
L30:mov a,#' '
lcall display
lcall DELAY
djnz b,L30
lcall DELAY_01S
ljmp L27
FREQ_500B:mov r4,#03h ;subroutine to make blink "500 Hz"
mov r7,#10
L31:mov a,#0C0h
lcall command
lcall DELAY
mov a,#'5'
lcall display
lcall DELAY
mov a,#'0'
lcall display
lcall DELAY
mov a,#'0'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'H'
lcall display
lcall DELAY
mov a,#'z'
lcall display
lcall DELAY
lcall DELAY_01S
lcall CHECK1
dec r7
cjne r7,#00h,L33
ljmp GENERATE
L33:mov a,#0C0h
lcall command
lcall DELAY
mov b,#06h
L34:mov a,#' '
lcall display
lcall DELAY
djnz b,L34
lcall DELAY_01S
ljmp L31
WAVE_SINEB:mov r3,#00h ;subroutine to make blink "SINE WAVE"
mov r7,#10
mov b,#0fh
mov a,#80h
lcall command
lcall DELAY
M1:mov a,#' ' ;get first line blank
lcall display
lcall DELAY
djnz b,M1
L35:mov a,#80h
lcall command
lcall DELAY
mov a,#'S'
lcall display
lcall DELAY
mov a,#'I'
lcall display
lcall DELAY
mov a,#'N'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'W'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'V'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
lcall CHECK2
dec r7
cjne r7,#00h,L37
ljmp GENERATE
L37:mov a,#80h
lcall command
lcall DELAY
mov b,#09h
L38:mov a,#' '
lcall display
lcall DELAY
djnz b,L38
ljmp L35
WAVE_SAWTOOTHB:mov r3,#01h ;subroutine to make blink "SAWTOOTH WAVE"
mov r7,#10
mov b,#0fh
mov a,#80h
lcall command
lcall DELAY
M2:mov a,#' '
lcall display
lcall DELAY
djnz b,M2
L39:mov a,#80h
lcall command
lcall DELAY
mov a,#'S'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'W'
lcall display
lcall DELAY
mov a,#'T'
lcall display
lcall DELAY
mov a,#'O'
lcall display
lcall DELAY
mov a,#'O'
lcall display
lcall DELAY
mov a,#'T'
lcall display
lcall DELAY
mov a,#'H'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'W'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'V'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
lcall CHECK2
dec r7
cjne r7,#00h,L41
ljmp GENERATE
L41:mov a,#80h
lcall command
lcall DELAY
mov b,#14
L42:mov a,#' '
lcall display
lcall DELAY
djnz b,L42
ljmp L39
WAVE_TRIANGULARB:mov r3,#02h ;subroutine to make blink "TRIANGULAR
WAVE"
mov r7,#10
L43:mov a,#80h
lcall command
lcall DELAY
mov a,#'T'
lcall display
lcall DELAY
mov a,#'R'
lcall display
lcall DELAY
mov a,#'I'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'N'
lcall display
lcall DELAY
mov a,#'G'
lcall display
lcall DELAY
mov a,#'U'
lcall display
lcall DELAY
mov a,#'L'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'R'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'W'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'V'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
lcall CHECK2
dec r7
cjne r7,#00h,L45
ljmp GENERATE
L45:mov a,#80h
lcall command
lcall DELAY
mov b,#15
L46:mov a,#' '
lcall display
lcall DELAY
djnz b,L46
ljmp L43
WAVE_SQUREB:mov r3,#03h ;subroutine to make blink "SQURE WAVE"
mov r7,#10
mov b,#0fh
mov a,#80h
lcall command
lcall DELAY
M3:mov a,#' '
lcall display
lcall DELAY
djnz b,M3
L47:mov a,#80h
lcall command
lcall DELAY
mov a,#'S'
lcall display
lcall DELAY
mov a,#'Q'
lcall display
lcall DELAY
mov a,#'U'
lcall display
lcall DELAY
mov a,#'R'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
mov a,#' '
lcall display
lcall DELAY
mov a,#'W'
lcall display
lcall DELAY
mov a,#'A'
lcall display
lcall DELAY
mov a,#'V'
lcall display
lcall DELAY
mov a,#'E'
lcall display
lcall DELAY
lcall CHECK2
dec r7
cjne r7,#00h,L49
ljmp GENERATE
L49:mov a,#80h
lcall command
lcall DELAY
mov b,#10
L50:mov a,#' '
lcall display
lcall DELAY
djnz b,L50
ljmp L47
CHECK2:mov p0,#0ffh ;subroutine to check key press position
mov a,p0
cjne a,#0f7h,NEXT16
ljmp FREQ_CHECK
NEXT16:cjne a,#0fbh,NEXT17
ljmp WAVE_CHECK
NEXT17:cjne a,#0fdh,NEXT19
inc r3
cjne r3,#04h,next18
mov r3,#00h
NEXT18:ljmp WAVE_CHECK
NEXT19:cjne a,#0feh,NEXT21
dec r3
cjne r3,#0ffh,NEXT20
mov r3,#03h
NEXT20:ljmp WAVE_CHECK
NEXT21:cjne a,#07fh,NEXT22
ljmp GENERATE
NEXT22:ret
GENERATE:cjne r3,#00h,NEXT23 ;subroutine to generate selected waveform
ljmp L51
NEXT23:cjne r3,#01h,NEXT24
ljmp L52
NEXT24:cjne r3,#02h,NEXT25
ljmp L53
NEXT25:ljmp L54
L51:cjne r4,#00h,NEXT26
ljmp SINE_50
NEXT26:cjne r4,#01h,NEXT27
ljmp SINE_100
NEXT27:cjne r4,#02h,NEXT28
ljmp SINE_250
NEXT28:ljmp SINE_500
L52:cjne r4,#00h,NEXT29
ljmp SAWTOOTH_50
NEXT29:cjne r4,#01h,NEXT30
ljmp SAWTOOTH_100
NEXT30:cjne r4,#02h,NEXT31
ljmp SAWTOOTH_250
NEXT31:ljmp SAWTOOTH_500
L53:cjne r4,#00h,NEXT32
ljmp TRIANGULAR_50
NEXT32:cjne r4,#01h,NEXT33
ljmp TRIANGULAR_100
NEXT33:cjne r4,#02h,NEXT34
ljmp TRIANGULAR_250
NEXT34:ljmp TRIANGULAR_500
L54:cjne r4,#00h,NEXT35
ljmp SQURE_50
NEXT35:cjne r4,#01h,NEXT36
ljmp SQURE_100
NEXT36:cjne r4,#02h,NEXT37
ljmp SQURE_250
NEXT37:ljmp SQURE_500
WAVE_CHECK:cjne r3,#00h,NEXT1
ljmp WAVE_SINEB
NEXT1:cjne r3,#01h,NEXT2
ljmp WAVE_SAWTOOTHB
NEXT2:cjne r3,#02h,NEXT3
ljmp WAVE_TRIANGULARB
NEXT3:ljmp WAVE_SQUREB
FREQ_CHECK:cjne r4,#00h,NEXT4
ljmp FREQ_50B
NEXT4:cjne r4,#01h,NEXT5
ljmp FREQ_100B
NEXT5:cjne r4,#02h,NEXT6
ljmp FREQ_250B
NEXT6:ljmp FREQ_500B
CHECK_GLOBLE:mov p0,#0ffh
mov a,p0
cjne a,#0f7h,NEXT7 ; first key pressed freq check
ljmp FREQ_CHECK
NEXT7:cjne a,#0fbh,NEXT8 ; second key pressed w/f check
ljmp WAVE_CHECK
NEXT8:ret
DELAY_01S: mov r1,#250 ;subrotine to generate 0.1sec delay
A6:mov r2,#200
djnz r2,$
djnz r1,A6
ret
DELAY_5US:mov r0,#5 ;subrotine to generate 10us delay
djnz r0,$
ret
DELAY_15US:mov r0,#15 ;subrotine to generate 30us delay
djnz r0,$
ret
DELAY_27US:mov r0,#27 ;subrotine to generate 54us delay
djnz r0,$
ret
DELAY_8US:mov r0,#8 ;subrotine to generate 16us delay
djnz r0,$
ret
DELAY_10MS:mov r0,#20 ;subrotine to generate 10ms delay
A2:mov r1,#250
djnz r1,$
djnz r0,A2
ret
DELAY_5MS:mov r0,#10 ;subrotine to generate 5ms delay
A3:mov r1,#250
djnz r1,$
djnz r0,A3
ret
DELAY_2MS:mov r0,#4 ;subrotine to generate 2ms delay
A4:mov r1,#250
djnz r1,$
djnz r0,A4
ret
DELAY_1MS:mov r0,#2 ;subrotine to generate 1ms delay
A5:mov r1,#250
djnz r1,$
djnz r0,A5
ret
DELAY_42US:mov r0,#42 ;subrotine to generate 84us delay
djnz r0,$
ret
DELAY_19US:mov r0,#19 ;subrotine to generate 19us delay
djnz r0,$
ret
DELAY_4US:mov r0,#4 ;subrotine to generate 4us delay
djnz r0,$
ret
command:
lcall ready ; Write when display not busy
mov p1,a ; Command character in P1
clr p3.5 ; Command resister chosen
clr p3.3 ; Write enabled
setb p3.4 ; Strobe character to display
clr p3.4
ret
ready:
clr p3.4 ; Display disabled
mov p1,#0ffh ; Configure P1 for input
clr p3.5 ; Select command register
setb p3.3 ; Read enabled
wait:
clr p3.4 ; Strobe display
setb p3.4 ; Read busy status of display
jb p1.7,wait ; Wait for not busy (BF = 0)
clr p3.4 ; End display strobe
ret
display:
lcall ready ; Write when display ready
mov P1,a ; Data character in P1
setb p3.5 ; Data resister chosen
clr p3.3 ; write enabled
setb p3.4 ; Strobe character to display
clr P3.4
ret
DELAY: MOV R0,#90 ;50 or higher for fast CPUs
HERE2: MOV R1,#255 ;R1=255
HERE1: DJNZ R1,HERE1 ;stay until R1 becomes 0
DJNZ R0,HERE2
RET
DELAY_20MS:mov r1,#40
A1:mov r0,#250
djnz r0,$
djnz r1,A1
ret
SINE_TABLE:db
127,131,135,139,143,147,151,154,159,163,167,170,174,178,181,185,189,192,196,199,202
,205,209,212,215,218,220,223,226,228,231,233,235,237,239,241,243,244,246,247,249,25
0,251,252,253,253,254,254,255,255,255
db
255,255,254,254,253,253,252,251,250,249,247,246,244,243,241,239,237,235,233,231,228
,226,223,220,218,215,212,209,205,202,199,196,192,189,185,181,178,174,170,167,163,15
9,154,151,147,143,139,135,131,127
db
123,119,115,111,107,103,100,95,91,87,84,80,76,73,69,65,62,58,55,52,49,45,42,39,36,3
4,31,28,26,23,21,19,17,15,13,11,10,8,7,5,4,3,2,1,1,1,0,0,0,0
db
0,0,0,0,1,1,1,2,3,4,5,7,8,10,11,13,15,17,19,21,23,26,28,31,34,36,39,42,45,49,52,55,
58,62,65,69,73,76,80,84,87,91,95,100,103,107,111,115,119,123
end