www.pudn.com > UCGUI390a.rar > Digit_SB_Show.c


 
/******************************************************************************** 
						数字示波器波形显示模块 
						崔刚 2007/04/20 
 
文件名:		Digit_SB_Show.c 
功能:		提供用于数字示波器显示的API 
备注:		基于嵌入式图形库 ucGUI 
********************************************************************************/ 
 
#include "GUI.h" 
#include "WM.h" 
#include "math.h" 
#include "stdlib.h" 
#include "time.h" 
 
#include "digit_sb_show.h" 
 
static void DrawGrid(); 
static void ShowWave(); 
static void DrawMark(); 
static void InitStatusLabel(); 
static void SetStatus(const char* s); 
static int	GetLimitedPosition(int pos, int times); 
static void WindowMoveTo(int direction, int iCH); 
static void DrawTimeWave(int iCH); 
static int	CHIsValid(int iCH); 
static int	CHtoShowIsValid(int iCHs2Show); 
static void SetWindowsAndGridLayout(); 
 
Status	_DSB_Status; 
 
Window	_DSB_WinForCH[2]; 
Grid	_DSB_Grid; 
 
void DSB_StatusReset() 
{ 
	int i; 
	for (i=0; i<2; i++) 
	{ 
		_DSB_Status.status_ch[i].domain				= TIME_DOMAIN; 
		_DSB_Status.status_ch[i].fft_ed				= 0;			//no fft 
		_DSB_Status.status_ch[i].pos_of_begin		= 0; 
		_DSB_Status.status_ch[i].sample_freq		= 0; 
		_DSB_Status.status_ch[i].times_of_enlarg	= 0;	 
	} 
	_DSB_Status.how_many_chs_show = 1; 
} 
 
//-------------------------------------------- 
//	设置需要多少路显示 
void DSB_SetHowManyCHs(int iHowMany) 
{ 
	_DSB_Status.how_many_chs_show = iHowMany; 
	SetWindowsAndGridLayout(); 
	DrawMark(); 
} 
 
 
void DSB_Enlarge(int iCH) 
{ 
	int times; 
	int pos; 
 
	if (!CHIsValid(iCH)) 
	{ 
		return; 
	} 
 
	times	= _DSB_Status.status_ch[iCH-1].times_of_enlarg; 
	pos		= _DSB_Status.status_ch[iCH-1].pos_of_begin; 
 
	if(times >= MAX_ENLARGE_TIMES) 
	{ 
		return; 
	} 
	 
	_DSB_Status.status_ch[iCH-1].times_of_enlarg++; 
	times++; 
	pos = pos + (POINTS_PER_WINDOW>>(times+1)); 
	_DSB_Status.status_ch[iCH-1].pos_of_begin = GetLimitedPosition(pos, times); 
	DrawTimeWave(iCH); 
} 
 
void DSB_Shrink(int iCH) 
{ 
	int times; 
	int pos; 
 
	if (!CHIsValid(iCH)) 
	{ 
		return; 
	} 
 
	times	= _DSB_Status.status_ch[iCH-1].times_of_enlarg; 
	pos		= _DSB_Status.status_ch[iCH-1].pos_of_begin; 
 
	if(times < 1) 
	{ 
		return; 
	} 
 
	_DSB_Status.status_ch[iCH-1].times_of_enlarg--; 
	times--; 
	pos = pos - (POINTS_PER_WINDOW>>(times+2)); 
	_DSB_Status.status_ch[iCH-1].pos_of_begin = GetLimitedPosition(pos, times); 
 
	DrawTimeWave(iCH); 
 
} 
 
 
//------------------------------------------ 
//	窗口左移,即波形向右移动 
void DSB_WindowLeftMove(int iCH) 
{ 
	WindowMoveTo(LEFT, iCH); 
} 
 
//------------------------------------------ 
//	窗口右移,即波形向左移动 
void DSB_WindowRightMove(int iCH) 
{ 
	WindowMoveTo(RIGHT, iCH); 
} 
 
 
//------------------------------------------- 
//	设置采样点显示到LCD上面的水平坐标 
void DSB_ResetTimeDomainScale(int iCH) 
{ 
	int i; 
 
	for(i=0; i>11 = "/2048" 
		_DSB_Status.status_ch[iCH-1].time_domain_buf[i].x = (i * WINDOW_WIDTH) >> POWER;	 
	} 
} 
 
void DSB_Initialization() 
{ 
 
	GUI_Init(); 
	GUI_SetBkColor(SCREEN_BKCOLOR); 
	GUI_Clear(); 
	 
	 
	SetStatus("time"); 
 
	DSB_ResetTimeDomainScale(1);	//初始化坐标点的横坐标,因为相对固定,不必每次计算 
	DSB_ResetTimeDomainScale(2); 
	DSB_StatusReset(); 
	InitStatusLabel(); 
} 
 
//---------------------------------------------------------- 
//功能: 
//	供外部调用的画=时域=波形的函数 
//输入: 
//	iCH:			第几路显示(只能是 1 或 2) 
//	pSampleData:	指向采样数据 
//	iMaxValue:		采样数据的最大值 
//	iMinValue:		采样数据的最小值 (意义??) 
//输出: 
//	没 
void DSB_ShowTimeDomainWave(int iCH, int* pSampleData, int iMaxValue, int iMinValue) 
{ 
	int			i; 
	int			CH; 
	GUI_RECT	WaveWindow; 
	int*		sample; 
	int			diff; 
 
	if (!CHIsValid(iCH)) 
	{ 
		return; 
	} 
 
	CH				= iCH-1; 
	WaveWindow.x0	= _DSB_WinForCH[CH].L; 
	WaveWindow.y0	= _DSB_WinForCH[CH].T; 
	WaveWindow.x1	= _DSB_WinForCH[CH].W + _DSB_WinForCH[CH].L; 
	WaveWindow.y1	= _DSB_WinForCH[CH].T + _DSB_WinForCH[CH].H; 
 
	sample			= pSampleData; 
	diff			= iMaxValue - iMinValue; 
 
	for(i=0; i>1),  
						_DSB_WinForCH[CH].L,  
						_DSB_WinForCH[CH].L + _DSB_WinForCH[CH].W); 
 
		GUI_DrawVLine(	_DSB_WinForCH[CH].L + _DSB_Grid.W * (H_GRIDS >>1),  
						_DSB_WinForCH[CH].T,  
						_DSB_WinForCH[CH].T + _DSB_WinForCH[CH].H); 
	} 
} 
 
//---------------------------------------------------------------- 
//	画网格刻度(序号 0 1 2 3----) 
extern GUI_CONST_STORAGE GUI_FONT GUI_Font6x8; 
static void DrawMark() 
{ 
	int i,CH; 
 
	GUI_SetFont(&GUI_Font6x8); 
	GUI_SetBkColor(SCREEN_BKCOLOR); 
	GUI_SetColor(SCREEN_FONTCOLOR); 
	GUI_Clear(); 
 
	for (CH=0; CH<_DSB_Status.how_many_chs_show; CH++) 
	{ 
		GUI_DispDecAt(	0,  
						_DSB_WinForCH[CH].L + _DSB_Grid.W*0,  
						2 + _DSB_WinForCH[CH].H + _DSB_WinForCH[CH].T,  
						1); 
		for (i=1; i POINTS_PER_WINDOW - (POINTS_PER_WINDOW>>times)) 
	{ 
		result = POINTS_PER_WINDOW - (POINTS_PER_WINDOW>>times); 
	} 
 
	if (pos < 0) 
	{ 
		result = 0; 
	} 
 
	return result; 
} 
 
 
static void WindowMoveTo(int direction, int iCH) 
{ 
	int times; 
	int pos; 
 
	if (!CHIsValid(iCH)) 
	{ 
		return; 
	} 
 
	times	= _DSB_Status.status_ch[iCH-1].times_of_enlarg; 
	pos		= _DSB_Status.status_ch[iCH-1].pos_of_begin; 
 
	if(times == 0) 
	{ 
		return; 
	} 
 
	if(direction == LEFT) 
	{ 
		pos = pos - (MOVE_POINTS>>times); 
	} 
	else if (direction == RIGHT) 
	{ 
		pos = pos + (MOVE_POINTS>>times); 
	} 
 
	_DSB_Status.status_ch[iCH-1].pos_of_begin = GetLimitedPosition(pos, times); 
	DrawTimeWave(iCH); 
 
} 
 
static void InitStatusLabel() 
{ 
	GUI_SetFont(&GUI_Font6x8); 
	GUI_DispStringAt("Status:", WINDOW_LEFT, 240-15); 
	GUI_DispStringAt("CH:", WINDOW_LEFT+180, 240-15); 
	GUI_DispStringAt("Time:", WINDOW_LEFT+250, 240-15); 
} 
 
static void SetStatus(const char* s) 
{ 
	char sh[20] = "Status:"; 
 
	strncat(sh,s,12); 
 
	GUI_SetFont(&GUI_Font6x8); 
	GUI_SetBkColor(GUI_RED); 
	GUI_ClearRect(WINDOW_LEFT, 240-15, WINDOW_LEFT+130, 235); 
	GUI_DispStringAt(sh, WINDOW_LEFT+5, 240-13); 
} 
 
 
//------------------------------------------------------------------ 
//	用于 放大缩小 时候的 时域 波形显示 
static void DrawTimeWave(int iCH) 
{ 
	int i; 
	int times		= _DSB_Status.status_ch[iCH-1].times_of_enlarg; 
	int pos			= _DSB_Status.status_ch[iCH-1].pos_of_begin; 
	int count		= POINTS_BUFFER_SIZE>>times; 
	GUI_POINT*	pt	=  _DSB_Status.status_ch[iCH-1].time_domain_buf + pos; 
 
	for (i=0; i>1) - 18; 
		_DSB_WinForCH[0].T = WINDOW_TOP; 
		_DSB_WinForCH[0].L = WINDOW_LEFT; 
 
		_DSB_WinForCH[1].W = WINDOW_WIDTH; 
		_DSB_WinForCH[1].H = (WINDOW_HEIGHT>>1) - 18; 
		_DSB_WinForCH[1].T = WINDOW_TOP+_DSB_WinForCH[0].H + 36; 
		_DSB_WinForCH[1].L = WINDOW_LEFT; 
	} 
 
	_DSB_Grid.H = _DSB_WinForCH[0].H / V_GRIDS; 
	_DSB_Grid.W = _DSB_WinForCH[0].W / H_GRIDS; 
 
} 
 
 
//Channel的值只能是1 或 2 
static int	CHIsValid(int iCH) 
{ 
	return (iCH==2 || iCH==1); 
} 
 
//只能同时显示1路或2路 
static int	CHtoShowIsValid(int iCHs2Show) 
{ 
	return (iCHs2Show==2 || iCHs2Show==1); 
}