STM32
直播中

钱一辰

7年用户 920经验值
私信 关注
[问答]

怎样去设计一个基于51单片机的简易智能家居系统呢

怎样去设计一个基于51单片机的简易智能家居系统呢?
基于51单片机的简易智能家居系统是由哪些部分组成的呢?

回帖(1)

李刚

2021-12-22 14:36:13
前言


在大一就学了单片机(大二才有的课程),也没有C语言这课程,我也是学了一点皮毛基础的语法。学完8位的单片机(STC89C51)后就学了32位的单片机(STM32F103ZET6),学了两年多的单片机,感谢和我一起参加比赛的队友,也很感谢我的老师对我的指导才有今天的小成就,自己也能做些小项目。今天给大家分享一个我自己设计的单片机小项目(软硬件结合),学会用这程序你自己做个控制智能小车是没问题的,希望对大家有帮助!
提示:本次博主主要介绍主要代码和所控制实现的功能,也希望对大家有帮助,有什么好的意见或者建议,能告诉博主将会十分感激。
  一、项目简介

该项目可以通过手机app连接单片机的蓝牙模块,控制实现单片机上的绿灯、黄灯的亮灭(类似于打开一楼的灯或是二楼的灯及控制灯的颜色),直流电机的开启与关闭(类似于打开风扇与关闭风扇),步进电机的正转与反转(类似于打开窗帘与闭关窗帘),数码管一直显示检测到的温度,如温度>=25°,直流电机自动开启转动,如温度>=60°,蜂鸣器会产生报警且红灯闪烁。如果火焰传感器检测到火焰,蜂鸣器也会产生报警且红灯闪烁,可控制蜂鸣器播放生日快乐、报警及关闭,单片机上两侧装有水银开关报警模块,如有谁轻微抬起单片机(达到防盗的作用),单片机上的蜂鸣器立即报警并且红灯闪烁。
提示:(如温度>=25°让直流电机自动转动,这里的25°可在程序中修改到一定的温度就会转动,温度>=60°也是一样的可修改,属于高温现象就产生报警)
二、开发环境/工具:

1.Keil 5/Keil 4

Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统。官网下载Keil的安装包.


2.STC-ISP

stc-isp是一款针对单片机所制作的相关烧录软件,通过这款STC单片机烧录工具,就能快速将用户的程序代码与相关的选项设置打包成为一个可以直接对目标芯片进行下载编程可执行文件(当然电脑也要装上ch340串口驱动)。官网下载STC-ISP软件(STC官网).

3.蓝牙串口助手

我用的蓝牙模块型号是HC-08,蓝牙模块可以通过串口和MCU控制设备进行数据传输。蓝牙模块可以做为主机和从机,主机就是能够搜索别的蓝牙模块并主动建立连接,从机则不能主动建立连接,如两个蓝牙配置连接成功后接可以进行无线数据透传。官网下载蓝牙模块资料包.
软件图标:





1.测试模块:用串口调试助手发送AT,如果收到OK,证明你的蓝牙模块没问题。
2.模块串口的波特率:因为单片机的波特率设置不了这么大,我就用默认为9600即可。
4.手机app

1.Android手机连接透传数据
(1)下载安装安卓手机串口测试软件,安装包官网资料(HC官网).
(2)打开手机蓝牙,打开刚才下载的BLE串口软件,搜索连接HC-08 (无需配对密码),连接成功,模块指示灯长亮,就可以进行数据透传了。





2.iPhone手机连接透传数据
(1)在App Store下载安装BLE串口软件,推荐两个亲测好用的APP“light-Blue"和“蓝牙助手”
(2)打开手机蓝牙,打开刚才下载的BL E串口软件,搜索连接HC-08 (无需配对密码),连接成功,模块指示灯长亮。软件界面下拉,点击UUID: FFEO,就到了数据界面,可以进行数据透传了。
温馨提示:BLE蓝牙模块,必须用BLE的串口软件才能连接,不能用手机自带蓝牙连接。且连接无需配对密码,也不能设置配对密码(这是手机自带的蓝牙协议决定的,非产品原因,市面上所有的BLE蓝牙模块都是这样,这也是BLE蓝牙模块的特性)。
三、硬件设计:

1.单片机与蓝牙模块连接


  单片机 - 蓝牙模块
TXD - RXD
RXD - TXD
VCC - VCC
GND - GND
2.单片机与火焰传感器模块连接


  单片机 - 火焰传感器模块
***it Flame = P2^0; //火焰
3.单片机与水银开关报警模块连接


  单片机 - 火焰传感器模块
***it Mercury1_Left = P2^1; //水银开关报警----左侧
***it Mercury2_Right = P2^2; //水银开关报警----右侧
四、程序设计:

1.头文件


/*********************************** 单片机原理及其应用 *********************************
* 实 验 名 :简易智能家居
* 实验平台 :51单片机开发板
* 设 计 者 :小枫
****************************************************************************************/
#include         //单片机头文件
#include "main.h"        //将宏定义、定义全局变量的值、函数声明放入main.h文件
#include "delay.h"        //包含延时头文件
#include "usart.h"        //包含串口通信头文件
#include "ds18b20.h"//包含温度传感器头文件
2.主函数程序


void main(void)
{
        int count = 0;        //定义局部变量
        Motor=0;        //上电后直流电机停止转动(风扇停止转动)
        Beep=0;          //上电后关闭蜂鸣器
        Wela_1 = 1;          //打开数码管共阳端
    Wela_2 = 1;
        UsartConfiguration();//初始化串口
        Read_RomCord();                          //读取64位序列码
        while(1)        //循环
        {
                if(count >= 1)
                {
                        temperature = Read_Temperature();        //读取温度
                        count = 0;
                }
                LEDdisplay(temperature);        //数码管显示温度
                count++;
               
                if(temperature>=25)        //如果温度大于等于25°
                {
                        Motor=1;        //直流电机转动
                }
                else        //否则
                {
                        Motor=0;        //直流电机停止
                }
                if(temperature>=60)        //如果温度大于等于60°,属于高温现象
                {
                        Led1_Red=0;        //红灯亮
                        Led2_Red=0;        //红灯亮
                        Beep=1;                        //打开蜂鸣器
                        Delay_ms(100);        //延迟100ms
                        Beep=0;                        //关闭蜂鸣器
                        Led1_Red=1;        //红灯灭
                        Led2_Red=1;        //红灯灭
                        Delay_ms(100);        //延迟100ms       
                }
                else        //否则
                {
                        Led1_Red=1;        //红灯灭
                        Led2_Red=1;        //红灯灭
                        Beep=0;                        //关闭蜂鸣器
                }
                if(Flame==1)        //如果火焰传感器检测到火焰
                {
                        Led2_Red=0;        //红灯亮
                        Beep=1;                        //打开蜂鸣器
                        Delay_ms(100);        //延迟100ms
                        Beep=1;                        //关闭蜂鸣器
                        Led2_Red=1;        //红灯灭
                        Delay_ms(100);        //延迟100ms
                }
                else        //否则
                {
                        Beep=0;                        //关闭蜂鸣器
                        Led2_Red=0;        //红灯灭
                }
                if(Mercury1_Left==0)        //如果有人抬起单片机的左边
                {
                        Led7_Red=0;        //红灯亮
                        Beep=1;                        //打开蜂鸣器
                        Delay_ms(300);        //延迟300ms
                        Led7_Red=1;        //红灯灭
                        Beep=0;                        //关闭蜂鸣器
                        Delay_ms(300);               
                }
                else        //否则
                {
                        Led7_Red=1;        //红灯灭
                        Beep=0;                        //关闭蜂鸣器
                }
                if(Mercury2_Right==0)
                {
                        Led8_Red=0;        //红灯灭
                        Beep=1;                        //打开蜂鸣器
                        Delay_ms(300);        //延迟300ms
                        Led8_Red=1;        //红灯灭
                        Beep=0;                        //关闭蜂鸣器
                        Delay_ms(300);        //延迟300ms               
                }
                else        //否则
                {
                        Beep=0;                        //关闭蜂鸣器
                        Led8_Red=1;        //红灯灭
                }               
        }
}
3.中断服务函数程序


void Com_Int(void) interrupt 4
{
  uchar i;        //定义局部变量 i
  uchar receive_data;        //定义局部变量
       
  EA = 0;        //关闭定时器总开关
       
  if(RI == 1) //当硬件接收到一个数据时,RI会置位
        {                
                RI = 0;        //清零
                receive_data = SBUF;//接收到的数据
                #if 0               
                if(receive_data == '1')         
                {
                        LED=0x00;        //LED全亮
                }
                else
                {
                        LED=0xff;        //LED全灭
                }
                #else               
                 switch (receive_data)        //switch选择
                 {
                                                 case '1':       
                                                   Led5_Yellow=0; //开灯
                                                   Led6_Yellow=0;
                                                   Led3_Green=0;
                                                   Led4_Green=0;
                                                 break;
                                                 
                                                 case '2':
                                                   Led5_Yellow=1; //关灯
                                                   Led6_Yellow=1;
                                                   Led3_Green=1;
                                                   Led4_Green=1;
                                                   MotorStop();
                                                   LED_PORT=0xff;
                                                 break;
                                                 
                                                 case '3':
                                                   Led_Display();//数码管9秒倒计时显示
                                                 break;
                                                 
                                                 case '4':
                                                   PlayMusic(); //播放生日快乐音乐
                                                 break;
                                                 
                                                 case '5':
                                                   Led3_Green=0; //开绿灯
                                                   Led4_Green=0;
                                                 break;
                                                 
                                                 case '6':
                                                   Led3_Green=1; //关绿灯
                                                   Led4_Green=1;
                                                 break;
                                                 
                                                 case '7':
                                                   Buzzer_Alarm(); //打开报警
                                                 break;
                                                 
                                                 case '8':
                                                   Beep=0; //关闭报警
                                                 break;
                                                 
                                                  case '9':
                                                   Led5_Yellow=0; //开黄灯
                                                   Led6_Yellow=0;
                                                 break;
                                                 
                                                 case 'a':
                                                   Led5_Yellow=1; //关黄灯
                                                   Led6_Yellow=1;
                                                 break;
                                                 
                                                 case 'b':
                                                   MotorCW(); //步进电机正转90°
                                                 break;
                                                 
                                                 case 'c':
                                                   MotorCCW(); //步进电机反转90°
                                                 break;
                                                 
                                                 case 'd':
                                                   Motor=1;        //打开风扇
                                                 break;
                                                 
                                                 case 'e':
                                                   Motor=0;        //关闭风扇
                                                 break;
                               
                                                case 'f':        //未定义
                                                       
                                                 break;
                                                 
                                                 case '0':        //未定义
                                                  
                                                 break;
                                                 
                                                 default : break;        //默认:返回
                 }               
                #endif
        }
               
                for(i=0; i<2; i++)
                {
                        SBUF = PuZh;           //将要发送的数据放入到发送寄存器
                        while(!TI);                    //等待发送数据完成
                        TI=0;                            //清除发送完成标志位
                        Delay_ms(1);                //延时1ms
                }
                EA = 1;                                //打开定时器总开关
}
4.串口驱动程序


#include "usart.h"


/*******************************************************************************
* 函 数 名        : UsartConfiguration()
* 函数功能                 : 设置串口
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/
void UsartConfiguration(void)
{       
        SCON=0X50;                        //设置为工作方式1,8位数据,可变波特率
        TMOD=0X20;                        //设置计数器工作方式2
        PCON=0X00;                        //波特率不加倍
        TH1=0XFd;                    //计数器初始值设置,9600@11.0592MHz
        TL1=0XFd;
        TR1=1;                                        //打开计数器
        ES = 1;         //开串口中断
          EA = 1;         //开总中断
}
5.温度DS18B20程序


#include "ds18b20.h"


unsigned char RomCode[8];


/*******************************************************************/
/*                                                                 */
/*us级延时函数                                                     */
/*                                                                 */
/*******************************************************************/


void Delay(unsigned int num)
{
  while( --num );
}


/*******************************************************************/
/*                                                                 */
/*初始化ds1820                                                     */
/*                                                                 */
/*******************************************************************/
bit Init_DS18B20(void)
{
                bit presence;
     DQ = 1;      //DQ复位
     Delay(8);    //稍做延时


     DQ = 0;      //单片机将DQ拉低
     Delay(90);   //精确延时 大于 480us


     DQ = 1;       //拉高总线
     Delay(8);


     presence = DQ;    //如果=0则初始化成功 =1则初始化失败
     Delay(100);
     DQ = 1;
     
     return(presence); //返回信号,0=presence,1= no presence
}


/*******************************************************************/
/*                                                                 */
/* 读一个字节                                                      */
/*                                                                 */
/*******************************************************************/
unsigned char ReadOneChar(void)
{
   unsigned char i = 0;
   unsigned char dat = 0;


   for (i = 8; i > 0; i--)
   {
     DQ = 0; // 给脉冲信号
     dat >>= 1;
     DQ = 1; // 给脉冲信号


     if(DQ)
     dat |= 0x80;
     Delay(4);
   }
    return (dat);
}


/*******************************************************************/
/*                                                                 */
/* 写一个字节                                                      */
/*                                                                 */
/*******************************************************************/
void  WriteOneChar(unsigned char dat)
{
  unsigned char i = 0;
  for (i = 8; i > 0; i--)
  {
    DQ = 0;
    DQ = dat&0x01;
    Delay(5);


    DQ = 1;
    dat>>=1;
  }
}


/*******************************************************************/
/*                                                                 */
/* 读取64位序列码                                                  */
/*                                                                 */
/*******************************************************************/
void Read_RomCord(void)
{
   unsigned char j;
   Init_DS18B20();
  
   WriteOneChar(0x33);          // 读序列码的操作
   for (j = 0; j < 8; j++)
   {
     RomCode[j] = ReadOneChar() ;
   }
}


/*******************************************************************/
/*                                                                 */
/* 读取温度                                                        */
/*                                                                 */
/*******************************************************************/
unsigned char Read_Temperature(void)
{
        unsigned char  i;
        unsigned char temp_comp;       
        unsigned char temp_data[2];
        unsigned char temp_alarm[2];
        Init_DS18B20();


        WriteOneChar(0xCC);        //跳过读序号列号的操作
        WriteOneChar(0x44);        //启动温度转换


        Init_DS18B20();


        WriteOneChar(0x55);         //匹配ROM命令
        for(i=0;i<8;i++)
        WriteOneChar(RomCode);


        WriteOneChar(0xBE);         //读取温度寄存器


        temp_data[0] = ReadOneChar();   //温度低8位
        temp_data[1] = ReadOneChar();   //温度高8位
        temp_alarm[0] = ReadOneChar();  //温度报警TH
        temp_alarm[1] = ReadOneChar();  //温度报警TL


        temp_comp=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//取温度整数值
        return temp_comp;                                                                                                                   
}

  总结

做这个小项目有的模块之前我也没有接触过,在遇到不懂的地方自己百度学习或是问我的小伙伴,因为我的小伙伴他硬件这方面比较懂,然后对于这款型号HC-08蓝牙模块个人感觉很不错,用这两个相同的蓝牙模块,用蓝牙测试架与电脑连接,打开蓝牙串口助手软件将一个蓝牙模块一键设置为主机,另一个一键设置为从机,然后两个蓝牙模块之间就可以就行通信了,相比对于其它型号的蓝牙模块配置为主机、从机简单多了,只有通过自己亲手去实践操作,才会有收获。
坚持不一定成功,但放弃就一定失败!
举报

更多回帖

×
20
完善资料,
赚取积分