With the DDS RAM registers a desired function "frequency (time)" can be implemented for one of the output channels and triggered either by the serial terminal or by an external signal on one of the mbed pins.
Revision 7:c186636817d0, committed 2012-11-09
- Comitter:
- ahambi
- Date:
- Fri Nov 09 16:02:56 2012 +0000
- Parent:
- 0:2160f1821475
- Commit message:
- With the DDS RAM registers a desired function "frequency(time)" can be implemented for one of the output channels and triggered either by the serial terminal or by an external signal on one of the mbed pins.
Changed in this revision
diff -r 2160f1821475 -r c186636817d0 main.cpp --- a/main.cpp Tue Jul 03 08:42:52 2012 +0000 +++ b/main.cpp Fri Nov 09 16:02:56 2012 +0000 @@ -1,8 +1,5 @@ -// compile --> copy to mbed -// ALT + B in serial terminal --> break command for mbed - // **************************************** -// *** frequency ramps with the the RAM *** +// *** frequency ramps with the RAM *** // **************************************** #include "mbed.h" @@ -30,6 +27,8 @@ double ref_clock = 400.0e6; // ##################### definition of functions ############################ + +// reset the DDS: int reset() { rst = 0; rst = 1; @@ -50,22 +49,29 @@ return 0; } +// This function always rounds values up (in mode ?? of the DDS a problem occurs +// if the final value is not reached int round(double a) { return int(a + 0.5); } +// Calculate the "Frequency Tuning Word (FTWO)" for the DDS registers: uint32_t FTWO_func(double frequency) { return 0xFFFFFFFF & round(frequency/ref_clock*pow(2.0,32.0)); } - + +// RSCW0, RSCW1, RSCW2 and RSCW3 are the RAM profiles of the DDS which can be filled with different +// parts of the ramp: +// ************* RSCW0 ****************** void writeRSCW0(int r0, int r1, uint32_t RSCW, double f[]) { int R_used = r1-r0; uint32_t FTWO[R_used]; ps0 = 0; ps1 = 0; update = 0; + // For the structure of the RSCW0 byte see the register map of the DDS. // Instruction byte: page 25, we want to write (0), so 0100 - // + internal adress of the register to be written in + // and internal adress of the register to be written in DDS._spi.write(0x00 | (0x07 & 0x1F)); // byte 5: Ramp rate first part DDS._spi.write(0xFF & RSCW); @@ -80,151 +86,118 @@ update = 1; wait_us(10);//5*1/(12.0e6)); update =0; - + + // The frequency ramp is given as an array of frequencies. Here the frequency tuning + // words (FTWOs) are calculated: i = 0; while (i<=(R_used)) { - //FTWO[i] = FTWO_func(frequency[i]); FTWO[R_used-i] = FTWO_func(f[i]); - //pc.printf("written %i %lf \r \n", i, f[i]); i += 1; } - + // Print start and final value of the RAM part: pc.printf("RSCW0 written: %lf %lf \r\n", f[0], f[R_used]); - + // Select the combination of ps0 and ps1 belonging to RSCW0 and start the RAM writing process: ps0 = 0; ps1 = 0; - + // Send instruction byte to start the RAM writing process: DDS._spi.write(0x0B); - + // Write the frequency tuning words into the RAM: i = 0; while (i<=(R_used)) { DDS.RAM_write_FTWO(FTWO[i]); - // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]); i += 1; } } +// ************* RSCW1 ****************** void writeRSCW1(int r0, int r1, uint32_t RSCW, double f[]) { int R_used = r1-r0; uint32_t FTWO[R_used]; ps0 = 1; ps1 = 0; update = 0; - // Instruction byte: page 25, we want to write (0), so 0100 - // + internal adress of the register to be written in DDS._spi.write(0x00 | (0x08 & 0x1F)); - // byte 5: Ramp rate first part DDS._spi.write(0xFF & RSCW); - // byte 4: Ramp rate second part DDS._spi.write(0xFF & (RSCW >> 8)); - // byte 3: final address <7:0> DDS._spi.write(0xFF & r1); - // byte 2 DDS._spi.write(((r0 << 2) & 0xFC) | ((r1 >> 8) & 0x03)); - // byte 1: beginning address <9:6> DDS._spi.write(0x20 | (((r0 >> 6) & 0x0F))); update = 1; - wait_us(10);//5*1/(12.0e6)); + wait_us(10); update =0; i = 0; while (i<=(R_used)) { - //FTWO[i] = FTWO_func(frequency[i]); FTWO[R_used-i] = FTWO_func(f[i]); - //pc.printf("written %i %lf \r \n", i, f[i]); i += 1; - } - + } pc.printf("RSCW1 written: %lf %lf \r\n", f[0], f[R_used]); ps0 = 1; ps1 = 0; - DDS._spi.write(0x0B); - i = 0; while (i<=(R_used)) { DDS.RAM_write_FTWO(FTWO[i]); - // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]); i += 1; } } - + +// ************* RSCW2 ****************** void writeRSCW2(int r0, int r1, uint32_t RSCW, double f[]) { int R_used = r1-r0; uint32_t FTWO[R_used]; ps0 = 0; ps1 = 1; update = 0; - // Instruction byte: page 25, we want to write (0), so 0100 - // + internal adress of the register to be written in DDS._spi.write(0x00 | (0x09 & 0x1F)); - // byte 5: Ramp rate first part DDS._spi.write(0xFF & RSCW); - // byte 4: Ramp rate second part DDS._spi.write(0xFF & (RSCW >> 8)); - // byte 3: final address <7:0> DDS._spi.write(0xFF & r1); - // byte 2 DDS._spi.write(((r0 << 2) & 0xFC) | ((r1 >> 8) & 0x03)); - // byte 1: beginning address <9:6> DDS._spi.write(0x20 | (((r0 >> 6) & 0x0F))); update = 1; - wait_us(10);//5*1/(12.0e6)); + wait_us(10); update =0; i = 0; while (i<=(R_used)) { - //FTWO[i] = FTWO_func(frequency[i]); FTWO[R_used-i] = FTWO_func(f[i]); - //pc.printf("written %i %lf \r \n", i, f[i]); i += 1; } - pc.printf("RSCW0 written: %lf %lf \r\n", f[0], f[R_used]); - + pc.printf("RSCW0 written: %lf %lf \r\n", f[0], f[R_used]); ps0 = 0; ps1 = 1; DDS._spi.write(0x0B); - i = 0; while (i<=(R_used)) { DDS.RAM_write_FTWO(FTWO[i]); - // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]); i += 1; } } - +// ************* RSCW3 ****************** void writeRSCW3(int r0, int r1, uint32_t RSCW, double f[]) { int R_used = r1-r0; uint32_t FTWO[R_used]; ps0 = 1; ps1 = 1; update = 0; - // Instruction byte: page 25, we want to write (0), so 0100 - // + internal adress of the register to be written in - DDS._spi.write(0x00 | (0x10 & 0x1F)); - // byte 5: Ramp rate first part + DDS._spi.write(0x00 | (0x0A & 0x1F)); DDS._spi.write(0xFF & RSCW); - // byte 4: Ramp rate second part DDS._spi.write(0xFF & (RSCW >> 8)); - // byte 3: final address <7:0> DDS._spi.write(0xFF & r1); - // byte 2 DDS._spi.write(((r0 << 2) & 0xFC) | ((r1 >> 8) & 0x03)); - // byte 1: beginning address <9:6> DDS._spi.write(0x20 | (((r0 >> 6) & 0x0F))); update = 1; - wait_us(10);//5*1/(12.0e6)); + wait_us(10); update =0; i = 0; while (i<=(R_used)) { - //FTWO[i] = FTWO_func(frequency[i]); FTWO[R_used-i] = FTWO_func(f[i]); - //pc.printf("written %i %lf \r \n", i, f[i]); i += 1; } @@ -232,17 +205,15 @@ ps0 = 1; ps1 = 1; - DDS._spi.write(0x0B); - i = 0; while (i<=(R_used)) { DDS.RAM_write_FTWO(FTWO[i]); - // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]); i += 1; } } +// Function to calculate the RSCW-word used in RSCW1, RSCW2, RSCW3 and RSCW4 uint64_t RSCW_func(int ram0, int ram1, double trise) { int RAM_used = ram1-ram0+1; double tmin = 1.0*4.0/ref_clock*RAM_used; // minimum 1 dwell of time 4/clock at each address @@ -254,9 +225,12 @@ return 0xFFFF & dwells; } -int counter(double t) {// for t in us +// The wait-function doesn't offer time resolution of mikroseconds. By using a process like +// counting up an integer number and measuring the time the mbed needs for this process a time +// resolution of some tens of nano-seconds can be reached. "counter()" is used in "start_ramp()" +// below: +int counter(double t) { int bins = int((t-91.8160e-9)/(41.6664e-9) + 0.5); - //pc.printf("bins = %i", bins); return bins; }; @@ -266,7 +240,7 @@ ps0 = 1; ps1 = 0; //----------------------------- - // NEVER EVER change this loop! + // NEVER EVER change this loop! (Allows for time measurement, see above) trigger = 0; trigger = 1; while(i<count){ @@ -277,11 +251,14 @@ ps0 = 0; ps1 = 0; i = 0; + while(i<count){ + i += 1; + } return 0; }; +// Functions used to select output channel 1 or 2 upon receive of an external trigger signal: void check_up(){ - // try to avoid initialization ramp ps0 = 0; ps1 = 1; ch_1(); DDS.CFR1_write(0x00000200); @@ -289,7 +266,6 @@ }; void check_down() { - // try to avoid initialization ramp ps0 = 0; ps1 = 1; ch_2(); DDS.CFR1_write(0x00000200); @@ -297,25 +273,27 @@ }; // ############################################################ - - // ##################### main part ############################ int main() { pc.printf(" \r \r \n \n ***** frequency sweep with DDS in RAM mode***** \r \r \n \n"); + pc.printf("Enter: \r \n"); + pc.printf("'1' or '2' --> select which of the two output channel should be ramped. \r \n"); + pc.printf("'a' --> frequency ramp with parameters 'trise' and 'tstay' and the frequency values in the mbed code is started and repeated with about 50 Hz. A trigger signal lies on output pin 13 of the mbed. \r \n"); + pc.printf("'t' --> read in a new value for 'tstay' \r \n"); reset(); - double tstay = 500.0e-6; + double tstay = 50.0e-6; // intermediate frequencies - double frequency0 = 78.98e6;//100.0e6; // both channels are initiated on this frequency - double frequency1 = 79.02e6;//110.0e6; + double frequency0 = 79.5e6;// both channels are initiated on this frequency + double frequency1 = 80.5e6; // tuning word RSCW0 variables - double trise_00 = 0.1e-6;//20.0e-6; - int ram0_00 = 50; - int ram1_00 = 55;//100; + double trise_00 = 100e-6; + int ram0_00 = 1; + int ram1_00 = 156; const int RAM_used_00 = ram1_00 - ram0_00; double f00 [RAM_used_00+1]; double frequency_init [1]; @@ -328,33 +306,20 @@ } // tuning word RSCW1 variables - double trise_10 = 0.1e-6; + double trise_10 = 10.0e-6;//0.1e-6; int ram0_10 = 250; - int ram1_10 = 255;//500; + int ram1_10 = 500; int RAM_used_10 = ram1_10-ram0_10; double f10 [RAM_used_10+1]; double P [RAM_used_10+1]; j = 0; while (j<=(RAM_used_10)) { - f10[j] = frequency1 + (frequency1-frequency0)/trise_10*j*trise_10/(RAM_used_10); + f10[j] = frequency0 + (frequency1-frequency0)/trise_10*j*trise_10/(RAM_used_10); j += 1; } - //### logistic function - /* - j = 0; - double alpha = log(double((RAM_used_10-1.0)*(RAM_used_10-1.0)))*1/RAM_used_10; - pc.printf("alpha %f\r\n",alpha); - double beta = 1/alpha*log(double(RAM_used_10-1)); - pc.printf("beta %f\r\n",beta); - while (j<=(RAM_used_10)) { - P[j] = 1.0/(1.0+exp(-(j-beta)*alpha)); - f10[j] = frequency0*(1-P[j]) + frequency1*P[j]; - j += 1; - } - f10[0] = frequency0; - f10[RAM_used_10] = frequency1; - pc.printf("P(0) = %f P(RAM_used) = %f \r\n", P[0], P[RAM_used_10]);*/ + + // (Logistic function from below could be added here) // ### calculation of RSCW-words ### uint64_t RSCW0 = RSCW_func(ram0_00, ram1_00, trise_00); @@ -362,7 +327,6 @@ uint64_t RSCW2 = RSCW_func(501, 501, 10.0e-6); // ### initialize both channels on the first intermediate frequency and write into their RAM - ch_1(); DDS.CFR1_write(0x00000200); @@ -378,36 +342,21 @@ writeRSCW1(ram0_10, ram1_10, RSCW1, f10); writeRSCW0(ram0_00, ram1_00, RSCW0, f00); writeRSCW2(501, 501, RSCW2, frequency_init); - /* - DDS.ASF_write(0xFFFF); - DDS.ARR_write(0xFF); - DDS.CFR1_write(0x84000200); - DDS.CFR1_write(0x80000200); - */ + //pc.printf("enter: \r \n 'u' to trigger ramp up \r \n 'd' to trigger ramp down \r \n 't' to enter new ramp time \r \n 's' for new start frequency \r \n 'e' for new end frequency \r \n"); char up_or_down = '0'; - double trise = trise_00; - + double trise = trise_00; while(1) { if(pc.readable()) { up_or_down = pc.getc(); if(up_or_down == 'a') { + pc.printf("a --> ramp started"); while(1) { start_ramp(trise, tstay); wait(2e-2); if(pc.readable()) break; } - //start_ramp(trise, tstay); - //pc.printf("sequence over ST \r \n"); - } - /*if (up_or_down == 'r') { - pc.printf("enter new time value in us: \n"); - pc.scanf("%lf", &trise); - trise = trise*1.0e-6; - initialize(frequency0, frequency1, RAM_start, RAM_final, trise); - check_down(); - }*/ if (up_or_down == 't') { pc.printf("enter new tstay value in us: \n"); pc.scanf("%lf", &tstay); @@ -466,8 +415,11 @@ initialize(frequency0, frequency1, RAM_start, RAM_final, trise); }*/ } + // Wait for a rising or falling edge on the mbed-mcs pin and select accordingly channel 1 or + // channel 2 for ramping mcs.rise(&check_up); mcs.fall(&check_down); + // start the ramp when a signal sets the mbed pin 'mexp' to '1' if(mexp) { while(mexp); start_ramp(trise, tstay); @@ -478,4 +430,19 @@ return 0; } + /* LOGISTIC FUNCTION + j = 0; + double alpha = log(double((RAM_used_10-1.0)*(RAM_used_10-1.0)))*1/RAM_used_10; + pc.printf("alpha %f\r\n",alpha); + double beta = 1/alpha*log(double(RAM_used_10-1)); + pc.printf("beta %f\r\n",beta); + while (j<=(RAM_used_10)) { + P[j] = 1.0/(1.0+exp(-(j-beta)*alpha)); + f10[j] = frequency0*(1-P[j]) + frequency1*P[j]; + j += 1; + } + f10[0] = frequency0; + f10[RAM_used_10] = frequency1; + pc.printf("P(0) = %f P(RAM_used) = %f \r\n", P[0], P[RAM_used_10]);*/ +
diff -r 2160f1821475 -r c186636817d0 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Nov 09 16:02:56 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479 \ No newline at end of file
diff -r 2160f1821475 -r c186636817d0 mbed.lib --- a/mbed.lib Tue Jul 03 08:42:52 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/projects/libraries/svn/mbed/trunk@43 \ No newline at end of file