📄 graph1.c
字号:
/* get input */
c = 0;
do {
if ((c = getch()) == 0) c = getch() - 0x3a;
} while (c < 1 && c > nkeys);
/* restore image */
putimage(x1,y1,imagebuf,COPY_PUT);
farfree(imagebuf);
return c;
}
/**************************************************************
* table_plot - this routine is used to list a table the a
* portion of the screen.
**************************************************************/
void table_plot(int x1, int y1, char *msg[])
{
int i,x,y,c,x2,y2,x3,y3,x4,y4,fxsiz;
int n,maxlength,nmessage;
char fmsg[32];
unsigned size;
void far *imagebuf;
/* determine the size of the message area */
for (nmessage=maxlength=0; msg[nmessage] != (char *)0; nmessage++) {
n = strlen(msg[nmessage]);
if (n > maxlength) maxlength = n;
}
x2 = x1 + 10 * maxlength;
y2 = y1 + 10 * (4 + nmessage);
/* save the bitmap for the window */
size = imagesize(x1,y1,x2,y2);
imagebuf = farmalloc(size);
getimage(x1,y1,x2,y2,imagebuf);
/* draw the background */
setfillstyle(SOLID_FILL,BLUE);
bar(x1,y1,x2,y2);
setfillstyle(SOLID_FILL,RED);
bar(x1+5,y1+5,x2-5,y2-5);
/* print the message */
x = (x1 + x2) / 2;
y = y1 + 20;
setcolor(WHITE);
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(CENTER_TEXT,CENTER_TEXT);
for (i=0; i < nmessage; i++) {
outtextxy(x,y,msg[i]);
y+=10;
}
/* wait for input */
getch();
/* restore image */
putimage(x1,y1,imagebuf,COPY_PUT);
farfree(imagebuf);
}
/**************************************************************
* const_monitor - This routine monitors the QAM Constellation.
**************************************************************/
int const_monitor(void)
{
int gdriver = DETECT, gmode, errorcode;
int xsiz,ysiz;
int nbytes,nwords,iscale;
int x,y,x1,x2,y1,y2,xctr,yctr,qpsk_xctr,qpsk_yctr;
int i,c,half_spacing;
int buf_status,done=0;
int ival,qval,hi,ilo,qlo;
int stat_win[4],fkey_win[4];
int ibuf[BUFSIZE],qbuf[BUFSIZE];
int qpsk_ibuf[64],qpsk_qbuf[64];
float grid_spacing,qpsk_grid_spacing,scale;
int val1, val2, val3, foo;
struct dostime_t time;
unsigned long t1, t2, deltaT;
float rms_nonlin,snr;
float snr_average=0.0;
float linear_noise_sum=0.0;
unsigned long RS_Correctable_Blocks_Accumulator = 0uL;
unsigned long RS_Uncorrectable_Blocks_Accumulator = 0uL;
unsigned long correctableBlocks, uncorrectableBlocks;
float num_points_in_snr_average=0.0;
float elapsedBits=0.0;
float bitsPerBaud=0.0;
float pre_fec_ber=0.0;
float post_fec_ber=0.0;
char snr_est_msg[32],qpsk_snr_msg[32],sample_cnt_msg[32],log_state_msg[32];
char pre_fec_ber_msg[32],post_fec_ber_msg[32];
char averaged_snr_msg[32];
char sd_sat_msg[32];
float i_err,q_err,err_sum;
int store_qam_to_file=0,store_qpsk_to_file=0;
int qam_samples_to_store=0,qpsk_samples_to_store=0;
FILE *fp;
long nsamples=0;
static int reduced_display = 1,accumulate = 0;
char *data_size_msg[] = {
"The constellation data will be stored in the DATA",
"directory. Specify the # of samples to store ",
(char *) 0
};
char *data_size_prompt[] = {
"256 Samples",
"2560 Samples",
"10K Samples",
(char *) 0
};
char *fkeys[] = {
"Zoom In " , /* F1 */
"Restart Meas." , /* F2 */
"" , /* F3 */
"Accumulate On" , /* F4 */
"Refresh" , /* F5 */
"" , /* F6 */
"" , /* F7 */
"Log QAM Data" , /* F8 */
"Reacquire" , /* F9 */
"Exit" /* F10 */
};
enum const_status_t {
QAM_LOCK_STATE = 0 ,
QAM_SNR_ESTIMATE ,
AVERAGED_SNR ,
SAMPLE_CNT ,
PRE_FEC_BER ,
POST_FEC_BER
};
int nstatus = 6; /* number of status lines in display */
plot_status_t status[] = {
"QAM Status : ", "In Lock" , "" ,
"QAM SNR Est : ", " " , "dB",
"Averaged SNR : ", " " , "dB",
"Sample Cnt : ", " " , "" ,
"BER (preFEC) : ", " " , "" ,
"BER (postFEC): ", " " , "" ,
};
/* read qam status */
qam_read_status();
/* init function key prompts */
fkeys[0] = (reduced_display) ? "Zoom In" : "Zoom Out";
fkeys[3] = (accumulate) ? "Accumulate Off" : "Accumulate On";
/* add persistence control */
/* zero buffer */
for (i=0; i<BUFSIZE; i++) ibuf[i] = qbuf[i] = 0;
/* init graphics mode and get screen size */
initgraph(&gdriver, &gmode, "");
if ((errorcode = graphresult()) != grOk) {
printf("Graphics error: %s\n", grapherrormsg(errorcode));
exit(1);
}
xsiz = getmaxx();
ysiz = getmaxy();
fkey_win[0] = 2*CONST_BORDER;
fkey_win[2] = xsiz - 2*CONST_BORDER;
fkey_win[1] = ysiz - 2*CONST_BORDER - FKEY_MENU_HEIGHT;
fkey_win[3] = ysiz - 2*CONST_BORDER;
/* get the start time for BER measurements */
_dos_gettime(&time);
t1 = (unsigned long) 360000uL*time.hour + 6000uL*time.minute + 100uL*time.second + time.hsecond;
while (!done) {
/* read qam status is in auto acq mode */
qam_read_status();
if (nsamples == 0) { /* redraw background */
/* draw in the background color */
setcolor(BLUE);
setfillstyle(SOLID_FILL,0);
bar(0,0,xsiz-1,ysiz-1);
/* draw the hotkey menu */
fkey_menu(1,fkey_win, fkeys);
/* draw the border */
setlinestyle(SOLID_LINE,0xffff,THICK_WIDTH);
setcolor(YELLOW);
rectangle(CONST_BORDER,CONST_BORDER,xsiz-CONST_BORDER,ysiz-CONST_BORDER);
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(CENTER_TEXT,CENTER_TEXT);
x1 = xsiz / 2;
y1 = CONST_BORDER / 2;
outtextxy(x1,y1,"QAM Constellation Monitor");
/* draw the QAM constellation plot border */
x1 = 2*CONST_BORDER;
y1 = 2*CONST_BORDER;
y2 = 256 + y1;
x2 = 256 + x1;
stat_win[0] = x2 + CONST_BORDER;
stat_win[1] = y1;
stat_win[2] = ysiz - 2*CONST_BORDER;
stat_win[3] = y1 + 120;
xctr = x1 + ((x2-x1) / 2);
yctr = y1 + ((y2-y1) / 2);
setcolor(YELLOW);
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
rectangle(x1,y1,x2,y2);
x = x1 + (x2-x1) / 2;
y = 3 * CONST_BORDER / 2;
settextstyle(SMALL_FONT,HORIZ_DIR,2);
settextjustify(CENTER_TEXT,CENTER_TEXT);
outtextxy(x,y,"QAM Constellation");
setcolor(CYAN);
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
line(x1,yctr,x2,yctr);
line(xctr,y1,xctr,y2);
setcolor(WHITE);
grid_spacing = 0.125*(x2-x1);
qpsk_grid_spacing = 0.5*128.0;
if (reduced_display) {
grid_spacing *= 0.5;
qpsk_grid_spacing *= 0.5;
}
}
/* !!! */ /* Mydelay(5000); */
/* sample data points and convert data */
for (i=0; i<BUFSIZE; i++) {
qam_read(MB_R,MB_LDSFT,&ibuf[i],&qbuf[i]);
if ((0x0080 & ibuf[i]) == 0x0080) ibuf[i] |= 0xff00;
if ((0x0080 & qbuf[i]) == 0x0080) qbuf[i] |= 0xff00;
}
/* store data to file if enabled */
if (store_qam_to_file) {
for (i=0; i<nwords; i++) fprintf(fp," %4d %4d\n" ,ibuf[i],qbuf[i]);
qam_samples_to_store -= nwords;
if (qam_samples_to_store <= 0) {
qam_samples_to_store = store_qam_to_file = 0;
fclose(fp);
}
}
if (store_qpsk_to_file) {
for (i=0; i<64; i++)
fprintf(fp," %4d %4d\n" ,qpsk_ibuf[i],qpsk_qbuf[i]);
qpsk_samples_to_store -= 64;
if (qpsk_samples_to_store <= 0) {
qpsk_samples_to_store = store_qpsk_to_file = 0;
fclose(fp);
}
}
nsamples += BUFSIZE;
nwords = BUFSIZE;
if ((nsamples > CONST_REFRESH) && (accumulate == 0)) nsamples = 0;
/* plot the QAM data points */
scale = (reduced_display) ? 0.5 : 1.0;
for (i=0; i<nwords; i++) {
x = xctr + (int) ((float) scale * ibuf[i]);
y = yctr + (int) ((float) scale * qbuf[i]);
/* dither point +- 1 pixel in zoom mode */
if (!reduced_display) {
x += CONST_DITHER;
y += CONST_DITHER;
}
putpixel(x,y,WHITE);
}
/* ---------------------------------------------- */
/* compute the rolling average of the SNR */
/* ---------------------------------------------- */
num_points_in_snr_average++;
/*
Convert to linear scale, invert and accumulate.
We invert so that the noise power is in the numerator, enabling us
to perform averaging on the quantity that we obtained
from the chip (noise power). Of course, we must invert again when
we convert back to a Signal : Noise ratio in dB scale
*/
linear_noise_sum += pow(10.0, -qam_status.snr_estimate / 20.0);
/* perform normalization and convert back to dB scale */
snr_average = -20.0 * log10(linear_noise_sum / num_points_in_snr_average);
/* ---------------------------------------------- */
/* compute BER measurements */
/* ---------------------------------------------- */
if (FEC_IN_LOCK) {
/* read in a 24-bit value 8 bits at a time from MSB->LSB */
qam_read(SB_R,SB_RSCR0,&val1,&foo);
qam_read(SB_R,SB_RSCR1,&val2,&foo);
qam_read(SB_R,SB_RSCR2,&val3,&foo);
correctableBlocks = ((unsigned long)val1)*65536uL;
correctableBlocks += ((unsigned long)val2)*256Lu;
correctableBlocks += ((unsigned long)val3);
/* accumulate the new reading */
RS_Correctable_Blocks_Accumulator += correctableBlocks;
/* read in a 16-bit value 8 bits at a time from MSB->LSB */
qam_read(SB_R,SB_RSUR0,&val1,&foo);
qam_read(SB_R,SB_RSUR1,&val2,&foo);
uncorrectableBlocks = ((unsigned long)val1)*256uL;
uncorrectableBlocks += ((unsigned long)val2);
/* accumulate the new reading */
RS_Uncorrectable_Blocks_Accumulator += uncorrectableBlocks;
/* bitsPerBaud is the Log2(QAM order) */
switch (QAM_MODE) {
case QAM_4 :
bitsPerBaud=2.0;
break;
case QAM_16 :
bitsPerBaud=4.0;
break;
case QAM_32 :
bitsPerBaud=5.0;
break;
case QAM_64 :
bitsPerBaud=6.0;
break;
case QAM_128:
bitsPerBaud=7.0;
break;
case QAM_256:
bitsPerBaud=8.0;
break;
}
/* compute the time elapsed since the last restart of measurements */
_dos_gettime(&time);
t2 = (unsigned long) 360000uL*time.hour + 6000uL*time.minute + 100uL*time.second + time.hsecond;
deltaT = 10uL * (t2 - t1); /* compute elapsed time in ms */
elapsedBits = ((float)deltaT)*1000.0*qam_status.symbol_rate* \
bitsPerBaud*(188./204.);
if (elapsedBits != 0.0) {
pre_fec_ber = ((float)RS_Correctable_Blocks_Accumulator) / elapsedBits;
post_fec_ber = ((float)RS_Uncorrectable_Blocks_Accumulator) / elapsedBits;
/*
Add correction factor which is based on an assumption about the number
of bytes in the block that were in error as well as how many bits were
incorrect in each of these imperfect bytes.
*/
post_fec_ber *= 12.0;
sprintf(pre_fec_ber_msg, "%5.2E", pre_fec_ber);
sprintf(post_fec_ber_msg,"%5.2E", post_fec_ber);
}
else {
/* indicate that there is a condition in which BER cannot be computed */
pre_fec_ber = UNDEFINED_BER;
post_fec_ber= UNDEFINED_BER;
strcpy(pre_fec_ber_msg, "Not valid");
strcpy(post_fec_ber_msg, "Not valid");
}
} // if (FEC_IN_LOCK)
else {
pre_fec_ber = UNDEFINED_BER;
post_fec_ber= UNDEFINED_BER;
strcpy(pre_fec_ber_msg, "");
strcpy(post_fec_ber_msg, "");
}
/* ---------------------------------------------- */
/* display statistics */
sprintf(snr_est_msg , "%5.2f", qam_status.snr_estimate);
sprintf(averaged_snr_msg,"%5.2f", snr_average);
sprintf(sample_cnt_msg, "%ld", nsamples);
status[QAM_LOCK_STATE].val = (QAM_IN_LOCK) ? "In Lock" : "Out Of Lock";
status[QAM_SNR_ESTIMATE].val = snr_est_msg;
status[AVERAGED_SNR].val = averaged_snr_msg;
status[SAMPLE_CNT].val = sample_cnt_msg;
status[PRE_FEC_BER].val = pre_fec_ber_msg;
status[POST_FEC_BER].val = post_fec_ber_msg;
status_plot(stat_win,"Status Info",status,nstatus);
/* prompt for user request */
if (kbhit()) {
c = fkey_menu(0,fkey_win, fkeys);
switch (c) {
case 1 : /* display size control */
reduced_display ^= 1;
nsamples = 0;
break;
case 2 :
/* initialize the data window for SNR average */
num_points_in_snr_average = linear_noise_sum = 0.0;
/* reset start time for BER measurements */
_dos_gettime(&time);
t1 = (unsigned long) 360000uL*time.hour + 6000uL*time.minute + 100uL*time.second + time.hsecond;
/* reset the accumulators for Reed-Solomon Blocks */
RS_Correctable_Blocks_Accumulator = 0L;
RS_Uncorrectable_Blocks_Accumulator = 0L;
break;
case 3 : //papi
break;
case 4 : /* persistence control */
accumulate ^= 1;
break;
case 5 : /* refresh screen */
nsamples = 0;
break;
case 6 : //papi
break;
case 7 : /* spare */
break;
case 8 : /* log QAM Data */
if (store_qam_to_file == 0) {
x = dialog_box(100,100,data_size_msg,data_size_prompt);
switch (x) {
case 1 : qam_samples_to_store = 256 ; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -