找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3365|回复: 8
收起左侧

单片机xdata可以直接映射到IO口吗?全局变量搞不懂

[复制链接]
ID:16255 发表于 2018-5-27 23:01 | 显示全部楼层 |阅读模式
最近淘到一片显示屏,用的是6963的芯片。在网上找了段驱动代码,但是自己读不懂...代码可以正常通过编译,说明代码是正确的。

而我不懂的是:
  • 程序中没有明显地定义液晶屏引脚与单片机的连接,而在第12 13行定义了两个xdata,后面的程序直接操作这两个变量,难道这样可以直接映射到IO口吗?
  • 要是我实际线路连接不一样,我要怎么重新定义这些变量?


附单片机代码:
  1. /*----------------------------------------------------------------------------------------*/   
  2. //240*128液晶显示驱动程序   
  3. //控制器件为:AT89S52   
  4. //T6963C接口:直接访问形式   
  5. //程序设计:卢印举   
  6. /*----------------------------------------------------------------------------------------*/   
  7. #include <reg51.h>   
  8. #include <math.h>   
  9. #include <hzk.c>   
  10.    
  11. //信号管脚定义(全局变量)(注意:因为液晶数据口接P0,直接访问方式)   
  12. unsigned char xdata Lcd_Cmd_Reg _at_ 0xfdff;    // C/D-P2.0   CE-P2.1  p2.0=1 p2.1=0   
  13. unsigned char xdata Lcd_Data_Reg _at_ 0xfcff;   // C/D-P2.0   CE-P2.1  p2.0=0 p2.1=0   
  14.    
  15. //以8*8字符计算,显示屏横向、纵向可以显示的点阵坐标;左、上、右、下以及当前的位置坐标   
  16. #define LCD_LEFT 0   
  17. #define LCD_TOP  0   
  18. #define LCD_RIGHT 239   
  19. #define LCD_BOTTOM 127   
  20. unsigned char data Lcd_CurrentX,Lcd_CurrentY,Lcd_Mask;   
  21.    
  22. unsigned char data LeftMask[]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01};   
  23. unsigned char data RightMask[]={0xff,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};   
  24.    
  25. /*----------------------------------------------------------------------------------------*/   
  26. //延时子程序   
  27. /*----------------------------------------------------------------------------------------*/   
  28. void Lcddelay(unsigned int t)     
  29. {  unsigned int i,j;   
  30.    for(i=0;i<t;i++)   
  31.       for(j=0;j<10;j++)   
  32.          ;   
  33. }   
  34.    
  35. void lcdwc(unsigned char cmdcode)   
  36. {  while((Lcd_Cmd_Reg & 0x3) != 0x3) ;  //当Lcd_Cmd_Reg低两位不同时为1   
  37.       Lcd_Cmd_Reg = cmdcode;   
  38. }   
  39.    
  40. void lcdwc2(unsigned char cmdcode,unsigned char cmddata)   
  41. {  while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  42.       Lcd_Data_Reg = cmddata;   
  43.    while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  44.       Lcd_Cmd_Reg = cmdcode;   
  45. }   
  46.    
  47. void lcdwc3(unsigned char cmdcode,unsigned char cmddata,unsigned char cmddata2)   
  48. {  while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  49.       Lcd_Data_Reg = cmddata;   
  50.    while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  51.       Lcd_Data_Reg = cmddata2;   
  52.    while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  53.       Lcd_Cmd_Reg = cmdcode;   
  54. }   
  55.    
  56. void lcdwd(unsigned char dispdata)           //写数据   
  57. {  while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  58.       Lcd_Data_Reg = dispdata;   
  59.    while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  60.       Lcd_Cmd_Reg = 0xc0;   
  61. }   
  62.    
  63. unsigned char lcdrdata(void)                 //读数据   
  64. {  while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  65.       Lcd_Cmd_Reg = 0xc5;   
  66.    while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  67.       return Lcd_Data_Reg;   
  68. }   
  69.    
  70. void lcdpos(void)                            //内部写数指针定位   
  71. {  unsigned int CurrentAddress;   
  72.    CurrentAddress = Lcd_CurrentY * 30 ;   
  73.    CurrentAddress += Lcd_CurrentX/8;   
  74.    lcdwc3(0x24,CurrentAddress & 0xff,CurrentAddress/256);   
  75. }   
  76.    
  77. unsigned char lcdrd(void)                    //读数据   
  78. {  lcdpos();   
  79.    return lcdrdata();   
  80. }   
  81.    
  82. void lcdcursornextbyte(void)  //当前坐标移动到下一个点   
  83. {  Lcd_CurrentX+=8;   
  84.    if(Lcd_CurrentX > LCD_RIGHT)   
  85.    {  Lcd_CurrentX = LCD_LEFT;   
  86.       Lcd_CurrentY++;   
  87.       if(Lcd_CurrentY > LCD_BOTTOM) Lcd_CurrentY = LCD_TOP;   
  88.    }   
  89. }   
  90.    
  91. void displaybyte(unsigned char dispdata)   
  92. {  lcdpos();   
  93.    if(Lcd_Mask == 0xff) lcdwd(dispdata);   
  94.    else   
  95.    {  unsigned char d=lcdrd();   
  96.       d&=(~Lcd_Mask);   
  97.       d|=(dispdata & Lcd_Mask);   
  98.       lcdwd(d);   
  99.    }   
  100.    lcdcursornextbyte();   
  101. }   
  102.    
  103. void Fill_Scr(unsigned char FillData)    //LCD整屏显示   
  104. {  Lcd_Mask=0xff;   
  105.    for(Lcd_CurrentX = LCD_LEFT,Lcd_CurrentY = LCD_TOP;1;)   
  106.    {  displaybyte(FillData);   
  107.       if((Lcd_CurrentX == LCD_LEFT) && (Lcd_CurrentY == LCD_TOP)) break;   
  108.    }   
  109. }   
  110.    
  111. void lcdreset()             //初始化LCD屏   
  112. {  lcdwc(0x80);   
  113.    lcdwc(0x98);   
  114.    lcdwc3(0x42,0,0);   
  115.    lcdwc3(0x43,30,0);   
  116. }   
  117.    
  118. void displaychinesechardot(unsigned int Index);   
  119. void displayenglishchardot(unsigned int Index);   
  120. void putsizeimage(unsigned char XSIZE,unsigned char YSIZE,unsigned char code *s);   
  121.    
  122. void putchar(unsigned int uChar)  //信息显示   
  123. {  unsigned int i;   
  124.    if(uChar<128)   
  125.       for(i=0;i != ENGLISHCHARNUMBER;i++)   
  126.       {  if(uChar ==EnglishCode[i])   
  127.          {  displayenglishchardot(i);   
  128.             break;   
  129.          }   
  130.       }   
  131.    else   
  132.       for(i=0;i != CHINESECHARNUMBER;i++)   
  133.       {  if(uChar ==ChineseCode[i])   
  134.          {  displaychinesechardot(i);   
  135.             break;   
  136.          }   
  137.       }   
  138. }   
  139.    
  140. void put_str(unsigned char code *s) //显示汉字或英文字符   
  141. {  unsigned int i;   
  142.    for (;*s != 0;s++)   
  143.    {  i=*s;   
  144.       if(*s > 127)   
  145.       {  s++;   
  146.          i=i*256+*s;   
  147.       }   
  148.       if(i == '\n')   
  149.       {  Lcd_CurrentX = LCD_LEFT;   
  150.          if(Lcd_CurrentY > LCD_BOTTOM-CHINESECHARSIZE+1)   
  151.             Lcd_CurrentY=LCD_TOP;   
  152.          else   
  153.             Lcd_CurrentY+=CHINESECHARSIZE;   
  154.       }   
  155.       putchar(i);   
  156.    }   
  157. }   
  158.    
  159. void put_str_xy(unsigned char x,unsigned char y,unsigned char code *s)//显示汉字或英文字符   
  160. {  Lcd_CurrentX=x;   
  161.    Lcd_CurrentY=y;   
  162.    put_str(s);   
  163. }   
  164.    
  165. void displaychinesechardot(unsigned int Index)   
  166. {  unsigned char code *s;   
  167.    s=ChineseCharDot+Index*CHINESECHARDOTSIZE;   
  168.    if(Lcd_CurrentX > LCD_RIGHT-CHINESECHARSIZE+1)   
  169.    {   Lcd_CurrentX = LCD_LEFT;   
  170.        Lcd_CurrentY+=CHINESECHARSIZE;   
  171.        if(Lcd_CurrentY > LCD_BOTTOM-CHINESECHARSIZE+1) Lcd_CurrentY=LCD_TOP;   
  172.    }   
  173.    putsizeimage(CHINESECHARSIZE,CHINESECHARSIZE,s);   
  174. }   
  175.    
  176. void displayenglishchardot(unsigned int Index)   
  177. {  unsigned char code *s;   
  178.    s=EnglishCharDot+Index*ENGLISHCHARDOTSIZE;   
  179.    if(Lcd_CurrentX > LCD_RIGHT-ENGLISHCHARSIZE+1)   
  180.    {  Lcd_CurrentX = LCD_LEFT;   
  181.       Lcd_CurrentY+=CHINESECHARSIZE;   
  182.       if(Lcd_CurrentY > LCD_BOTTOM-CHINESECHARSIZE+1)   
  183.          Lcd_CurrentY=LCD_TOP;   
  184.    }   
  185.    putsizeimage(ENGLISHCHARSIZE,CHINESECHARSIZE,s);   
  186. }   
  187.    
  188. void point(unsigned char bitdata)   
  189. {  if(bitdata==0)   
  190.       bitdata=0xf0+(0x7-(Lcd_CurrentX & 0x7));   
  191.    else   
  192.       bitdata=0xf8+(0x7-(Lcd_CurrentX & 0x7));   
  193.    while((Lcd_Cmd_Reg & 0x3) != 0x3) ;   
  194.       Lcd_Cmd_Reg = bitdata;   
  195. }   
  196.    
  197. /*----------------------------------------------------------------------------------------*/   
  198. //绘制点子程序,最后一位为像素大小   
  199. /*----------------------------------------------------------------------------------------*/   
  200. void pointxy(unsigned char x,unsigned char y,unsigned char bitdata)         
  201. {  Lcd_CurrentX=x;   
  202.    Lcd_CurrentY=y;   
  203.    lcdpos();   
  204.    point(bitdata);   
  205. }   
  206.    
  207. /*----------------------------------------------------------------------------------------*/   
  208. //画线子程序:最后一位为线条的像素宽度   
  209. /*----------------------------------------------------------------------------------------*/   
  210. void linexy(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char bitdata)   
  211. {                                                       //线   
  212.    unsigned char i,k;   
  213.    if(abs(y1-y0)>abs(x1-x0))   
  214.    {  if(y1>y0)   
  215.          for(i=y0;i<=y1;i++)   
  216.          {  if(x1>x0)   
  217.             {  k=x1-x0;   
  218.                k*=(i-y0);   
  219.                k/=y1-y0;   
  220.                pointxy(x0+k,i,bitdata);   
  221.             }   
  222.             else  //x1<x0   
  223.             {  k=x0-x1;   
  224.                k*=(i-y0);   
  225.                k/=y1-y0;   
  226.                pointxy(x0-k,i,bitdata);   
  227.             }   
  228.          }   
  229.       else        //y1<y0   
  230.          for(i=y0;i>=y1;i--)   
  231.          {  if(x1>x0)   
  232.             {  k=x1-x0;   
  233.                k*=(y0-i);   
  234.                k/=y0-y1;   
  235.                pointxy(x0+k,i,bitdata);   
  236.             }   
  237.             else   //x1<x0   
  238.             {  k=x0-x1;   
  239.                k*=(y0-i);   
  240.                k/=y0-y1;   
  241.                pointxy(x0-k,i,bitdata);   
  242.             }   
  243.          }   
  244.    }   
  245.    else            //abs(y1-y0)<abs(x1-x0)   
  246.    {  if(x1>x0)   
  247.          for(i=x0;i<=x1;i++)   
  248.          {  if(y1==y0)   
  249.                pointxy(i,y0,bitdata);   
  250.             else if(y1>y0)   
  251.             {  k=y1-y0;   
  252.                k*=(i-x0);   
  253.                k/=x1-x0;   
  254.                pointxy(i,y0+k,bitdata);   
  255.             }   
  256.             else     //y1<y0   
  257.             {  k=y0-y1;   
  258.                k*=(i-x0);   
  259.                k/=x1-x0;   
  260.                pointxy(i,y0-k,bitdata);   
  261.             }   
  262.          }   
  263.       else   
  264.          for(i=x0;i>=x1;i--)   
  265.          {  if(y1==y0)   
  266.                pointxy(i,y0,bitdata);   
  267.             else if(y1>y0)   
  268.             {  k=y1-y0;   
  269.                k*=(x0-i);   
  270.                k/=x0-x1;   
  271.                pointxy(i,y0+k,bitdata);   
  272.             }   
  273.             else     //y1<y0   
  274.             {  k=y0-y1;   
  275.                k*=(x0-i);   
  276.                k/=x0-x1;   
  277.                pointxy(i,y0-k,bitdata);   
  278.             }   
  279.        }   
  280.   }   
  281. }   
  282.    
  283. void rect(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char bitdata)   
  284. {                                                      //矩形   
  285.    linexy(x0,y0,x0,y1,bitdata);   
  286.    linexy(x0,y0,x1,y0,bitdata);   
  287.    linexy(x0,y1,x1,y1,bitdata);   
  288.    linexy(x1,y0,x1,y1,bitdata);   
  289. }   
  290.    
  291. void putsizeimage(unsigned char XSIZE,unsigned char YSIZE,unsigned char code *s)   
  292. {  unsigned char k,lx,ly,a1,a2,x;   
  293.    Lcddelay(1000);   
  294.    k=Lcd_CurrentX&0X7;   
  295.    XSIZE+=k;   
  296.    x=Lcd_CurrentX;   
  297.    for(ly=0;ly<YSIZE;ly++,Lcd_CurrentY++)   
  298.       for(Lcd_CurrentX=x,lx=k,a1=0;lx<XSIZE;s++)   
  299.       {  unsigned char p;   
  300.          a2=*s;   
  301.          for(p=0;p<k;p++)   
  302.          {  a2>>=1;   
  303.             if((a1&0x1)==1) a2+=0x80;   
  304.             a1>>=1;   
  305.          }   
  306.          lcdpos();   
  307.          p=XSIZE&0X7;   
  308.          if(lx<8)   
  309.          {  if(XSIZE<8)   
  310.             {  Lcd_Mask=LeftMask[k] & RightMask[p];   
  311.                a1=lcdrd();   
  312.                a1&=(~Lcd_Mask);   
  313.                a1|=(a2 & Lcd_Mask);   
  314.                lcdwd(a1);   
  315.                lx=XSIZE;   
  316.                 Lcd_CurrentX+=XSIZE-k;   
  317.             }   
  318.             else   //XSIZE>=8   
  319.             {  Lcd_Mask=LeftMask[k];   
  320.                a1=lcdrd();   
  321.                a1&=(~Lcd_Mask);   
  322.                a1|=(a2 & Lcd_Mask);   
  323.                lcdwd(a1);   
  324.                lx+=8-k;   
  325.                Lcd_CurrentX+=8-k;   
  326.             }   
  327.          }   
  328.          else if(lx>=XSIZE-p)  //lx>=8   
  329.          {  if(k>=p)   
  330.             {  s--;   
  331.                a1=*s;   
  332.                a2=0;   
  333.                for(p=0;p<k;p++)   
  334.                {  a2>>=1;   
  335.                   if((a1&0x1)==1) a2+=0x80;   
  336.                      a1>>=1;   
  337.                }   
  338.                p=XSIZE&0X7;   
  339.             }   
  340.             Lcd_Mask=RightMask[p];   
  341.             a1=lcdrd();   
  342.             a1&=(~Lcd_Mask);   
  343.             a1|=(a2 & Lcd_Mask);   
  344.             lcdwd(a1);   
  345.             lx+=p;   
  346.             Lcd_CurrentX+=p;   
  347.          }   
  348.          else    //lx>=8 and lx<XSIZE-p   
  349.          {  lcdwd(a2);   
  350.             lx+=8;   
  351.             Lcd_CurrentX+=8;   
  352.          }   
  353.          a1=*s;   
  354.       }   
  355.   Lcd_CurrentY-=YSIZE;   
  356. }   
  357.    
  358. void main()   
  359. {   
  360.    lcdreset();   
  361.    Fill_Scr(0x55);            //显示竖条   
  362.    Lcddelay(6000);            //系统延时   
  363.    Fill_Scr(0xff);            //显示黑屏   
  364.    Lcddelay(6000);   
  365. //   put_str_xy(0,0,"创新科技检测技术有限公司,联系电话0512-86163888");//显示汉字   
  366.    put_str("创新科技检测技术有限公司,联系电话0512-86163888");   
  367.    Fill_Scr(0x00);   
  368. //        
  369.    rect(12,12,88,88,6);   
  370.    Lcddelay(5000);   
  371.    //Fill_Scr(0xff);   
  372.    //rect(12,12,88,120,0);   
  373.    lcdreset();   
  374. }   
复制代码
回复

使用道具 举报

ID:16255 发表于 2018-5-28 22:03 来自手机 | 显示全部楼层
24小时必答吗?已经24小时了吗?已经快24小时了。
回复

使用道具 举报

ID:16255 发表于 2018-6-2 09:45 | 显示全部楼层
24小时必答吗?已经24小时了吗?已经100小时了。
回复

使用道具 举报

ID:16255 发表于 2018-6-7 13:28 | 显示全部楼层
24小时必答吗?已经24小时了吗?已经240小时了。
回复

使用道具 举报

ID:16255 发表于 2018-9-7 10:24 | 显示全部楼层
24小时必答吗?已经24小时了吗?已经2400+小时了。
回复

使用道具 举报

ID:387733 发表于 2018-9-18 19:49 | 显示全部楼层
早先的51单片机内部没有XRAM,而且都是使用总线结构,P0是数据8位数据总线,与低8位地址总线,P2是高8位地址总线。而外部设备的寻址也是通过映射到XRAM段,操作外设与XRAM读取类似。12、13行定义的应该是液晶屏的命令和数据的选通信号。

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:155507 发表于 2018-9-18 21:31 | 显示全部楼层
题主你好,你这样的提问。我估计没几个人会回答你的。

其实就一条解决方案:研读T6963C手册!!!

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:387733 发表于 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,完成对液晶屏数据寄存器的读写。

评分

参与人数 1黑币 +30 收起 理由
admin + 30 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表