标题:
单片机xdata可以直接映射到IO口吗?全局变量搞不懂
[打印本页]
作者:
mengsiu
时间:
2018-5-27 23:01
标题:
单片机xdata可以直接映射到IO口吗?全局变量搞不懂
最近淘到一片显示屏,用的是6963的芯片。在网上找了段驱动代码,但是自己读不懂...代码可以正常通过编译,说明代码是正确的。
而我不懂的是:
程序中没有明显地定义液晶屏引脚与单片机的连接,而在第12 13行定义了两个xdata,后面的程序直接操作这两个变量,难道这样可以直接映射到IO口吗?
要是我实际线路连接不一样,我要怎么重新定义这些变量?
附单片机代码:
/*----------------------------------------------------------------------------------------*/
//240*128液晶显示驱动程序
//控制器件为:AT89S52
//T6963C接口:直接访问形式
//程序设计:卢印举
/*----------------------------------------------------------------------------------------*/
#include <reg51.h>
#include <math.h>
#include <hzk.c>
//信号管脚定义(全局变量)(注意:因为液晶数据口接P0,直接访问方式)
unsigned char xdata Lcd_Cmd_Reg _at_ 0xfdff; // C/D-P2.0 CE-P2.1 p2.0=1 p2.1=0
unsigned char xdata Lcd_Data_Reg _at_ 0xfcff; // C/D-P2.0 CE-P2.1 p2.0=0 p2.1=0
//以8*8字符计算,显示屏横向、纵向可以显示的点阵坐标;左、上、右、下以及当前的位置坐标
#define LCD_LEFT 0
#define LCD_TOP 0
#define LCD_RIGHT 239
#define LCD_BOTTOM 127
unsigned char data Lcd_CurrentX,Lcd_CurrentY,Lcd_Mask;
unsigned char data LeftMask[]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01};
unsigned char data RightMask[]={0xff,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
/*----------------------------------------------------------------------------------------*/
//延时子程序
/*----------------------------------------------------------------------------------------*/
void Lcddelay(unsigned int t)
{ unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++)
;
}
void lcdwc(unsigned char cmdcode)
{ while((Lcd_Cmd_Reg & 0x3) != 0x3) ; //当Lcd_Cmd_Reg低两位不同时为1
Lcd_Cmd_Reg = cmdcode;
}
void lcdwc2(unsigned char cmdcode,unsigned char cmddata)
{ while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Data_Reg = cmddata;
while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Cmd_Reg = cmdcode;
}
void lcdwc3(unsigned char cmdcode,unsigned char cmddata,unsigned char cmddata2)
{ while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Data_Reg = cmddata;
while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Data_Reg = cmddata2;
while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Cmd_Reg = cmdcode;
}
void lcdwd(unsigned char dispdata) //写数据
{ while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Data_Reg = dispdata;
while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Cmd_Reg = 0xc0;
}
unsigned char lcdrdata(void) //读数据
{ while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Cmd_Reg = 0xc5;
while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
return Lcd_Data_Reg;
}
void lcdpos(void) //内部写数指针定位
{ unsigned int CurrentAddress;
CurrentAddress = Lcd_CurrentY * 30 ;
CurrentAddress += Lcd_CurrentX/8;
lcdwc3(0x24,CurrentAddress & 0xff,CurrentAddress/256);
}
unsigned char lcdrd(void) //读数据
{ lcdpos();
return lcdrdata();
}
void lcdcursornextbyte(void) //当前坐标移动到下一个点
{ Lcd_CurrentX+=8;
if(Lcd_CurrentX > LCD_RIGHT)
{ Lcd_CurrentX = LCD_LEFT;
Lcd_CurrentY++;
if(Lcd_CurrentY > LCD_BOTTOM) Lcd_CurrentY = LCD_TOP;
}
}
void displaybyte(unsigned char dispdata)
{ lcdpos();
if(Lcd_Mask == 0xff) lcdwd(dispdata);
else
{ unsigned char d=lcdrd();
d&=(~Lcd_Mask);
d|=(dispdata & Lcd_Mask);
lcdwd(d);
}
lcdcursornextbyte();
}
void Fill_Scr(unsigned char FillData) //LCD整屏显示
{ Lcd_Mask=0xff;
for(Lcd_CurrentX = LCD_LEFT,Lcd_CurrentY = LCD_TOP;1;)
{ displaybyte(FillData);
if((Lcd_CurrentX == LCD_LEFT) && (Lcd_CurrentY == LCD_TOP)) break;
}
}
void lcdreset() //初始化LCD屏
{ lcdwc(0x80);
lcdwc(0x98);
lcdwc3(0x42,0,0);
lcdwc3(0x43,30,0);
}
void displaychinesechardot(unsigned int Index);
void displayenglishchardot(unsigned int Index);
void putsizeimage(unsigned char XSIZE,unsigned char YSIZE,unsigned char code *s);
void putchar(unsigned int uChar) //信息显示
{ unsigned int i;
if(uChar<128)
for(i=0;i != ENGLISHCHARNUMBER;i++)
{ if(uChar ==EnglishCode[i])
{ displayenglishchardot(i);
break;
}
}
else
for(i=0;i != CHINESECHARNUMBER;i++)
{ if(uChar ==ChineseCode[i])
{ displaychinesechardot(i);
break;
}
}
}
void put_str(unsigned char code *s) //显示汉字或英文字符
{ unsigned int i;
for (;*s != 0;s++)
{ i=*s;
if(*s > 127)
{ s++;
i=i*256+*s;
}
if(i == '\n')
{ Lcd_CurrentX = LCD_LEFT;
if(Lcd_CurrentY > LCD_BOTTOM-CHINESECHARSIZE+1)
Lcd_CurrentY=LCD_TOP;
else
Lcd_CurrentY+=CHINESECHARSIZE;
}
putchar(i);
}
}
void put_str_xy(unsigned char x,unsigned char y,unsigned char code *s)//显示汉字或英文字符
{ Lcd_CurrentX=x;
Lcd_CurrentY=y;
put_str(s);
}
void displaychinesechardot(unsigned int Index)
{ unsigned char code *s;
s=ChineseCharDot+Index*CHINESECHARDOTSIZE;
if(Lcd_CurrentX > LCD_RIGHT-CHINESECHARSIZE+1)
{ Lcd_CurrentX = LCD_LEFT;
Lcd_CurrentY+=CHINESECHARSIZE;
if(Lcd_CurrentY > LCD_BOTTOM-CHINESECHARSIZE+1) Lcd_CurrentY=LCD_TOP;
}
putsizeimage(CHINESECHARSIZE,CHINESECHARSIZE,s);
}
void displayenglishchardot(unsigned int Index)
{ unsigned char code *s;
s=EnglishCharDot+Index*ENGLISHCHARDOTSIZE;
if(Lcd_CurrentX > LCD_RIGHT-ENGLISHCHARSIZE+1)
{ Lcd_CurrentX = LCD_LEFT;
Lcd_CurrentY+=CHINESECHARSIZE;
if(Lcd_CurrentY > LCD_BOTTOM-CHINESECHARSIZE+1)
Lcd_CurrentY=LCD_TOP;
}
putsizeimage(ENGLISHCHARSIZE,CHINESECHARSIZE,s);
}
void point(unsigned char bitdata)
{ if(bitdata==0)
bitdata=0xf0+(0x7-(Lcd_CurrentX & 0x7));
else
bitdata=0xf8+(0x7-(Lcd_CurrentX & 0x7));
while((Lcd_Cmd_Reg & 0x3) != 0x3) ;
Lcd_Cmd_Reg = bitdata;
}
/*----------------------------------------------------------------------------------------*/
//绘制点子程序,最后一位为像素大小
/*----------------------------------------------------------------------------------------*/
void pointxy(unsigned char x,unsigned char y,unsigned char bitdata)
{ Lcd_CurrentX=x;
Lcd_CurrentY=y;
lcdpos();
point(bitdata);
}
/*----------------------------------------------------------------------------------------*/
//画线子程序:最后一位为线条的像素宽度
/*----------------------------------------------------------------------------------------*/
void linexy(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char bitdata)
{ //线
unsigned char i,k;
if(abs(y1-y0)>abs(x1-x0))
{ if(y1>y0)
for(i=y0;i<=y1;i++)
{ if(x1>x0)
{ k=x1-x0;
k*=(i-y0);
k/=y1-y0;
pointxy(x0+k,i,bitdata);
}
else //x1<x0
{ k=x0-x1;
k*=(i-y0);
k/=y1-y0;
pointxy(x0-k,i,bitdata);
}
}
else //y1<y0
for(i=y0;i>=y1;i--)
{ if(x1>x0)
{ k=x1-x0;
k*=(y0-i);
k/=y0-y1;
pointxy(x0+k,i,bitdata);
}
else //x1<x0
{ k=x0-x1;
k*=(y0-i);
k/=y0-y1;
pointxy(x0-k,i,bitdata);
}
}
}
else //abs(y1-y0)<abs(x1-x0)
{ if(x1>x0)
for(i=x0;i<=x1;i++)
{ if(y1==y0)
pointxy(i,y0,bitdata);
else if(y1>y0)
{ k=y1-y0;
k*=(i-x0);
k/=x1-x0;
pointxy(i,y0+k,bitdata);
}
else //y1<y0
{ k=y0-y1;
k*=(i-x0);
k/=x1-x0;
pointxy(i,y0-k,bitdata);
}
}
else
for(i=x0;i>=x1;i--)
{ if(y1==y0)
pointxy(i,y0,bitdata);
else if(y1>y0)
{ k=y1-y0;
k*=(x0-i);
k/=x0-x1;
pointxy(i,y0+k,bitdata);
}
else //y1<y0
{ k=y0-y1;
k*=(x0-i);
k/=x0-x1;
pointxy(i,y0-k,bitdata);
}
}
}
}
void rect(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char bitdata)
{ //矩形
linexy(x0,y0,x0,y1,bitdata);
linexy(x0,y0,x1,y0,bitdata);
linexy(x0,y1,x1,y1,bitdata);
linexy(x1,y0,x1,y1,bitdata);
}
void putsizeimage(unsigned char XSIZE,unsigned char YSIZE,unsigned char code *s)
{ unsigned char k,lx,ly,a1,a2,x;
Lcddelay(1000);
k=Lcd_CurrentX&0X7;
XSIZE+=k;
x=Lcd_CurrentX;
for(ly=0;ly<YSIZE;ly++,Lcd_CurrentY++)
for(Lcd_CurrentX=x,lx=k,a1=0;lx<XSIZE;s++)
{ unsigned char p;
a2=*s;
for(p=0;p<k;p++)
{ a2>>=1;
if((a1&0x1)==1) a2+=0x80;
a1>>=1;
}
lcdpos();
p=XSIZE&0X7;
if(lx<8)
{ if(XSIZE<8)
{ Lcd_Mask=LeftMask[k] & RightMask[p];
a1=lcdrd();
a1&=(~Lcd_Mask);
a1|=(a2 & Lcd_Mask);
lcdwd(a1);
lx=XSIZE;
Lcd_CurrentX+=XSIZE-k;
}
else //XSIZE>=8
{ Lcd_Mask=LeftMask[k];
a1=lcdrd();
a1&=(~Lcd_Mask);
a1|=(a2 & Lcd_Mask);
lcdwd(a1);
lx+=8-k;
Lcd_CurrentX+=8-k;
}
}
else if(lx>=XSIZE-p) //lx>=8
{ if(k>=p)
{ s--;
a1=*s;
a2=0;
for(p=0;p<k;p++)
{ a2>>=1;
if((a1&0x1)==1) a2+=0x80;
a1>>=1;
}
p=XSIZE&0X7;
}
Lcd_Mask=RightMask[p];
a1=lcdrd();
a1&=(~Lcd_Mask);
a1|=(a2 & Lcd_Mask);
lcdwd(a1);
lx+=p;
Lcd_CurrentX+=p;
}
else //lx>=8 and lx<XSIZE-p
{ lcdwd(a2);
lx+=8;
Lcd_CurrentX+=8;
}
a1=*s;
}
Lcd_CurrentY-=YSIZE;
}
void main()
{
lcdreset();
Fill_Scr(0x55); //显示竖条
Lcddelay(6000); //系统延时
Fill_Scr(0xff); //显示黑屏
Lcddelay(6000);
// put_str_xy(0,0,"创新科技检测技术有限公司,联系电话0512-86163888");//显示汉字
put_str("创新科技检测技术有限公司,联系电话0512-86163888");
Fill_Scr(0x00);
//
rect(12,12,88,88,6);
Lcddelay(5000);
//Fill_Scr(0xff);
//rect(12,12,88,120,0);
lcdreset();
}
复制代码
作者:
mengsiu
时间:
2018-5-28 22:03
24小时必答吗?已经24小时了吗?已经快24小时了。
作者:
mengsiu
时间:
2018-6-2 09:45
24小时必答吗?已经24小时了吗?已经100小时了。
作者:
mengsiu
时间:
2018-6-7 13:28
24小时必答吗?已经24小时了吗?已经240小时了。
作者:
mengsiu
时间:
2018-9-7 10:24
24小时必答吗?已经24小时了吗?已经2400+小时了。
作者:
sxhwdz
时间:
2018-9-18 19:49
早先的51单片机内部没有XRAM,而且都是使用总线结构,P0是数据8位数据总线,与低8位地址总线,P2是高8位地址总线。而外部设备的寻址也是通过映射到XRAM段,操作外设与XRAM读取类似。12、13行定义的应该是液晶屏的命令和数据的选通信号。
作者:
angmall
时间:
2018-9-18 21:31
题主你好,你这样的提问。我估计没几个人会回答你的。
其实就一条解决方案:研读T6963C手册!!!
作者:
sxhwdz
时间:
2018-9-19 06:58
unsigned char xdata Lcd_Cmd_Reg _at_ 0xfdff; // C/D-P2.0 CE-P2.1 p2.0=1 p2.1=0
unsigned char xdata Lcd_Data_Reg _at_ 0xfcff; // C/D-P2.0 CE-P2.1 p2.0=0 p2.1=0
液晶屏C/D连接的是P2.0,CE连接的是P2.1,RD连接P3.7,WR连接P3.6。当对地址 0xfdff 的 Lcd_Cmd_Reg 读/写时,C/D=1,CE=0,完成对液晶屏指令寄存器的读写。对地址 0xfcff 的 Lcd_Data_Reg 读/写时,C/D=0,CE=0,完成对液晶屏数据寄存器的读写。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1