
51单片机实战训练——基于蓝牙的智能家居控制器(含项目源码)
开发软件:Keil4(编写程序)、STC-ISP(烧录下载)目标效果:通过手机蓝牙app,控制单片机小灯亮灭(模拟电灯)、步进电机(模拟窗帘),检测家居环境(实时掌握室内温湿度)。另外使用矩阵键盘作为本地备用。
51单片机实战训练——基于蓝牙的智能家居控制器(含项目源码)
开发软件:Keil4(编写程序)、STC-ISP(烧录下载)
目标效果:通过手机蓝牙app,控制单片机小灯亮灭(模拟电灯)、步进电机(模拟窗帘),检测家居环境(实时掌握室内温湿度)。另外使用矩阵键盘作为本地备用。
一、HC05蓝牙模块
HC-05 蓝牙串口通信模块,是基于 Bluetooth Specification V2.0 带 EDR 蓝牙协议的
数传模块。无线工作频段为 2.4GHz ISM,调制方式是 GFSK。模块最大发射功率为 4dBm,
接收灵敏度-85dBm,板载 PCB 天线,可以实现 10 米距离通信。
模块采用邮票孔封装方式,模块大小 27mm×13mm×2mm,方便客户嵌入应用系统之
内,自带 LED 灯,可直观判断蓝牙的连接状态。
模块采用 CSR 的 BC417 芯片,支持 AT 指令,用户可根据需要更改角色(主、从模式)
以及串口波特率、设备名称等参数,使用灵活。
1-1.基本参数
1-2.工作原理简单说明
如上图所示,HC-05 模块用于代替全双工通信时的物理连线。左边的设备向模块发送串口数据,模块的 RXD 端
口收到串口数据后,自动将数据以无线电波的方式发送到空中。右边的模块能自动接收到,并从 TXD 还原最初左
边设备所发的串口数据。从右到左也是一样的。
1-3.模块功能测试
博主到手HC05模块后进行了一番调试
将板子USB转TTL模块的键帽拔下后,TX接RX、RX接TX、VCC接5v、GND接GND
上电后,模块红灯快闪
手机打开测试软件HCBluetooth,找到HC05模块连接,向蓝牙模块发送信息
电脑运行串口助手就可以接收到信息
当然,电脑端也可发送,手机端也可以接收
由以上工作,我们可以确定HC-05模块正常工作
(文章这里好像无法附带程序,需要的同学可以在评论区留言或者私信博主领取)
1-4.蓝牙模块代码
蓝牙模块波特率为9600,我们之前uart模块需要做一些针对性修改
//修改后的UART模块
//UART.h
#ifndef __UART_H__
#define __UART_H__
#define UART_REC_LEN 10 //定义最大接收字节数 50
extern unsigned char UART_RX_BUF[UART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern unsigned int UART_RX_STA; //接收状态标记
void UART_Init();
void UART_SendData(unsigned char Data);
void UART_SendString(unsigned char *pbuf);
#endif
//UART.c
#include <REGX52.H>
#include "UART.h"
void delay_10us(unsigned int ten_us)
{
while(ten_us--);
}
unsigned char UART_RX_BUF[UART_REC_LEN];
unsigned int UART_RX_STA=0;
void UART_Init() //9600bps
{
SCON |=0x50;
PCON = 0x80;
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ES=0; //关闭接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
void UART_SendData(unsigned char Data)
{
ES=0; //关闭串口中断
TI=0; //清发送完毕中断请求标志位
SBUF=Data; //发送
while(TI==0); //等待发送完毕
TI=0; //清发送完毕中断请求标志位
ES=1; //允许串口中断
}
void UART_SendString(unsigned char *pbuf)
{
while(*pbuf!='\0') //遇到空格跳出循环
{
UART_SendData(*pbuf);
delay_10us(5);
pbuf++;
}
}
//蓝牙模块
//Bluetooth.h
#ifndef _bluetooth_H
#define _bluetooth_H
void bluetooth_control_init(void);
void bluetooth_control(void);
#endif
//Bluetooth.c
#include <REGX52.H>
#include "Bluetooth.h"
#include "UART.h"
//定义LED1管脚
sbit LED1=P2^0;
//定义蓝牙控制命令
#define LED1_ON_CMD 0X31 //手机发送1亮
#define LED1_OFF_CMD 0X30 //手机发送0灭
//蓝牙控制初始化
void bluetooth_control_init(void)
{
UART_Init();
ES=1;//允许串口中断
}
//蓝牙控制
void bluetooth_control(void)
{
//计划这里控制向手机传输温湿度数据,并显示在LCD1602上
while(1)
{
}
}
//串口中断服务函数
//接收手机APP发送的信号后控制板载资源
void UART_IRQn() interrupt 4
{
if(RI)
{
RI=0;
UART_RX_BUF[0]=SBUF;//读取接收到的数据
//蓝牙控制
if(UART_RX_BUF[0]==LED1_ON_CMD)
LED1=0;
else if(UART_RX_BUF[0]==LED1_OFF_CMD)
LED1=1;
}
}
二、步进电机模块
2-1.基本参数
- 型号:28BYJ-48
- 电压:5V DC
- 步距角(未减速):5.625°(每步),经减速后输出轴实际步距角为 5.625° / 64 ≈ 0.0879°。
- 减速比:1:64(电机转64圈,输出轴转1圈)。
- 相数:4相单极性(5根线:红为公共端,橙、黄、粉、蓝为线圈)。
- 总步数/圈:全步模式(单相激励):64 × 64步 = 4096步/圈(因争议,实际常用2048步/圈)。半步模式(混合激励):64 × 8步 × 8 = 2048步/圈。
- 扭矩:约30~40mN·m(负载能力较低,适合轻载场景)。
- 转速:约15 RPM(受驱动频率限制)。
2-2.工作原理
2-2-1.结构
- 定子:4组线圈,通过公共端(红)连接电源,其余四线依次控制。
- 转子:永磁体,通过齿轮组减速输出。
- 减速齿轮:降低转速、提升扭矩(1:64)。
2-2-2.驱动模式
- 全步(单相激励):每次激活一相,步距角0.0879°,扭矩较小。
- 全步(双相激励):每次激活两相,扭矩更大,耗电更高。
- 半步:交替单相和双相,步数翻倍(如2048步/圈),运行更平滑。
2-2-3.旋转方向
通过线圈通电顺序控制正反转(如顺序A-B-C-D-A或A-D-C-B-A)。
2-3.驱动代码
//步进电机模块
//StepMotor.h
/* StepMotor.h */
#ifndef __STEP_MOTOR_H__
#define __STEP_MOTOR_H__
// 电机控制函数接口
void StepMotor_Init(void);
void StepMotor_Start(void);
void StepMotor_Stop(void);
void StepMotor_Reverse(void);
void StepMotor_HighSpeed(void);
void StepMotor_LowSpeed(void);
void StepMotor_Update(void); // 需要在主循环中持续调用
#endif
//StepMotor.c
/* StepMotor.c */
#include "StepMotor.h"
#include <reg52.h>
// 引脚定义
sbit IN1_A = P1^0;
sbit IN2_B = P1^1;
sbit IN3_C = P1^2;
sbit IN4_D = P1^3;
// 电机状态参数
#define MAX_SPEED 1
#define MIN_SPEED 5
static unsigned char isRunning = 0; // 运行状态标志
static unsigned char direction = 0; // 旋转方向
static unsigned char currentStep = 0; // 当前步序
static unsigned char delayTime = MAX_SPEED; // 延时参数
/* 私有函数声明 */
static void SendPulse(unsigned char step);
static void DelayMs(unsigned int ms);
/**************** 公有函数实现 ****************/
void StepMotor_Init(void) {
IN1_A = 0;
IN2_B = 0;
IN3_C = 0;
IN4_D = 0;
}
void StepMotor_Start(void) {
isRunning = 1;
}
void StepMotor_Stop(void) {
isRunning = 0;
// 断电所有线圈
IN1_A = 0;
IN2_B = 0;
IN3_C = 0;
IN4_D = 0;
}
void StepMotor_Reverse(void) {
direction = !direction;
}
void StepMotor_HighSpeed(void) {
if(delayTime > MAX_SPEED) delayTime--;
}
void StepMotor_LowSpeed(void) {
if(delayTime < MIN_SPEED) delayTime++;
}
/**************** 主循环更新函数 ****************/
void StepMotor_Update(void) {
if(!isRunning) return;
SendPulse(currentStep++);
if(currentStep >= 8) currentStep = 0;
DelayMs(delayTime);
}
/**************** 私有函数实现 ****************/
static void SendPulse(unsigned char step) {
unsigned char effectiveStep = direction ? (7 - step) : step;
switch(effectiveStep) {
case 0: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=0;break;
case 1: IN1_A=1;IN2_B=1;IN3_C=0;IN4_D=0;break;
case 2: IN1_A=0;IN2_B=1;IN3_C=0;IN4_D=0;break;
case 3: IN1_A=0;IN2_B=1;IN3_C=1;IN4_D=0;break;
case 4: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=0;break;
case 5: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=1;break;
case 6: IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=1;break;
case 7: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=1;break;
}
}
static void DelayMs(unsigned int ms) {
unsigned int i, j;
for(i = ms; i > 0; i--)
for(j = 110; j > 0; j--);
}
三、实操步骤
有了上面的内容储备,我们就可以开始做这个基于蓝牙的智能家具控制器了
3-1.开关灯
我们设计0为关灯,1为开灯
#include <REGX52.H>
#include "Bluetooth.h"
#include "LCD1602.h"
#include "StepMotor.h"
void main()
{
bluetooth_control_init();
while(1)
{
bluetooth_control();
}
}
3-2.开关窗帘(驱动步进电机模拟)
修改蓝牙模块
#include <REGX52.H>
#include "StepMotor.h"
#include "Bluetooth.h"
#include "UART.h"
//定义LED1管脚
sbit LED1=P2^0;
//定义蓝牙控制命令
#define LED1_ON_CMD 0X31 //手机发送1亮
#define LED1_OFF_CMD 0X30 //手机发送0灭
#define SM_START_CMD 0X32 //手机发送2电机运动
#define SM_STOP_CMD 0X33 //手机发送3电机停止
#define SM_REVERSE_CMD 0X34 //手机发送4电机反方向运动
#define SM_HS_CMD 0X35 //手机发送5电机加速
#define SM_LS_CMD 0X36 //手机发送6电机减速
//蓝牙控制初始化
void bluetooth_control_init(void)
{
UART_Init();
ES=1;//允许串口中断
}
//蓝牙控制
void bluetooth_control(void)
{
//计划这里控制向手机传输温湿度数据,并显示在LCD1602上
}
//串口中断服务函数
//接收手机APP发送的信号后控制板载资源
void UART_IRQn() interrupt 4
{
if(RI)
{
RI=0;
UART_RX_BUF[0]=SBUF;//读取接收到的数据
//蓝牙控制
if(UART_RX_BUF[0]==LED1_ON_CMD)
{LED1=0;}
else if(UART_RX_BUF[0]==LED1_OFF_CMD)
{LED1=1;}
else if(UART_RX_BUF[0]==SM_START_CMD)
{StepMotor_Start();}
else if(UART_RX_BUF[0]==SM_STOP_CMD)
{StepMotor_Stop();}
else if(UART_RX_BUF[0]==SM_REVERSE_CMD)
{StepMotor_Reverse();}
else if(UART_RX_BUF[0]==SM_HS_CMD)
{StepMotor_HighSpeed();}
else if(UART_RX_BUF[0]==SM_LS_CMD)
{StepMotor_LowSpeed();}
}
}
修改主函数
#include <REGX52.H>
#include "Bluetooth.h"
#include "LCD1602.h"
#include "StepMotor.h"
void main()
{
EA=0;
StepMotor_Init();
bluetooth_control_init();
EA=1;
while(1)
{
bluetooth_control();
StepMotor_Update();
}
}
3-3.读取室内温湿度
修改蓝牙模块
//bluetooth.c
#include <REGX52.H>
#include "StepMotor.h"
#include "Bluetooth.h"
#include "UART.h"
#include "DHT11.h"
#include "LCD1602.h"
//定义LED1管脚
sbit LED1=P2^0;
//定义蓝牙控制命令
#define LED1_ON_CMD 0X31 //手机发送1亮
#define LED1_OFF_CMD 0X30 //手机发送0灭
#define SM_START_CMD 0X32 //手机发送2电机运动
#define SM_STOP_CMD 0X33 //手机发送3电机停止
#define SM_REVERSE_CMD 0X34 //手机发送4电机反方向运动
#define SM_HS_CMD 0X35 //手机发送5电机加速
#define SM_LS_CMD 0X36 //手机发送6电机减速
//蓝牙控制初始化
void bluetooth_control_init(void)
{
UART_Init();
ES=1;//允许串口中断
}
//蓝牙控制
void bluetooth_control(void)
{
unsigned int i=0;
unsigned char temp,humi;
unsigned char bluetooth_send_buf[3];
while(1)
{
i++;
if(i%50==0)//间隔一段时间读取温度值,间隔时间要大于温度传感器转换温度时间
{
DHT11_ReadData(&temp,&humi);
LCD_ShowNum(1,7,temp,2);
LCD_ShowNum(2,7,humi,2);
bluetooth_send_buf[0]=temp/10;
bluetooth_send_buf[1]=temp%10;
UART_SendString(bluetooth_send_buf);
bluetooth_send_buf[0]=humi/10;
bluetooth_send_buf[1]=humi%10;
UART_SendString(bluetooth_send_buf);
}
}
}
//串口中断服务函数
//接收手机APP发送的信号后控制板载资源
void UART_IRQn() interrupt 4
{
if(RI)
{
RI=0;
UART_RX_BUF[0]=SBUF;//读取接收到的数据
//蓝牙控制
if(UART_RX_BUF[0]==LED1_ON_CMD)
{LED1=0;}
else if(UART_RX_BUF[0]==LED1_OFF_CMD)
{LED1=1;}
else if(UART_RX_BUF[0]==SM_START_CMD)
{StepMotor_Start();}
else if(UART_RX_BUF[0]==SM_STOP_CMD)
{StepMotor_Stop();}
else if(UART_RX_BUF[0]==SM_REVERSE_CMD)
{StepMotor_Reverse();}
else if(UART_RX_BUF[0]==SM_HS_CMD)
{StepMotor_HighSpeed();}
else if(UART_RX_BUF[0]==SM_LS_CMD)
{StepMotor_LowSpeed();}
}
}
//主函数
#include <REGX52.H>
#include "Bluetooth.h"
#include "LCD1602.h"
#include "StepMotor.h"
void main()
{
EA=0;
StepMotor_Init();
bluetooth_control_init();
LCD_Init();
LCD_ShowString(1,1,"Temp: C");
LCD_ShowString(2,1,"Humi: %RH");
EA=1;
while(1)
{
bluetooth_control();
StepMotor_Update();
}
}
写到这里呢,51单片机的内容就告一段落了。
之后打算学习stm32的相关内容
/
/
/
/
/
作者才开始在CSDN上分享学习内容,写的不好请多多包涵。
欢迎大家在评论区和作者讨论。
码字不易,求各位看官点个关注/赞/收藏,新人博主真的很需要助力~~
更多推荐
所有评论(0)