|
|
//藍牙: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;
}
}
}
}
|
評分
-
查看全部評分
|