#include <reg52.h>
#include <intrins.h>
#include <STDIO.H>
#define uint unsigned int
#define uchar unsigned char
sbit RX=P2^1;
sbit TX=P2^0; //超声波
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P3^7; //数码管位选
sbit rs=P2^4; //1602的数据/指令选择控制线
sbit rw=P2^5; //1602的读写控制线
sbit en=P2^6; //1602的使能控制线
sbit buzzer=P2^7; //蜂鸣器
/* 超声波 */
uchar count; //中断累加变量
long int distance; //测量所得距离
unsigned char code table[ ]={"0123456789"}; //定义字符数组显示数字
#define GPIO_DIG P0
//--定义全局变量--//
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,};
/*------------------------------------------------
延时函数
------------------------------------------------*/
void delay(uint n)
{
uint x,y;
for(x=n;x>0;x--)
for(y=110;y>0;y--);
}
/*------------------------------------------------
延时函数
------------------------------------------------*/
void delayt(uint x)
{
uchar j;
while(x-- > 0)
{
for(j = 0;j < 125;j++)
{
;
}
}
}
/*------------------------------------------------
定时器0初始化,用于计算响应信号时间
------------------------------------------------*/
void init_t0()
{
TMOD=0x01;
TL0=0x66;
TH0=0xfc; //1ms
ET0=1;
EA=1;
}
/*------------------------------------------------
超声波模块触发信号
------------------------------------------------*/
void trigger()
{
TX=1;
delayt(1);
TX=0;
}
/*------------------------------------------------
超声波模块相应端口初始化函数
------------------------------------------------*/
void init_measuring()
{
TX=0;
RX=0;
count=0;
}
/*------------------------------------------------
超声波模块距离测试函数
------------------------------------------------*/
void measuring()
{
uchar l;
uint h,y;
TR0 = 1;
while(RX)
{
;
}
TR0 = 0;
l = TL0;
h = TH0;
y = (h << 8) + l;
y = y - 0xfc66;//us部分
distance = y + 1000 * count;//计算总时间,单位是微秒
TL0 = 0x66;
TH0 = 0xfc;
delayt(30);
distance = 3453* distance / 20000;//原始为:(0.34毫米/us)*时间/2//
}
/********************LCD****************************/
/*------------------------------------------------
1602写命令函数
------------------------------------------------*/
void lcd_wcom(uchar com)
{
rs=0; //选择指令寄存器
rw=0; //选择写
P1=com; //把命令字送入P0
delay(5); //延时一小会儿,让1602准备接收数据
en=1; //使能线电平变化,命令送入1602的8位数据口,这点非常重要
en=0;
}
/*------------------------------------------------
1602写数据函数
------------------------------------------------*/
void lcd_wdat(uchar 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 display(uint x)
{
uchar qian,bai,shi,ge;
qian=x/1000;
bai=(x/100)%10;
shi=(x/10)%10;
ge=x%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]);
}
/*------------------------------------------------
LCD主函数
------------------------------------------------*/
void LCD()
{ //uint i;
lcd_init(); //液晶初始化
init_t0(); //定时器0初始化
init_measuring(); //超声波相应端口初始化
while(1)// for(i=0;i<1;i++)
{ lcd_xianshi(); //液晶显示特定字符
trigger(); //触发超声波启动
while(RX==0) //等待回声
{
;
}
measuring(); //进行距离测量
display(distance); //对测量结果进行显示
init_measuring(); //超声波相应端口初始化
delayt(60); //每次测量间隔60ms
}
}
/**********************蜂鸣器*************************************/
/***********蜂鸣器响应函数*********/
void Conut1(uint x)
{
if(x>=42000) //超出测量
{
buzzer=1;
}
else
{
buzzer=1;
delayt(x); //printf("S=%fCM\n",S);
buzzer=0;
delayt(x);
}
}
/*************蜂鸣器主函数***********/
void Buzzer()
{ //uint i;
init_t0(); //定时器0初始化
init_measuring(); //超声波相应端口初始化
//for(i=0;i<1;i++)
while(1)
{
trigger(); //触发超声波启动
while(RX==0) //等待回声
{
;
}
measuring(); //进行距离测量
Conut1(distance); //对测量结果进行显示
init_measuring(); //超声波相应端口初始化
delayt(60); //每次测量间隔60ms
}
}
/****************数码管******************/
/*******************************************************************************
函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DigDisplay()
{
uchar i;
uint 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位
//case(4):
// LSA=1;LSB=1;LSC=1;LSD=0; break;//显示第3位
}
GPIO_DIG=disbuff[i];//发送段码
j=10; //扫描间隔时间设定
while(j--);
GPIO_DIG=0x00;//消隐
}
}
/*****************数码管显示函数*******************/
void Conut3(uint x)
{
if(x>=42000) //超出测量范围显示“ERR0”
{
disbuff[0]=0x3f; //“-”
disbuff[1]=0x50; //“-”
disbuff[2]=0x50; //“-”
disbuff[3]=0x79; //“-”
}
else
{
disbuff[3]=DIG_CODE[x%10000/1000];
disbuff[2]=DIG_CODE[x%1000/100];
disbuff[1]=DIG_CODE[x%100/10];
disbuff[0]=DIG_CODE[x%10/1];
}
}
/****************数码管***********************/
void SMG()
{
//uint i;
init_t0(); //定时器0初始化
init_measuring(); //超声波相应端口初始化
//for(i=0;i<1;i++)
while(1)
{
trigger(); //触发超声波启动
while(RX==0) //等待回声
{
;
}
measuring(); //进行距离测量
DigDisplay();
Conut3(distance); //对测量结果进行显示
init_measuring(); //超声波相应端口初始化
delayt(60); //每次测量间隔60ms
}
}
/*……………………………………………中断服务函数…………………………*/
void T_0()interrupt 1
{
TF0 = 0;
TL0 = 0x66;
TH0 = 0xfc;
count++;
if(count==18)
{
TR0 =0;
TL0 = 0x66;
TH0 = 0xfc;
count = 0;
}
}
/***********************蓝牙********************************/
void UART_Init(void)
{
TMOD &= 0x0f; // 清空定时器1
TMOD |= 0x20; // 定时器1工作于方式2
TH1 = 0xfd; // 为定时器1赋初值
TL1 = 0xfd; // 等价于将波特率设置为9600
ET1 = 0; // 防止中断产生不必要的干扰
TR1 = 1; // 启动定时器1
//PS=1;
SCON |= 0x50; // 串口工作于方式1,允许接收
}
void main(void)
{
uchar X;
UART_Init();
while(1)
{
X=SBUF;
while(!RI);
RI=0;
/* switch(X)
{case 'L':
LCD(); break;
case 'S':
SMG(); break;
case 'B':
Buzzer(); break;
} */
//default:break;
if(X=='L')
LCD();
else if(X=='S')
SMG();
else //if(X=='B')
Buzzer();
//else
// {;}
//}
}
}
|