图形工具的使用 1. 启动CCS后,打开位于C:\ti\tutorial\evm6201\modem下的工程文件modem.pjt。 2. 打开工程文件后,在编译选项中关闭各种优化选项,打开调试选项。然后编译连接并加载程序到目标系统中。 3. 在main()函数中找到对ReadNextData()函数调用的地方。在此处设置“File I/O”。设置两个文件输入,分别是pseudo.dat输入到g_ModemData.dataSymbols,长度为1,以及gauss32.dat输入到g_ModemData.cNoise,长度为2。 4. 选择“View”|“Graph”|“TimeFrequency”命令,出现了“Graph Property”的对话框,用于设置显示图形的特性,在这里进行简单设置。 5. 选择“Debug”|“Probe point”命令,出现探针对话框,将探针与一个图形显示连接。 6. 选择“Debug”|“Animate”命令,这时在波形显示窗口中应该可以看到不断刷新的波形。
7. 选择“View”|“Graph”|“Eye Diagram”命令,出现眼图属性设置对话框。将探针与该眼图连接,然后运行“Animate”。
8. 选择“View”|“Graph”|“Constellation”命令,出现星座图属性设置对话框。将探针与该眼图连接,然后运行“Animate”。
modemtx.h代码
#include "sinetab.h" #include "razedcos.h"
#define NUM_CONSTELATION_POINTS 16 #define SAMPLES_PER_BAUD 32 #define BAUD_PER_LOOP 1
struct POINT { int I; /* in-phase symbol amplitude */ int Q; /* quadrature-phase symbol amplitude */ };
struct MODEM_PARAMETERS { int samplesPerBaud; int phase; int carrierFreq; int noiseLevel; /* 0 to 16 */ int dataSymbols[BAUD_PER_LOOP]; struct POINT cPoints[BAUD_PER_LOOP]; struct POINT cNoise[BAUD_PER_LOOP]; int Idelay[SIZE_SHAPING_FILTER]; int Qdelay[SIZE_SHAPING_FILTER]; int OutputBuffer[SAMPLES_PER_BAUD*BAUD_PER_LOOP]; int SymbolClock[SAMPLES_PER_BAUD*BAUD_PER_LOOP]; };
/* function prototypes */ int SineLookup(int); int CosineLookup(int); int Modulation(int, int, int); void ShapingFilter(int *, int); void ModemTransmitter(int, int *); void Initialize(void); void ReadNextData(void); void ReadConstellation(void); void AddNoiseSignal(void);
modemtx.c代码
#include "modemtx.h" #include "razedcos.h" /* table for raised cosine shaping filter */ #include "sinetab.h" /* sine look-up table */
/* definition of constelation space */ struct POINT constellation[NUM_CONSTELATION_POINTS] = { /* first quadrant */ {0x1000, 0x1000}, {0x3000, 0x3000}, {0x1000, 0x3000}, {0x3000, 0x1000},
/* second quadrant */ {-0x1000, 0x1000}, {-0x3000, 0x3000}, {-0x1000, 0x3000}, {-0x3000, 0x1000},
/* third quadrant */ {-0x1000, -0x1000}, {-0x3000, -0x3000}, {-0x1000, -0x3000}, {-0x3000, -0x1000},
/* fourth quadrant */ {0x1000, -0x1000}, {0x3000, -0x3000}, {0x1000, -0x3000}, {0x3000, -0x1000}, };
/* global structures */ struct MODEM_PARAMETERS g_ModemData;
struct TEST { long I; long j; } g_test;
/******************************************************* SineLookup() ============
This function returns a sine function. It is implemented with a 1/4 wave look up table. To
*******************************************************/ int SineLookup(int sample) { int sineValue;
/* Find offset into 1/4 wave table, adjusting for quadrants 2 and 4 */ int offset = sample & (SIZE_SINE_TABLE-1); if (sample & SIZE_SINE_TABLE) offset = SIZE_SINE_TABLE-1-offset;
/* Read value from sine table, adjusting the sign for quadrants 3 and 4 */ sineValue = sineTable[offset]; if (sample & (SIZE_SINE_TABLE*2)) sineValue = -sineValue;
return(sineValue); }
/******************************************************* CosineLookup() ==============
This function returns a cosine function. It is implemented by calling the SineLookup() function and adjusting the phase.
*******************************************************/ int CosineLookup(int sample) { return( SineLookup(sample + SIZE_SINE_TABLE) ); }
/******************************************************* Modulation() ==============
This function the modulated result of an in-phase and quadrature phase component, added together.
*******************************************************/ int Modulation(int Isample, int Qsample, int phase) { #if defined(PROD_C6X) /* work-around C6x compiler bug when using long multiplication */ long result = (short)Isample * (short)SineLookup(phase); result += (short)Qsample * (short)CosineLookup(phase); #else long result = (long)Isample * (long)SineLookup(phase); result += (long)Qsample * (long)CosineLookup(phase); #endif result >>= 14; return((int)result); }
/******************************************************* ShapingFilter() ===============
This function shapes either the in-phase or quadrature phase component using a raised cosine filter. The user must pass in a delayLine big enough to hold the shaping filter. The output is calculated one baud at a time, and is found at the front of the delay line.
*******************************************************/ void ShapingFilter(int *delayLine, int amplitudeOfSymbol) { int I;
/* shift the delay line */ for(I = 0; I < SIZE_SHAPING_FILTER - SAMPLES_PER_BAUD; I++ ) { delayLine[I] = delayLine[I+SAMPLES_PER_BAUD]; }
/* clear end of delay buffer before addition operation */ for( ; I < SIZE_SHAPING_FILTER; I++ ) { delayLine[I] = 0; }
/* add new symbol into delay line */ for( I = SIZE_SHAPING_FILTER; I--; ) { #if defined(PROD_C6X) delayLine[I] += (((short)raisedCosineTable[I] * (short)amplitudeOfSymbol)>>14); #else delayLine[I] += ((raisedCosineTable[I] * (long)amplitudeOfSymbol)>>14); #endif } }
/******************************************************* ModemTransitter() =================
This function runs the Tx modulator to generate one baud of output signal. This function calls the ShapingFilter() function to generate I and Q samples, then modulates by the carrier frequency and adds the I and Q together.
*******************************************************/ void ModemTransmitter(int baudIndex, int *outputBuffer) { /* local variables */ int Iamplitude; /* Quadrature component amplitude */ // int Qamplitude; /* Quadrature component amplitude */ // int n; /* loop index for each baud */ // static struct POINT ConstellationPoint;
/******************* 1. Look up in-phase and quadrature amplitudes ********************/ Iamplitude = g_ModemData.cPoints[baudIndex].I; // Qamplitude = g_ModemData.cPoints[baudIndex].Q;
/******************* 2. Run in-phase and quadrature components through baseband shaping filter, with interpolation ********************/ ShapingFilter(g_ModemData.Idelay, Iamplitude); /*RP:TEMP ShapingFilter(g_ModemData.Qdelay, Qamplitude); */
/******************* 4. Modulate the in-phase and quadrature components to generate the output signal from the transmitter ********************/ /*RP:TEMP for (n = 0; n < SAMPLES_PER_BAUD; n++ ) { outputBuffer[n] = Modulation(g_ModemData.Idelay[n], g_ModemData.Qdelay[n], g_ModemData.phase);
increment phase for next pass g_ModemData.phase += g_ModemData.carrierFreq; } */ }
/******************************************************* Initialize() ============
This function initializes the global modem parameter structure;
*******************************************************/ void Initialize(void) { int I;
#if defined(C54X) asm(" RSBX OVM"); #endif
g_ModemData.carrierFreq = 15; /* increment through 125Hz sine table */ g_ModemData.phase = 0; /* initialize phase for carrier */ g_ModemData.samplesPerBaud = SAMPLES_PER_BAUD; g_ModemData.noiseLevel = 0;
/* zero delay lines for shaping filter */ for( I = SIZE_SHAPING_FILTER; I--; ) { g_ModemData.Idelay[I] = 0; g_ModemData.Qdelay[I] = 0; } /* clear output buffer */ for( I = SAMPLES_PER_BAUD*BAUD_PER_LOOP; I--; ) { g_ModemData.OutputBuffer[I] = 0; }
/* clear data, constellation, and noise buffers */ for( I = BAUD_PER_LOOP; I--; ) { g_ModemData.dataSymbols[I] = 0; g_ModemData.cPoints[I].I = 0; g_ModemData.cPoints[I].Q = 0; g_ModemData.cNoise[I].I = 0; g_ModemData.cNoise[I].Q = 0; }
for( I = BAUD_PER_LOOP; I--; ) { int j; g_ModemData.SymbolClock[I*SAMPLES_PER_BAUD] = 1; for( j = SAMPLES_PER_BAUD; --j > 0; ) { g_ModemData.SymbolClock[I*SAMPLES_PER_BAUD+j] = -1; } } }
/* read next data, convert to constellation points, and add noise */ void ReadNextData(void) { /* add code here to generate modem data */ ReadConstellation(); }
/* convert data to constellation points and add noise */ void ReadConstellation(void) { AddNoiseSignal(); }
/******************************************************* AddNoiseSignal() ================
This function adds noise to the constellation points for the modem transmitter;
*******************************************************/ void AddNoiseSignal(void) { /* Add code here to read noise signal from disk */
int I; int noiseVolume = 10 - g_ModemData.noiseLevel;
for( I = BAUD_PER_LOOP; I--; ) { /* convert data to constellation points */ g_ModemData.cPoints[I] = constellation[(g_ModemData.dataSymbols[I])&15];
/* Add noise to constellation points, only if level not zero */ if (g_ModemData.noiseLevel != 0) { if (noiseVolume < 0) { /* if volume is negative, shift to the left */ g_ModemData.cPoints[I].I += (g_ModemData.cNoise[I].I << (-noiseVolume)); g_ModemData.cPoints[I].Q += (g_ModemData.cNoise[I].Q << (-noiseVolume)); } else { g_ModemData.cPoints[I].I += (g_ModemData.cNoise[I].I >> noiseVolume); g_ModemData.cPoints[I].Q += (g_ModemData.cNoise[I].Q >> noiseVolume); } } } }
/******************************************************* Main() ======
Main loop for modem transmitter example program.
*******************************************************/ void main(void) { int I;
g_test.I = -16; g_test.j = 0x12345678; g_test.j <<= 4; g_test.I *= g_test.j;
/* Initialize modem transmitter */ Initialize();
/* testing the carrier signal generator */ for(I = 0; I < SAMPLES_PER_BAUD; I++ ) { g_ModemData.OutputBuffer[I] = SineLookup(I*g_ModemData.carrierFreq); }
for(I = 0; I < SAMPLES_PER_BAUD; I++ ) { g_ModemData.OutputBuffer[I] = CosineLookup(I*g_ModemData.carrierFreq); }
/* loop forever */ while(1) { /* get modem data, convert to constellation points, and add noise. */ ReadNextData();
/* run modem on new data */ for( I = 0; I < BAUD_PER_LOOP; I++ ) { ModemTransmitter(I, &(g_ModemData.OutputBuffer[I*SAMPLES_PER_BAUD])); } } }
razedcos.h代码
#define SIZE_SHAPING_FILTER 255
extern int raisedCosineTable[SIZE_SHAPING_FILTER];
razed32.c代码 #include "razedcos.h"
/************************************* Raised Cosine Shaping Filter (alpha = 0.5, 4 samples/baud) **************************************/
int raisedCosineTable[SIZE_SHAPING_FILTER] = { /*annie*/ 0x9, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3e, 0x46, 0x4c, 0x52, 0x57, 0x5b, 0x5e, 0x5f, 0x5f, 0x5e, 0x5b, 0x57, 0x52, 0x4c, 0x45, 0x3e, 0x36, 0x2d, 0x25, 0x1d, 0x15, 0xe, 0x8, 0x4, 0x1, 0x0, 0x1, 0x4, 0xa, 0x13, 0x1e, 0x2b, 0x3c, 0x4e, 0x63, 0x7a, 0x93, 0xad, 0xc8, 0xe4, 0xff, 0x119, 0x132, 0x148, 0x15c, 0x16b, 0x177, 0x17c, 0x17c, 0x175, 0x166, 0x14f, 0x12f, 0x106, 0xd3, 0x97, 0x50, 0x0, 0xffffffa7, 0xffffff43, 0xfffffed7, 0xfffffe62, 0xfffffde6, 0xfffffd63, 0xfffffcdc, 0xfffffc51, 0xfffffbc4, 0xfffffb36, 0xfffffaaa, 0xfffffa22, 0xfffff9a0, 0xfffff925, 0xfffff8b5, 0xfffff852, 0xfffff7fe, 0xfffff7bc, 0xfffff78f, 0xfffff777, 0xfffff779, 0xfffff796, 0xfffff7d1, 0xfffff82a, 0xfffff8a5, 0xfffff943, 0xfffffa04, 0xfffffaeb, 0xfffffbf7, 0xfffffd2a, 0xfffffe83, 0x0, 0x1a6, 0x36f, 0x55c, 0x76b, 0x99a, 0xbe7, 0xe4e, 0x10ce, 0x1362, 0x1607, 0x18b9, 0x1b75, 0x1e36, 0x20f7, 0x23b5, 0x266a, 0x2913, 0x2ba9, 0x2e2a, 0x3090, 0x32d7, 0x34fa, 0x36f7, 0x38c9, 0x3a6c, 0x3bde, 0x3d1c, 0x3e24, 0x3ef3, 0x3f88, 0x3fe2, 0x4000, 0x3fe2, 0x3f88, 0x3ef3, 0x3e24, 0x3d1c, 0x3bde, 0x3a6c, 0x38c9, 0x36f7, 0x34fa, 0x32d7, 0x3090, 0x2e2a, 0x2ba9, 0x2913, 0x266a, 0x23b5, 0x20f7, 0x1e36, 0x1b75, 0x18b9, 0x1607, 0x1362, 0x10ce, 0xe4e, 0xbe7, 0x99a, 0x76b, 0x55c, 0x36f, 0x1a6, 0x0, 0xfffffe83, 0xfffffd2a, 0xfffffbf7, 0xfffffaeb, 0xfffffa04, 0xfffff943, 0xfffff8a5, 0xfffff82a, 0xfffff7d1, 0xfffff796, 0xfffff779, 0xfffff777, 0xfffff78f, 0xfffff7bc, 0xfffff7fe, 0xfffff852, 0xfffff8b5, 0xfffff925, 0xfffff9a0, 0xfffffa22, 0xfffffaaa, 0xfffffb36, 0xfffffbc4, 0xfffffc51, 0xfffffcdc, 0xfffffd63, 0xfffffde6, 0xfffffe62, 0xfffffed7, 0xffffff43, 0xffffffa7, 0x0, 0x50, 0x97, 0xd3, 0x106, 0x12f, 0x14f, 0x166, 0x175, 0x17c, 0x17c, 0x177, 0x16b, 0x15c, 0x148, 0x132, 0x119, 0xff, 0xe4, 0xc8, 0xad, 0x93, 0x7a, 0x63, 0x4e, 0x3c, 0x2b, 0x1e, 0x13, 0xa, 0x4, 0x1, 0x0, 0x1, 0x4, 0x8, 0xe, 0x15, 0x1d, 0x25, 0x2d, 0x36, 0x3e, 0x45, 0x4c, 0x52, 0x57, 0x5b, 0x5e, 0x5f, 0x5f, 0x5e, 0x5b, 0x57, 0x52, 0x4c, 0x46, 0x3e, 0x36, 0x2d, 0x24, 0x1b, 0x12, 0x9 };
sinetab.h代码 #define SIZE_SINE_TABLE 128
extern int sineTable[SIZE_SINE_TABLE];
sinetab.c代码 #include "sinetab.h"
/************************************* 1/4 wave sine table. 20Hz at 8KHz. **************************************/
int sineTable[SIZE_SINE_TABLE] = { 0x0, 0xc9, 0x192, 0x25b, 0x324, 0x3ed, 0x4b5, 0x57e, 0x646, 0x70e, 0x7d6, 0x89d, 0x964, 0xa2b, 0xaf1, 0xbb7, 0xc7c, 0xd41, 0xe06, 0xeca, 0xf8d, 0x1050, 0x1112, 0x11d3, 0x1294, 0x1354, 0x1413, 0x14d2, 0x158f, 0x164c, 0x1708, 0x17c3, 0x187e, 0x1937, 0x19ef, 0x1aa7, 0x1b5d, 0x1c12, 0x1cc6, 0x1d79, 0x1e2b, 0x1edc, 0x1f8b, 0x203a, 0x20e7, 0x2193, 0x223d, 0x22e6, 0x238e, 0x2435, 0x24da, 0x257d, 0x2620, 0x26c0, 0x2760, 0x27fd, 0x289a, 0x2934, 0x29cd, 0x2a65, 0x2afb, 0x2b8f, 0x2c21, 0x2cb2, 0x2d41, 0x2dce, 0x2e5a, 0x2ee4, 0x2f6b, 0x2ff2, 0x3076, 0x30f8, 0x3179, 0x31f7, 0x3274, 0x32ef, 0x3367, 0x33de, 0x3453, 0x34c6, 0x3537, 0x35a5, 0x3612, 0x367c, 0x36e5, 0x374b, 0x37af, 0x3811, 0x3871, 0x38cf, 0x392a, 0x3984, 0x39db, 0x3a30, 0x3a82, 0x3ad3, 0x3b21, 0x3b6c, 0x3bb6, 0x3bfd, 0x3c42, 0x3c85, 0x3cc5, 0x3d03, 0x3d3e, 0x3d78, 0x3dae, 0x3de3, 0x3e15, 0x3e44, 0x3e72, 0x3e9d, 0x3ec5, 0x3eeb, 0x3f0f, 0x3f30, 0x3f4f, 0x3f6b, 0x3f85, 0x3f9c, 0x3fb1, 0x3fc4, 0x3fd4, 0x3fe1, 0x3fec, 0x3ff5, 0x3ffb, 0x3fff };
|