bukumingshen 发表于 2011-12-13 18:15:36

基于51单片机的超声波测距程序(含12864液晶显示)

#include   <AT89X51.H>
#include   <intrins.h>       
//引脚定义
    sbit   RX    =P1 ^ 1;        //超声波的TRIG
    sbit   TX    =P1 ^ 2;        //c超声波的ECHO
    sbit   SID   =P2^1;        //数据        12864的R/W(SID)
    sbit   SCLK=P2^2;        //时钟       12864的E(SLCK)

//Function Definition 函数声明
//12864
void Write_char(bit start, unsigned char ddata);
void Send_byte(unsigned char bbyte);
void Delaynms(unsigned int di);
void Lcd_init(void);
void Disp_img(unsigned char *img);
void LCD_Write_string(unsigned char X,unsigned char Y,unsigned char *s);
void LCD_set_xy( unsigned char x, unsigned char y );
void LCD_w_word(unsigned char *str);
unsigned char code num[]={"0123456789 :.-"};
unsigned char code CM[] ={"CM"};
unsigned inttime=0;
         long S=0;
         bitflag =0;
unsigned char disbuff           ={ 0,0,0,0};

/******************************************************************************/
void Lcd_init(void)        //初始化LCD
{
        Delaynms(10); //启动等待,等LCM讲入工作状态
        Write_char(0,0x30);//8 位介面,基本指令集
        Write_char(0,0x0c);//显示打开,光标关,反白关
        Write_char(0,0x01);//清屏,将DDRAM的地址计数器归零
}

/******************************************************************************/
void Write_char(bit start, unsigned char ddata) //写指令或数据
{
        unsigned char start_data,Hdata,Ldata;
        if(start==0)
                start_data=0xf8;       //写指令
    else   
            start_data=0xfa;//写数据

        Hdata=ddata&0xf0;                  //取高四位
        Ldata=(ddata<<4)&0xf0;//取低四位
        Send_byte(start_data);          //发送起始信号
        Delaynms(5); //延时是必须的
        Send_byte(Hdata);              //发送高四位
        Delaynms(1);//延时是必须的
        Send_byte(Ldata);                  //发送低四位
        Delaynms(1);//延时是必须的
}

/******************************************************************************/
void Send_byte(unsigned char bbyte) //发送一个字节
{
        unsigned char i;
        for(i=0;i<8;i++)
           {
                   SID=bbyte&0x80; //取出最高位
                SCLK=1;
                   SCLK=0;
                   bbyte<<=1; //左移
           }
}

/******************************************************************************/
void Delaynms(unsigned int di) //延时
{
        unsigned int da,db;
        for(da=0;da<di;da++)
                   for(db=0;db<10;db++);
}

/******************************************************************************/
       
/******************************************************************************/
void Clr_Scr(void)//清屏函数
{
        Write_char(0,0x01);
}

/******************************************************************************/
//设置LCD显示的起始位置,X为行,Y为列
void LCD_set_xy( unsigned char x, unsigned char y )
{       
    unsigned char address;
        switch(x)
        {
                case 0: address = 0x80 + y; break;   
            case 1: address = 0x80 + y; break;
                case 2: address = 0x90 + y; break;
                  case 3: address = 0x88 + y; break;
                case 4: address = 0x98 + y; break;
                default:address = 0x80 + y; break;
        }
    Write_char(0, address);
}


/******************************************************************************/
//        中英文字符串显示函数
void LCD_Write_string(unsigned char X,unsigned char Y,unsigned char *s)       
{
        LCD_set_xy( X, Y );
   
    while (*s)
    {
                Write_char( 1, *s );
          s ++;
                Delaynms(1);
        }
}

/******************************************************************************/
//        数字显示函数
void LCD_Write_number(unsigned char s)
{       
        Write_char(1,num);
        Delaynms(1);
}
/******************************************************************************/
void Lcd_Mark2(void)                //单位为CM
{
        Clr_Scr();//清屏       
        LCD_Write_string(3,6,CM);//       
}

//向LCM发送一个字符串,长度64字符之内。
//应用:lcm_w_word("您好!");
void LCD_w_word(unsigned char *str)
{
                while(*str != '\0')
                {
                        Write_char(1,*str++);
      }
                *str = 0;
}



/********************************************************/
void Conut(void)
{
        time=TH0*256+TL0;
        TH0=0;
        TL0=0;
        S=(time)/52;       //算出来是CM          12M晶振
        if(flag==1)                      //超出测量
        {       
               flag=0;
                   LCD_set_xy( 3, 4 );
                   LCD_Write_number(13);
                   LCD_Write_number(12);
                   LCD_set_xy( 3, 5 );
                   LCD_Write_number(13);
                   LCD_Write_number(13);          
       }
       else
       {
//                   disbuff=time/10000;
//                   disbuff=time%10000/1000;
//                   disbuff=time%1000/100;
//                disbuff=time%100/10 ;
//                disbuff=time%10;
//                   LCD_set_xy( 3, 1 );
//                   LCD_Write_number(disbuff);
//                   LCD_Write_number(disbuff);
//                   LCD_Write_number(disbuff);
//                LCD_Write_number(disbuff);
//                LCD_Write_number(disbuff);
                   disbuff=S%10000/1000;
                   disbuff=S%1000/100;
                disbuff=S%100/10 ;
                disbuff=S%10;
                   LCD_set_xy( 3, 4 );
                   LCD_Write_number(disbuff);
                   LCD_Write_number(disbuff);
                   LCD_Write_number(disbuff);
                LCD_Write_number(disbuff);
       }
}
/********************************************************/
void delayms(unsigned int ms)
{
        unsigned char i=100,j;
        for(;ms;ms--)
        {
                while(--i)
                {
                        j=10;
                        while(--j);
                }
        }
}
/********************************************************/
void zd0() interrupt 1                //T0中断用来计数器溢出,超过测距范围
{
        flag=1;                                                       //中断溢出标志
}
/********************************************************/
voidStartModule()                          //T1中断用来扫描数码管和计800MS启动模块
{
          TX=1;                                         //800MS启动一次模块
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          TX=0;
          }
/********************************************************/
void main(void)
{
    TMOD=0x01;                   //设T0为方式1,GATE=1
        TH0=0;
        TL0=0;
        TR0=1;
        Lcd_init();       //设置液晶显示器
        Clr_Scr();      //清屏       
        Delaynms(1000);
        Lcd_init();       //从图形显示状态下返回
    Lcd_Mark2();
        LCD_set_xy( 3, 0 );
        LCD_w_word("距离为:");

        while(1)
        {
               StartModule();                                              
               while(!RX);                //当RX为零时等待
               {}
               TR0=1;                          //开启计数
               while(RX);                        //当RX为1计数并等待
               {
                       TR0=0;                                //关闭计数
                       Conut();
                       delayms(100);                   //80MS
               }       
        }

}

yuan2010 发表于 2012-2-21 20:16:41

给出原理图就好了。

xslff 发表于 2012-2-21 20:21:12

Mark

wtiechen1969 发表于 2012-2-21 22:32:10

记号

chinasy519 发表于 2012-2-21 22:39:17

是用HC-SR04超声波模块做的吗?

lyw225 发表于 2012-2-22 16:22:18

很好

jmml4 发表于 2012-2-22 21:49:12

mark

fox_deng 发表于 2012-2-24 18:11:01

一直想做个,今天学习了!

feeson 发表于 2012-2-27 11:37:25

只见代码一堆。

beiguoqishi2 发表于 2012-3-24 09:29:22

为什么每个代码上都有一条横线???网址导入数据的问题??

paradisespace 发表于 2012-4-21 08:05:54

这个。。。。。

jetli 发表于 2012-4-21 08:50:01

beiguoqishi2 发表于 2012-3-24 09:29 static/image/common/back.gif
为什么每个代码上都有一条横线???网址导入数据的问题??

我还以为是我的电脑字库出错了呐。。。原来别人也一样看到,

不过copy到程序里面,没有出错就万幸了。{:sweat:}

zhenglu891028 发表于 2012-4-21 14:01:19

不错下载看看
页: [1]
查看完整版本: 基于51单片机的超声波测距程序(含12864液晶显示)