*** PROGRAMMABLE FUNCTION GENERATOR ***
Download as Archive
// reset vector address = 0000h //
org 0000h
ljmp main
// ***** INTERRUPT SERVICE ROUTINES ******//
// Serial ISR -> called when a byte is received serially (RI sets)
// receives Query from user, compares it with queries stored in ROM (stringCmp)
// stringCmp -> responds to the query
// RETI -> returns to where it is called
org 0023h
serialIsr: JB TI,serialIsrExit
LCALL recQuery
LCALL stringCmp
CLR RI
serialIsrExit: RETI
// ******* END OF ISR ******** //
org 0100h
//******* MAIN *******//
// initialize r4 ( waveform type )
// enable global and local(serial) interrupts
// initialize serial
// generate wave ( type of wave is known from r4 )
main: mov r4,#00
mainLoop: setb ea
setb es
lcall initSerial
lcall generateWave
sjmp mainLoop
// *********** SUBROUTINES ************//
// initialization of serial
initSerial:mov tmod,#21h
mov scon,#50h
mov th1,#253
mov tl1,#253
setb tr1
ret
// receive a byte serially and store it in 'a'
recserial: jnb ri,$
mov a,sbuf
clr ri
ret
// receives a Query byte by byte and store it in RAM starting from 40h
// stores length of query in 'r1'
recQuery: mov r0,#40h
mov r1,#00h
recQueryLoop: lcall recserial
mov @r0,a
inc r1
inc r0
cjne a,#13,recQueryLoop
recQueryExit: ret
// fetch response byte by byte from ROM and send serially
// gets 'r3' as argument ( length of response )
sendResp:clr a
movc a,@a+dptr
lcall sendserial
inc dptr
djnz r3,sendResp
ret
// send a byte serially
sendSerial:clr ti
mov sbuf,a
jnb ti,$
ret
// gets 'r2' as argument ( r2 * 50 ms = total delay time )
dynamicDelay: mov th0,#4bh
mov tl0,#0fdh
clr tf0
setb tr0
jnb tf0,$
djnz r2,dynamicDelay
ret
// subroutine for wave generation
// the type of wave depends on value of 'r4'
// 0-> square ; 1-> sine; 2-> triangle; 3-> sawtooth
generateWave: CJNE R4,#00H,notSquare
LCALL squareWave
RET
notSquare: CJNE R4,#01H,notSine
LCALL sineWave
RET
notSine: CJNE R4,#02H,notTri
LCALL triWave
RET
notTri: CJNE R4,#03H,notSaw
LCALL sawToothWave
notSaw: RET
// generates square wave of time period 1s ( PORT0 -> P0 )
squareWave: mov p0,#00h
mov r2,#10 // 10 * 50ms = 500ms
lcall dynamicDelay
mov p0,#0ffh
mov r2,#10 // 10 * 50ms = 500ms
lcall dynamicDelay
// generates triangle wave ( PORT0 -> P0 )
triWave: MOV A,#00H
triWaveRef1: MOV P0,A
INC A
JNZ triWaveRef1
MOV A,#0FFH
triWaveRef2: MOV P0,A
DEC A
JNZ triWaveRef2
RET
// generates sawtooth wave ( PORT0 -> P0 )
sawToothWave: MOV A,#00H
sawWaveRef1: MOV P0,A
INC A
JNZ sawWaveRef1
MOV P0,#00H
RET
// generates sine wave ( PORT0 -> P0 )
sineWave: MOV R6,#37D
MOV DPTR,#sineLookUp
sineRef: MOV A,#00H
MOVC A,@A+DPTR
MOV P0,A
INC DPTR
DJNZ R6,sineRef
RET
// returns the type of wave serially (byte by byte fetching from ROM)
// depending on value of R4
getMode: CJNE R4,#01,notSine1
MOV DPTR,#SINE
MOV R3,#6D
LCALL sendResp
SJMP getModeExit
notSine1: CJNE R4,#00,notSquare1
MOV DPTR,#SQUARE
MOV R3,#8D
LCALL sendResp
SJMP getModeExit
notSquare1: CJNE R4,#02,notTri1
MOV DPTR,#TRIANGLE
MOV R3,#10D
LCALL sendResp
SJMP getModeExit
notTri1: CJNE R4,#03,getModeExit
MOV DPTR,#SAWTOOTH
MOV R3,#10D
LCALL sendResp
getModeExit: RET
// compares the query from user (stored in RAM) and the query stored in ROM
// responds back if match if found
// responds with "CMD ERR" if query from user is invalid
stringCmp:mov b,r1
mov r0,#40h // starting RAM address
mov dptr,#qry1 // *IDN?
chkagain1:clr a
movc a,@a+dptr
clr c
subb a,@r0
jnz exit1
inc r0
inc dptr
djnz b,chkagain1
mov r3,#33d // 33 bytes
mov dptr,#resp1
lcall sendResp
ret
exit1: mov b,r1
mov r0,#40h
mov dptr,#qry2 // :VER?
chkagain2:clr a
movc a,@a+dptr
clr c
subb a,@r0
jnz exit2
inc r0
inc dptr
djnz b,chkagain2
mov r3,#13d // 13 bytes
mov dptr,#resp2
lcall sendResp
ret
exit2: mov b,r1
mov r0,#40h
mov dptr,#qry3 // :MODE:SIN?
chkagain3:clr a
movc a,@a+dptr
clr c
subb a,@r0
jnz exit3
inc r0
inc dptr
djnz b,chkagain3
mov r3,#21d // 21 bytes ( mode set sucessful)
mov dptr,#modeSetSuccess
lcall sendResp
mov r4,#01h // sine
ret
exit3: mov b,r1
mov r0,#40h
mov dptr,#qry4 // :MODE:SQR?
chkagain4:clr a
movc a,@a+dptr
clr c
subb a,@r0
jnz exit4
inc r0
inc dptr
djnz b,chkagain4
mov r3,#21d // 21 bytes
mov dptr,#modeSetSuccess
lcall sendResp
mov r4,#00h // sqr
ret
exit4: mov b,r1
mov r0,#40h
mov dptr,#qry5 // :MODE:TRI?
chkagain5:clr a
movc a,@a+dptr
clr c
subb a,@r0
jnz exit5
inc r0
inc dptr
djnz b,chkagain5
mov r3,#21d // 21 bytes
mov dptr,#modeSetSuccess
lcall sendResp
mov r4,#02 // tri
ret
exit5: mov b,r1
mov r0,#40h
mov dptr,#qry6 // :MODE:SAW?
chkagain6:clr a
movc a,@a+dptr
clr c
subb a,@r0
jnz exit6
inc r0
inc dptr
djnz b,chkagain6
mov r3,#21d // 21 bytes
mov dptr,#modeSetSuccess
lcall sendResp
mov r4,#03// saw
ret
exit6: mov b,r1
mov r0,#40h
mov dptr,#qry7
chkagain7:clr a
movc a,@a+dptr
clr c
subb a,@r0
jnz exit7
inc r0
inc dptr
djnz b,chkagain7
lcall getMode // sends wave type serially
ret // depending on R4
exit7: mov r3,#09d // 9 bytes
mov dptr,#resp7 // command error
lcall sendresp
ret
//********* END OF SUBROUTINES **********//
//******** ROM ********//
org 0500h
qry1:db"*IDN?",13 //6 bytes
resp1:db"PROGRAMMABLE FUNCTION GENERATOR",13,10 //33 bytes
qry2:db":VER?",13 //6 bytes
resp2:db"VERSION 1.1",13,10 //13 bytes
qry3:db":MODE:SIN?",13 //11 bytes
resp3:db"SINE WAVE",13,10 //11 bytes
qry4:db":MODE:SQR?",13 //11 bytes
resp4:db"SQUARE WAVE",13,10 //13 bytes
qry5:db":MODE:TRI?",13 //11 bytes
resp5:db"TRIANGULAR WAVE",13,10 //17 bytes
qry6:db":MODE:STH?",13 //11 bytes
resp6:db"SAWTOOTH WAVE",13,10 //15 bytes
qry7:db":MODE?",13 //7 bytes
resp7:db"CMD ERR",13,10 //9 bytes
modeSetSuccess: DB "MODE SET SUCCESSFUL",13,10// 21
SINE: DB "SINE",13,10//6
SQUARE: DB "SQUARE",13,10//8
SAWTOOTH: DB "SAWTOOTH",13,10//10
TRIANGLE: DB "TRIANGLE",13,10//10
sineLookUp:
db 80h,96h,0abh,0c0h,0d2h,0e2h,0efh
db 0f8h,0feh,0ffh,0feh,0f8h,0efh,0e2h
db 0d2h,0c0h,0abh,096h,80h,6ah,54h
db 40h,2eh,1eh,11h,08h,02h,00h,02h,08h
db 02h,00h,02h,08h,11h,1eh,2eh,40h,54h,6ah,80h
end
// ********* THE END ***********//
Comments
Post a Comment