概述
基于51单片机的蓝牙智能台灯
目录
基于51单片机的蓝牙智能台灯
一、功能:
二、系统组成:
三、设计思路:
四、硬件:
1. 51最小系统板(学过51的都基本了解,这里不做赘述)
2. 光敏电阻
3. ADC0832
4. HC-05蓝牙模块
5.超声波测距模块HC-SR04
6.双向可控硅
五、软件
1.电路原理图
2.源代码
六、遇到的问题
七、实物图
一、功能:
1.当人靠近的时候,灯会自己亮,当人离开的时候,灯会自己灭
2.靠的太近的时候,蜂鸣器会发出报警
3.可以连接手机蓝牙,进行亮度调光,发送1,最亮,;发送2,较亮;发送3,最暗;发送4,灭
4.切换模式,可以随着环境亮度自动调光
二、系统组成:
51最小系统板+光敏电阻及AD模块+蓝牙模块+超声波测距模块+继电器+可控硅+电源
三、设计思路:
利用超声波测距,设定不同的距离范围,执行不同的操作,人坐在台灯前,靠的太近,离开,分别对应不同的范围,实现灯的亮灭和报警。可控硅可以实现用小功率控制大功率的效果,在可控硅的的触发脚并联不同阻值的电阻,由四路继电器连接,蓝牙给51单片机发送数字,控制继电器的通断,实现不同亮度的调节。对于自动调光,可采用光敏电阻和ADC0832实现,不同的光照,光敏电阻的阻值不同,利用ADC0832将模拟量转化成数字量,设定不同的范围,执行不同的操作。
四、硬件:
1. 51最小系统板(学过51的都基本了解,这里不做赘述)
2. 光敏电阻
光敏电阻的工作原理是基于内光电效应。当光敏电阻受到一定波长范围的光照时, 它的阻值(亮电阻)急剧减少, 电路中电流迅速增大。 一般希望暗电阻越大越好, 亮电阻越小越好,此时光敏电阻的灵敏度高。 实际光敏电阻的暗电阻值一般在兆欧级, 亮电阻在几千欧以下
3. ADC0832
(1)引脚功能
CS:片选使能,低电平使能
CH0:模拟输入通道0
CH1:模拟输入通道1
GND:芯片参考0电位
VCC:电源输入
CLK:芯片时钟输入
DI:信号数据输入,选择通道控制
DO:信号数据输出,转换数据输出
(2)使用方法
ADC0832芯片与单片机在正常情况下应有4条数据线相连,分别是CLK和CS、D1和D0。但在实际通信时D1端与DO端未同时有效,并且双向连接到单片机,所以在设计电路时可将D1和DO接在一个单片机管脚上进行使用。本设计中ADC0832芯片的D1端和DO端均接到了单片机的P0^0口,选择数据信号从D1端进行输入,数据由D0端进行输出;CLK端接到了单片机的P0^1口为AD芯片提供时钟输入;使能端CS接到了单片机的P0^2口;传感器模拟电压输出到通道CH0端
4. HC-05蓝牙模块
(1)VCC:当然这个引脚是接电源的正极,电压的范围为3.3v到5.0v
(2)GND:直接接地
(3)TXD:模块串口发送引脚(TTL电平,不能直接接RS232电平),可直接接单片机的RXD引脚
(4)RXD:模块串口接收引脚(TTL电平,不能直接接RS232电平),可直接接单片机的TXD引脚
(5)KEY:用于进入AT状态:高电平有效(悬空默认为低电平)
(6)蓝牙AT指令
a. AT+RESET:该指令顾名思义,是复位HC05蓝牙设备的,蓝牙模块复位后,当然原来连接也就断开了,模块处于INITIALIZED状态,还需要注意的是,如果在用MCU的串口给蓝牙模块发送复位命令,一定要注意发送复位命令1s后才能继续发送其他命令,因为如果你1s内发送其他命令,此时蓝牙模块可能还在复位中,没法响应命令。当然,如果你是用串口工具发送,一般发送两个命令的间隔不会太短。
>AT+RESETrn
OK
b. AT+INIT:该指令初始化SPP规范库,所谓的SPP就是蓝牙串口端口协议,总之,没有初始化SPP库就没发扫描周围的蓝牙设备,没有与摸个蓝牙设备连接。,所以,在应用程序中,一定要初始化SPP库,没有初始化SPP库,就发送扫描指令或连接指令,蓝牙模块会返回ERROR:(16)错误,表示没有初始化SPP库。还有个要注意的是,如果发送多次该指令,蓝牙模块会放回ERROR:(17)重复初始化错误。还有,每次断电后再上电或蓝牙模块复位后,都要重新初始化SPP库。
>AT+INITrn
OK //正确
FALL //失败
ERROR:(17) //重复初始化
c. AT+ROLE:该指令用于选择HC05蓝牙模块的角色,总共有三种角色:master,slave,loop-slave.
AT+ROLE=0rn 将蓝牙模块设置成从角色,只能被动连接
AT+ROLE=1rn 将蓝牙模块设置成主角色,可以查询周围SPP蓝牙从设备,并发送连接
AT+ROLE=2rn 将蓝牙模块设置成回环角色,被动连接,接收远程蓝牙模块主设备数据并将数据原样返回给远程蓝牙设备
这几个指令用在不同的场合,当设置蓝牙模块为从设备的时候,可以用手机的相关蓝牙装串口软件连接该设备,进行通讯;当设置成主角色的时候,可以搜索周遭的蓝牙从设备,并连接,这种模式在应用中很常用;回环角色很多时候都是用来做测试用的。
>AT+ROLE=1rn
OK
d. AT+PSWD:这个指令时设置蓝牙模块的配对密码,蓝牙模块在做从模块的时候,如果用手机要连接该蓝牙设备,就要键入蓝牙的配对密码才能连接,比如说HC05默认的配对密码是1234,那么就要在手机的输入该配对密码1234才能连接我们的HC05
>AT+PSWD=1234rn
OK
e. AT_UART:这个指令是设置串口的参数,指令的格式如下:
AT+UART=<Param>,<Param1>,<Param2>rn
Param:波特率,一些常用的波特率都可以设置
Param1:停止位,一般设置成0,表示为1个停止位
Param2:校验位,一帮设置为0,表示不用校验
该指令是设置蓝牙模块与蓝牙模块之间通讯时,蓝牙模块的串口参数。HC05模块在默认的配置下是设置成9600,也就是说,在AT模式下,我们用38400与HC05通讯,而在HC05与某蓝牙模块通讯时,则我们用9600的波特率接收HC05从蓝牙模块的接收到的数据。这里建议将波特率改为38400,这是因为,当用串口调试工具连接HC05时,AT模式是用38400波特率,而连接后默认是9600,这样的不断的切换串口调试工具的波特率,会很麻烦,所以设置成38400后,就方便调试了。
>AT+UART=38400,0,0rn
OK
f. AT+INQM:设置或查询访问模式,格式如此:
AT+INQM=<Param>,<Param1>,<Param2>r]n
Param:0——inquiry_mode_standard,1——inquiry_mode_rssi,表示标准查询还是带信号强度的查询。
Param1:最多蓝牙设备响应的数量
Param2:最大查询时间(1~48,折合成时间,1,28s~61.44s)
将这个指令是为扫描指令做铺垫,根据自己的实际情况调整。
>AT+INQM=1,1,15
OK
g. AT+INQ:查询蓝牙设备,返回的格式如下:
+INQ:<Param>,<Param1>,<Param>....
Param:蓝牙地址
Param1:设备类
Param2:RSSI信号强度
举个例子:+INQ:98D3:31:500DF8,1F00,7FFF,
98D3:31:500DF8表示蓝牙的地址,这里有需要补充下蓝牙的相关知识,蓝牙地址的由NAP(24位地址低端部分):UAP(8为地址高端部分):LAP(16为无意义地址部分),所以该地址:98D3表示LAP,31表示UAP,500DF8表示LAP
>AT+INQ
+INQ:98D3:31:500DF8,1F00,7FFF //有的话列出
OK
h. AT+RNAME:这个指令获得远端蓝牙设备的名字,我们手机上看到的就是这个名字,而不会直接给出蓝牙设备地址
>AT+RNAME? 98D3,31,500DF8 //主要这里是逗号,而不是冒号
+RNAME:EST527
OK
i. AT+LINK:这个命令连接远程设备蓝牙,其实没有什么好说的,连接上后,LED引脚输出高电平,如果该引脚有接上拉LED灯,则会发现LED灭了。
>AT+LINK=98D3,31,500DF8
OK
j. AT+STATE:这个指令用来查询蓝牙模块当前的状态,状态种类如下:
INITIALIZED——初始化状态
READY——准备状态
PAIRABLE——可配对状态
PAIRED——配对状态
INQUIRING——查询状态
CONNECTING——正在连接状态
CONNECTED——连接状态
DISCONNECTED——断开连接
UNKNOW————位置状态
>AT+STATE
+STATE:INITIALIZED
OK
+STATE:PAIRED
OK
k. AT+CMODE:这个指令其实很重要。
AT+CMODE=0rn 指定蓝牙地址连接模式(指定蓝牙地址呦绑定指令设置)
AT+CMODE=1rn 任意蓝牙地址连接模式(不受绑定指令的设置地址约束)
AT+CMODE=2rn 回环角色
为0时,该指令设置模块为指定地址配对,如果先设置模块为任意地址,然后配对,接下去使用该指令,则模块会记忆最后一次配对的地址,下次上电会一直搜索该地址的模块,直到搜索到为止。
为1时,该指令设置模块可以对任意地址的蓝牙模块进行配对,只要有模块的配对秘钥跟自己的一样的就能自动连上。
AT+CMODE=1rn
OK
(7)测试代码
#include<reg52.h>
#include<math.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar aa,bb;
uchar Buffer[4] = {0};
uint xms,i,j;
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void Com_Int(void) interrupt 4
{EA = 0;
if(RI == 1) //当硬件接受到一个数据时,RI会置位
{
Buffer[0] = SBUF - 48; //这里减去48是因为从电脑发送过来的是ASCII码
RI = 0;}
EA = 1;
}
/********************************************************************
串口初始化
***********************************************************************/
void Com_Init(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd; //波特率9600
TL1 = 0xFd;
TR1 = 1; //启动定时器1
ES = 1; //开启串口中断
EA = 1; //开启总中断
}
/**************************************************************************
主函数
**************************************************************************/void main()
{
delayms(100);Com_Init();
while(1)
{
switch(Buffer[0])
{case 1: led1=1; break;
case 2: led1=0 ; break;
default:break;
}
}
}
5.超声波测距模块HC-SR04
(1)引脚:VCC、Trig、Echo、GND
VCC接电源正极
GND接电源负极
Trig是传感器触发信号输入引脚---P3^2
Echo是传感器测距数据输出引脚--P3^3
(2)工作原理
单片机向模块的Trig引脚发出至少10μs的高电平信号以触发传感器测距。模块自动发送8个40kHz的方波,模块自动检测是否有信号返回。
当有信号返回时,通过IO输出一高电平,该高电平持续的时间就是超声波从发射到返回的时间。时间单位 一般为微秒(μs),声速约为344m/s,
则可推导:
测试距离(m)= [高电平时间(μs)×10^(-6)×声速(344m/s)]/2
= 高电平时间(μs)×172/10^6
此时的测试距离的单位为米,转换为厘米则
测试距离(cm)= 高电平时间(μs)×172/10^6×100
= 高电平时间(μs)/58
6.双向可控硅
(1)引脚
1------T1主电极
2------T2主电极
3------G门极
(2)工作原理
双向可控硅是两个方向都可以导通的,所以就不区分阳极和阴极。只要在G极注入正向电压就可以让T1和T2极导通了,非常适用于交流电工作的器件的控制。可控硅一旦导通,不管G脚的电压如何变,所控制的器件状态保持不变,要想改变状态,只有切断总电源
五、软件
1.电路原理图
说明:继电器的com端和火线相连,常开端和电阻相连,IN脚连接单片机的IO口,当给其一个低电平,继电器导通,NO端和com端的电平将相同,及相当于NO端也连接到火线。可控硅导通,灯泡点亮,因为电源是交流电,当到过零电压,灯泡熄灭。可控硅G脚高电压保持的时间跟相连的电阻有关,这样可以通过单片机控制不同的继电器,从而实现调光。
2.源代码
#include "1602.h"
#define uchar unsigned char
#define uint unsigned int
#define VELOCITY_30C 3495
#define VELOCITY_23C 3453
uchar aa,bb;
uchar Buffer[4] = {0};
uint xms,i,j;
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
sbit INPUT= P3^3;
sbit OUTPUT= P3^2;sbit DW1=P1^4;
sbit DW2=P1^5;
sbit DW3=P1^6;
sbit Beep=P1^3;
sbit rw = P1^1;
long int distance=0;
uchar table[]=" Welcome to ";
uchar table0[]=" yfmcu ";
uchar table1[]="There's no echo.";
uchar table2[]=" yfmcu ";
uchar table3[]="Distance:";
uchar count;
extern void write_date(uchar date);
extern void write_com(uchar com);
extern void delay(uint x);
/******************************************************************************/
/******************************************************************************/
void Delay_xMs(unsigned int x)
{
unsigned int i,j;
for(i = 0;i < x;i++ )
{
for(j = 0;j < 3;j++ )
{
;
}
}
}/******************************************************************************/
/******************************************************************************/
void delayt(uint x)
{
uchar j;
while(x-- > 0)
{
for(j = 0;j < 125;j++)
{
;
}
}
}
/******************************************************************************/
/******************************************************************************/
void Init_MCU(void)
{
TMOD = 0x01;
TL0 = 0x66;
TH0 = 0xfc;
ET0 = 1;
EA = 1;
}
/******************************************************************************/
/******************************************************************************/
void Init_Parameter(void)
{
OUTPUT =1;
INPUT = 1;
count = 0;
distance = 0;
}/******************************************************************************/
/******************************************************************************/
void Trig_SuperSonic(void)
{
OUTPUT = 1;
delayt(1);
OUTPUT = 0;
}
/******************************************************************************/
/******************************************************************************/
void Measure_Distance(void)
{
uchar l;
uint h,y;
TR0 = 1;
while(INPUT)
{
;
}
TR0= 0;
l = TL0;
h = TH0;
y = (h << 8) + l;
y = y - 0xfc66;
distance = y + 1000 * count;
TL0 = 0x66;
TH0= 0xfc;
delayt(30);
distance = VELOCITY_30C * distance / 90000;
}
void Com_Int(void) interrupt 4
{EA = 0;
if(RI == 1)
{
Buffer[0] = SBUF - 48;
RI = 0;}
EA = 1;
}
/********************************************************************
´®¿Ú³õʼ»¯
***********************************************************************/
void Com_Init(void)
{
TMOD|= 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TR1 = 1;
ES = 1;
EA = 1;
}
void light_l()
{
/*if(Buffer[0]==1||distance>200&&distance<700)
{
DW4=0;
DW1=0;
DW2=1;
DW3=1;
}
else if(Buffer[0]==2)
{
DW4=0;
DW1=1;
DW2=0;
DW3=1;
}
else if(Buffer[0]==3)
{
DW4=0;
DW1=1;
DW2=1;
DW3=0;
}
else if(Buffer[0]==4||distance>700)
{
DW4=1;
DW1=1;
DW2=1;
DW3=1;
}*/if(distance>700)
{
Beep=1;
DW1=1;
DW2=1;
DW3=1;
if(Buffer[0]==1||distance>200&&distance<700)
{
DW1=0;
DW2=1;
DW3=1;
}
}
else if(Buffer[0]==2)
{
DW1=1;
DW2=0;
DW3=1;
}
else if(Buffer[0]==3)
{
DW1=1;
DW2=1;
DW3=0;
}
}
/*void jiance()
{
int flag=0;
if(distance>200&&distance<700)
flag=0;
else
flag=1;
}
void light_l()
{
switch(Buffer[0]-flag)
{
case 1:
DW4=0;
DW1=0;
DW2=1;
DW3=1;
break;
case 2:
DW4=0;
DW1=1;
DW2=0;
DW3=1;
break;
case 3:
DW4=0;
DW1=1;
DW2=1;
DW3=0;
break;
}
}*/
void main()
{
delayms(100);Com_Init();
rw = 0;
//Init_MCU();
Init_Parameter();Delay_xMs(30000);
while(1)
{
Trig_SuperSonic();
while(INPUT == 0)
{
;
}
Measure_Distance();
light_l();
if(distance>0&&distance<100)
Beep=0;
else Beep=1;
Init_Parameter();
delayt(100);
}
/******************************************************************************/
/******************************************************************************/
void timer0 (void) interrupt 1
{
TF0 = 0;
TL0 = 0x66;
TH0 = 0xfc;
count++;
if(count == 18)
{
TR0 =0;
TL0 = 0x66;
TH0 = 0xfc;
count = 0;
}
}
/******************************************************************************/
六、遇到的问题
1.当超声波避障和ADC0832,蓝牙串口同时工作,会导致定时器紊乱
解决方法:用两个单片机,将ADC0832单独放在一个单片机上控制,把一个设置为主机,一个设置为从机,实现两个单片机之间的通信
七、实物图
最后
以上就是故意雪糕为你收集整理的2021-04-25 基于51单片机的蓝牙智能台灯六、遇到的问题七、实物图的全部内容,希望文章能够帮你解决2021-04-25 基于51单片机的蓝牙智能台灯六、遇到的问题七、实物图所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复