⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chaosheng.c.txt

📁 用于测距发送频率为40K使用定时器测距范围在三米左右
💻 TXT
字号:
超声波测距的程序
硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。
液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。
超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。
超声波的接收电路包含一块CD40106处理芯片。
技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。
#include<reg51.h>
#include <intrins.h>
#define Busy    0x80  //用于检测LCM状态字中的Busy标识
#define LCM_Data  P0 
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long


extern void cs_t(void);
extern void delay(uint);



void LCMInit(void);
void DisplayOneChar(uchar X, uchar Y, uchar DData);
void DisplayListChar(uchar X, uchar Y, uchar  *DData);
void Delay5Ms(void);
void Delay100Ms(void);

void WriteDataLCM(uchar WDLCM);
void WriteCommandLCM(uchar WCLCM,BuysC);


data float distant=0.0;
uchar ReadDataLCM(void);
uchar ReadStatusLCM(void);
uchar  cdle_net[] = {"--Daoche_Leida--"};
uchar  email[] = {"Juli:"};
uchar  cls[]={"         "};
uchar DIS[7];
data ulong time;
float distant;
sbit LCM_RS=P1^1;  //定义LCD引脚
sbit LCM_RW=P1^2; 
sbit LCM_E=P1^3; 
sbit P10=P1^0;


data uchar flag;

void zhuanhuan(float juli)
{
unsigned long juli1;
juli1=juli*100;
DIS[6]=juli1%10+0x30;
juli1=juli1/10;
DIS[5]=juli1%10+0x30;
juli1=juli1/10;
DIS[4]='.';
DIS[3]=juli1%10+0x30;
juli1=juli1/10;
DIS[2]=juli1%10+0x30;
juli1=juli1/10;
DIS[1]=juli1%10+0x30;
DIS[0]=juli1/10+0x30;

}

void main(void)
{
    
    Delay100Ms(); //启动等待,等LCM讲入工作状态
    P10=1;    
    TMOD=0x01;             //计数器0工作在方式1
    TH0=0;
    TL0=0;                  //计数值初始化
    IT1=0;                 //低电平触发中断
    EA=1;                //开总中断
    //IP=0x04;             //设置外部中断1为高优先级中断
    flag=0;
    LCMInit(); //LCM初始化
    
    
    while(1)
    {
     cs_t();
     Delay5Ms();        
     ET0=1;         //打开计数器0中断
     EX1=1;         //打开外部中断1
     TR0=1;
     while(!flag) 
     {
      DisplayListChar(0, 0, cdle_net);
      DisplayListChar(0, 1, email);
     }
     if(flag==1)
     {
      time=TH0;
      time=(time<<8)|TL0;
      distant=time*1.72/100;
      zhuanhuan(distant);
      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');
      else   DisplayOneChar(5,1,DIS[0]);
      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');
      else   DisplayOneChar(6,1,DIS[1]);
      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');
      else   DisplayOneChar(7,1,DIS[2]);
      DisplayOneChar(8,1,DIS[3]);
      DisplayOneChar(9,1,DIS[4]);
      DisplayOneChar(10,1,DIS[5]);
      DisplayOneChar(11,1,DIS[6]);
      DisplayOneChar(12,1,'c');
      DisplayOneChar(13,1,'m');
      flag=0;
      }
     else
     {
      DisplayListChar(5,1,"error!      ");
      flag=0;
     }
     TH0=0;
     TL0=0;
    Delay100Ms();
    }
}



void cs_r(void) interrupt 2
{
TR0=0;
EX1=0;
ET0=0;
flag=1;
}


void overtime(void) interrupt 1
{
EX1=0;
TR0=0;
ET0=0;
flag=2;
}


//写数据
void WriteDataLCM(uchar WDLCM) 
{
    ReadStatusLCM(); //检测忙
    LCM_Data=WDLCM;
    LCM_RS=1;
    LCM_RW=0;
    LCM_E=0; //若晶振速度太高可以在这后加小的延时
    LCM_E=0; //延时
    LCM_E=1;
}

//写指令
void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测
{
    if (BuysC) ReadStatusLCM(); //根据需要检测忙
    LCM_Data = WCLCM;
    LCM_RS = 0;
    LCM_RW = 0;    
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;    
}

//读数据
uchar ReadDataLCM(void)
{
    LCM_RS = 1; 
    LCM_RW = 1;
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;
    return(LCM_Data);
}

//读状态
uchar ReadStatusLCM(void)
{
    LCM_Data=0xFF; 
    LCM_RS=0;
    LCM_RW=1;
    LCM_E=0;
    LCM_E=0;
    LCM_E=1;
    while(LCM_Data & Busy); //检测忙信号
    return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
    LCM_Data=0;
    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
    Delay5Ms(); 
    WriteCommandLCM(0x38,0);
    Delay5Ms(); 
    WriteCommandLCM(0x38,0);
    Delay5Ms(); 

    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
    WriteCommandLCM(0x08,1); //关闭显示
    WriteCommandLCM(0x01,1); //显示清屏
    WriteCommandLCM(0x06,1); // 显示光标移动设置
    WriteCommandLCM(0x0F,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
    Y &= 0x1;
    X &= 0xF; //限制X不能大于15,Y不能大于1
    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
    X |= 0x80; //算出指令码
    WriteCommandLCM(X, 1); //发命令字
    WriteDataLCM(DData); //发数据
}

//按指定位置显示一串字符
void DisplayListChar(uchar X, uchar Y, uchar  *DData)
{
    uchar ListLength;

  ListLength = 0;
    Y &= 0x1;
    X &= 0xF; //限制X不能大于15,Y不能大于1
    while (DData[ListLength]>0x20) //若到达字串尾则退出
        {
            if (X <= 0xF) //X坐标应小于0xF
                {
                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
                    ListLength++;
                    X++;
                }
        }
}

//5ms延时
void Delay5Ms(void)
{
    uint TempCyc = 200;
    while(TempCyc--);
}

//400ms延时
void Delay100Ms(void)
{
    uchar TempCycA = 1;
    uint TempCycB;
    while(TempCycA--)
        {
            TempCycB=7269;
            while(TempCycB--);
}


;-------------------------------------
;超声发生子程序(12M晶振38.5Hz)
;-------------------------------------
                    NAME     CS_T
?PR?CS_T?CS_T       SEGMENT  CODE
                    PUBLIC   CS_T
                    RSEG     ?PR?CS_T?CS_T
CS_T:               PUSH     ACC
                    MOV      TH0,   #00H
                    MOV      TL0,   #00H
                    MOV      A,     #4D
                    SETB     TR0
CS_T1:              CPL      P1.0
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    NOP
                    DJNZ     ACC,  CS_T1
                    POP      ACC
                    RET
;
                    END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -