时间:2017年12月

阶段:大二上学期

背景:单片机原理与应用课设

名称:智能灯控

摘要

本系统实现了多方式控灯功能,有按键控灯、串口指令控灯、点对点无线射频控灯、AI模式控灯。其中AI模式控灯是通过红外模块感应外界是否有人靠近来控制灯的亮灭及通过光敏传感器模块感应外界光照强度进而动态调整PWM占空比的输出来控制灯的亮度。

物联网是新一代信息技术的重要组成部分,也是“信息化”时代的重要发展阶段。互联网是物联网个过渡,物联网将成为新时代的发展灵魂。

处于AI时代来临前的我深感可庆,传统的灯控需要大量的布线,若要实现双控、三控及多控更是需要加大用线量,且开关还需要特别定制,及其麻烦,对于远程控制更是不敢想象。

我们将要设计并打造出一款基于ZigBee模块,多传感器,多方式开关,远程智能控制的灯控系统,达到智能照明的节能、环保、舒适、方便的功能。

关键词  物联网;智能;控制;LED灯

前言

1.1 系统研究背景

传统的灯控需要大量的布线,若要实现双控、三控及多控更是需要加大用线量,且开关还需要特别定制,及其麻烦,对于远程控制更是不敢想象。

1.2 系统研究的意义和目的

设计并打造出一款基于ZigBee模块,多传感器,多方式开关,远程智能控制的灯控系统,达到智能照明的节能、环保、舒适、方便的功能。

系统概述

2.1 系统的结构

本系统有软件和硬件两部分组成。

软件部分:串口调试助手,控制灯的亮灭、打开和关闭AI模式和实时监测灯的变化情况和日志

硬件部分:两个ZigBee模块,其中控制模块可以控制灯的亮灭和打开和关闭AI模式,被控制模块有人体红外感应模块、光敏传感器和LED发光二极管,其本身按键S1可以控制灯的亮灭,S2按键可以控制AI模式的开和关。AI模式是通过红外感应模块和光敏传感器智能控灯。

图2.1  系统结构图

2.2  系统的功能

1)按键控灯:开发板按键S1可以控制灯的亮和灭;

2)串口控灯:串口调试助手可发1开灯,和0关灯,控制灯的亮和灭;

3)无线控灯:一对一无线控制灯的开关,安全,可靠,无线发送模块的按键S1为灯控按键;

4)AI模式控灯:智能灯控的核心,AI模式可以感应周围是否有人经过来控制灯的开和关,并且可以根据外界的光照强度来调节自身灯的亮度,达到了节能、环保、舒适的绝佳效果;

5)多方式AI模式开关:本系统提供多方式控制AI模式的开启和关闭,其方式有:按键S2、串口、无线发送模块按键S2;

6)实时信息:串口助手实时上报灯的亮灭情况和当前受到哪方面的控制,如无线开灯时,串口将会显示“----无线开灯成功-----”和“/////AI模式关闭/////”信息,以达到最佳安全级别。

2.3  开发环境

IAR Embedded Workbench微型处理器开发环境

硬件系统设计

3.1  Zigbee芯片 CC2530

ZigBee是基于IEEE802.15.4标准的低功耗局域网协议。根据国际标准规定,ZigBee技术是一种短距离、低功耗的无线通信技术。这一名称(又称紫蜂协议)来源于蜜蜂的八字舞,由于蜜蜂(bee)是靠飞翔和“嗡嗡”(zig)地抖动翅膀的“舞蹈”来与同伴传递花粉所在方位信息,也就是说蜜蜂依靠这样的方式构成了群体中的通信网络。其特点是近距离、低复杂度、自组织、低功耗、低数据速率。主要适合用于自动控制和远程控制领域,可以嵌入各种设备。简而言之,ZigBee就是一种便宜的,低功耗的近距离无线组网通讯技术。ZigBee是一种低速短距离传输的无线网络协议。ZigBee协议从下到上分别为物理层(PHY)、媒体访问控制层(MAC)、传输层(TL)、网络层(NWK)、应用层(APL)等。其中物理层和媒体访问控制层遵循IEEE 802.15.4标准的规定。

3.2  LED发光二极管

LED发光二极管采用的是2*5*7MM雾状白蓝色发光二极管,二极管的阳极接在ZigBee模块的P1_0引脚,阴极接ZigBee模块的GND引脚。

图3.1  LED发光二极管实物图

3.3 人体红外感应模块

人体红外感应模块采用的是完整版的HC-SR501人体模块,自动感应,红外感应模块的VCC接在ZigBee模块的5.0vVCC引脚,GND接在ZigBee模块的GND 引脚,out接在ZigBee模块的P1_3引脚。

           

图3.2      人体红外感应模块原理图             图3.3     人体红外感应模块实物图

3.4 光敏电阻传感器

光敏电阻传感器采用的是4线光敏电阻传感器模块,光敏电阻型号为:5516,本产品使用的是AO模拟量输出,光敏电阻传感器的VCC脚接在ZigBee模块的3.3vVCC引脚,GND接在ZigBee模块的GND引脚,AO接在ZigBee模块的P0_5引脚。

            

图3.4   光敏传感器模块原理图                    图 3.5  光敏传感器模块实物图

软件系统设计

4.1系统整体功能设计

ADC环境光照强度魔术转换;PWM多级调光;多中断智能处理;人体红外感应;无线远距离控制。

图4.1  程序流程图

4.2  AI模式

AI模式可以感应周围是否有人经过来控制灯的开和关,并且可以根据外界的光照强度来调节自身灯的亮度,达到了节能、环保、舒适的绝佳效果。

主函数while(1)循环里,if((boozd==1)&&(P1_3==1))(boozd为AI模式是否允许标志位,P1_3==1表示当前有人经过)成立则会不断获取当前ADC环境光照强度魔术转换后的值,然后用if(){}else if(){}方法与标准区间进行比较,若比较成功将会以当前区间所对应的LED亮度动态调整PWM占空比输出,然后将进行新判断、获取、比较。

图 4.2-1

如图 4.2-1,串口调试助手发送 2,收到 CC2530 串口发送的的信息,此时红外人体感应模块和光敏传感器模块两者协调工作,共同控制 LED 灯,也可以通过接收 CC2530 单片机的按键模块的 S2 按键来打开和关闭 AI 模式,也可通过发送CC2530 单片机的按键 S2 来控制 AI 模式的启动与关闭;

图 4.2-2

如图 4.2-2,系统处于 AI 模式时用手握紧光敏传感器模块,让光敏传感器模块处于黑暗的环境下,可见 LED 灯的亮度

图 4.2-3

如图 4.2-3,系统处于 AI 模式时,打开手机闪光灯靠近光敏传感器模块,可见LED 灯的亮度明显降低,当闪光灯更加接近光敏传感器模块时,LED 灯会熄灭

4.3 多中断智能处理

本系统包含3大中断处理函数:

1》》串口接收中断处理函数:

#pragma vector=URX0_VECTOR

__interrupt void urx0(){}

可判断串口接收到的数据,然后进行智能处理,当接收到‘1’时,会以最大亮开灯和关闭AI模式,并且向串口调试助手发送“---串口开灯成功-----”和“----AI模式关闭-----”日志,当收到‘0’时,将向串口发送“/////串口关灯成功////”日志;当收到‘2’时,模块将会利用标志位判断AI模式是否打开,若打开则进行关闭操作,并向串口发送“----AI模式打开-----”日志;当收到其他数据时,模块将向串口将会发送“!!!无该指令!!!”日志。

图 4.3-1
如图 4.3-1,串口调试助手发送‘1’,LED 灯会以全亮的形式打开,并关闭AI模式

图 4.3-2

如图 4.3-2,串口调试助手发送‘0’,LED 灯熄灭 (2 按键中断处理函数:

#pragma vector=P0INT_VECTOR
__interrupt void p0int(){}
模块按键有 S1 和 S2,分别对应的是 ZigBee 模块的 P0_0 和 P0_1 引脚,S1可以控制灯的亮灭,当按键按下且 if(P0IFG&0x01)成立则表示可进入 S1 中断处理函数,函数里将根据标志位状态进行下一步操作,若标志位显示此时灯是灭的,则将会进行开灯功能,并向串口发送相应日志;S2 可以控制 AI 模式的开和关,当按按下且 if(P0IFG&0x02)成立将进入 S2 中断处理函数,函数里将根据标志位状态进行下一步操作,若标志位显示此时 AI 模式已开启,则会进行关闭 AI 模式操作,并先串口发送相应日志。

图 4.3-3
如图 4.3-3,当按下接收 CC2530 单片机的按键模块的 S2 按键,串口调
试助手收到单片机发来的 AI 模式打开的信息,此时 AI 模式正在运行中。

图 4.3-4
如图 4.3-4,当再次按下接收 CC2530 单片机的按键模块的 S2 按键,串口调试助手收到单片机发来的 AI 模式关闭信息,此时 LED 灯熄灭

图 4.3-5
如图 4.3-5,当按下接收 CC2530 单片机的按键模块的 S1 按键,串口调试
助手收到单片机发来的按键开灯成功和 AI 模式关闭信息,此时 LED 最亮显示

图 4.3-6
如图 4.3-6,当再次按下接收 CC2530 单片机的按键模块的 S1 按键,串口调试助手收到单片机发来的 LED 关闭信息,此时 LED 灯熄灭
3》》RF 中断处理函数

#pragma vector=RF_VECTOR __interrupt void x1(){}

当 ZigBee 模式收到发送模块数据时且 if(RFIRQF0 & 0x40)成立将进入 RF接收处理函数,读取数据包的倒数第 4 和第 3 个有效字节,倒数第 3 位数据对应串口发送‘2’的功能,倒数第 4 位数据对应的是串口发送‘1’的功能

图 4.3-7

如图 4.3-7,当发送 CC2530 单片机模块按下 S1 按键时 ,接受 CC2530 将会进入 RF 中断,并收到“0x0D,0x51,0x88,0x00, 0x07,0x20,0xEF,0xBE,0x20, 0x50,'1','0'” 数据包,经过解析可知是控制灯的亮灭指令,接受单片机模块执行开灯和关闭 AI 模式

图 4.3-8

如图 4.3-8,当发送 CC2530 单片机模块再次按下 S1 按键时 ,接受CC2530 将会再次进入 RF 中断,并再次接收到“0x0D,0x51,0x88,0x00, 0x07,0x20,0xEF,0xBE,0x20, 0x50,'1','0'” 数据包,经过解析可知是控制灯的亮灭指令,接受单片机模块执行关灯操作

图 4.3-9

如图 4.3-9,当发送 CC2530 单片机模块按下 S2 按键时 ,接受 CC2530 将会进入RF 中断,并收到“0x0D,0x51,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20, 0x50,'0','2'” 数据包,经过解析可知是控制 AI 模式的启动与停止指令,接受单片机判断此时 AI 模式是否开启然后继续相反操作。

图 4.3-10

如图 4.3-10,当发送 CC2530 单片机模块再次按下 S2 按键时 ,接受 CC2530将会再次进入 RF 中断,并收到“0x0D,0x51,0x88,0x00,0x07,0x20,0xEF, 0xBE,0x20,0x50,'0','2'” 数据包,经过解析可知是控制 AI 模式的启动与停止指令,接受单片机判断此时 AI 模式是否开启然后进行相反操作。

系统调试

5.1. 系统硬件调试
单个功能一一测试完成后,发现 ZigBee 模块仅有一个 GND 引脚,所以把全
部传感器、二极管等的 GND 引脚一起用 1 根杜邦线引入 ZigBee 模块的 GND 引脚。

5.1 硬件总体实物图

5.2. 系统软件调试
如何更加准确的知道当前环境的光照情况,明暗变化的光照强度 ADC 变化,可以通过:

char str[30];
sprintf(str,"adc 数值为:%d",adc);
uartTX_Send(str);
在主函数实时发送 ADC 的值到串口调试助手里,获取每个光照阶段里 ADC转换的值,计算 PWM 占空比以达到最佳的调光效果。

相关部分代码

RF收

 #include<iocc2530.h>
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#define LED P1_1
#define uint unsigned int
bool boozd=;
bool boog=;
uint pwmx[]={0x00,0xF7,0xE1,0xC8,0xAF,0x96,0x7D,0x64,0x4B,0x32,0x01};
uint adc;
float adcResu;
void InitLED(){//*****************初始化LED灯
P1SEL &=0xFD;
P1DIR |=0x02;
LED=;
}
void InitADC(){//********************初始化ADC
P0DIR &=0xDF;//P0_5为输入
APCFG |=0x20;//设置为模拟口
ADCCON3 =0x75;//0011 0101,端口电压,512抽取率,P0_5
adc=;
ADCH=;
ADCL=;//清除ADC数据
ADCCON1=0x30;//停止ADC转换
ADCCON1 |=0x40;//启动ADC转换
}
void Initclock()//*************************************时钟初始化
{//32MHz
SLEEPCMD &=0xFB;//开启全部RC振荡器,避免16MHZRC振荡器被关闭
while((SLEEPSTA&0x40)==);//等待32MHZ上电稳定
CLKCONCMD &=0xBF;//设置32MHZ为系统时钟源
while(CLKCONSTA&0x40);//等待32MHZ成功成为系统时钟源
CLKCONCMD |=0x38;
CLKCONCMD &=0xF8;//系统时钟不分频输出,定时器为250KHZ
SLEEPCMD |=0x04;//关闭不用的RC振荡器
} void InitUart(){//*******************************串口初始化
PERCFG &=0xFE;//将串口0的位置选在P0口
P2DIR &=0x3F; //P0口的外设优先级控制设为串口0优先
P0SEL |=0x0C;//P0口的2、3管脚设为外设工作方式
U0CSR |=0xC0;//USART0工作的UART模式,接收使能
U0UCR=0x02;//据格式为8位数据位、1位停止位、没有校验位
U0GCR |=;//波特率为115200
U0BAUD |=;
EA=;
URX0IE=;//接收中断打开
UTX0IF=;
URX0IF=;
}
void delay(uint i){//*********************延时函数
for(uint j=;j<i;j++)
for(uint x=;x<;x++);
}
void uartTX_Send(char *strx){//********************串口发送
while(*strx!='\0'){
U0DBUF=*strx;
while((U0CSR&0x02)==);//等待发送完成
*strx++;
U0CSR &=0xFD;
}
}
void InitTime(){//**********************pwm
//输出比较,P1_0
P1SEL |=0x01;
P1DIR &=0xEE;
PERCFG |=0x40;
P2DIR |=0xC0;//定时器通道2-3最高优先级
T1CTL=0x02;//模模式,0x00-T1CC0!!!!!!!!!!!!!!!!
T1CCTL2=0x1C;
T1CC0H=0x00;
T1CC0L=0xFA;//周期为1ms,频率为1KHZ 必须设置!!!!
T1CC2H=0x00;
T1CC2L=pwmx[];
//0x00 0xF7 0xE1 0xC8 0xAF 0x96 0x7D 0x64 0x4B 0x32 0x19
}
void InitButton(){//*******************按键中断初始化
P0SEL &=0xFC;
P0DIR &=0xFC;
P0INP &=0xFC;
P2INP &=0xFC;
PICTL |=0x01;
P0IE=;
P0IEN |=0x03;
P0IF=;
P0IFG &=0xFC;
}
void Initho(){//******************************红外感应初始化
//P1_3
P1SEL &=0xF7;
P1DIR &=0xF7;
P1INP &=0xF7;
P2INP |=0x40;
}
void InitWX()//***********************************射频的初始化
{
FRMCTRL0 |=0x60;
TXFILTCFG =0x09;
AGCCTRL1 =0x15;
FSCAL1=0x00; RFIRQM0 |=0x40;//打开接收中断
IEN2 |=0x01;
FREQCTRL=(+(-)*);// 25号信道可改设置载波为2475M PAN_ID0=0x07;
PAN_ID1=0x20;//PAMID RFST=0xEC;//清除接收缓冲器
RFST=0xE3;//开启接收使能 SHORT_ADDR0=0xEF;
SHORT_ADDR1=0xBE;//设置模块网络地址
}
void main(){
InitLED();
Initclock();
InitUart();
InitADC();
InitTime();
InitButton();
Initho();
InitWX();
boozd=;
boog=;
while(){
if(ADCCON1&0x80){
adc |=(ADCL>>);
adc |=(ADCH<<);
if((boozd==)&&(P1_3==)){
LED=;
if(adc>){T1CC2H=0x00;T1CC2L=pwmx[];}
else if(adc>){T1CC2H=0x00;T1CC2L=pwmx[];}
else if(adc>){T1CC2H=0x00;T1CC2L=pwmx[];}
else if(adc>){T1CC2H=0x00;T1CC2L=pwmx[];}
else if(adc>){T1CC2H=0x00;T1CC2L=pwmx[];}
if(adc<){T1CC2H=0x00;T1CC2L=pwmx[];}
/* char str[30];
sprintf(str,"adc数值为:%d",adc);
uartTX_Send(str);*/
}else if(boog){
LED=;
T1CC2H=0x00;
T1CC2L=pwmx[];
}
InitADC();//再次启动
delay(); }
}
}
#pragma vector=URX0_VECTOR
__interrupt void urx0(){ //*******************串口中断处理函数 char bufch1;
bufch1=U0DBUF;
if(bufch1=='')
{boog=;
T1CC2H=0x00;
T1CC2L=pwmx[];
boozd=;
LED=;
uartTX_Send("\r\n ----串口开灯成功----- \r\n");
uartTX_Send("\r\n ----AI模式关闭----- \r\n");
}
else if(bufch1=='')
{boog=;
boozd=;
LED=;
T1CC2H=0x00;
T1CC2L=pwmx[];
uartTX_Send("\r\n /////串口关灯成功//// \r\n");
}
else if(bufch1==''){
boog=;
LED=;
boozd=;
uartTX_Send("\r\n ----AI模式打开----- \r\n");
}
else
uartTX_Send("\r\n !!!无该指令!!! \r\n"); }
#pragma vector=P0INT_VECTOR//**************按键中断处理函数
__interrupt void p0int(){
if(P0IFG&0x01){
delay();
if(P0_0==){
boog=;
if(LED==){
LED=;
boozd=;
T1CC2H=0x00;
T1CC2L=pwmx[];
uartTX_Send("\r\n /////按键关灯成功//// \r\n"); }else{
LED=;
boozd=;
uartTX_Send("\r\n ----按键开灯成功----- \r\n");
uartTX_Send("\r\n /////AI模式关闭///// \r\n");
T1CC2H=0x00;
T1CC2L=pwmx[];
}
}
}
if(P0IFG&0x02){
delay();
if(P0_1==){
boog=;
if(boozd==){
boozd=;
LED=;
uartTX_Send("\r\n ----AI模式打开----- \r\n");
}else{
boozd=;
LED=;
uartTX_Send("\r\n /////AI模式关闭///// \r\n");
}
}
}
P0IF=;
P0IFG &=0xFC;
}
#pragma vector=RF_VECTOR//******************RF中断处理函数
__interrupt void x1()
{
if(RFIRQF0 & 0x40){ static int len;
static char ch;
len=ch=;
len=RFD; //第一个字节
while(len>){
ch=RFD;
if(len==){
if(ch==''){
boog=;
if(LED==){
LED=;
boozd=;
T1CC2H=0x00;
T1CC2L=pwmx[];
uartTX_Send("\r\n /////无线关灯成功//// \r\n"); }else{
LED=;
boozd=;
uartTX_Send("\r\n ----无线开灯成功----- \r\n");
uartTX_Send("\r\n /////AI模式关闭///// \r\n");
T1CC2H=0x00;
T1CC2L=pwmx[];
}}}
if(len==){
if(ch==''){
boog=;
if(boozd==){
boozd=;
LED=;
uartTX_Send("\r\n ----AI模式打开----- \r\n");
}else{
boozd=;
LED=;
uartTX_Send("\r\n /////AI模式关闭///// \r\n");
}}}
len--;
}
RFIRQF0 &=~0x40;
S1CON=;
RFST =0xEC;
RFST=0xE3;
}}

RF发

 #include<iocc2530.h>
void Initwx()//********************************射频的初始化
{
EA=;
FRMCTRL0 |=0x60;
TXFILTCFG =0x09;
AGCCTRL1 =0x15;
FSCAL1=0x00; RFIRQM0 |=0x40;//打开射频接收中断,应该在下面写接收中断函数
IEN2 |=0x01;//RFIE中断开
FREQCTRL=(+(-)*);//设置信道为25则载波为2475M PAN_ID0=0x07;//////PANID
PAN_ID1=0x20;//0x2007 RFST=0xEC;//清除接收缓冲器
RFST=0xE3;//开启接收使能
EA=;
}
void fa( char *fsj,int len){//************************发送函数
RFST=0xEC;//确保接收是空
RFST=0xE3;//清接收标志位
while(FSMSTAT1 & 0x22);//等待射频发送准备好
RFST =0xEE;//确保发送队列为空
RFIRQF1 &=~0x02;//清空发送标志位
for(int i=;i<len;i++){
RFD=fsj[i];}
RFST=0xE9;//发送缓冲区的数据 while(!(RFIRQF1 & 0x02));//等待发送完成
RFIRQF1=~0x02;//清发送完成标志
} void delay(){//*****************延时函数
for(int i=;i<;i++)
for(int j=;j<;j++);
}
void go32m()//*************************时钟频率初始化
{
SLEEPCMD &=0xFB;//开启全部RC振荡器,避免16MHZRC振荡器被关闭
while((SLEEPSTA&0x40)==);//等待32MHZ上电稳定
CLKCONCMD &=0xBF;//设置32MHZ为系统时钟源
while(CLKCONSTA&0x40);//等待32MHZ成功成为系统时钟源
CLKCONCMD |=0x38;
CLKCONCMD &=0xF8;//系统时钟不分频输出,定时器为250KHZ
SLEEPCMD |=0x04;//关闭不用的RC振荡器
}
void InitButton()//**************************
{
P0SEL &=0xFC;
P0DIR &=0xFC;
P0INP &=0xFC;
P2INP &=0xFC;
PICTL |=0x01;
P0IE=;
P0IEN |=0x03;
P0IF=;
P0IFG &=0xFC;
}
void InitLED(){//***************************************
P1SEL &=0xFC;
P1DIR |=0x03;
P1_0=;
P1_1=; }
void main(){
InitLED();
go32m();
InitButton();
Initwx();
SHORT_ADDR0=0x50;
SHORT_ADDR1=0x20;//设置模块网络地址为0x2050;
while();
}
#pragma vector=P0INT_VECTOR
__interrupt void xx()
{
if(P0IFG&0x01){
delay();
if(P0_0==){ P1_0=~P1_0;
char fsj[]={0x0D,0x51,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,'',''};
fa(fsj,); //发送函数
}
}
if(P0IFG&0x02){
delay();
if(P0_1==){ P1_0=~P1_0;
char fsj[]={0x0D,0x51,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,'',''};
fa(fsj,); //发送函数
}
}
P0IF=;
P0IFG &=0xFC;}

最新文章

  1. 安卓开发NDK环境搭建
  2. ScrollView中嵌套ListView显示
  3. 【JAVA 文件概述】
  4. 攻城狮在路上(叁)Linux(二十一)--- linux磁盘检查 fsck \ badblocks
  5. HDU1667 : The Rotation Game
  6. 设计模式:单例模式(Singleton)
  7. Oracle序列使用:建立、删除
  8. Oracle自增ID实现
  9. 黑白棋游戏 (codevs 2743)题解
  10. 8个月从CS菜鸟到拿到Google Offer的经历+内推
  11. Mysql 插入记录时检查记录是否已经存在,存在则更新,不存在则插入记录SQL
  12. Linux 磁盘分区修改与管理
  13. JSONPath使用
  14. 在Pycharm中运行Scrapy爬虫项目的基本操作
  15. js中boolean类型的理解
  16. 推荐.Net、C# 逆向反编译四大工具利器
  17. 爬虫之进阶 基于twisted实现自制简易scrapy框架(便于对scrapy源码的理解)
  18. recovery 下界面UI旋转90 180 270修改
  19. 公式编辑器MathType基本使用方法总结----应付本科毕业论文完全没问题啦^_^
  20. import pandas as pd Python安装pandas模块

热门文章

  1. Quartz.Net—初识
  2. python爬虫-爬取你想要的小姐姐
  3. Mybatis笔记3
  4. WUSTOJ 1296: JAM计数法(Java)
  5. 2.Excel VBA术语
  6. hdu 5432
  7. javascript 之 扩展对象 Object.assing
  8. 艾瑞克&#183;弗洛姆 ( Erich Fromm )
  9. SpringBoot启动流程与源码
  10. 【转载】C#通过IndexOf方法判断某个字符串是否包含在另一个字符串中