展开全部
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//===============================LCD1602接口定义=====================
//定义引脚
#define LCM_Data P0 //数据接口
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
sbit LCM_RW = P2^1; //读写控制输入端
sbit LCM_RS = P2^0; //寄存器选择输入端
sbit LCM_E = P2^2; //使能信号输入端
void WritEDAtaLCM (uchar WDLCM);
void WriteCommandLCM (uchar WCLCM,BuysC);
uchar ReadDataLCM (void);
uchar ReadStatusLCM (void);
void DisplayOneChar (uchar X,uchar Y,uchar ASCII);
void DisplayListChar (uchar X,uchar Y,uchar delayms,uchar code *DData);
void DisplayCursorPos (uchar X, uchar Y);
void LCMInit (void);
void DisplayIntData (uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu);
void DisplayCharData (uchar X, uchar Y,uchar ZiFu);
//===============================超声波模块定义========================
sbit RemPin = P3^2;// 接收端(这个不能修改,因为是外部中断(INT0)的引脚)
sbit TxPin = P3^5;// 发射端
uint length = 0; // 测距的长度0.00M
uchar flag = 0; // 测距的标志 有信号接收=1;
void DelayUs(uint us)
{
while(us--);
}
void DelayMs(uint Ms)
{
uint i,TempCyc;
for(i=0;i<Ms;i++)
{
TempCyc = 250;
while(TempCyc--);
}
}
//==============================LCD1602显示子程序================================================
void WritEDAtaLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 1;
}
void WriteCommandLCM(unsigned char 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;
}
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}
unsigned char 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 DisplayOneChar( unsigned char X, unsigned char Y, unsigned char ASCII)
{
X &= 0x1;
Y &= 0xF; //限制Y不能大于15,X不能大于1
if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;
Y |= 0x80; // 算出指令码
WriteCommandLCM(Y, 0); //这里不检测忙信号,发送地址码
WritEDAtaLCM(ASCII);
}
void DisplayListChar(uchar X,uchar Y,uchar delayms, uchar code *DData)
{
unsigned char ListLength;
ListLength = 0;
X &= 0x1;
Y &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]!='\0') //若到达字串尾则退出
{
if (Y <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
Y++;
DelayMs(delayms);//延时显示字符串
}
else
break;//跳出循环体
}
}
void DisplayCursorPos( unsigned char X, unsigned char Y)
{
X &= 0x1;
Y &= 0xF; //限制Y不能大于15,X不能大于1
if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;
Y |= 0x80; // 算出指令码
WriteCommandLCM(Y, 1); //这里不检测忙信号,发送地址码
}
void LCMInit(void)
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
DelayMs(5);
WriteCommandLCM(0x38,0);
DelayMs(5);
WriteCommandLCM(0x38,0);
DelayMs(5);
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
DelayMs(100);
}
void DisplayIntData(uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu)
{
uchar i=0,k=0, BCD[5]={0};
if(Digit>5) Digit=5;
if(ZhengShu<0)
{
k=1;//负数示志位
ZhengShu=-ZhengShu;
}
BCD[4] = ZhengShu / 10000; //求出万位数据
ZhengShu = ZhengShu % 10000;
BCD[3] = ZhengShu / 1000; //求出千位数据
ZhengShu = ZhengShu % 1000;
BCD[2] = ZhengShu / 100; //求出百位数据
ZhengShu = ZhengShu % 100;
BCD[1] = ZhengShu / 10; //求出十位数据
BCD[0] = ZhengShu % 10; //求出个位数据
for(i=0;i<Digit;i++)//输出显示的数值
{
if((i==XiaoShu)&&(0!=XiaoShu))
{
DisplayOneChar(X,Y-i,'.');//输出小数点
Y= Y-1;
}
DisplayOneChar(X,Y-i,BCD[i]+0x30); //显示一个字符
}
if(k==1)
DisplayOneChar(X,Y-1,'-');//输出负符
}
void DisplayCharData(uchar X, uchar Y,uchar ZiFu)
{
uchar i=0;
uchar ValueBCD[3];
ValueBCD[0] = ZiFu / 100; //求出百位数据
ZiFu = ZiFu % 100;
ValueBCD[1] = ZiFu / 10; //求出十位数据
ValueBCD[2] = ZiFu % 10; //求出个位数据
for(i=0;i<3;i++)//输出显示的数值
{
DisplayOneChar(X,Y+i,ValueBCD[i]+0x30); //显示一个字符
}
}
//==============================超声波模块测试子程序================================================
void delay25us_40KHz(unsigned char us)
{
while(us--)
{
TxPin = 0;
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();
TxPin = 1;
_nop_();_nop_();
_nop_();_nop_();
}
TxPin = 1;
}
void init0int() interrupt 0
{
uint timer_us = 0;
TR0=0; //关闭定时器0
timer_us = TH0*256+TL0;
if(timer_us>190)timer_us=timer_us-180; //修正测距的距离
length = ((unsigned long)(340)*timer_us)/2000;//计算长度,是扩大100倍
flag = 0;
EA = 0; //禁止所有中断
}
void timer0int (void) interrupt 1
{
TR0=0; //关闭定时器0
length = 0; //超出测量时间显示示0
flag = 1; //
EA = 0; //禁止所有中断
}
void main(void)
{
LCMInit(); //1602初始化
EX0 = 1; //允许总中断中断,使能 INT0 外部中断
ET0 = 1;
TMOD=0x11; //设定T0为16位时器,设定T1为16位时器
DisplayOneChar( 1, 11, 'M');
DisplayListChar(0,2,0, "Range Finder "); //显示字符串
while(1)
{
DisplayIntData(1, 10,length,5,3);//显示测量距离
TH0=0x00;
TL0=0x00;
TR0=1; //启动定时器0
EA = 1; //允许所有中断
delay25us_40KHz(15); //发出脉冲信号
DelayMs(200);
}
}
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//===============================LCD1602接口定义=====================
//定义引脚
#define LCM_Data P0 //数据接口
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
sbit LCM_RW = P2^1; //读写控制输入端
sbit LCM_RS = P2^0; //寄存器选择输入端
sbit LCM_E = P2^2; //使能信号输入端
void WritEDAtaLCM (uchar WDLCM);
void WriteCommandLCM (uchar WCLCM,BuysC);
uchar ReadDataLCM (void);
uchar ReadStatusLCM (void);
void DisplayOneChar (uchar X,uchar Y,uchar ASCII);
void DisplayListChar (uchar X,uchar Y,uchar delayms,uchar code *DData);
void DisplayCursorPos (uchar X, uchar Y);
void LCMInit (void);
void DisplayIntData (uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu);
void DisplayCharData (uchar X, uchar Y,uchar ZiFu);
//===============================超声波模块定义========================
sbit RemPin = P3^2;// 接收端(这个不能修改,因为是外部中断(INT0)的引脚)
sbit TxPin = P3^5;// 发射端
uint length = 0; // 测距的长度0.00M
uchar flag = 0; // 测距的标志 有信号接收=1;
void DelayUs(uint us)
{
while(us--);
}
void DelayMs(uint Ms)
{
uint i,TempCyc;
for(i=0;i<Ms;i++)
{
TempCyc = 250;
while(TempCyc--);
}
}
//==============================LCD1602显示子程序================================================
void WritEDAtaLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 1;
}
void WriteCommandLCM(unsigned char 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;
}
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}
unsigned char 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 DisplayOneChar( unsigned char X, unsigned char Y, unsigned char ASCII)
{
X &= 0x1;
Y &= 0xF; //限制Y不能大于15,X不能大于1
if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;
Y |= 0x80; // 算出指令码
WriteCommandLCM(Y, 0); //这里不检测忙信号,发送地址码
WritEDAtaLCM(ASCII);
}
void DisplayListChar(uchar X,uchar Y,uchar delayms, uchar code *DData)
{
unsigned char ListLength;
ListLength = 0;
X &= 0x1;
Y &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]!='\0') //若到达字串尾则退出
{
if (Y <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
Y++;
DelayMs(delayms);//延时显示字符串
}
else
break;//跳出循环体
}
}
void DisplayCursorPos( unsigned char X, unsigned char Y)
{
X &= 0x1;
Y &= 0xF; //限制Y不能大于15,X不能大于1
if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;
Y |= 0x80; // 算出指令码
WriteCommandLCM(Y, 1); //这里不检测忙信号,发送地址码
}
void LCMInit(void)
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
DelayMs(5);
WriteCommandLCM(0x38,0);
DelayMs(5);
WriteCommandLCM(0x38,0);
DelayMs(5);
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
DelayMs(100);
}
void DisplayIntData(uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu)
{
uchar i=0,k=0, BCD[5]={0};
if(Digit>5) Digit=5;
if(ZhengShu<0)
{
k=1;//负数示志位
ZhengShu=-ZhengShu;
}
BCD[4] = ZhengShu / 10000; //求出万位数据
ZhengShu = ZhengShu % 10000;
BCD[3] = ZhengShu / 1000; //求出千位数据
ZhengShu = ZhengShu % 1000;
BCD[2] = ZhengShu / 100; //求出百位数据
ZhengShu = ZhengShu % 100;
BCD[1] = ZhengShu / 10; //求出十位数据
BCD[0] = ZhengShu % 10; //求出个位数据
for(i=0;i<Digit;i++)//输出显示的数值
{
if((i==XiaoShu)&&(0!=XiaoShu))
{
DisplayOneChar(X,Y-i,'.');//输出小数点
Y= Y-1;
}
DisplayOneChar(X,Y-i,BCD[i]+0x30); //显示一个字符
}
if(k==1)
DisplayOneChar(X,Y-1,'-');//输出负符
}
void DisplayCharData(uchar X, uchar Y,uchar ZiFu)
{
uchar i=0;
uchar ValueBCD[3];
ValueBCD[0] = ZiFu / 100; //求出百位数据
ZiFu = ZiFu % 100;
ValueBCD[1] = ZiFu / 10; //求出十位数据
ValueBCD[2] = ZiFu % 10; //求出个位数据
for(i=0;i<3;i++)//输出显示的数值
{
DisplayOneChar(X,Y+i,ValueBCD[i]+0x30); //显示一个字符
}
}
//==============================超声波模块测试子程序================================================
void delay25us_40KHz(unsigned char us)
{
while(us--)
{
TxPin = 0;
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();
TxPin = 1;
_nop_();_nop_();
_nop_();_nop_();
}
TxPin = 1;
}
void init0int() interrupt 0
{
uint timer_us = 0;
TR0=0; //关闭定时器0
timer_us = TH0*256+TL0;
if(timer_us>190)timer_us=timer_us-180; //修正测距的距离
length = ((unsigned long)(340)*timer_us)/2000;//计算长度,是扩大100倍
flag = 0;
EA = 0; //禁止所有中断
}
void timer0int (void) interrupt 1
{
TR0=0; //关闭定时器0
length = 0; //超出测量时间显示示0
flag = 1; //
EA = 0; //禁止所有中断
}
void main(void)
{
LCMInit(); //1602初始化
EX0 = 1; //允许总中断中断,使能 INT0 外部中断
ET0 = 1;
TMOD=0x11; //设定T0为16位时器,设定T1为16位时器
DisplayOneChar( 1, 11, 'M');
DisplayListChar(0,2,0, "Range Finder "); //显示字符串
while(1)
{
DisplayIntData(1, 10,length,5,3);//显示测量距离
TH0=0x00;
TL0=0x00;
TR0=1; //启动定时器0
EA = 1; //允许所有中断
delay25us_40KHz(15); //发出脉冲信号
DelayMs(200);
}
}
艾因蒂克
2024-11-28 广告
2024-11-28 广告
超声阵列探头是艾因蒂克科技(上海)有限公司在超声检测领域的一项重要技术产品。它采用先进的阵列设计,能够显著提高超声检测的精度和效率。该探头通过多个超声传感器的协同工作,实现对被检测物体的全方位、多角度扫描,从而更准确地发现物体内部的缺陷和问...
点击进入详情页
本回答由艾因蒂克提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询