⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spy_lcd.c

📁 此程序主要测试50HZ~3KHZ音频范围幅频特性测试程序.程序包含主控程序和显示程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
							else if(s==0xff) dwl(a|(0xff<<(p1.y%8)));
							else {dwl(a^(0xff<<(p1.y%8)));}
						}
						else if(i==max+1)//最下边一页的处理
						{
							if(s==0) dwl(a&(0xff<<(p2.y%8+1)));
							else if(s==0xff) dwl(a|(0xff>>(7-p2.y%8)));
							else {dwl(a^(0xff>>(7-p2.y%8)));}
						}
						else //中间页的处理
						{
							if(s==0) {dwl(0);}
							else if(s==0xff) {dwl(0xff);}
							else {dwl(~a);}
						}
					}
					else
					{
						if(s==0) dwl(a&((0xff>>(8-p1.y%8))|(0xff<<(p2.y%8+1))));
						else if(s==0xff) dwl(a|((0xff<<(p1.y%8))&(0xff>>(7-p2.y%8))));
						else {dwl(a^((0xff<<(p1.y%8))&(0xff>>(7-p2.y%8))));}
					}
				}
				else
				{
					iwr(0xb8|(i-1));
					iwr(0x40|(j-64));
					a=drr();
					a=drr();
					iwr(0x40|(j-64));
					if(min!=max)
					{

						if(i==min+1)
						{
							if(s==0) {dwr(a&(0xff>>(8-p1.y%8)));}
							else if(s==0xff) {dwr(a|(0xff<<(p1.y%8)));}
							else {dwr(a^(0xff<<(p1.y%8)));}
						}
						else if(i==max+1)
						{
							if(s==0) {dwr(a&(0xff<<(p2.y%8+1)));}
							else if(s==0xff) {dwr(a|(0xff>>(7-p2.y%8)));}
							else {dwr(a^(0xff>>(7-p2.y%8)));}
						}
						else
						{
							if(s==0) {dwr(0);}
							else if(s==0xff) {dwr(0xff);}
							else {dwr(~a);}
						}
					}
					else
					{
						if(s==0) dwr(a&((0xff>>(8-p1.y%8))|(0xff<<(p2.y%8+1))));
						else if(s==0xff) dwr(a|((0xff<<(p1.y%8))&(0xff>>(7-p2.y%8))));
						else {dwr(a^((0xff<<(p1.y%8))&(0xff>>(7-p2.y%8))));}
					}
				}
			}
		}
	}
}

/*将8位的字模数据写入光标指定的位置进行显示*/
void disp_one_modu(uchar m)
{
	uchar a;
	if((cursor.x<128)&&(cursor.y<64))
	{
		if(cursor.x<=63)
		{
			iwl(0xb8|cursor.y/8);
			iwl(0x40|cursor.x);
			a=drl();
			a=drl();
			iwl(0x40|cursor.x);
			dwl((m<<(cursor.y%8))|(a&(0xff>>(8-cursor.y%8))));
			if((cursor.y+8)<64)
			{
				iwl(0xb8|(cursor.y+8)/8);
				iwl(0x40|cursor.x);
				a=drl();
				a=drl();
				iwl(0x40|cursor.x);
				dwl((a&(0xff<<(cursor.y%8)))|(m>>(8-cursor.y%8)));
			}
		}
		else
		{
			iwr(0xb8|cursor.y/8);
			iwr(0x40|(cursor.x-64));
			a=drr();
			a=drr();
			iwr(0x40|(cursor.x-64));
			dwr((m<<(cursor.y%8))|(a&(0xff>>(8-cursor.y%8))));
			if((cursor.y+8)<64)
			{
				iwr(0xb8|(cursor.y+8)/8);
				iwr(0x40|(cursor.x-64));
				a=drr();
				a=drr();
				iwr(0x40|(cursor.x-64));
				dwr((a&(0xff<<(cursor.y%8)))|(m>>(8-cursor.y%8)));
			}
		}
	}
	else
	{
		if(cursor.x>=128) zf_ovx=1;
		if(cursor.y>=64) zf_ovy=1;
	}
}

/*在光标处显示一个汉字,n是字库中的位置,width表示字符的宽度,pt为字库首地址,s为1表示正显,为0表示反显*/
void disp_one_hz(uchar n,uchar width,uchar code *pt,bit s)
{
	uchar a,i;
	uint b;
	a=cursor.x;
	zf_ovx=0;
	zf_ovy=0;
	for(i=0;i<width;i++)
	{
		if(zf_ovx==0) {b=i+n*(width<<1);disp_one_modu(s?*(pt+b):~(*(pt+b)));}
		cursor.x++;
		if(cursor.x==128) zf_ovx=1;
	}
	zf_ovx=0;
	if((cursor.y+8)<64)//张工编的程序总会执行这句,所以不会出错
	{
		cursor.x=a;
		a=cursor.y;
		cursor.y+=8;
	for(i=width;i<(width<<1);i++)
	{
		if(zf_ovx==0) {b=i+n*(width<<1);disp_one_modu(s?*(pt+b):~(*(pt+b)));}
		cursor.x++;
		if(cursor.x==128) zf_ovx=1;
	}
	}
	cursor.y=a;//有错
	zf_ovx=0;
	zf_ovy=0;
}



/*串口初始化,11.0592晶振,baud rate:9600bps*/
void  init(void)
{
	TMOD=0x21;
	TH1=0xfd;
	TL1=0xfd;
	PCON=0;
	SCON=0x50;
	TR1=1;					/*启动T1*/
	ES=1;					/*开串口中断*/
}

/*串口中断子程序*/
void serial(void) interrupt 4 using 2
{
   if(RI)
   {
      if((SBUF==0x1b)&&(sum==0))  {istart=1;iend=0;shuju[0]=0x1b;}  //是正常数据么?
     else
      {  if(istart==1)  //
           { sum=sum+1;
	        if(sum<=3) {shuju[sum]=SBUF;
			            if(sum==3) {sum=0; iend=1;istart=0;} //复位各状态标志
			           }

           }
      }
	RI=0;
   }
 }



void transfer(uint a)  //显示数字:0~65535
{
	if(a>=0&&a<10) //判断a是否为个位数
       {disp_one_hz(a,5,numeric,1);} //显示个位数
	else if(a>=10&&a<100)//判断a是否为十位数
	   {
		disp_one_hz(a/10,5,numeric,1);//显示十位数
		disp_one_hz(a%10,5,numeric,1);//显示个位数
	   }
    else if(a>=100&&a<1000)//判断a是否为百位数
       {disp_one_hz(a/100,5,numeric,1);//显示百位数
        a=a%100;
        disp_one_hz(a/10,5,numeric,1);//显示十位数
        disp_one_hz(a%10,5,numeric,1);//显示个位数
       }
    else if(a>=1000&&a<10000)//判断a是否为千位数
       {disp_one_hz(a/1000,5,numeric,1);//显示千位数
        a=a%1000;
        disp_one_hz(a/100,5,numeric,1);//显示百位数
        a=a%100;
        disp_one_hz(a/10,5,numeric,1);//显示十位数
        disp_one_hz(a%10,5,numeric,1);//显示个位数
       }
   	else if(a==65535)
       {disp_one_hz(6,5,numeric,1);
        disp_one_hz(5,5,numeric,1);
        disp_one_hz(5,5,numeric,1);
        disp_one_hz(3,5,numeric,1);
        disp_one_hz(5,5,numeric,1);
       }
    else if(a>=10000&&a<65535)//判断a是否为万位数
      { disp_one_hz(a/10000,5,numeric,1);//显示万位数
        a=a%10000;
        disp_one_hz(a/1000,5,numeric,1);//显示千位数
        a=a%1000;
        disp_one_hz(a/100,5,numeric,1);//显示百位数
        a=a%100;
        disp_one_hz(a/10,5,numeric,1);//显示十位数
        disp_one_hz(a%10,5,numeric,1);//显示个位数
       }
}


void freq_value(uint PL) //显示扫频时频率变化值,
{       
        p1.x=100;
        p1.y=0;
        p2.x=127;
	p2.y=15;
        draw_srec(p1,p2,0);//先清这一行数字区域
        cursor.x=100;
	cursor.y=0;
	transfer(PL);
}

void PLUS_value(uint ZY) //显示扫频时幅值变化值
{       p1.x=100;
        p1.y=16;
        p2.x=127;
	    p2.y=31;
        draw_srec(p1,p2,0);//先清这一行数字区域
        cursor.x=100;
	cursor.y=16;
	transfer((ZY/10)); //显示整数部分
	disp_one_hz(10,5,numeric,1);  //显示小数点
	transfer((ZY%10)); //显示小数点后面的数字(一位)

}

void voltage_value(uint DY) //显示扫频议输出的幅值
{       p1.x=100;
        p1.y=47;
        p2.x=127;
	p2.y=63;
        draw_srec(p1,p2,0);//先清这一行数字区域
        cursor.x=100;
	cursor.y=47;
	transfer(DY);
}


void pinduanhao(uchar PDH)  //显示频段号   PDH =1为A频段,=2为B频段,=3为C频段
{   cursor.x=114;
	cursor.y=32;
	transfer(PDH);
}


void saopingeshi(uchar SPGS) //显示为扫频格式  SPGS=1为单次,=2为循环扫频
{   cursor.x=121;
	cursor.y=32;
	transfer(SPGS);
}


void zuobiaozhu()   //显示界面初始化
 {  point PP1,PP2;
    offlcd(); /*关闭LCD*/
	onlcd();  /*打开LCD*/
	clr_lcd(); /*清屏*/

    PP1.x=0;
    PP1.y=0;
    PP2.x=0;
    PP2.y=63;
  draw_line(PP1,PP2,1);  //画纵轴
    PP1.x=0;
    PP1.y=63;
    PP2.x=99;
    PP2.y=63;
  draw_line(PP1,PP2,1); //画横轴
 //显示字母f
  cursor.x=107;
  cursor.y=32;
  disp_one_hz(5,6,letter,1); //显示f


 }



 void main()
{  
  point fre_bre;
  point zbdwstar_cx;
  point zbdwend_cx;
 
  zuobiaozhu();   //显示界面初始化
  init();	/*初始化串口*/
  EA=1;		/*总中断允许*/
  DENG=0;

  /*主程序循环*/
 for(;;)
 { // sp_fre=1;sp_bre=1; st_st=1;bre_sp=32;  //调试程序时用


   if(iend==1&&istart==0) //串口接受完一组数据了么?
   {
     if(shuju[0]==0x1b) //是正常数据么?
       {
	     	switch(shuju[1]) //数据命令类型判断
			{
			case 0x92:	//为扫频时发出的频率值
				{

				 sp_fre=1; //置扫频时频率值处理标志
				 shuju[3]=shuju[3]<<8; //变成高2位
                 fre_sp=shuju[3]|shuju[2];
				 if(fre_sp==50) //接受到的频率等50HZ么?
				 {st_st=1; }//以此来刷新显示幅频特性区
		   	     freq_value(fre_sp); //显示扫频时频率变化值,
				 tally=fre_sp;
		    	}break;
            case 0x94:	//为扫频时发出的幅度比值
				{sp_bre=1; //置扫频时幅值处理标志
				 shuju[3]=shuju[3]<<8; //变成高2位
                 bre_sp=shuju[3]|shuju[2];

                 PLUS_value(bre_sp);//显示扫频时幅值变化值

				}break;
	    	case 0x11:	//为扫频议发出的固定幅值
				{
				 shuju[3]=shuju[3]<<8; //变成高2位
			     voltaga_sp=shuju[3]|shuju[2];
	             voltage_value(voltaga_sp); //显示扫频议输出的幅值

				}break;
			case 0xa0:	//为查询时发出的频率值
				{
				 cx_fre=1;  //置查询时频率值处理标志
				 shuju[3]=shuju[3]<<8;//变成高2位
			     fre_cx=shuju[3]|shuju[2];
				 freq_value(fre_cx); //显示查询时频率变化值,
                // if((counter_cx>=0)&&(counter_cx<=99))
                   {  
				      if((fre_cx)<(tally))  //确定查询竖线是向左移么?
				    	{
						 // if(counter_cx>0)
					       {counter_cx--; 
						    direction=0; //置查询光标线向左移标志
						    } // 如果fre_cx0==fre_cx说明查询键到了频段的两端还在按下。这时cuuter_cx不计数
				    	}
					  if(fre_cx>tally) //确定查询竖线是向右移么?
					    {
						  //if(counter_cx<99)
					      {counter_cx++;
						   direction=1; ///置查询光标线向右移标志
						  }
					    } 
                     
                   }
				 if(fre_cx==50)  { counter_cx=0; }
                 if((fre_cx==3018&&pdlx==1)||(fre_cx==2003&&pdlx==2)||(fre_cx==1001&&pdlx==3))
                     {counter_cx=99;tally=fre_cx; }
				
                 tally=fre_cx; //把新查询到的频率值赋给老频率值  
				}break;
			case 0x80:	//为查询时发出的幅度值
                { 
                  cx_bre=1;      //置查询时幅值处理标志
				  shuju[3]=shuju[3]<<8;   //变成高2位
				  bre_cx=shuju[3]|shuju[2];
	              PLUS_value(bre_cx);    //显示查询时幅值变化值
                }break;
			case 0xc0:	//为扫频频段号命令
				{
			    pdlx=shuju[2];
	            pinduanhao(pdlx);  //显示频段号   PDH =1为A频段,=2为B频段,=3为C频段

				}break;
			case 0xc1:	//为扫频格式:单次/循环命令
				{
				spgs=shuju[2];
	            saopingeshi(spgs); //显示为扫频格式  SPGS=1为单次,=2为循环扫频

				}break;

			}
		 }   iend=0;//在此置0是:让数据命令类型判断只能执行一次,或着说只有此串口再接受到新数据才能再判断
	   }
    
	 
    if(sp_fre==1&&sp_bre==1)  //绘幅频曲线图
	 { sp_fre=0;
	   sp_bre=0;
	   
	   if(st_st==1) //开始键按下了么?
	    {p1.x=1;
         p1.y=0;
         p2.x=99;
	     p2.y=62;
         draw_srec(p1,p2,0);//清曲线显示区域图形
	    //	DENG=!DENG; 
        zbdwstar_cx.x=0;
        zbdwstar_cx.y=0;
        zbdwend_cx.x=0;
        zbdwend_cx.y=63;
        draw_line(zbdwstar_cx,zbdwend_cx,1);  //画纵轴线
		zbdwstar_cx.x=0;
        zbdwstar_cx.y=63;
        zbdwend_cx.x=99;
        zbdwend_cx.y=63;
        draw_line(zbdwstar_cx,zbdwend_cx,1);  //画横轴线

	     st_st=0;  //开始键按下标志复位
		 counter=0; //频率计数器标志复位
		 counter_cx=0;// 查询计数器标志复位
        // shuju_y[]=0; //清曲线Y轴坐标数据
	     }
	   fre_bre.x=counter;   //根据频率计数值定位X轴光标
       fre_bre.y=33-(bre_sp/10); //根据幅值比值定位Y轴光标, 63-30=33处开始显示曲线,另外除十是将主机发过来的数据小数点舍去,此处没进行四舍五入算法因为曲线只是显示大概位置,具体参数要看幅值处显示的参数
       shuju_y[counter]=fre_bre.y;  //记录扫过曲线点Y轴的坐标
       disp_one_dot(fre_bre,1); //绘制幅频特性曲线

	   counter++; //频率计数器标志+1
	   counter_cx++;// 查询计数器标志+1
	   if(spgs==1&&counter_cx>99) {counter_cx=99;} //只需判断是否在单次扫频格式下,在循环格式下遇到开始键按下自动置零
	  
       if(spgs==2&&counter>99) //判断当前为循环扫频格式么?
	     {counter=0;}

	 }
	if(cx_fre==1&&cx_bre==1) 	//显示查询位置竖线
	 { cx_fre=0;
	   cx_bre=0;
       
	   zbdwstar_cx.x=counter_cx;
       zbdwstar_cx.y=0;
       zbdwend_cx.x=counter_cx;
       zbdwend_cx.y=62;
       draw_line(zbdwstar_cx,zbdwend_cx,1);  //画光标显示竖线
       fre_bre.x=counter_cx;   //根据频率计数值定位X轴光标
	   fre_bre.y=shuju_y[counter_cx]; //根据幅值比值定位Y轴光标
       disp_one_dot(fre_bre,0); //将查询线与幅频特性曲线交差点进行反显

	   if((counter_cx>=0)&&(counter_cx<100))  //查询光标线是否在曲线两端
	    { if(direction==0)//光标线是向左移吗?
		  {
		    zbdwstar_cx.x=counter_cx+1;
            zbdwstar_cx.y=0;
            zbdwend_cx.x=counter_cx+1;
            zbdwend_cx.y=62;
            draw_line(zbdwstar_cx,zbdwend_cx,0); //清前一个光标显示竖线
        	fre_bre.x=counter_cx+1;   //根据频率计数值定位X轴光标
	        fre_bre.y=shuju_y[counter_cx+1]; //根据幅值比值定位Y轴光标
            disp_one_dot(fre_bre,1); //恢复本点幅频特性曲线

		  }
		  if((direction==1)&&(counter_cx>0))//光标线是向右移吗?
          {
		    zbdwstar_cx.x=counter_cx-1;
            zbdwstar_cx.y=0;
            zbdwend_cx.x=counter_cx-1;
            zbdwend_cx.y=62;
            draw_line(zbdwstar_cx,zbdwend_cx,0); //清前一个光标显示竖线
			if(counter_cx-1==0)
             { zbdwstar_cx.x=0;
               zbdwstar_cx.y=0;
               zbdwend_cx.x=0;
               zbdwend_cx.y=63;
               draw_line(zbdwstar_cx,zbdwend_cx,1);  //画纵轴线
			  }
        	fre_bre.x=counter_cx-1;   //根据频率计数值定位X轴光标
	        fre_bre.y=shuju_y[counter_cx-1]; //根据幅值比值定位Y轴光标
            disp_one_dot(fre_bre,1); //恢复本点幅频特性曲线
		  } 
       }


	 }
 }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -