|
//藍(lán)牙:RX接p3.0,TX接3.1
//超聲波模塊:TRIG接 P2.0 ECH0 接P2.1
//數(shù)碼管:共陽數(shù)碼管P0接數(shù)據(jù)口,P2.4 P2.3 P2.2接選通數(shù)碼管
//蜂鳴器:接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為液晶顯示器對比度調(diào)整端,接正電源時對比度最弱,接地電源時對比度最高,對比度過高時會產(chǎn)生“鬼影”,使用時可以通過一個10K的電位器調(diào)整對比度(建議接地,弄不好有的模塊會不顯示)
第4腳:RS為寄存器選擇,高電平時選擇數(shù)據(jù)寄存器、低電平時選擇指令寄存器。
第5腳:RW為讀寫信號線,高電平時進(jìn)行讀操作,低電平時進(jìn)行寫操作。
第6腳:E端為使能端,當(dāng)E端由高電平跳變成低電平時,液晶模塊執(zhí)行命令。
第7~14腳:D0~D7為8位雙向數(shù)據(jù)線。
第15~16腳:空腳(有的用來接背光)
*********************/
#include<reg52.h>
#include <intrins.h>
#include <STDIO.H>
#define buzzer 'B'
#define shumaguan 'S'
#define lcd 'L' //程序?qū)?yīng)手機(jī)軟件的字符
/****************超聲波***************************/
sbit ECHO=P2^1;
sbit TRIG=P2^0; //超聲波
unsigned int time=0;
unsigned int timer=0; //測距中間變量
unsigned long S=0; //距離
/*****************藍(lán)牙*************************/
bit flag_REC=0;
bit flag =0; //藍(lán)牙接受標(biāo)識符
unsigned char i=0;
unsigned char dat=0;
unsigned char buff[5]=0; //接收緩沖字節(jié)
/***********************數(shù)碼管******************/
#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的數(shù)據(jù)/指令選擇控制線
sbit rw=P2^6; //1602的讀寫控制線
sbit en=P2^7; //1602的使能控制線
unsigned char code table[ ]={"0123456789"}; //定義字符數(shù)組顯示數(shù)字
/****************蜂鳴器*********************************/
sbit bee=P3^7; //蜂鳴器
/********************延時函數(shù)**********************************/
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);
}
}
/************************數(shù)碼管準(zhǔn)備函數(shù)********************************/
/*******************************************************************************
* 函 數(shù) 名 : DigDisplay
* 函數(shù)功能 : 使用數(shù)碼管顯示
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=1;i<4;i++)
{
switch(i) //位選,選擇點亮的數(shù)碼管,
{
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];//發(fā)送段碼
j=10; //掃描間隔時間設(shè)定
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的各個準(zhǔn)備函數(shù)********************************/
/********************1602寫命令函數(shù)**********************/
void lcd_wcom(unsigned char com)
{
rs=0; //選擇指令寄存器
rw=0; //選擇寫
P1=com; //把命令字送入P1
delay(5); //延時一小會兒,讓1602準(zhǔn)備接收數(shù)據(jù)
en=1; //使能線電平變化,命令送入1602的8位數(shù)據(jù)口,這點非常重要
en=0;
}
/*------------------------------------------------
1602寫數(shù)據(jù)函數(shù)
------------------------------------------------*/
void lcd_wdat(unsigned char dat)
{
rs=1; //選擇數(shù)據(jù)寄存器
rw=0; //選擇寫
P1=dat; //把要顯示的數(shù)據(jù)送入P0
delay(5); //延時一會兒,讓1602準(zhǔn)備接收數(shù)據(jù),也是檢測忙信號,這點非常重要
en=1; //使能線電平變化,數(shù)據(jù)送入1602的8位數(shù)據(jù)口
en=0;
}
/*------------------------------------------------
1602初始化函數(shù)
------------------------------------------------*/
void lcd_init()
{
lcd_wcom(0x38); //8位數(shù)據(jù),雙列,5*7字形 ,用到功能設(shè)定指令
lcd_wcom(0x0c); //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍,用到顯示開關(guān)控制指令
lcd_wcom(0x06); //顯示地址遞增,即寫一個數(shù)據(jù)后,顯示位置右移一位,用到了寫入模式設(shè)置指令
lcd_wcom(0x01); //清屏,用到了清屏指令
}
/*------------------------------------------------
1602顯示固定字符函數(shù)
------------------------------------------------*/
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顯示函數(shù)*****************/
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]);
}
/***********超聲波模塊啟動函數(shù)********************/
void StartModule() //計800MS啟動超聲波模塊
{
TRIG=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TRIG=0;
}
/*********************蜂鳴器主函數(shù)***********************************/
void Buzzer(void)
{ unsigned int i;
TMOD=0x21; //設(shè)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); //當(dāng)RX為零時等待
TR0=1; //開啟計數(shù)
while(ECHO); //當(dāng)RX為1計數(shù)并等待
TR0=0; //關(guān)閉計數(shù)
Conut1(); //計算
}
bee=1;
}
/**************************數(shù)碼管主函數(shù)******************************/
void SMG(void)
{ unsigned int i;
TMOD=0x21; //設(shè)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); //當(dāng)RX為零時等待
TR0=1; //開啟計數(shù)
while(ECHO); //當(dāng)RX為1計數(shù)并等待
TR0=0;
DigDisplay(); //關(guān)閉計數(shù)
Conut2(); //計算
}
GPIO_DIG=0xff;
}
/**************************LCD主函數(shù)******************************/
void LCD(void)
{ unsigned int i;
TMOD=0x21; //設(shè)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); //當(dāng)RX為零時等待
TR0=1; //開啟計數(shù)
while(ECHO); //當(dāng)RX為1計數(shù)并等待
TR0=0; //關(guān)閉計數(shù)
Conut3(); //計算
}
lcd_wcom(0x01);
}
/**********************串口中斷服務(wù)程序***********************************/
void sint() interrupt 4 //中斷接收3個字節(jié)
{
if(RI) //是否接收中斷
{
RI=0;
dat=SBUF;
if(dat=='O'&&(i==0)) //接收數(shù)據(jù)第一幀
{
buff[i]=dat;
flag=1; //開始接收數(shù)據(jù)
}
else
if(flag==1)
{
i++;
buff[i]=dat;
if(i>=2)
{i=0;flag=0;flag_REC=1 ;} // 停止接收
}
}
}
/***************************主函數(shù)*******************************/
void main(void)
{
TMOD=0x20;
TH1=0xFd; //11.0592M晶振,9600波特率,定時器1設(shè)置波特率
TL1=0xFd;
SCON=0x50;
PCON=0x00;
TR1=1;
ES=1;
EA=1;
while(1) //無限循環(huán),等待藍(lán)牙的數(shù)據(jù)
{
if(flag_REC==1) //藍(lán)牙數(shù)據(jù)標(biāo)志位
{
flag_REC=0;
if(buff[0]=='O'&&buff[1]=='N') //第一個字節(jié)為O,第二個字節(jié)為N,第三個字節(jié)為控制碼
switch(buff[2])
{
case buzzer : // 前進(jìn)
Buzzer();
break;
case shumaguan: // 后退
SMG();
break;
case lcd: // 左轉(zhuǎn)
LCD();
break;
}
}
}
}
*********************/
#include<reg52.h>
#include <intrins.h>
#include <STDIO.H>
#define buzzer 'B'
#define shumaguan 'S'
#define lcd 'L' //程序?qū)?yīng)手機(jī)軟件的字符
/****************超聲波***************************/
sbit ECHO=P2^1;
sbit TRIG=P2^0; //超聲波
unsigned int time=0;
unsigned int timer=0; //測距中間變量
unsigned long S=0; //距離
/*****************藍(lán)牙*************************/
bit flag_REC=0;
bit flag =0; //藍(lán)牙接受標(biāo)識符
unsigned char i=0;
unsigned char dat=0;
unsigned char buff[5]=0; //接收緩沖字節(jié)
/***********************數(shù)碼管******************/
#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的數(shù)據(jù)/指令選擇控制線
sbit rw=P2^6; //1602的讀寫控制線
sbit en=P2^7; //1602的使能控制線
unsigned char code table[ ]={"0123456789"}; //定義字符數(shù)組顯示數(shù)字
/****************蜂鳴器*********************************/
sbit bee=P3^7; //蜂鳴器
/********************延時函數(shù)**********************************/
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);
}
}
/************************數(shù)碼管準(zhǔn)備函數(shù)********************************/
/*******************************************************************************
* 函 數(shù) 名 : DigDisplay
* 函數(shù)功能 : 使用數(shù)碼管顯示
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=1;i<4;i++)
{
switch(i) //位選,選擇點亮的數(shù)碼管,
{
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];//發(fā)送段碼
j=10; //掃描間隔時間設(shè)定
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的各個準(zhǔn)備函數(shù)********************************/
/********************1602寫命令函數(shù)**********************/
void lcd_wcom(unsigned char com)
{
rs=0; //選擇指令寄存器
rw=0; //選擇寫
P1=com; //把命令字送入P1
delay(5); //延時一小會兒,讓1602準(zhǔn)備接收數(shù)據(jù)
en=1; //使能線電平變化,命令送入1602的8位數(shù)據(jù)口,這點非常重要
en=0;
}
/*------------------------------------------------
1602寫數(shù)據(jù)函數(shù)
------------------------------------------------*/
void lcd_wdat(unsigned char dat)
{
rs=1; //選擇數(shù)據(jù)寄存器
rw=0; //選擇寫
P1=dat; //把要顯示的數(shù)據(jù)送入P0
delay(5); //延時一會兒,讓1602準(zhǔn)備接收數(shù)據(jù),也是檢測忙信號,這點非常重要
en=1; //使能線電平變化,數(shù)據(jù)送入1602的8位數(shù)據(jù)口
en=0;
}
/*------------------------------------------------
1602初始化函數(shù)
------------------------------------------------*/
void lcd_init()
{
lcd_wcom(0x38); //8位數(shù)據(jù),雙列,5*7字形 ,用到功能設(shè)定指令
lcd_wcom(0x0c); //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍,用到顯示開關(guān)控制指令
lcd_wcom(0x06); //顯示地址遞增,即寫一個數(shù)據(jù)后,顯示位置右移一位,用到了寫入模式設(shè)置指令
lcd_wcom(0x01); //清屏,用到了清屏指令
}
/*------------------------------------------------
1602顯示固定字符函數(shù)
------------------------------------------------*/
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顯示函數(shù)*****************/
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]);
}
/***********超聲波模塊啟動函數(shù)********************/
void StartModule() //計800MS啟動超聲波模塊
{
TRIG=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TRIG=0;
}
/*********************蜂鳴器主函數(shù)***********************************/
void Buzzer(void)
{ unsigned int i;
TMOD=0x21; //設(shè)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); //當(dāng)RX為零時等待
TR0=1; //開啟計數(shù)
while(ECHO); //當(dāng)RX為1計數(shù)并等待
TR0=0; //關(guān)閉計數(shù)
Conut1(); //計算
}
bee=1;
}
/**************************數(shù)碼管主函數(shù)******************************/
void SMG(void)
{ unsigned int i;
TMOD=0x21; //設(shè)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); //當(dāng)RX為零時等待
TR0=1; //開啟計數(shù)
while(ECHO); //當(dāng)RX為1計數(shù)并等待
TR0=0;
DigDisplay(); //關(guān)閉計數(shù)
Conut2(); //計算
}
GPIO_DIG=0xff;
}
/**************************LCD主函數(shù)******************************/
void LCD(void)
{ unsigned int i;
TMOD=0x21; //設(shè)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); //當(dāng)RX為零時等待
TR0=1; //開啟計數(shù)
while(ECHO); //當(dāng)RX為1計數(shù)并等待
TR0=0; //關(guān)閉計數(shù)
Conut3(); //計算
}
lcd_wcom(0x01);
}
/**********************串口中斷服務(wù)程序***********************************/
void sint() interrupt 4 //中斷接收3個字節(jié)
{
if(RI) //是否接收中斷
{
RI=0;
dat=SBUF;
if(dat=='O'&&(i==0)) //接收數(shù)據(jù)第一幀
{
buff[i]=dat;
flag=1; //開始接收數(shù)據(jù)
}
else
if(flag==1)
{
i++;
buff[i]=dat;
if(i>=2)
{i=0;flag=0;flag_REC=1 ;} // 停止接收
}
}
}
/***************************主函數(shù)*******************************/
void main(void)
{
TMOD=0x20;
TH1=0xFd; //11.0592M晶振,9600波特率,定時器1設(shè)置波特率
TL1=0xFd;
SCON=0x50;
PCON=0x00;
TR1=1;
ES=1;
EA=1;
while(1) //無限循環(huán),等待藍(lán)牙的數(shù)據(jù)
{
if(flag_REC==1) //藍(lán)牙數(shù)據(jù)標(biāo)志位
{
flag_REC=0;
if(buff[0]=='O'&&buff[1]=='N') //第一個字節(jié)為O,第二個字節(jié)為N,第三個字節(jié)為控制碼
switch(buff[2])
{
case buzzer : // 蜂鳴器
Buzzer();
break;
case shumaguan: // 數(shù)碼管
SMG();
break;
case lcd: // LCD
LCD();
break;
}
}
}
}
|
評分
-
查看全部評分
|