大斧 发表于 2012-4-21 13:37:16

初学者变态的1602玩法...

小弟刚学到1602,刚开始的时候卡死在初始化上了,一见Delay就头大,索性咱不要Delay了.
把测试程序贴上来,求大家看看代码有什么毛病,和隐患。
这是main()
#include <reg52.h>
//#include <STC90.H>       //STC单片机用的,可代替reg52.h
#include "LCD1602.h"
#include "MacroAndConst.h"
#include "Time.h"


xdata unsigned char str[] ="LCD1602 Init OK!";
xdata unsigned char str2[]="BUSYCount=";
void main(void)
{
    unsigned j,i,k,g,s,b,q;
        Timer0Init();
        EA=1;
    LCD1602_Init();
    while(1)
      {
      while(!LCD1602_Write(0x80,1))k++;
      for(i=0;i<=16;i++)
                  {
                     while(!LCD1602_Write(str,0))k++;
                        }
                while(!LCD1602_Write(0xC0,1))k++;
            for(i=0;i<12;i++)
                  {
                     while(!LCD1602_Write(str2,0))k++;               
                        }
                g=k%10+0x30;
                s=k/10%10+0x30;
                b=k/100%10+0x30;
                q=k/1000%10+0x30;
               
                while(!LCD1602_Write(q,0))k++;
                while(!LCD1602_Write(b,0))k++;
                while(!LCD1602_Write(s,0))k++;
                while(!LCD1602_Write(g,0))k++;
                j=0;
               
                while(j<=500)
                        {
                               if(SysTime1Ms)
                                {
                             j++;
                             SysTime1Ms=0;
                                }
                        }
                k=0;                               
                while(!LCD1602_Write(0x01,1))k++; //清屏       
      }
}

这是1602.c//#include <STC90.H>
#include <reg52.h>
#include <intrins.h>
#include "MacroAndConst.h"
#include "Time.h"

/*         晶振=12M      */

//////LCD1602端口定义//////
sbit LCD1602_RS=P2^6;                  //0=读写状态or命令 ,1=读写数据
sbit LCD1602_RW=P2^5;                  //0=写,1=读
sbit LCD1602_EN=P2^7;                  //1=读,高脉冲=写
sbit LCD1602BUSY=P0^7;      //1=液晶忙,0=空闲
#define LCD1602_DAT P0


//////LCD1602忙判断///////////////////////
bit LCD1602_Busy(void)
{
    LCD1602BUSY=1;
    LCD1602_EN=0;
    LCD1602_RS=0;
    LCD1602_RW=1;
    LCD1602_EN=1;       
    while(LCD1602BUSY)return 0;                  //空闲标志=1
    LCD1602_EN=0;       
    return 1;
                                       
}

//////LCD1602写命令或数据函数//////
bit LCD1602_Write(uchar LCD_DAT,bit ComOrDat)   
{       
           //while(!SysTime1Ms);SysTime1Ms=0;                //写命令内的延时,死循环
        if((!ComOrDat)&&LCD1602_Busy())                        //ComOrDat=0,写数据
      {
      LCD1602_RS=1;
      LCD1602_RW=0;
      LCD1602_DAT=LCD_DAT;
      LCD1602_EN=1;
      LCD1602_EN=0;
      return 1;      
      }
    if((ComOrDat)&&LCD1602_Busy())                                //ComOrDat=1,写命令
      {
      LCD1602_EN=0;
      LCD1602_RS=0;
      LCD1602_RW=0;
      LCD1602_DAT=LCD_DAT;
      LCD1602_EN=1;
      LCD1602_EN=0;
      return 1;
      }
    return 0;
}

////////初始化最关键,注意调节延时。仿真失败不代表真机不行。//////
void LCD1602_Init(void)      
{       
                                          //仿真用延时
    while(!LCD1602_Write(0x38,1));
    while(!LCD1602_Write(0x08,1)); //关显,无光标
           while(!LCD1602_Write(0x01,1)); //清屏
    while(!LCD1602_Write(0x0c,1)); //开显,无光标
//while(!LCD1602_Write(0x06,1));
       
}这是time.c#include "MacroAndConst.h"
#include <reg52.h>

bit SysTime1Ms;
bit SysTime2Ms;

void Delay1Ms(unsigned long j)                   //初始化不必忌讳用Delay
{
        //if(j=0)return;
    while(j--)
    {
      while(!SysTime1Ms);
      SysTime1Ms=0;
    }
}

void Timer0Init(void)
{
    TMOD &= 0xf0 ;
    TMOD |= 0x01 ;      //定时器0工作方式1
    TH0=0xfc ;      //定时器初始值
    TL0=0x17;
    TR0= 1 ;
    ET0= 1 ;
}

void SysTimeIst() interrupt 1       
{
//static unsigned int c;
        TH0=0xfC ;      //定时器初始值
    TL0=0x1f;
    SysTime1Ms=1;
//        if(++c>=1){SysTime2Ms=1;c=0;}
}
头文件1602.h#ifndef         _LCD1602_H_
#define                _LCD1602_H_

extern bit LCD1602_Write(unsigned char,bit);
extern void LCD1602_Init(void);
#endif
time.h#ifndef _Time_H_
#define _Time_H_
extern void Timer0Init(void);
extern void Delay1Ms(unsigned long);
extern bit SysTime1Ms;
extern bit SysTime2Ms;
#endif

liang118038 发表于 2012-4-21 14:10:50

试一下将查忙部分用简单的延时来替换试试吧,一般都是这个问题.

wangshaosh123 发表于 2012-4-21 14:14:36

找个例子研究下吧网上多的是
贴一大堆程序让大家找BUG   看着都累

dengwuyu111 发表于 2012-4-21 14:31:54

不要做浮躁的工程师哦。。亲

大斧 发表于 2012-4-21 15:01:46

编译已经通过,运行正常
main()循环3个写命令,32个写数据
STC90C516RD+:
12M 12T读出BUSY计数为50-53,6T下计数为126-129
33.8688M 6T计数为401-403,12T计数为181-18316M计数484-488


STC12C5A60S2:
1T 外部12M计数为353-356,内部RC 计数为331-334
33.8688M晶振不行了,一团麻子....
27M也不行....麻子{:titter:}

jetli 发表于 2012-4-21 17:05:54

没有 cowboy 的人肉驱动1602变态,,,{:titter:}

airfex 发表于 2012-4-21 18:27:05

没有什么变态,各有各法能用就行。

Sullivan 发表于 2012-4-21 18:37:42

BT在哪里?

ShawnLinson 发表于 2012-4-21 20:16:24

为何要变态了,常态不是很好么?

huayuliang 发表于 2012-4-21 20:43:07

用定时器做延时。。。。有啥变态?
有时候程序里做超时等待,还不能用软件延时,硬件定时器+状态变量是最简单的了。

guozaizb 发表于 2012-4-22 10:01:37

程序写的太个性了,不太容易看明白呀

大斧 发表于 2012-4-22 11:13:52

主要是看初始化函数和main()的while()
我的意思是,用while死等忙信号难道不危险吗?
难道大家的1602始终都会有空的吗?不会卡死?
如果大家都认为这类写法很正常,是不是说大家都没有被忙信号卡死过?

mcu_lover 发表于 2012-4-22 12:05:56

忙等待 要加入超时处理。
页: [1]
查看完整版本: 初学者变态的1602玩法...