📄 spy_lcd.c
字号:
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 + -