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上分享学习内容,写的不好请多多包涵。
欢迎大家在评论区和作者讨论。
码字不易,求各位看官点个关注/赞/收藏,新人博主真的很需要助力~~

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐