📄 显示部分程序.c
字号:
#include <STC12C5A60S2.H>
#define uchar unsigned char
#define uint unsigned int
#define LCD_PORT P2
#define Left 1
#define Right 2
sbit LCD_Busy=P2^7;
sbit LCD_EN = P0^3;
sbit LCD_RS = P0^1;
sbit LCD_RW = P0^2;
sbit LCD_RST= P0^0;
sbit LCD_CS2= P0^5;
sbit LCD_CS1= P0^4;
//sbit FR=P3^7;
//sbit key1=P3^2;
sbit key2=P3^3;
//sbit key3=P3^6;
//sbit key4=P2^0;
uchar DisBuf[30],Page_Num,Clm_Num,zhou[4];
uchar pointY=15,pointX=16;
uchar i,cai3=0;
uint x,y,caiy1=0,caiy2=0,caiy3=0,caiy4=0,caix1=0,caix2=0,caix3=0,caix4=0;
uchar shi=0,ge=0,ms=0,stop=0,gao=0,di=0;
uchar cai[4],cai0[3],temp[8] ;
unsigned int n,m,count,count2,T0count,time,flag,shu1,shu2,shu3;
code char Table[]= //数字0~9
{
0x7E, 0xa1, 0x99, 0x85, 0x7E, // 0 0*5
0x82, 0x81, 0xff, 0x80, 0x80, // 1 1*5
0xc2, 0xa1, 0x91, 0x89, 0x86, // 2 2*5
0x42, 0x81, 0x89, 0x89, 0x76, // 3 3*5
0x18, 0x14, 0x12, 0xff, 0x10, // 4 4*5
0x4F, 0x89, 0x89, 0x89, 0x71, // 5 5*5
0x7e, 0x89, 0x89, 0x89, 0x72, // 6 6*5
0x01, 0x01, 0xf9, 0x05, 0x03, // 7 7*5
0x76, 0x89, 0x89, 0x89, 0x76, // 8 8*5
0x4e, 0x91, 0x91, 0x91, 0x7E, // 9 9*5
0x10, 0x28, 0x44, 0x82, 0x00, // < 10*5
0x00, 0x82, 0x44, 0x28, 0x10, // > 11*5
};
code char Table1[]= //括号
{
0x00, 0x3C, 0x42, 0x81, // ( 4*0
0x81, 0x42, 0x3C, 0x00, // ) 4*1
// < 8
};
code char Table3[]= //字母
{
0xFF, 0x11, 0x11, 0x11, 0x0E, // P 0*5
0x3f, 0x40, 0x80, 0x40, 0x3f, // V 1*5
0xff, 0x08, 0x08, 0x08, 0xff, // H 2*5
0xc4, 0xa4, 0x94, 0x8c, 0x00, // z 3*5
0xff, 0x09, 0x09, 0x09, 0x09, // F 4*5
0xFF, 0x19, 0x29, 0x49, 0x86, // R 5*5
0xFF, 0x89, 0x89, 0x89, 0x89, // E 6*5
0x7e, 0x81, 0xa1, 0x41, 0xBE, // Q 7*5
};
code char Table4[]= //小数点
{
0x80,
};
void Delay_us(unsigned int DelayTime)
{
while(DelayTime) DelayTime--;
}
void Delay_x10ms(unsigned char DelayTime) //***************10ms延时**********//
{
unsigned char i,j,k;
for(i=0;i<DelayTime;i++)
for(j=0;j<10;j++)
for(k=0;k<120;k++) {;}
}
/*----------------------------------------------------------------------------
下面这个函数用于液晶模块的忙信号检测。
----------------------------------------------------------------------------*/
void LCD_Check_Busy(void)
{
LCD_PORT = 0x00;
Delay_us(5);
while(LCD_Busy)
{
LCD_EN = 0;
LCD_RS = 0;
LCD_RW = 1;
Delay_us(5);
LCD_EN = 1;
Delay_us(10);
}
LCD_EN = 0;
}
//度屏程序
uchar Readdata1()
{
uchar rdata;
LCD_CS1=1;LCD_CS2=0;
LCD_Check_Busy();
LCD_RS=1;
LCD_RW=1;
LCD_EN=1;
rdata=LCD_PORT;
Delay_us(3);
LCD_EN=0;
Delay_us(1);
return rdata;
}
uchar Readdata2()
{
uchar rdata;
LCD_CS1=0;LCD_CS2=1;
LCD_Check_Busy();
LCD_RS=1;
LCD_RW=1;
LCD_EN=1;
rdata=LCD_PORT;
Delay_us(3);
LCD_EN=0;
Delay_us(1);
return rdata;
}
/*----------------------------------------------------------------------------
下面这个函数用于向液晶模块写入控制指令代码。
函数入口参数:Command ------ 向液晶模块写入的控制指令代码 。
CS_Num ------ 左右半屏的选数值
----------------------------------------------------------------------------*/
void LCD_WriteCommand(uchar Command, uchar CS_Num)
{
LCD_Check_Busy();
if(CS_Num==1) /*选择左半屏*/
{
LCD_CS1 = 1;
LCD_CS2 = 0;
}
else /*选择右半屏*/
{
LCD_CS1 = 0;
LCD_CS2 = 1;
}
Delay_us(2);
LCD_EN = 0; /* 使能信号为L */
LCD_RS = 0; /* 置寄存器选择为L */
LCD_RW = 0; /* 置读/写选择为L */
LCD_PORT= Command; /* 将控制指令代码输出到的数据端口 */
LCD_EN = 1; /* 使能信号为H */
Delay_us(2); /* 延时2us */
LCD_EN = 0; /* 使能信号为L */
LCD_CS1 = 1; /* 置片选1为L */
LCD_CS2 = 1; /* 置片选2为L */
}
/*----------------------------------------------------------------------------
下面这个函数用于向液晶模块写入显示数据。
函数入口参数:Data------ 向液晶模块写入的显示数据 。
CS_Num-------左右半屏的选数值
----------------------------------------------------------------------------*/
void LCD_WriteData(uchar Data,uchar CS_Num)
{
LCD_Check_Busy();
if(CS_Num==1) /*选择左半屏*/
{
LCD_CS1 = 1;
LCD_CS2 = 0;
cai3=Readdata1();
Data+=cai3;
}
else /*选择右半屏*/
{
LCD_CS1 = 0;
LCD_CS2 = 1;
cai3=Readdata2();
Data+=cai3;
}
Delay_us(2);
LCD_EN = 0;
LCD_RS = 1; /* 置寄存器选择为H */
LCD_RW = 0; /* 置读/写选择为L */
LCD_PORT= Data; /* 将显示数据输出到的数据端口 */
LCD_EN = 1; /* 使能信号为H */
Delay_us(2); /* 延时2us */
LCD_EN = 0; /* 使能信号为L */
LCD_CS1= 1; /* 置片选1为L */
LCD_CS2= 1; /* 置片选2为L */
}
/*---------------------------------------------------------------------------
下面这个函数用于液晶模块的清屏。
---------------------------------------------------------------------------*/
void LCD_CLR(uchar Side_Num)
{
uchar i,k,COM;
for(i=0;i<8;i++)
{
COM=0xB8+i;
LCD_WriteCommand(COM,Side_Num);
COM=0x40;
LCD_WriteCommand(COM,Side_Num);
for(k=0;k<64;k++)
{
LCD_WriteData(0x00,Side_Num);
}
}
}
/*---------------------------------------------------------------------------
下面这个函数用于向液晶模块初始化。
如果没有写完一个半屏的数据就要充分结合此函数来达到要显示的效果
---------------------------------------------------------------------------*/
void LCD_Initial(void)
{
LCD_RST = 0; /* 置复位信号为低电平 */
Delay_x10ms(10);
LCD_RST = 1; /* 置复位信号为高电平 */
Delay_x10ms(10);
LCD_WriteCommand(0x3F,Left); /*显示开*/
LCD_WriteCommand(0x3F,Right);
LCD_WriteCommand(0xC0,Left); /*起始行*/
LCD_WriteCommand(0xC0,Right);
LCD_WriteCommand(0xB8,Left); /*起始页*/
LCD_WriteCommand(0xB8,Right);
LCD_WriteCommand(0x40,Left); /*起始列*/
LCD_WriteCommand(0x40,Right);
}
void LCD_ror_wr(uchar x,uchar *a)
{
uchar j;
if(x<64)
{
for(j=0;j<8;j++)
{
LCD_WriteCommand(0xB8+j,Left);
LCD_WriteCommand(0x40+x,Left);
LCD_WriteData(a[j],Left);
}
}
else
{
x-=64;
for(j=0;j<8;j++)
{
LCD_WriteCommand(0xB8+j,Right);
LCD_WriteCommand(0x40+x,Right);
LCD_WriteData(a[j],Right);
}
}
}
/*------------------------------------------------
下面这个函数用于任何点描点
--------------------------------------------------*/
void LCD_Display(uchar x,y)
{
uchar a[8];
uchar j;
y=63-y;
for(j=0;j<8;j++) a[j]=0x0;
a[0]=0x01;
a[7]=0x80;
if((x==0)||(x==96))
{
for(j=0;j<8;j++)
a[j]=0xff;
}
/* if(x%2==0)
{
a[pointY>>3]|=0x01<<(pointY&0x07);
a[(pointY+16)>>3]|=0x01<<((pointY+16)&0x07);
a[(pointY+32)>>3]|=0x01<<((pointY+32)&0x07);
a[(pointY+48)>>3]|=0x01<<((pointY+48)&0x07);
}
if(x==pointX)
for(j=0;j<64;j++)
if(j%2==0)
a[j>>3]|=0x01<<(j&0x07);
if(x==(pointX+16))
for(j=0;j<64;j++)
if(j%2==0)
a[j>>3]|=0x01<<(j&0x07);
if(x==(pointX+32))
for(j=0;j<64;j++)
if(j%2==0)
a[j>>3]|=0x01<<(j&0x07);
if(x==(pointX+48))
for(j=0;j<64;j++)
if(j%2==0)
a[j>>3]|=0x01<<(j&0x07);
if(x==(pointX+64))
for(j=0;j<64;j++)
if(j%2==0)
a[j>>3]|=0x01<<(j&0x07);
if(x==(pointX+80))
for(j=0;j<64;j++)
if(j%2==0)
a[j>>3]|=0x01<<(j&0x07);
*/
a[y/8]|=0x01<<(y&0x07);
LCD_ror_wr(x,a);
}
unsigned char ad1()
{
ADC_CONTR=0x80;//开 A/D 转换电源,选择AD速度
P1ASF=0x00;//选择 P1.0 作为 A/D 转换通道
ADC_CONTR|=0x08;//启动 A/D 转换
while((ADC_CONTR&0x10)==0);//等待 A/D 转换结束
ADC_CONTR&=0xE7;//将 ADC_FLAG 清0
Delay_us(4);
return(ADC_RES);//保存 A/D 转换结果
}
unsigned char ad2()
{
ADC_CONTR=0x81;//开 A/D 转换电源,选择AD速度
P1ASF=0x02;//选择 P1.0 作为 A/D 转换通道
ADC_CONTR|=0x08;//启动 A/D 转换
while((ADC_CONTR&0x10)==0);//等待 A/D 转换结束
ADC_CONTR&=0xE7;//将 ADC_FLAG 清0
Delay_us(4);
return(ADC_RES);//保存 A/D 转换结果
}
/*------------------------------------------------
下面这个函数?
--------------------------------------------------*/
void zhi(uchar x,y,n,uchar *s)
{
uchar i;
for(i=0;i<n;i++)
if((x+i)>63)
{
LCD_WriteCommand(0xB8+y,Right);
LCD_WriteCommand(0x40+x+i-64,Right);
LCD_WriteData(s[i],Right);
}
else
{
LCD_WriteCommand(0xB8+y,Left);
LCD_WriteCommand(0x40+x+i,Left);
LCD_WriteData(s[i],Left);
}
}
void stop_play(void) interrupt 0
{
stop=1;
while(stop){stop=key2;}
}
void play_stop(void) interrupt 2
{
gao=0;
di=0;
cai[0]=0;
cai[1]=255;
cai[2]=0;
cai[3]=0;
cai0[0]=0;
cai0[1]=9;
cai0[2]=0;
shi=0;
ge=0;
ms=0;
}
/*---------------------------------------------------------------------------
下面这个函数初始化一开始的显示值。
---------------------------------------------------------------------------*/
void display_int(void)
{
zhi(98,0,5,Table3+5*0); //显示PPV 单位 V 小数点。
zhi(104,0,5,Table3+5*0);
zhi(110,0,5,Table3+5*1);
zhi(117,2,5,Table3+5*1);
zhi(107,2,1,Table4);
zhi(98,4,5,Table3+5*4); //显示 FREQ 和 单位 HZ 小数点
zhi(104,4,5,Table3+5*5);
zhi(110,4,5,Table3+5*6);
zhi(116,4,5,Table3+5*7);
zhi(117,6,5,Table3+5*2);
zhi(123,6,5,Table3+5*3);
//zhi(107,6,1,Table4);
zhi(101,2,5,Table+5*shi);
zhi(110,2,5,Table+5*ge);
zhi(98,6,5,Table+5*0);
zhi(104,6,5,Table+5*0);
zhi(110,6,5,Table+5*0);
for(x=0;x<98;x++)
{
LCD_Display(x,0);
}
}
/*---------------------------------------------------------------------------
下面这个函数初始化一开始变量值,和中断
---------------------------------------------------------------------------*/
void data_int(void)
{
x=0;
EA=1;
EX0=1;
EX1=1;
P3=0Xff;
P1=0Xff;
cai[0]=0;
cai[1]=255;
cai[2]=0;
cai[3]=0;
cai0[0]=0;
cai0[1]=9;
cai0[2]=0;
shi=0;
ge=0;
}
/*---------------------------------------------------------------------------
下面这个函数计算峰峰值 和 频率 并显示出来
---------------------------------------------------------------------------*/
void display_vvp_hz(void)
{
cai[3]=ad1();
// cai0[2]=gao+di;
n=(unsigned int)cai[3];
m=n/4;
shi=m/10;
ge=m%10;
zhi(101,2,5,Table+5*shi);
zhi(110,2,5,Table+5*ge);
cai[0]=ad2();
n=(unsigned int)cai[0];
count=n*2;
shu3=count/100;
count=count%100;
shu1=count/10; // 获取计数值的十位
shu2=count%10;
zhi(98,6,5,Table+5*shu3);
zhi(104,6,5,Table+5*shu1);
zhi(110,6,5,Table+5*shu2);
}
//定时器0的中断函数
void T0_int() interrupt 1
{
TL0=0xf0;
TH0=0xdb;
time--;
if(time==0){ //定时1s
shu1=TH1;
shu2=TL1;
count=shu1*256+shu2;
flag=1;
TH1=0;
TL1=0;
time=108;
}
}
/*---------------------------------------------------------------------------
主函数
---------------------------------------------------------------------------*/
void main(void)
{
LCD_Initial();
Delay_x10ms(10);
LCD_CLR(Left);
Delay_x10ms(10);
LCD_CLR(Right);
Delay_x10ms(10);
data_int();
display_int();
while(1)
{
caiy1=ad1(); caiy2=ad1(); //caiy3=ad1(); caiy4=ad1();
y=(9*caiy1+caiy2)/80;
caix1=ad2(); caix2=ad2(); //caix3=ad2(); caix4=ad2();
x=(9*caix1+caix2)/80;
if(y<64) //当接收到的数据是有效值的时候
{
y=y+5;
x=x+8;
LCD_Display(x,y); //显示在液晶屏上描绘当前数据点。
display_vvp_hz();
// 时间轴 加1;下一个点会描绘在X+1处。
}
if(x==97) x=0; //当时间轴满了,超过了方格范围,时间轴变回起点。
Delay_x10ms(10); //延时,延时值MS越大,单位时间内能取得的点越少,波形显示就越窄。。反之越宽。
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -