|
//蓝牙:RX接p3.0,TX接3.1
//超声波模块:TRIG接 P2.0 ECH0 接P2.1
//数码管:共阳数码管P0接数据口,P2.4 P2.3 P2.2接选通数码管
//蜂鸣器:接P3.7
/**************SMC1602A(16*2)模拟口线接线方式
连接线图:
---------------------------------------------------
|LCM-----51 | LCM-----51 | LCM------51 |
--------------------------------------------------|
|DB0-----P1.0 | DB4-----P1.4 | RW-------P2.6 |
|DB1-----P1.1 | DB5-----P1.5 | RS-------P2.5 |
|DB2-----P1.2 | DB6-----P1.6 | E--------P2.7 |
|DB3-----P1.3 | DB7-----P1.7 | VLCD接1K电阻到GND|
---------------------------------------------------
第1脚:VSS为地电源
第2脚:VDD接5V正电源
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度(建议接地,弄不好有的模块会不显示)
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15~16脚:空脚(有的用来接背光)
*********************/
#include<reg52.h>
#include <intrins.h>
#include <STDIO.H>
#define buzzer 'B'
#define shumaguan 'S'
#define lcd 'L' //程序对应手机软件的字符
/****************超声波***************************/
sbit ECHO=P2^1;
sbit TRIG=P2^0; //超声波
unsigned int time=0;
unsigned int timer=0; //测距中间变量
unsigned long S=0; //距离
/*****************蓝牙*************************/
bit flag_REC=0;
bit flag =0; //蓝牙接受标识符
unsigned char i=0;
unsigned char dat=0;
unsigned char buff[5]=0; //接收缓冲字节
/***********************数码管******************/
#define GPIO_DIG P0
sbit LSA=P2^2;
sbit LSB=P2^3; //位选
sbit LSC=P2^4;
//--定义全局变量--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //段选
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char disbuff[4] ={ 0,0,0,0,};
/*********************LCD****************************/
sbit rs=P2^5; //1602的数据/指令选择控制线
sbit rw=P2^6; //1602的读写控制线
sbit en=P2^7; //1602的使能控制线
unsigned char code table[ ]={"0123456789"}; //定义字符数组显示数字
/****************蜂鸣器*********************************/
sbit bee=P3^7; //蜂鸣器
/********************延时函数**********************************/
void delay(unsigned int k)
{
unsigned int x,y;
for(x=0;x<k;x++)
for(y=0;y<110;y++);
}
/*********************蜂鸣器***********************************/
void Conut1(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.87)/100; //算出来是CM
if(S>=6200) //超出测量
{
bee=1;
delay(S/10);
bee=0;
delay(S/10);
}
else
{
bee=1;
delay(S);
bee=0;
delay(S);
}
}
/************************数码管准备函数********************************/
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=1;i<4;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(1):
LSA=0;LSB=1;LSC=1;break;//显示第1位
case(2):
LSA=1;LSB=0;LSC=1; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
}
GPIO_DIG=disbuff[i];//发送段码
j=10; //扫描间隔时间设定
while(j--);
GPIO_DIG=0x00; //消隐
}
}
void Conut2(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S= (long)(time*0.17); //算出来是CM
if(S>=6200) //超出测量范围显示“ERR0”
{
disbuff[0]=0x3f; //“-”
disbuff[1]=0x50; //“-”
disbuff[2]=0x50; //“-”
disbuff[3]=0x79; //“-”
}
else
{
disbuff[3]=DIG_CODE[S%10000/1000];
disbuff[2]=DIG_CODE[S%1000/100];
disbuff[1]=DIG_CODE[S%100/10];
disbuff[0]=DIG_CODE[S%10/1];
}
}
/************************LCD的各个准备函数********************************/
/********************1602写命令函数**********************/
void lcd_wcom(unsigned char com)
{
rs=0; //选择指令寄存器
rw=0; //选择写
P1=com; //把命令字送入P1
delay(5); //延时一小会儿,让1602准备接收数据
en=1; //使能线电平变化,命令送入1602的8位数据口,这点非常重要
en=0;
}
/*------------------------------------------------
1602写数据函数
------------------------------------------------*/
void lcd_wdat(unsigned char dat)
{
rs=1; //选择数据寄存器
rw=0; //选择写
P1=dat; //把要显示的数据送入P0
delay(5); //延时一会儿,让1602准备接收数据,也是检测忙信号,这点非常重要
en=1; //使能线电平变化,数据送入1602的8位数据口
en=0;
}
/*------------------------------------------------
1602初始化函数
------------------------------------------------*/
void lcd_init()
{
lcd_wcom(0x38); //8位数据,双列,5*7字形 ,用到功能设定指令
lcd_wcom(0x0c); //开启显示屏,关光标,光标不闪烁,用到显示开关控制指令
lcd_wcom(0x06); //显示地址递增,即写一个数据后,显示位置右移一位,用到了写入模式设置指令
lcd_wcom(0x01); //清屏,用到了清屏指令
}
/*------------------------------------------------
1602显示固定字符函数
------------------------------------------------*/
void lcd_xianshi()
{
lcd_wcom(0x80+0x40);
lcd_wdat('D');
lcd_wdat('i');
lcd_wdat('s');
lcd_wdat('t');
lcd_wdat('a');
lcd_wdat('n');
lcd_wdat('c');
lcd_wdat('e');
lcd_wdat(':');
lcd_wcom(0x80+0x4c);
lcd_wdat('.');
lcd_wcom(0x80+0x4e);//单位是厘米//
lcd_wdat('c');
lcd_wdat('m');
}
/*************lcd显示函数*****************/
void Conut3(void)
{
unsigned char qian,bai,shi,ge;
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.87)/100; //算出来是CM
qian=S/1000;
bai=(S/100)%10;
shi=(S/10)%10;
ge=S%10;
lcd_wcom(0x80+0x49);//单位是厘米//
lcd_wdat(table[qian]);
lcd_wdat(table[bai]);
lcd_wdat(table[shi]);
lcd_wcom(0x80+0x4d);
lcd_wdat(table[ge]);
}
/***********超声波模块启动函数********************/
void StartModule() //计800MS启动超声波模块
{
TRIG=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TRIG=0;
}
/*********************蜂鸣器主函数***********************************/
void Buzzer(void)
{ unsigned int i;
TMOD=0x21; //设T0为方式1,GATE=1;
SCON=0x50;
TH0=0;
TL0=0;
TR0=0;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
for(i=0;i<5;i++)//while(1)
{
StartModule();
while(!ECHO); //当RX为零时等待
TR0=1; //开启计数
while(ECHO); //当RX为1计数并等待
TR0=0; //关闭计数
Conut1(); //计算
}
bee=1;
}
/**************************数码管主函数******************************/
void SMG(void)
{ unsigned int i;
TMOD=0x21; //设T0为方式1,GATE=1;
SCON=0x50;
TH0=0;
TL0=0;
TR0=0;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
for(i=0;i<5;i++)//while(1)
{
StartModule();
while(!ECHO); //当RX为零时等待
TR0=1; //开启计数
while(ECHO); //当RX为1计数并等待
TR0=0;
DigDisplay(); //关闭计数
Conut2(); //计算
}
GPIO_DIG=0xff;
}
/**************************LCD主函数******************************/
void LCD(void)
{ unsigned int i;
TMOD=0x21; //设T0为方式1,GATE=1;
SCON=0x50;
TH0=0;
TL0=0;
TR0=0;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
lcd_init(); //液晶初始化
for(i=0;i<5;i++)//while(1)
{
lcd_xianshi(); //液晶显示特定字符
StartModule();
while(!ECHO); //当RX为零时等待
TR0=1; //开启计数
while(ECHO); //当RX为1计数并等待
TR0=0; //关闭计数
Conut3(); //计算
}
lcd_wcom(0x01);
}
/**********************串口中断服务程序***********************************/
void sint() interrupt 4 //中断接收3个字节
{
if(RI) //是否接收中断
{
RI=0;
dat=SBUF;
if(dat=='O'&&(i==0)) //接收数据第一帧
{
buff[i]=dat;
flag=1; //开始接收数据
}
else
if(flag==1)
{
i++;
buff[i]=dat;
if(i>=2)
{i=0;flag=0;flag_REC=1 ;} // 停止接收
}
}
}
/***************************主函数*******************************/
void main(void)
{
TMOD=0x20;
TH1=0xFd; //11.0592M晶振,9600波特率,定时器1设置波特率
TL1=0xFd;
SCON=0x50;
PCON=0x00;
TR1=1;
ES=1;
EA=1;
while(1) //无限循环,等待蓝牙的数据
{
if(flag_REC==1) //蓝牙数据标志位
{
flag_REC=0;
if(buff[0]=='O'&&buff[1]=='N') //第一个字节为O,第二个字节为N,第三个字节为控制码
switch(buff[2])
{
case buzzer : // 前进
Buzzer();
break;
case shumaguan: // 后退
SMG();
break;
case lcd: // 左转
LCD();
break;
}
}
}
}
*********************/
#include<reg52.h>
#include <intrins.h>
#include <STDIO.H>
#define buzzer 'B'
#define shumaguan 'S'
#define lcd 'L' //程序对应手机软件的字符
/****************超声波***************************/
sbit ECHO=P2^1;
sbit TRIG=P2^0; //超声波
unsigned int time=0;
unsigned int timer=0; //测距中间变量
unsigned long S=0; //距离
/*****************蓝牙*************************/
bit flag_REC=0;
bit flag =0; //蓝牙接受标识符
unsigned char i=0;
unsigned char dat=0;
unsigned char buff[5]=0; //接收缓冲字节
/***********************数码管******************/
#define GPIO_DIG P0
sbit LSA=P2^2;
sbit LSB=P2^3; //位选
sbit LSC=P2^4;
//--定义全局变量--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //段选
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char disbuff[4] ={ 0,0,0,0,};
/*********************LCD****************************/
sbit rs=P2^5; //1602的数据/指令选择控制线
sbit rw=P2^6; //1602的读写控制线
sbit en=P2^7; //1602的使能控制线
unsigned char code table[ ]={"0123456789"}; //定义字符数组显示数字
/****************蜂鸣器*********************************/
sbit bee=P3^7; //蜂鸣器
/********************延时函数**********************************/
void delay(unsigned int k)
{
unsigned int x,y;
for(x=0;x<k;x++)
for(y=0;y<110;y++);
}
/*********************蜂鸣器***********************************/
void Conut1(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.87)/100; //算出来是CM
if(S>=6200) //超出测量
{
bee=1;
delay(S/10);
bee=0;
delay(S/10);
}
else
{
bee=1;
delay(S);
bee=0;
delay(S);
}
}
/************************数码管准备函数********************************/
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=1;i<4;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(1):
LSA=0;LSB=1;LSC=1;break;//显示第1位
case(2):
LSA=1;LSB=0;LSC=1; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
}
GPIO_DIG=disbuff[i];//发送段码
j=10; //扫描间隔时间设定
while(j--);
GPIO_DIG=0x00; //消隐
}
}
void Conut2(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S= (long)(time*0.17); //算出来是CM
if(S>=6200) //超出测量范围显示“ERR0”
{
disbuff[0]=0x3f; //“-”
disbuff[1]=0x50; //“-”
disbuff[2]=0x50; //“-”
disbuff[3]=0x79; //“-”
}
else
{
disbuff[3]=DIG_CODE[S%10000/1000];
disbuff[2]=DIG_CODE[S%1000/100];
disbuff[1]=DIG_CODE[S%100/10];
disbuff[0]=DIG_CODE[S%10/1];
}
}
/************************LCD的各个准备函数********************************/
/********************1602写命令函数**********************/
void lcd_wcom(unsigned char com)
{
rs=0; //选择指令寄存器
rw=0; //选择写
P1=com; //把命令字送入P1
delay(5); //延时一小会儿,让1602准备接收数据
en=1; //使能线电平变化,命令送入1602的8位数据口,这点非常重要
en=0;
}
/*------------------------------------------------
1602写数据函数
------------------------------------------------*/
void lcd_wdat(unsigned char dat)
{
rs=1; //选择数据寄存器
rw=0; //选择写
P1=dat; //把要显示的数据送入P0
delay(5); //延时一会儿,让1602准备接收数据,也是检测忙信号,这点非常重要
en=1; //使能线电平变化,数据送入1602的8位数据口
en=0;
}
/*------------------------------------------------
1602初始化函数
------------------------------------------------*/
void lcd_init()
{
lcd_wcom(0x38); //8位数据,双列,5*7字形 ,用到功能设定指令
lcd_wcom(0x0c); //开启显示屏,关光标,光标不闪烁,用到显示开关控制指令
lcd_wcom(0x06); //显示地址递增,即写一个数据后,显示位置右移一位,用到了写入模式设置指令
lcd_wcom(0x01); //清屏,用到了清屏指令
}
/*------------------------------------------------
1602显示固定字符函数
------------------------------------------------*/
void lcd_xianshi()
{
lcd_wcom(0x80+0x40);
lcd_wdat('D');
lcd_wdat('i');
lcd_wdat('s');
lcd_wdat('t');
lcd_wdat('a');
lcd_wdat('n');
lcd_wdat('c');
lcd_wdat('e');
lcd_wdat(':');
lcd_wcom(0x80+0x4c);
lcd_wdat('.');
lcd_wcom(0x80+0x4e);//单位是厘米//
lcd_wdat('c');
lcd_wdat('m');
}
/*************lcd显示函数*****************/
void Conut3(void)
{
unsigned char qian,bai,shi,ge;
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.87)/100; //算出来是CM
qian=S/1000;
bai=(S/100)%10;
shi=(S/10)%10;
ge=S%10;
lcd_wcom(0x80+0x49);//单位是厘米//
lcd_wdat(table[qian]);
lcd_wdat(table[bai]);
lcd_wdat(table[shi]);
lcd_wcom(0x80+0x4d);
lcd_wdat(table[ge]);
}
/***********超声波模块启动函数********************/
void StartModule() //计800MS启动超声波模块
{
TRIG=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TRIG=0;
}
/*********************蜂鸣器主函数***********************************/
void Buzzer(void)
{ unsigned int i;
TMOD=0x21; //设T0为方式1,GATE=1;
SCON=0x50;
TH0=0;
TL0=0;
TR0=0;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
for(i=0;i<5;i++)//while(1)
{
StartModule();
while(!ECHO); //当RX为零时等待
TR0=1; //开启计数
while(ECHO); //当RX为1计数并等待
TR0=0; //关闭计数
Conut1(); //计算
}
bee=1;
}
/**************************数码管主函数******************************/
void SMG(void)
{ unsigned int i;
TMOD=0x21; //设T0为方式1,GATE=1;
SCON=0x50;
TH0=0;
TL0=0;
TR0=0;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
for(i=0;i<5;i++)//while(1)
{
StartModule();
while(!ECHO); //当RX为零时等待
TR0=1; //开启计数
while(ECHO); //当RX为1计数并等待
TR0=0;
DigDisplay(); //关闭计数
Conut2(); //计算
}
GPIO_DIG=0xff;
}
/**************************LCD主函数******************************/
void LCD(void)
{ unsigned int i;
TMOD=0x21; //设T0为方式1,GATE=1;
SCON=0x50;
TH0=0;
TL0=0;
TR0=0;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
lcd_init(); //液晶初始化
for(i=0;i<5;i++)//while(1)
{
lcd_xianshi(); //液晶显示特定字符
StartModule();
while(!ECHO); //当RX为零时等待
TR0=1; //开启计数
while(ECHO); //当RX为1计数并等待
TR0=0; //关闭计数
Conut3(); //计算
}
lcd_wcom(0x01);
}
/**********************串口中断服务程序***********************************/
void sint() interrupt 4 //中断接收3个字节
{
if(RI) //是否接收中断
{
RI=0;
dat=SBUF;
if(dat=='O'&&(i==0)) //接收数据第一帧
{
buff[i]=dat;
flag=1; //开始接收数据
}
else
if(flag==1)
{
i++;
buff[i]=dat;
if(i>=2)
{i=0;flag=0;flag_REC=1 ;} // 停止接收
}
}
}
/***************************主函数*******************************/
void main(void)
{
TMOD=0x20;
TH1=0xFd; //11.0592M晶振,9600波特率,定时器1设置波特率
TL1=0xFd;
SCON=0x50;
PCON=0x00;
TR1=1;
ES=1;
EA=1;
while(1) //无限循环,等待蓝牙的数据
{
if(flag_REC==1) //蓝牙数据标志位
{
flag_REC=0;
if(buff[0]=='O'&&buff[1]=='N') //第一个字节为O,第二个字节为N,第三个字节为控制码
switch(buff[2])
{
case buzzer : // 蜂鸣器
Buzzer();
break;
case shumaguan: // 数码管
SMG();
break;
case lcd: // LCD
LCD();
break;
}
}
}
}
|
评分
-
查看全部评分
|