; DDS3.ASM ; ; DIRECT DIGITAL FREQUENCY SYNTHESIS ; ; THIS TEST WILL USE A 4-BIT R2R NETWORK ON PINS P1.0 THRU P1.3. ; ; USING A 20-BIT PHASE ACCUMLATOR. THE MOST SIGNIFICANT FOUR BITS ; ARE USED AS AN INDEX INTO OUR 16-STEP SINE WAVE TABLE. ; ; OUR PHASE INCREMENT IS A 24-BIT VALUE ALLOWING FOR STEPS GREATER ; THAN 1-STEP. ; ;============================================================================ $NOLIST $INCLUDE(MOD8252) $LIST ;============================================================================ BASEADDR EQU 0000H FLAGS EQU 20H STACKSTART EQU 05FH ;STACK STARTING ADDRESS PA1 EQU 30H PA2 EQU 31H PA3 EQU 32H PI1 EQU 33H PI2 EQU 34H PI3 EQU 35H ;============================================================================ ; POWER-ON RESET VECTOR ;============================================================================ ORG BASEADDR LJMP START ORG BASEADDR+03H ;EXTERNAL 0 RETI ORG BASEADDR+0BH ;TIMER 0 RETI ORG BASEADDR+013H ;EXTERNAL 1 RETI ORG BASEADDR+01BH ;TIMER 1 RETI ORG BASEADDR+023H ;SERIAL (UART) RETI ORG BASEADDR+02BH ;TIMER 2 RETI ORG BASEADDR+033H ;=================================================================== ; OUR 16-STEP 4-BIT SINE WAVE TABLE ; NOTE THESE VALUES ALL HAVE THEIR UPPER FOUR BITS SET HIGH ; TO KEEP THE PORT PINS AS "INPUTS" ;=================================================================== SINE_WAVE: DB 0F8H, 0FAH, 0FDH, 0FEH, 0FFH, 0FEH, 0FDH, 0FAH DB 0F8H, 0F5H, 0F2H, 0F1H, 0F0H, 0F1H, 0F2H, 0F5H ;=================================================================== ; START OF MAIN PROGRAM CODE ;=================================================================== START: MOV SP,#STACKSTART ;SET UP OUR STACK ;START THE PHASE ACCUMULATOR AT ZERO MOV PA1,#0 MOV PA2,#0 MOV PA3,#0 ;STARTING THE PHASE INCREMENT VALUE MOV PI1,#066H MOV PI2,#066H MOV PI3,#0 MAIN_LOOP: ;GET DAC/R2R VALUE FROM TABLE MOV A,PA3 ANL A,#0FH MOV DPTR,#SINE_WAVE MOVC A,@A+DPTR ;OUTPUT IT TO THE R2R (PORT1) MOV P1,A ;BUMP OUR 20-BIT PHASE ACCUMULATOR BY OUR 24-BIT PHASE INCREMENT VALUE MOV A,PA1 ADD A,PI1 MOV PA1,A MOV A,PA2 ADDC A,PI2 MOV PA2,A MOV A,PA3 ADDC A,PI3 MOV PA3,A ;CONTINUE ON FOREVER LJMP MAIN_LOOP ; ;DELAY FOR 1 MILLISECOND TIMES VALUE IN ACC ; MSDELAY: PUSH B MOV B,#0C9H DJNZ B,$ DJNZ B,$ POP B DJNZ ACC,MSDELAY RET ;************************************************ ; ; INIT SERIAL PORT TO 9600/8/1/N ; INIT_SERIAL: MOV SCON,#52H ; MODE 1, 8 BIT WORD MOV TMOD,#20H ; 8/BIT AUTO RELOAD, FREE RUNNIN TIMER MOV TH1,#0FDH ; 9600 BAUD SETB TR1 RET ;************************************************ ; ; THIS SUBROUTINE RECEIVES A CHARACTER AT THE SERIAL PORT ; AND PLACES IT IN REGISTER A. ; RECV_BYTE: MOV A,#0 JNB RI,NADA CLR RI ; CLEAR THE RECEIVE FLAG ONCE RECIEVED MOV A,SBUF ; PLACE RECEIVED BYTE IN REGISTER A NADA: RET ;************************************************ ; ; THIS SUBROUTINE SENDS THE CONTENTS OF REGISTER A THROUGH THE SERIAL PORT. ; SEND_BYTE: JNB TI,SEND_BYTE ; WAIT FOR THE TI FLAG TO SET CLR TI ; CLEAR THE TI FLAG ONCE SENT MOV SBUF,A ; SEND THE CONTENTS OF REGISTER A RET ; RETURN ;***************************************************************************** ; ;PRINT PRINT: PUSH ACC ; push the A and DPTR registers so their contents PUSH DPH ; don't get lost in case they are being used PUSH DPL ; before calling this function. ; move the stack pointer down low in order to pop the first string's byte ; address MOV A,SP ADD A,#0FDH MOV SP,A POP DPH POP DPL ; send (PRINT) the string back to the PC computer READ_TX: CLR A MOVC A,@A+DPTR INC DPTR JZ BC SND: ACALL SEND_BYTE LJMP READ_TX ; place the new return addres in stack BC: PUSH DPL PUSH DPH ; move the stack pointer up high in order to pop the A and DPTR registers MOV A,SP ADD A,#3 MOV SP,A POP DPL POP DPH POP ACC RET ;************************************************ ; subroutine binasc ; binasc takes the contents of the accumulator and converts it ; into two ascii hex numbers. the result is returned in the ; accumulator and r2. binasc: mov r2, a ; save in r2 anl a, #0fh ; convert least sig digit. add a, #0f6h ; adjust it jnc noadj1 ; if a-f then readjust add a, #07h noadj1: add a, #3ah ; make ascii xch a, r2 ; put result in reg 2 swap a ; convert most sig digit anl a, #0fh ; look at least sig half of acc add a, #0f6h ; adjust it jnc noadj2 ; if a-f then re-adjust add a, #07h noadj2: add a, #3ah ; make ascii ret ;************************************************ ACC2HEX: PUSH ACC LCALL BINASC LCALL SEND_BYTE MOV A,R2 LCALL SEND_BYTE MOV A,#13 LCALL SEND_BYTE MOV A,#10 LCALL SEND_BYTE POP ACC RET ;************************************************ ; ;CONVERT ASCII IN ACC TO UPPERCASE ;RETURN UPPERCASE ASCII CHAR IN ACC ; UPPERC: ANL A,#07FH CJNE A,#'a',UPPERC3 UPPERC3: JC UPPERC5 CJNE A,#'z',UPPERC4 UPPERC4: JNC UPPERC5 ANL A,#0DFH UPPERC5: RET ;=================================================================== END ;END OF PROGRAM