/* Final Project ECE 476 Gus Lott - GKL6@cornell.edu Maruthi Narayanan - MN252@cornell.edu DISC DOCTOR This code is the intellectual property of the authors */ #include #include #include #include #pragma regalloc- register char accumulatorX1; register char accumulatorX2; register char incX1; register char incX2; register char accumulatorY1; register char accumulatorY2; register char incY1; register char incY2; register char incZ1; register char incZ2; register char accumulatorZ1; register char accumulatorZ2; #pragma regalloc+ unsigned int i; unsigned char sinTable[256] @0x0300; void main(void){ accumulatorX1=0; accumulatorX2=0; accumulatorY1=0; accumulatorY2=0; accumulatorZ1=0; accumulatorZ2=0; //Init sine table for DDS for (i=0; i<256; i++) { sinTable[i] = (unsigned char)(128 + (127.0 * sin(6.283*((float)i)/255.0))); } //Set bottom of X increments incX1=0x01; incX2=0x00; //Set bottom of Y increments incY1=0x05; incY2=0x00; //Set bottom of Z increments incZ1=0x09; incZ2=0x00; //Fs = 160 kHz for 50 clock cycles per sample //DDRn SETUP FOR D/A DDRD=0xff; DDRC=0xff; DDRB=0xff; //Initialize ADC ADMUX=0b00000000; //Right Adjusts Data ADCSR=0b11000111; ADCSR.6=1; //Start a conversion #asm ;PREPARE VARIABLES cli ldi r27,0x03 clr r15 clr r21 clr r22 clr r23 mov r28,_incX1 mov r29,_incY1 mov r30,_incZ1 ;The program never leaves this assembly loop, so we do not have to worry about overwriting ;any relevant C variables that codevision uses. We can use any/all of the registers and memory space ;MAIN LOOP SampleLoop: ;CHECK if Sample is ready, bypass Acquisition code if it is not ready ;NUMBERS to right are clock cycles per opperation for counting in r19, $06 ;Bring in ADCSR ;1 andi r19,$40 ;isolate ;1 tst r19 ;1 brne noAD ;1 if false, 2 if true ;DETERMINE Which value is ready (x,y,z) since the signals are multiplexed ;AD value is ready cpi r23,1 ;1 breq yin ;1 if false, 2 if true cpi r23,2 ;1 breq zin ;1 if false, 2 if true ;IF X value, use actual raw A/D value to increment one DDS accumulator with a given increment offset xin: nop in _incX2,$04 ;low byte of ADC input ;1 in r22,$05 ;high byte of ADC input ;1 andi r22,0b00000011 ;1 mov _incX1,r28 ;1 add _incX1,r22 ;1 ldi r19, 0b00000001; ;1 out $07,r19 ;1 ldi r23,1 ;1 rjmp nextConverstion ;2 ;SIMILAR method for other 2 directions ;WHEN completed with acquisition, point to next channel in the sequence (x to y to z back to x etc) yin: nop nop in _incY2,$04 ;low byte of ADC input ;1 in r22,$05 ;high byte of ADC input andi r22,0b00000011 mov _incY1,r29 add _incY1,r22 ldi r19, 0b00000010; ;1 out $07,r19 ;1 ldi r23,2 ;1 rjmp nextConverstion ;2 zin: in _incZ2,$04 ;low byte of ADC input ;1 in r22,$05 ;high byte of ADC input andi r22,0b00000011 mov _incZ1,r30 add _incZ1,r22 ldi r19, 0b00000000; ;1 out $07,r19 ;1 ldi r23,0 ;1 rjmp nextConverstion ;2 nextConverstion: ;INITIATE The next A/D conversion sbi $06,6 ;initiate another conversion ;2 rjmp postAD ;2 noAD: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop postAD: ;OPEN INPUT BUFFER on D/A CONVERTER cbi $15,5 ;INCREMENT EACH OF THREE ACCUMULATORS add _accumulatorX2, _incX2 adc _accumulatorX1, _incX1 add _accumulatorY2, _incY2 adc _accumulatorY1, _incY1 add r15, _incZ2 adc _accumulatorZ1, _incZ1 ;EXTRACT CORRESPONDING SINE VALUES FROM THE TABLE ;FOR EACH OF THE THREE ACCUMULATORS mov r26,_accumulatorX1 ld r16,X mov r26,_accumulatorY1 ld r17,X mov r26,_accumulatorZ1 ld r18,X clr r19 clr r20 ;ADD THE LEVELS OF THE SINE WAVES TOGETHER ;THIS IS THE FINAL STEP IN THE FREQUENCY DIVISION MULTIPLEXING ENCODING SCHEME add r16,r17 ;add x and y sine values adc r19,r20 ;carry into r19 add r16,r18 ;add x/y sum and z sine value adc r19,r20 ;carry into r19 ;OUTPUT THE 10-BIT VALUE TO THE PORT PINS THAT ARE CONNECTED TO THE D/A converter out $12,r16 ;8 LSBs on PORTD out $15,r19 ;2 MSBs on PORTC ;LATCH IN NEW VALUE TO D/A Converter sbi $15,5 ;LOOP FOR A TOTAL OF 50 CLOCK CYCLES rjmp SampleLoop #endasm }