搜索
bottom↓
回复: 12

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

[复制链接]

出0入0汤圆

发表于 2011-12-13 18:15:36 | 显示全部楼层 |阅读模式
#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 int  time=0;
         long S=0;
         bit  flag =0;
unsigned char disbuff[4]           ={ 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[1]=time/10000;
//                   disbuff[2]=time%10000/1000;
//                   disbuff[3]=time%1000/100;
//                disbuff[4]=time%100/10 ;
//                disbuff[5]=time%10;
//                   LCD_set_xy( 3, 1 );
//                   LCD_Write_number(disbuff[1]);
//                   LCD_Write_number(disbuff[2]);
//                   LCD_Write_number(disbuff[3]);
//                LCD_Write_number(disbuff[4]);
//                LCD_Write_number(disbuff[5]);
                   disbuff[1]=S%10000/1000;
                   disbuff[2]=S%1000/100;
                disbuff[3]=S%100/10 ;
                disbuff[4]=S%10;
                   LCD_set_xy( 3, 4 );
                   LCD_Write_number(disbuff[1]);
                   LCD_Write_number(disbuff[2]);
                   LCD_Write_number(disbuff[3]);
                LCD_Write_number(disbuff[4]);
         }
}
/********************************************************/
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;                                                         //中断溢出标志
}
/********************************************************/
void  StartModule()                          //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
                 }       
        }

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-2-21 20:16:41 | 显示全部楼层
给出原理图就好了。

出0入0汤圆

发表于 2012-2-21 20:21:12 | 显示全部楼层
Mark

出0入0汤圆

发表于 2012-2-21 22:32:10 | 显示全部楼层
记号

出0入0汤圆

发表于 2012-2-21 22:39:17 | 显示全部楼层
是用HC-SR04超声波模块做的吗?

出0入0汤圆

发表于 2012-2-22 16:22:18 | 显示全部楼层
很好

出0入0汤圆

发表于 2012-2-22 21:49:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-24 18:11:01 | 显示全部楼层
一直想做个,今天学习了!

出0入0汤圆

发表于 2012-2-27 11:37:25 | 显示全部楼层
只见代码一堆。

出0入0汤圆

发表于 2012-3-24 09:29:22 | 显示全部楼层
为什么每个代码上都有一条横线???网址导入数据的问题??

出0入0汤圆

发表于 2012-4-21 08:05:54 | 显示全部楼层
这个。。。。。

出0入0汤圆

发表于 2012-4-21 08:50:01 | 显示全部楼层
beiguoqishi2 发表于 2012-3-24 09:29
为什么每个代码上都有一条横线???网址导入数据的问题??

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

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

出0入0汤圆

发表于 2012-4-21 14:01:19 | 显示全部楼层
不错  下载看看
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 21:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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