1. 项目介绍
随着空调降温设备的频繁使用,全球气候不断变暖空调降温设备排放出的物质对环境的影响越来越大。二是人们在熟睡之后经常因为温度太低而感冒或者温度升高而不适,风扇相比空调更加适用于老人儿童和体质较弱的人使用。 通过物联网技术的智能风扇设计可以解决因为睡熟导致降温设备依旧运行工作,实现更加节能更加智能的控制。
通过温度传感器对环境温度进行数据采集和语音控制模块来调节风速实现对风扇的智能控制,使风扇随温度变化来自动调节风力大小。
具体实现功能如下:
- 实现语音控制,可以识别到语音命令并自动做出相应的工作;
- 实现温度实时监测;
- 实现通过实时温度来自动控制风扇转速;
- 实现通电后可以进行风扇的开光和转数调节:
实现思路:
采用DHT11温湿度传感器,采集环境温度,根据设置的温度阀值与采集的环境温度做对比,控制风扇的开关,也可以通过语音识别模块检测语音完成语音控制。
实现的功能总结如下:
- 按下开发板上的按键控制风扇的开关(LED灯的开关)
- 通过语音控制风扇的开关(LED灯的开关) 语音由语音模块进行识别。
- 在主函数里每500ms采集一次DHT11温度,然后通过OLED显示屏显示。
完整项目源码下载地址: 基于CC2530设计的智能风扇.zip-嵌入式文档类资源-CSDN下载
2. 硬件介绍
2.1 OLED显示屏
OLED采用0.96寸的SPI接口显示屏。分辨率是128x64.
代码语言:javascript复制具体接线如下:
#define LCD_SCL P1_2 //SCLK 时钟 D0(SCLK)
#define LCD_SDA P1_3 //SDA D1(MOSI) 数据
#define LCD_RST P1_7 //_RES hardware reset 复位
#define LCD_DC P0_0 //A0 H/L 命令数据选通端,H:数据,L:命令
VCC接3.3V
GND接GND
2.2 DHT11温湿度传感器
DHT11是单总线数字温湿度传感器,电压兼容3v~5v,单片机可以直接IO口连接模拟时序完成数据读取。
具体接线如下:
代码语言:javascript复制DATA接在P0_7口
VCC接3.3V
GND接GND
2.3 语音模块
语音模块采用LD3320芯片进行识别,可以设置内部识别的词条,支持二次开发编程。
默认内置的识别词条如下:
下面是语音识别模块的实物图:
3. 案例代码
3.1 语音识别模块代码
代码语言:javascript复制/*******************************************************
** CPU: STC11L08XE
** 晶振:22.1184MHZ
** 波特率:9600 bit/S
** 口令模式: 即每次识别时都需要说“小杰”这个口令 ,才能够进行下一级的识别
/*********************************************************/
#include "config.h"
/************************************************************************************/
// nAsrStatus 用来在main主程序中表示程序运行的状态,不是LD3320芯片内部的状态寄存器
// LD_ASR_NONE: 表示没有在作ASR识别
// LD_ASR_RUNING: 表示LD3320正在作ASR识别中
// LD_ASR_FOUNDOK: 表示一次识别流程结束后,有一个识别结果
// LD_ASR_FOUNDZERO: 表示一次识别流程结束后,没有识别结果
// LD_ASR_ERROR: 表示一次识别流程中LD3320芯片内部出现不正确的状态
/***********************************************************************************/
uint8 idata nAsrStatus = 0;
void MCU_init();
void ProcessInt0(); //识别处理函数
void delay(unsigned long uldata);
void User_handle(uint8 dat);//用户执行操作函数
void Delay200ms();
void Led_test(void);//单片机工作指示
uint8_t G0_flag = DISABLE; //运行标志,ENABLE:运行。DISABLE:禁止运行
sbit LED = P4 ^ 2; //信号指示灯
sbit SRD1 = P1 ^ 7;
sbit SRD2 = P1 ^ 6;
sbit SRD3 = P1 ^ 5;
sbit SRD4 = P1 ^ 4;
/***********************************************************
* 名 称: void main(void)
* 功 能: 主函数 程序入口
* 入口参数:
* 出口参数:
* 说 明:
* 调用方法:
**********************************************************/
void main(void)
{
uint8 idata nAsrRes;
uint8 i = 0;
P1M0 = 0xFF;
P1M1 = 0x00;
SRD1 = SRD2 = SRD3 = SRD4 = 0;
Led_test();
MCU_init();
LD_Reset();
UartIni(); /*串口初始化*/
nAsrStatus = LD_ASR_NONE; // 初始状态:没有在作ASR
PrintCom("<G>欢迎使用");
while(1)
{
switch(nAsrStatus)
{
case LD_ASR_RUNING:
case LD_ASR_ERROR:
break;
case LD_ASR_NONE:
{
nAsrStatus = LD_ASR_RUNING;
if (RunASR() == 0) /* 启动一次ASR识别流程:ASR初始化,ASR添加关键词语,启动ASR运算*/
{
nAsrStatus = LD_ASR_ERROR;
}
break;
}
case LD_ASR_FOUNDOK: /* 一次ASR识别流程结束,去取ASR识别结果*/
{
nAsrRes = LD_GetResult(); /*获取结果*/
User_handle(nAsrRes);//用户执行函数
nAsrStatus = LD_ASR_NONE;
break;
}
case LD_ASR_FOUNDZERO:
default:
{
nAsrStatus = LD_ASR_NONE;
break;
}
}// switch
}// while
}
/***********************************************************
* 名 称: LED灯测试
* 功 能: 单片机是否工作指示
* 入口参数: 无
* 出口参数:无
* 说 明:
**********************************************************/
void Led_test(void)
{
LED = ~ LED;
Delay200ms();
LED = ~ LED;
Delay200ms();
LED = ~ LED;
Delay200ms();
LED = ~ LED;
Delay200ms();
LED = ~ LED;
Delay200ms();
LED = ~ LED;
}
/***********************************************************
* 名 称: void MCU_init()
* 功 能: 单片机初始化
* 入口参数:
* 出口参数:
* 说 明:
* 调用方法:
**********************************************************/
void MCU_init()
{
P0 = 0xff;
P1 = 0x00;
P2 = 0xff;
P3 = 0xff;
P4 = 0xff;
AUXR &= 0x7F; //定时器时钟12T模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x28; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
LD_MODE = 0; // 设置MD管脚为低,并行模式读写
IE0 = 1;
EX0 = 1;
EA = 1;
WDT_CONTR = 0x3D;
}
/***********************************************************
* 名 称: 延时函数
* 功 能:
* 入口参数:
* 出口参数:
* 说 明:
* 调用方法:
**********************************************************/
void Delay200us() //@22.1184MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 5;
j = 73;
do
{
while (--j);
}
while (--i);
}
void delay(unsigned long uldata)
{
unsigned int j = 0;
unsigned int g = 0;
while(uldata--)
Delay200us();
}
void Delay200ms() //@22.1184MHz
{
unsigned char i, j, k;
i = 17;
j = 208;
k = 27;
do
{
do
{
while (--k);
}
while (--j);
}
while (--i);
}
/***********************************************************
* 名 称: 中断处理函数
* 功 能:
* 入口参数:
* 出口参数:
* 说 明:
* 调用方法:
**********************************************************/
void ExtInt0Handler(void) interrupt 0
{
ProcessInt0();
}
/***********************************************************
* 名 称:用户执行函数
* 功 能:识别成功后,执行动作可在此进行修改
* 入口参数: 无
* 出口参数:无
* 说 明:
**********************************************************/
void User_handle(uint8 dat)
{
if(0 == dat)
{
G0_flag = ENABLE;
PrintCom("<G>你好,主人");
LED = 0;
}
else if(ENABLE == G0_flag)
{
G0_flag = DISABLE;
LED = 1;
switch(dat)
{
case CODE_1: /*命令“开灯”*/
SRD1 = 1;
PrintCom("<G>灯已打开");
break;
case CODE_2: /*命令“关灯”*/
SRD1 = 0;
PrintCom("<G>灯已关闭rn");
break;
case CODE_3: /*命令“打开电视”*/
SRD2 = 1;
PrintCom("<G>电视机已打开rn");
break;
case CODE_4: /*命令“关闭电视”*/
SRD2 = 0;
PrintCom("<G>电视机已关闭rn");
break;
case CODE_5: /*命令“打开冰箱”*/
SRD3 = 1;
PrintCom("<G>冰箱已打开rn");
break;
case CODE_6: /*命令“关闭冰箱”*/
SRD3 = 0;
PrintCom("<G>冰箱已关闭rn");
break;
case CODE_7: /*命令“打开空调”*/
SRD4 = 1;
PrintCom("<G>空条已打开rn");
break;
case CODE_8: /*命令“关闭空调”*/
SRD4 = 0;
PrintCom("<G>空条已关闭rn");
break;
case CODE_9: /*命令“全部打开”*/
SRD1 = 1;
SRD2 = 1;
SRD3 = 1;
SRD4 = 1;
PrintCom("<G>已全部打开rn");
break;
case CODE_10: /*命令“全部关闭”*/
SRD1 = 0;
SRD2 = 0;
SRD3 = 0;
SRD4 = 0;
PrintCom("<G>已全部关闭rn");
break;
case CODE_11: /*命令“.....”*/
PrintCom("");
break;
case CODE_12: /*命令“.....”*/
PrintCom("");
break;
case CODE_13: /*命令“.....”*/
PrintCom("");
break;
case CODE_14: /*命令“.....”*/
PrintCom("");
break;
case CODE_15: /*命令“.....”*/
PrintCom("");
break;
case CODE_16: /*命令“.....”*/
PrintCom("");
break;
case CODE_17: /*命令“.....”*/
PrintCom("");
break;
case CODE_18: /*命令“.....”*/
PrintCom("");
break;
case CODE_19: /*命令“.....”*/
PrintCom("");
break;
case CODE_20: /*命令“.....”*/
PrintCom("");
break;
case CODE_21: /*命令“.....”*/
PrintCom("");
break;
case CODE_22: /*命令“.....”*/
PrintCom("");
break;
case CODE_23: /*命令“.....”*/
PrintCom("");
break;
case CODE_24: /*命令“.....”*/
PrintCom("");
break;
case CODE_25: /*命令“.....”*/
PrintCom("");
break;
case CODE_26: /*命令“.....”*/
PrintCom("");
break;
case CODE_27: /*命令“.....”*/
PrintCom("");
break;
case CODE_28: /*命令“.....”*/
PrintCom("");
break;
case CODE_29: /*命令“.....”*/
PrintCom("");
break;
case CODE_30: /*命令“.....”*/
PrintCom("");
break;
case CODE_31: /*命令“.....”*/
PrintCom("");
break;
case CODE_32: /*命令“.....”*/
PrintCom("");
break;
case CODE_33: /*命令“.....”*/
PrintCom("");
break;
case CODE_34: /*命令“.....”*/
PrintCom("");
break;
case CODE_35: /*命令“.....”*/
PrintCom("");
break;
case CODE_36: /*命令“.....”*/
PrintCom("");
break;
case CODE_37: /*命令“.....”*/
PrintCom("");
break;
case CODE_38: /*命令“.....”*/
PrintCom("");
break;
case CODE_39: /*命令“.....”*/
PrintCom("");
break;
case CODE_40: /*命令“.....”*/
PrintCom("");
break;
case CODE_41: /*命令“.....”*/
PrintCom("");
break;
case CODE_42: /*命令“.....”*/
PrintCom("");
break;
case CODE_43: /*命令“.....”*/
PrintCom("");
break;
case CODE_44: /*命令“.....”*/
PrintCom("");
break;
case CODE_45: /*命令“.....”*/
PrintCom("");
break;
case CODE_46: /*命令“.....”*/
PrintCom("");
break;
case CODE_47: /*命令“.....”*/
PrintCom("");
break;
case CODE_48: /*命令“.....”*/
PrintCom("");
break;
case CODE_49: /*命令“.....”*/
PrintCom("");
break;
default:/*text.....*/
break;
}
}
else
{
//PrintCom("请说出一级口令rn"); /*text.....*/
}
}
void tm0_isr() interrupt 1
{
TL0 = 0x00; //设置定时初值
TH0 = 0x28; //设置定时初值
WDT_CONTR=0x3D;
}
3.2 cc2530串口代码
代码语言:javascript复制#include "uart.h"
/*
函数功能:串口0初始化
*/
void Init_Uart0(void)
{
PERCFG&=~(1<<0); //串口0的引脚映射到位置1,即P0_2和P0_3
P0SEL|=0x3<<2; //将P0_2和P0_3端口设置成外设功能
U0BAUD = 216; //32MHz的系统时钟产生115200BPS的波特率
U0GCR&=~(0x1F<<0);//清空波特率指数
U0GCR|=11<<0; //32MHz的系统时钟产生115200BPS的波特率
U0UCR |= 0x80; //禁止流控,8位数据,清除缓冲器
U0CSR |= 0x3<<6; //选择UART模式,使能接收器
}
/*
函数功能:UART0发送字符串函数
*/
void UR0SendString(char *str)
{
while(*str!='