3194|5

68

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

还是LCD1602显示问题,帮忙看下代码? [复制链接]

刚学习不久,代码写的比较烂,主要想学习下LCD,抄了下某开发板的代码,自己改了下,代码如下:
#include
#include
#include
#include
#include
#define uchar unsigned char
#define uint  unsigned int
sbit E=P2^7;                //1602使能引脚
sbit RW=P2^6;                //1602读写引脚       
sbit RS=P2^5;                //1602数据/命令选择引脚

uchar stringaz[15];
uchar  disp1[]={"   sattracker   "};
uchar  disp2[]={"AZ:000 EL:000 "};
uchar az[4];
uchar el[4];
uchar iaz,azlen;
uint record,a,j,k,douhao,len;
int numaz,numel;
/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay()
{
        int i,j;
        for(i=0; i<=10; i++)
        for(j=0; j<=2; j++)
;
}
/********************************************************************
* 名称 : Convert(uchar In_Date)
* 功能 : 因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。
* 输入 : 1602资料上的值
* 输出 : 送到1602的值
***********************************************************************/
uchar Convert(uchar In_Date)
{
    uchar i, Out_Date = 0, temp = 0;
    for(i=0; i<8; i++)
    {
        temp = (In_Date >> i) & 0x01;
        Out_Date |= (temp << (7 - i));
    }
    return Out_Date;
}

/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/

void enable(uchar del)
{
        P0 = Convert(del);
        RS = 0;
        RW = 0;
        E = 0;
        delay();
        E = 1;
        delay();
}

/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void write(uchar del)
{
        P0 = Convert(del);
        RS = 1;
        RW = 0;
        E = 0;
        delay();
        E = 1;
        delay();
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
        enable(0x01);
        enable(0x38);
        enable(0x0c);
        enable(0x06);
        enable(0xd0);
}


/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
                  L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
        uchar a;
        if(hang == 1) a = 0x80;
        if(hang == 2) a = 0xc0;
        a = a + lie - 1;
        enable(a);
        while(1)
        {
                if(*p == '\0')
           break;
                write(*p);
                p++;
        }
}


/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
        uchar x,j;
        for(j=0;j         for(x=0;x<=148;x++);       
}



/********************************************************************
* 名称 : Com_Int()
* 功能 : 串口中断子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Int(void) interrupt 4
{
         if(RI)
         {  
       RI = 0;
           stringaz[iaz++]=SBUF;
            if(SBUF == '*')
              {
               stringaz[iaz]='\0';
               iaz=0;
             
              }
      }
}



void data_cl()
{
douhao=0;
j=0;
k=0;
len=strlen(stringaz);
for(a=0;a   {
   if(stringaz[a]==',')
     {
         douhao++;
         a++;
         }
    if(douhao==1)
         {
      az[j]=stringaz[a];
          j++;
         }
        if(douhao==2)
         {
         el[k]=stringaz[a];
         k++;
         }
    if(stringaz[a]=='*')
          {
           numaz=atoi(az);//数据格式的AZ数据
           numel=atoi(el);//数据格式的EL数据
          azlen=strlen(az);//查看AZ的长度

          j=0;
          k=0;
          }
   
    }  

}


/********************************************************************
* 名称 : Com_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Init(void)
{
     TMOD = 0x20;
     PCON = 0x00;
     SCON = 0x50;                       
     TH1 = 0xFd;    //设置波特率 9600
     TL1 = 0xFd;
     TR1 = 1;
                   //启动定时器1
         ES = 1;                //开串口中断
         EA = 1;                //开总中断               
}


/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{   
   
    j=0;
        k=0;
        Delay_1ms(1);
        Com_Init();
    L1602_init();
        L1602_string(1,1,disp1);
        L1602_string(2,1,disp2);
         
        while(1)
        {
         data_cl();       
         if(azlen==3)    //当AZ数据是三位数时
         {
         disp2[3]=numaz/100+'0';//3位数据时候的百位
         disp2[4]=numaz%100/10+'0';//十位
         disp2[5]=numaz%100%10+'0';//个位
         L1602_string(2,1,disp2);//送显
         }
         if(azlen==2)    //AZ数据是2位的时候
         {
         disp2[3]=0x30;        //高位显示0是不是可以用来清楚原来写的高位数据
         disp2[4]=numaz/10+'0'; //2位AZ数据的10位
         disp2[5]=numaz%10+'0'; //2位数据时候的个位
         L1602_string(2,1,disp2);
         }
       

             
        }     

}
串口调试软件发送特定格式的数据(如:“#,11,22,*”11放分离出的AZ数组,22放分离出的EL数组,EL数组暂时没用),串口数据接收正常,数码管显示正常(现在暂时没用),现在的问题是:比如第一次送个2位的数据如11,LCD显示011,正常,再送个3位的数据333,LCD显示333,但要是再换回2位的数据如44,LCD就显示443。程序写的比较烂,看下哪出了问题。
这是开发板的代码,好象也没什么查看BUSY标志的,但是可以很好显示。

最新回复

谢了楼上的几位朋友,问题解决,程序结构不太好,不过现在可以显示,主要问题是在新一次向数组写入数据时要数组清零。覆盖掉前面接收时候的数据!代码写的很烂,好在显示没什么问题!  详情 回复 发表于 2010-2-24 21:02
点赞 关注

回复
举报

81

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
显示数据不足位数的时候,可以有两种方法:
1.最高位为零,不显示,需要发送不显示的驱动字符,例如“2F”,假设是这个字符。
2.最高位为零显示,择将最高位所有连续的零都显示出来。

楼主要将得到的字符做判断,看看最高位是否有连续的零出现,如果有,择需要改为零驱动的字符显示。
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
if(azlen==2)    //AZ数据是2位的时候 改为
else if(azlen==2)    //AZ数据是2位的时候
在 data_cl()中azlen直接等于j就ok了!不用在用函数计算了!
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

4
 
2楼的朋友这个判断程序怎么写?郁闷中~~~~~
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

5
 

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #define uchar unsigned char
  7. #define uint  unsigned int
  8. sbit E=P2^7; //1602使能引脚
  9. sbit RW=P2^6; //1602读写引脚
  10. sbit RS=P2^5; //1602数据/命令选择引脚

  11. uchar stringaz[15];
  12. uchar  disp1[]={"  sattracker  "};
  13. uchar  disp2[]={"AZ:000 EL:000 "};
  14. uchar az[4];
  15. uchar el[4];
  16. uchar iaz,azlen;
  17. uint record,a,j,k,douhao,len;
  18. int numaz,numel;
  19. unsigned char last_rev_len=0;//上次接收的长度
  20. /********************************************************************
  21. * 名称 : delay()
  22. * 功能 : 延时,延时时间大概为140US。
  23. * 输入 : 无
  24. * 输出 : 无
  25. ***********************************************************************/

  26. void delay()
  27. {
  28. int i,j;
  29. for(i=0; i <=10; i++)
  30. for(j=0; j <=2; j++)
  31. ;
  32. }
  33. /********************************************************************
  34. * 名称 : Convert(uchar In_Date)
  35. * 功能 : 因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。
  36. * 输入 : 1602资料上的值
  37. * 输出 : 送到1602的值
  38. ***********************************************************************/
  39. uchar Convert(uchar In_Date)
  40. {
  41.     uchar i, Out_Date = 0, temp = 0;
  42.     for(i=0; i <8; i++)
  43.     {
  44.         temp = (In_Date >> i) & 0x01;
  45.         Out_Date |= (temp < < (7 - i));
  46.     }
  47.     return Out_Date;
  48. }

  49. /********************************************************************
  50. * 名称 : enable(uchar del)
  51. * 功能 : 1602命令函数
  52. * 输入 : 输入的命令值
  53. * 输出 : 无
  54. ***********************************************************************/

  55. void enable(uchar del)
  56. {
  57. P0 = Convert(del);
  58. RS = 0;
  59. RW = 0;
  60. E = 0;
  61. delay();
  62. E = 1;
  63. delay();
  64. }

  65. /********************************************************************
  66. * 名称 : write(uchar del)
  67. * 功能 : 1602写数据函数
  68. * 输入 : 需要写入1602的数据
  69. * 输出 : 无
  70. ***********************************************************************/

  71. void write(uchar del)
  72. {
  73. P0 = Convert(del);
  74. RS = 1;
  75. RW = 0;
  76. E = 0;
  77. delay();
  78. E = 1;
  79. delay();
  80. }

  81. /********************************************************************
  82. * 名称 : L1602_init()
  83. * 功能 : 1602初始化,请参考1602的资料
  84. * 输入 : 无
  85. * 输出 : 无
  86. ***********************************************************************/
  87. void L1602_init(void)
  88. {
  89. enable(0x01);
  90. enable(0x38);
  91. enable(0x0c);
  92. enable(0x06);
  93. enable(0xd0);
  94. }


  95. /********************************************************************
  96. * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
  97. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  98. L1602_string(1,5,"ab cd ef;")
  99. * 输入 : 行,列,需要输入1602的数据
  100. * 输出 : 无
  101. ***********************************************************************/
  102. void L1602_string(uchar hang,uchar lie,uchar *p)
  103. {
  104. uchar a;
  105. if(hang == 1) a = 0x80;
  106. if(hang == 2) a = 0xc0;
  107. a = a + lie - 1;
  108. enable(a);
  109. while(1)
  110. {
  111. if(*p == '\0')
  112.           break;
  113. write(*p);
  114. p++;
  115. }
  116. }


  117. /********************************************************************
  118. * 名称 : Delay_1ms()
  119. * 功能 : 延时子程序,延时时间为 1ms * x
  120. * 输入 : x (延时一毫秒的个数)
  121. * 输出 : 无
  122. ***********************************************************************/
  123. void Delay_1ms(uint i)//1ms延时
  124. {
  125. uchar x,j;
  126. for(j=0;j
  127. for(x=0;x <=148;x++);
  128. }


  129. /********************************************************************
  130. * 名称 : Com_Int()
  131. * 功能 : 串口中断子函数
  132. * 输入 : 无
  133. * 输出 : 无
  134. ***********************************************************************/
  135. void Com_Int(void) interrupt 4
  136. {
  137.         if(RI)
  138.         {  
  139.       RI = 0;
  140.                   stringaz[iaz]=SBUF;
  141.             if(stringaz[iaz] == '*')
  142.             {
  143. //              stringaz[iaz]='\0';
  144.               last_rev_len = iaz ;//记录长度
  145.                      data_cl();//数组转换
  146.               iaz=0;
  147.            }
  148.            else iaz++;
  149.   }
  150. }


  151. void data_cl()
  152. {
  153. douhao=0;
  154. j=0;
  155. k=0;
  156. //len=strlen(stringaz);
  157. for(a=0;a
  158.   {
  159.           if(stringaz[a]==',')
  160.             {
  161.                 douhao++;
  162.                 a++;
  163.                 }  
  164.           else if(stringaz[a]=='*')
  165.           {
  166.                   numaz=atoi(az);//数据格式的AZ数据
  167.                   numel=atoi(el);//数据格式的EL数据
  168.                   azlen=j;//strlen(az);//查看AZ的长度
  169.           }
  170.           if(douhao==1)
  171.                 {
  172.                   az[j]=stringaz[a];
  173.                   j++;
  174.                 }
  175.                 else if(douhao==2)
  176.                 {
  177.                         el[k]=stringaz[a];
  178.                         k++;
  179.                 }
  180.   }  
  181. }
  182. /********************************************************************
  183. * 名称 : Com_Init()
  184. * 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
  185. * 输入 : 无
  186. * 输出 : 无
  187. ***********************************************************************/
  188. void Com_Init(void)
  189. {
  190.     TMOD = 0x20;
  191.     PCON = 0x00;
  192.     SCON = 0x50;
  193.     TH1 = 0xFd;    //设置波特率 9600
  194.     TL1 = 0xFd;
  195.     TR1 = 1;
  196.   //启动定时器1
  197. ES = 1; //开串口中断
  198. EA = 1; //开总中断
  199. }


  200. /********************************************************************
  201. * 名称 : Main()
  202. * 功能 : 主函数
  203. * 输入 : 无
  204. * 输出 : 无
  205. ***********************************************************************/
  206. void Main()
  207. {  
  208.    
  209.     j=0;
  210. k=0;
  211. Delay_1ms(1);
  212. Com_Init();
  213. L1602_init();
  214. L1602_string(1,1,disp1);
  215. L1602_string(2,1,disp2);

  216.         while(1)
  217.         {
  218.         //        data_cl(); //去掉,在中断中判断
  219.                 if(azlen==3)    //当AZ数据是三位数时
  220.                 {
  221.                 disp2[3]=numaz/100+'0';//3位数据时候的百位
  222.                 disp2[4]=numaz%100/10+'0';//十位
  223.                 disp2[5]=numaz%100%10+'0';//个位
  224.                 }
  225.                 else if(azlen==2)    //AZ数据是2位的时候
  226.                 {
  227.                 disp2[3]='0';        //高位显示0是不是可以用来清楚原来写的高位数据
  228.                 disp2[4]=numaz/10+'0'; //2位AZ数据的10位
  229.                 disp2[5]=numaz%10+'0'; //2位数据时候的个位
  230.                 }
  231.                 else     //AZ数据不是2、3位的时候
  232.                 {
  233.                 disp2[3]='0';        //高位显示0是不是可以用来清楚原来写的高位数据
  234.                 disp2[4]='0'; //2位AZ数据的10位
  235.                 disp2[5]='0'; //2位数据时候的个位
  236.                 }  
  237.                 L1602_string(2,1,disp2);
  238.         }   

  239. }

复制代码
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

6
 
谢了楼上的几位朋友,问题解决,程序结构不太好,不过现在可以显示,主要问题是在新一次向数组写入数据时要数组清零。覆盖掉前面接收时候的数据!代码写的很烂,好在显示没什么问题!
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表