基于51单片机的智能无线LED灯控制 蓝牙手机APP控制灯亮灭亮度方案原理图设计

硬件电路的设计

(下方附文件)
系统的功能分析及体系结构设计
3.1.1系统功能分析
本设计由STC89C52单片机电路+8位LED灯电路+蓝牙模块电路+电源电路组成。
1、通过手机APP可以控制8路LED灯的亮灭。
2、通过手机APP可以控制8路LED灯的亮度。每个灯的亮度有3档。
3、可以发送指令控制8个灯全灭和全亮。
//蓝牙发送数据内容:
ON // 打开所有灯 大写字母’O’
SN // 关闭所有灯
Ax //一档打开 第x个灯 x为1-8中的一个数 如A2表示把led2灯打开的亮度为1挡
Bx //二档打开 第x个灯 x为1-8中的一个数 如A2表示把led2灯打开的亮度为2挡
Cx //三档打开 第x个灯 x为1-8中的一个数 如A2表示把led2灯打开的亮度为3挡
3.1.2系统总体结构
本系统具体框图如下图所示:
在这里插入图片描述
原理图:
在这里插入图片描述
STC89C52单片机核心系统电路设计
STC89C52RC是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K字节系统可编程Flash存储器。STC89C52使用经典的MCS-51内核,但是做了很多的改进使得芯片具有传统51单片机不具备的功能。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。具有以下标准功能:8k字节Flash,512字节RAM, 32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,3个16 位定时器/计数器,4个外部中断,一个7向量4级中断结构(兼容传统51的5向量2级中断结构),全双工串行口。另外 STC89C52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35MHz,6T/12T可选。

LED信号指示灯电路设计
LED灯即发光二极管,它是半导体二极管的一种,可以把电能转化成光能。发光二极管与普通二极管一样是由一个PN结组成,也具有单向导电性。在电路中,R_P1是单排阻,单排阻的作用是限流,保护LED灯。只要单片机的控制引脚拉低,则LED灯亮,否则,LED灯不亮。其具体电路原理图如下图所示。
在这里插入图片描述
JDY-30蓝牙模块电路设计
蓝牙模块是指集成蓝牙功能的芯片基本电路集合,用于无线网络通讯。本蓝牙模块就是为了只能无线数据传输而专门打造的,本模块支持串行接口,支持SP蓝牙串口协议,具有成本低、体积小、收发灵敏性高等特点,只需配备少许的外围元件就能实现大功能。
一、模块特点
(1)支持蓝牙 SPP 串口协议
(2)内置 PCB 天线
(3)支持 UART 接口
(4)蓝牙 Class 2
(5)数据传输比 BLE 蓝牙快、可达到 8K 每秒以上的速率
(6)支持与 SPP 主蓝牙模块连接通信(JDY-30 为从 SPP 蓝牙模块)
(7)支持与电脑 SPP 蓝牙通信
(8)支持 Android 手机 SPP 通信
二、产品应用范围
(1) POS 机
(2)蓝牙打印机
(3)蓝牙玩具
(4)蓝牙高速数据传输产品应用
(5)小家电
(6)汽车电子
三、模块技术参数
(1)工作电压:3.3V-6V
(2)工作温度:-40℃-85℃
(3)天线:PCB板载天线
(4)功耗:19mA
四、模块接口说明
(1)RXD 串口输入,电平为TTL电平
(2)TXD 串口输出,电平为TTL电平
(3)GND 接GND
(4)VCC 接3.3V-6V
蓝牙模块接口电路图如下图所示。
在这里插入图片描述

系统软件设计

在这里插入图片描述

#include <reg52.h> 
#include <intrins.h>
#include <stdio.h>
#include  <math.h>    //Keil library  
#include "delay.h"
//	操作方法
// 蓝牙发送字符 CX或cX 表示关闭x位灯, x取值1-8
// 蓝牙发送字符 OX或oX 表示关闭x位灯, x取值1-8
sbit LED1=P1^0;	  	//初始化led灯对应引脚
sbit LED2=P1^1;
sbit LED3=P1^2;
sbit LED4=P1^3;
sbit LED5=P1^4;
sbit LED6=P1^5;
sbit LED7=P1^6;
sbit LED8=P1^7;

#define INIT 0xFF	   //常量定义
#define OPEN 0x02
#define CLOSE 0x03
#define DAGN01 0x04
#define DAGN02 0x05
#define DAGN03 0x06

unsigned long times_5ms=0;		 	//定时器计数
unsigned char Commd_Flag=INIT;		//命令接受标识

unsigned char pwmLed01 = 3; //pwm调整参数
unsigned char pwmLed02 = 3; //pwm调整参数
unsigned char pwmLed03 = 3; //pwm调整参数
unsigned char pwmLed04 = 3; //pwm调整参数
unsigned char pwmLed05 = 3; //pwm调整参数
unsigned char pwmLed06 = 3; //pwm调整参数
unsigned char pwmLed07 = 3; //pwm调整参数
unsigned char pwmLed08 = 3; //pwm调整参数

unsigned char countLed01 = 0;//pwm计数 
unsigned char countLed02 = 0;//pwm计数
unsigned char countLed03 = 0;//pwm计数
unsigned char countLed04 = 0;//pwm计数
unsigned char countLed05 = 0;//pwm计数
unsigned char countLed06 = 0;//pwm计数
unsigned char countLed07 = 0;//pwm计数
unsigned char countLed08 = 0;//pwm计数

void Init_Timer0(void);				//函数声明
void UART_Init(void);
void SendByte(unsigned char dat);
void SendStr(unsigned char *s,unsigned char length);

void main (void)
{
	Init_Timer0();        //定时器0初始化
	UART_Init();		   //蓝牙 串口 波特率9600

	LED1=0;	
	LED2=0;		
	LED3=0;		
	LED4=0;			
	LED5=0;	
	LED6=0;		
	LED7=0;		
	LED8=0;

 	DelayMs(200); 
	LED1=1;	//关闭相应的灯 并恢复命令标志
	LED2=1;				
	LED3=1;				
	LED4=1;				
	LED5=1;	
	LED6=1;				
	LED7=1;		
	LED8=1;	

	DelayMs(10);          //延时有助于稳定

	P1=0x00;
	while(1)         //主循环
	{
			;//蓝牙的接收处理 均在中断中处理 请查看串口中断

		countLed01++;
		if(countLed01<pwmLed01)	   // 占空比调节
		{LED1=0;}			  //打开	
		else if(countLed01<=10)	//关闭时间段
		{
		 	LED1=1;			//关闭
			if(countLed01 == 10)	 countLed01=0;  //一个周期结束
		}

		countLed02++;
		if(countLed02<pwmLed02)	   //占空比调节
		{LED2=0;}			  //打开	
		else if(countLed02<=10)	//关闭时间段
		{
		 	LED2=2;			//关闭
			if(countLed02 == 10)	 countLed02=0;  //一个周期结束
		}

		countLed03++;
		if(countLed03<pwmLed03)	   //占空比调节
		{LED3=0;}			  //打开	
		else if(countLed03<=10)	//关闭时间段
		{
		 	LED3=1;			//关闭
			if(countLed03 == 10)	 countLed03=0;  //一个周期结束
		}


		countLed04++;
		if(countLed04<pwmLed04)	   //占空比调节
		{LED4=0;}			  //打开	
		else if(countLed04<=10)	//关闭时间段
		{
		 	LED4=1;			//关闭
			if(countLed04 == 10)	 countLed04=0;  //一个周期结束
		}


		countLed05++;
		if(countLed05<pwmLed05)	   //占空比调节
		{LED5=0;}			  //打开	
		else if(countLed05<=10)	//关闭时间段
		{
		 	LED5=1;			//关闭
			if(countLed05 == 10)	 countLed05=0;  //一个周期结束
		}

		countLed06++;
		if(countLed06<pwmLed06)	   //占空比调节
		{LED6=0;}			  //打开	
		else if(countLed06<=10)	//关闭时间段
		{
		 	LED6=1;			//关闭
			if(countLed06 == 10)	 countLed06=0;  //一个周期结束
		}

		countLed07++;
		if(countLed07<pwmLed07)	   // 占空比调节
		{LED7=0;}			  //打开	
		else if(countLed07<=10)	//关闭时间段
		{
		 	LED7=1;			//关闭
			if(countLed07 == 10)	 countLed07=0;  //一个周期结束
		}

		countLed08++;
		if(countLed08<pwmLed08)	   // 占空比调节
		{LED8=0;}			  //打开	
		else if(countLed08<=10)	//关闭时间段
		{
		 	LED8=1;			//关闭
			if(countLed08 == 10)	 countLed08=0;  //一个周期结束
		}

	}
}

void Init_Timer0(void)
{
	TMOD |= 0x01;	  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响		     
	TH0=(65536-10000)/256;		  //重新赋值 20ms
	TL0=(65536-10000)%256;
	EA=1;            //总中断打开
	ET0=1;           //定时器中断打开
	TR0=1;           //定时器开关打开
}
void UART_Init(void)
{
    SCON  = 0x50;		        // SCON: 模式 1, 8-bit UART, 使能接收  
    TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装
    TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz
	TL1 = TH1;  
    TR1   = 1;                  // TR1:  timer 1 打开                         
    EA    = 1;                  //打开总中断
    ES    = 1;                  //打开串口中断
} 

void Timer0_isr(void) interrupt 1 
{
	TH0=(65536-5000)/256;		  //重新赋值 5ms
	TL0=(65536-5000)%256;
	times_5ms++;

}

void UART_SER (void) interrupt 4 	//串行中断服务程序
{
	unsigned char R_buf;
	if(RI)                        //判断是接收中断产生
	{
		RI=0;                      //标志位清零
		R_buf=SBUF;
		if((R_buf=='O')||(R_buf=='o'))
		{
			Commd_Flag=OPEN;	//接收到打开灯标志
		}
		else if((R_buf=='S')||(R_buf=='s'))
		{
			Commd_Flag=CLOSE;	//接收到 关闭灯标志
		}
		else if((R_buf=='A')||(R_buf=='a'))
		{				  
			Commd_Flag=DAGN01;	//接收到 关闭灯标志
		}
		else if((R_buf=='B')||(R_buf=='b'))
		{
			Commd_Flag=DAGN02;	//接收到 关闭灯标志
		}
		else if((R_buf=='C')||(R_buf=='c'))
		{
			Commd_Flag=DAGN03;	//接收到 关闭灯标志
		}
		else if((R_buf!='1')&&(R_buf!='2')&&(R_buf!='3')&&(R_buf!='4')&&(R_buf!='5')&&(R_buf!='6')&&(R_buf!='7')&&(R_buf!='8')&&(R_buf!='N'))
		{
			Commd_Flag=INIT;	 //否则 初始化接受标志
		}

		if((Commd_Flag==OPEN)||(Commd_Flag==DAGN01))			//根据命令值进行打开相应的灯
		{
			switch(R_buf)
			{
				case '1':pwmLed01=3;Commd_Flag=INIT;break;	//打开相应的灯 并恢复命令标志
				case '2':pwmLed02=3;Commd_Flag=INIT;break;			
				case '3':pwmLed03=3;Commd_Flag=INIT;break;			
				case '4':pwmLed04=3;Commd_Flag=INIT;break;			
				case '5':pwmLed05=3;Commd_Flag=INIT;break;	
				case '6':pwmLed06=3;Commd_Flag=INIT;break;			
				case '7':pwmLed07=3;Commd_Flag=INIT;break;			
				case '8':pwmLed08=3;Commd_Flag=INIT;break;
				case 'N':pwmLed01=3;pwmLed02=3;pwmLed03=3;pwmLed04=3;pwmLed05=3;pwmLed06=3;pwmLed07=3;pwmLed08=3;Commd_Flag=INIT;break;
				default:break;						 //此处错误判断 不可恢复命令标准
			}
		}
else if(Commd_Flag==CLOSE)//根据命令值进行关闭相应的灯
		{
			switch(R_buf)
			{
				case '1':pwmLed01=1;Commd_Flag=INIT;break;	//打开相应的灯 并恢复命令标志
				case '2':pwmLed02=1;Commd_Flag=INIT;break;			
				case '3':pwmLed03=1;Commd_Flag=INIT;break;			
				case '4':pwmLed04=1;Commd_Flag=INIT;break;			
				case '5':pwmLed05=1;Commd_Flag=INIT;break;	
				case '6':pwmLed06=1;Commd_Flag=INIT;break;			
				case '7':pwmLed07=1;Commd_Flag=INIT;break;			
				case '8':pwmLed08=1;Commd_Flag=INIT;break;
				case 'N':pwmLed01=1;pwmLed02=1;pwmLed03=1;pwmLed04=1;pwmLed05=1;pwmLed06=1;pwmLed07=1;pwmLed08=1;Commd_Flag=INIT;break;
				default:break;						 //此处错误判断 不可恢复命令标准
			}
		}
		else if(Commd_Flag==DAGN02)//根据命令值进行关闭相应的灯
		{
			switch(R_buf)
			{
				case '1':pwmLed01=6;Commd_Flag=INIT;break;	//打开相应的灯 并恢复命令标志
				case '2':pwmLed02=6;Commd_Flag=INIT;break;			
				case '3':pwmLed03=6;Commd_Flag=INIT;break;			
				case '4':pwmLed04=6;Commd_Flag=INIT;break;			
				case '5':pwmLed05=6;Commd_Flag=INIT;break;	
				case '6':pwmLed06=6;Commd_Flag=INIT;break;			
				case '7':pwmLed07=6;Commd_Flag=INIT;break;			
				case '8':pwmLed08=6;Commd_Flag=INIT;break;				
				default:break;						 //此处错误判断 不可恢复命令标准
			}
		}
		else if(Commd_Flag==DAGN03)//根据命令值进行关闭相应的灯
		{
			switch(R_buf)
			{
				case '1':pwmLed01=9;Commd_Flag=INIT;break;	//打开相应的灯 并恢复命令标志
				case '2':pwmLed02=9;Commd_Flag=INIT;break;			
				case '3':pwmLed03=9;Commd_Flag=INIT;break;			
				case '4':pwmLed04=9;Commd_Flag=INIT;break;			
				case '5':pwmLed05=9;Commd_Flag=INIT;break;	
				case '6':pwmLed06=9;Commd_Flag=INIT;break;			
				case '7':pwmLed07=9;Commd_Flag=INIT;break;			
				case '8':pwmLed08=9;Commd_Flag=INIT;break;				
				default:break;						 //此处错误判断 不可恢复命令标准
			}
		}

		SBUF=R_buf;				   //返回接收到的数据
	}
	if(TI)  //如果是发送标志位,清零
	TI=0;
} 


.

链接:https://pan.baidu.com/s/1sFb6z-PEftuB7srQjIs6gQ
提取码:92cq

.

  • 25
    点赞
  • 214
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值