STM32嵌入式实现智能家居控制系统
" E! F' d1 x9 @8 p
8 w7 k7 U: W# J$ @9 `: Z9 I; M3 h本文将讲述如何用STM32嵌入式实现智能家居控制系统,所谓智能就是实时监测自主控制一些因素,如,温度、湿度、光照强度等,当室内光线较暗时自动打开灯,根据光线亮度的不同开灯数量也不同,当室内温度过高时红灯不停的闪烁,蜂鸣器也报警提醒主人室内温度过高要打开空调,当室内湿度过高时风扇开始工作,让室内湿度降下来,那么如何实现这些功能呢?下面我们开始介绍!
/ a# E8 Q1 V0 j2 G% k! N0 [9 ^5 j8 g' e; o, G F
一、本文用到的器件有:% o) J1 e9 ^; s5 G: ?5 g4 Y
STM32F103R6 单片机
+ I$ m: h, ^% @* KLCD12864 液晶显示屏 _. R5 K G6 b3 s9 L4 p
DHT11 温湿度传感器
$ ]4 l5 u: E+ _% b5 {6 ?RETCH 光敏电阻2 E% R8 H6 h% c* r5 E1 q3 _$ K
FAN-DC 直流风扇6 |5 e2 D. ^1 K. r! A
BUZZER 蜂鸣器
: S0 C) k# \' R3 V) p" S8 X; k6 V电阻、按键等& X5 a% Q9 K. P( T: C) K8 o
: V) @8 t- N1 E6 y9 U0 W' k% w( d* ?
* O$ H! ?/ B* m- \二、实现的功能是:2 `1 x7 u' K2 K* R; D4 j, {
有两种控制模式,分别是默认的智能控制模式和手动控制模式,按下按键MODE可切换控制模式+ W( P5 g& x0 i0 ?, p- [5 I
% w+ s; e4 I5 a
: `' E6 |5 b1 w1 P: E( R3 x
智能控制模式中温湿度传感器实时监测当前温湿度,当温度大于30红灯闪烁,蜂鸣器报警,当湿度大于50时,风扇工作,当光照强度小于3000时点亮一个灯,小于2000时点亮二个灯. o, K, V# V5 h, U& S1 U n2 ?
9 y/ F8 l& J7 o1 l2 j
/ S! X1 ?# k2 x/ a手动控制模式中,按下UP键或者 DOWN键可上下移动光标,按下OK键可打开或关闭当前状态
& K) S3 [3 c7 o8 g5 t
7 D5 k+ }6 e: C4 t( r- C O6 v9 `& V' J/ ~6 ^/ ^9 L
自动模式中手动可调节,手动模式中自动模式不能调节, B; N2 ]& S! g/ V% V/ e
$ ^4 A; ^% {& f. { }
' M/ _" ~. K7 y+ D1 W三、原理图如下:
8 C; c5 ?5 z6 v四、代码实现:+ m) t5 n3 T+ P- f
- 6 v* H/ J4 Z$ C- n0 s4 y
- #include "stm32f10x.h"
8 T2 F1 ~& e% m- I - #include "LQ12864.h"2 n. ?6 E: G% N. |
- #include "DTH11.h"; Z& z# t$ A" B5 B+ [( n, O: J
- #include <stdio.h>
5 S2 M8 _9 d1 m4 C - #include "adc.h"$ Q# H9 W6 j4 H3 }; d& d
! q2 w2 C/ C5 g8 \5 Y" ` t- #define UP 1
% m+ ]( Y" Q3 z( z- l - #define DOWN 2; h8 Y+ K& o" r r
- #define OK 3
+ V. l/ C# w7 T - #define MODE 4
* O3 G9 V: A2 i ? _ - #define NONE 0
* P1 i# K( F8 p6 B - ; M# L% p) {3 V( K! t- Z& s3 b
2 \7 V+ X* }% _- void main_delay(int time)7 H( _& u' a0 T
- {
{! S9 H6 ~( l - int i,j;
; H" a4 q+ f+ w. |8 ~ - for(i = 0; i < time; i++)- A; T |, p& I
- {, S6 [" V+ a- r- a
- for(j = 0; j < 1000; j++)6 T8 t) ^9 k9 |
- {
8 \$ l; V: q$ V8 ?0 `7 y D - j++;
$ U0 `; ?" g/ T* J - j--;
1 ~0 }1 D& n( n/ ]0 V2 B6 [ - }
8 p; Y$ C" k) p$ p, A) i8 j - }, F# C2 t. Q* Y' a o# j; B' I
- }
8 H& x9 _- r+ p6 }
6 ^& j4 w \4 B' I- //按键初始化 + V) p: ?% D8 B9 {2 i# K7 H
- void keyInit()
% t3 s: ?. }! G* w/ d" M5 P - {
4 e1 k" z8 ?% z; z) W - GPIO_InitTypeDef init;& w. X4 ]8 ~8 d9 ?8 x
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);6 N5 d# |9 \+ S. [7 u; i
- init.GPIO_Mode = GPIO_Mode_IPU;//输入模式
1 t6 t5 l v1 ]; J - init.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
# F' p# M5 v- a( o# s8 j - init.GPIO_Speed = GPIO_Speed_50MHz;: ]9 ]( K F1 O$ A
- GPIO_Init(GPIOA,&init);7 C H6 O2 P0 N4 @- d2 @7 ^( w
- }- ?6 ^. S5 p& V
- //读取按键的值2 B. f Y4 g% B, O# |8 m
- int keyRead()
/ W A8 S' v: ]9 W, @1 B. u- X, K% r - {
, G; _7 I4 W) s0 D; E- F6 N' Y% u% r5 b - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0): W/ ~0 z! ~( Y! z' m: i: R
- return UP;//上
+ P/ L( w3 u3 Q3 V: k+ X - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0)
8 `- B% h6 [/ }9 n3 ^8 W. m - return DOWN;//下
3 P% x# I- h T - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0)8 `" c" g- J7 z
- return OK;//确定# o( w/ U3 ?) t# Q( H
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0)
! A; |3 e) Z: t6 e( Y3 }9 h - return MODE;//模式切换3 M: R' c% \0 R X3 }. h
- return NONE;
: I) _% e' k0 J3 H( \2 @ - }% k- J7 s! {$ i% j* b3 c- q
- , [5 C' p( ?) P
- //风扇初始化
, r$ c+ P; a1 t1 W, {; t2 T - void fanInit()9 c" f( H! F: m8 M' q {& [
- {. B( q' J1 f" N Z
- GPIO_InitTypeDef init;4 m( s5 K; b% n! X+ a5 Y
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
$ `( {% b/ P k" Z' t1 _6 z& S. A, q - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式 e6 J, ~% T" f1 c4 {; F; X5 `
- init.GPIO_Pin = GPIO_Pin_1;
9 W+ Z3 M- N0 S7 m. T+ ? - init.GPIO_Speed = GPIO_Speed_50MHz;8 p3 b. q, V, Y# y# ?/ v$ w5 c
- GPIO_Init(GPIOC,&init);
5 [7 Z1 J9 q6 Q3 x - GPIO_SetBits(GPIOC,GPIO_Pin_1);//置1 风扇关" w, `" p+ G, F$ i i5 z
- }
; u) p6 n3 _, U% z - //控制风扇开关 fanSwitch(1);//开风扇 fanSwitch(0);//关风扇: \9 z2 }" m3 |, w9 q* T
- void fanSwitch(int sw)// 参数 传递1 开 传递0 关
6 E% g ]8 `. p6 s9 ^1 I - {// 1 真 0 假 真执行:左边,开风扇,假执行:右边,关风扇# v/ g8 i9 Q) i" P( P
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_1) : GPIO_SetBits(GPIOC,GPIO_Pin_1);+ r. w6 k" Z6 |3 e: b' P
- }! J3 L" G- m. i! q3 B5 {& @
- 4 v' o/ h7 i3 J! G1 A5 m- T
- //蜂鸣器初始化: l o8 y$ |( a" e
- void buzzerInit()
; c3 V- |' R5 N% `) v - {. j7 R# X4 q7 R2 a o' o2 A! R P
- GPIO_InitTypeDef init;
. m# j1 f' U$ L5 B5 W - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);9 u+ i0 ^$ q# |: X* r5 B4 V
- init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式; s9 t4 W( r1 [. ^" ?; H) F. g) v
- init.GPIO_Pin = GPIO_Pin_2;
* J8 h% B# F! I - init.GPIO_Speed = GPIO_Speed_50MHz;
( X% `, g$ A- E- Q1 E+ P - GPIO_Init(GPIOC,&init);
7 d' ?; ]" C9 q) X - GPIO_SetBits(GPIOC,GPIO_Pin_2);//置1 蜂鸣器关; a4 F9 L2 u2 E6 }
- }3 i) d% F% g7 m7 w* c5 c- q
- //蜂鸣器开关% d2 ], F6 @$ Q- M
- void buzzerSwitch(int sw) //1开 0关+ [; Q+ O1 `4 q) @0 E
- {
4 [5 x" ?+ @/ v$ h; u( c8 p/ o8 R" q - sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_2) : GPIO_SetBits(GPIOC,GPIO_Pin_2);3 m" f9 O* H) F
- }
0 N) t+ f/ d, m. \% } - % K# |, e2 ^' ]
- //LED初始化
7 i( i5 V- [: L$ z3 d# z/ B- r - void ledInit()
+ n' y6 Z( Y" x0 t, V# ~ - {) A/ O ?4 r! G z1 K6 A
- GPIO_InitTypeDef init;
1 J; ~% y# E9 S: l+ s G! X! c - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
: S7 y- Z1 I# }7 E: s6 ?, B- a. W' i - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式( ~4 U( A' Z! P, m
- init.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;
: z# k) o& }2 P6 r# O% o7 D - init.GPIO_Speed = GPIO_Speed_50MHz;% i$ }; o0 R9 ?- C' z8 I4 s, |
- GPIO_Init(GPIOA,&init);$ F2 J$ d+ a/ Y* J/ s4 o: g
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7);//置1 LED关
, D, r: T2 @4 [) H2 w R5 w+ h - }
& C7 p' z T3 O: K& W
8 w9 t9 s: p8 v- //控制LED的开关 ledSwitch(3,1);$ w! n0 f+ [% D! i
- void ledSwitch(int n,int sw)//n代表灯的编号 sw 1开 0关
% ~$ O9 T# \/ ?/ e3 l S - {* w# F/ i; I3 n! o
- switch(n)$ V% M+ I4 z3 z! t2 L6 {1 w0 {1 _
- {) o3 J5 q' |$ H8 _+ a- J
- case 1: //编号为1的LED3 \7 i/ Z& v% \5 ^, E! X+ y H
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_6) : GPIO_SetBits(GPIOA,GPIO_Pin_6);; [ ]% L7 c" E9 d
- break;
3 t# M, |( T1 ~! L, F - case 2: //编号为2的LED
& a5 b; q% w1 R$ g/ h - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_7) : GPIO_SetBits(GPIOA,GPIO_Pin_7);1 A' `7 ^" F7 H5 @# H
- break;: m+ i; Y n5 T' l0 S) O' r9 [# J6 c# U
- case 3: //编号为3的LED
& `+ g/ |& ?2 `; F5 \3 J& k - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_1) : GPIO_SetBits(GPIOA,GPIO_Pin_1);
/ D2 e8 H- h9 `( t - break;
' V3 r O1 S3 R( \* C7 @5 w4 ? - }
( @2 t! D. C) C+ [& x - }
+ g2 U) I" _5 F - ! n$ N x8 q/ g* |
- 6 H: e3 C. c% h4 I1 v
- //系统初始化函数(相关初始化的函数)
: u/ u* l* Q# o; K& x d( j; L0 h - void systemInit()
. W4 C* A+ u% U) Y6 i3 D# N. ^ - {
9 o1 X3 }' E3 k+ n' q8 R6 ?1 W6 p - LCD_Init();//LCD屏幕初始化' C( h! W$ E' \6 i, J2 @& k4 a
- Adc_Init();//ADC初始化
3 f: ^2 v- \8 O1 K9 |+ s! h3 a - DHT11_Init();//温湿度传感器初始化) V4 j9 J) I: o9 I! K1 J9 X
- keyInit();//按键初始化
1 d8 @; I+ X4 K9 c' x8 s8 T: g - fanInit();//风扇初始化' ]) u5 s: N0 X. W" M% R
- buzzerInit();//蜂鸣器初始化7 h7 t* l$ _0 p, x7 G1 {
- ledInit();//led初始化5 y9 q" k9 [- `" d1 p5 _
- }6 r$ f- e, s6 Y2 v6 B4 D9 n. X* j
: I7 D$ y& M% t% a7 U( ?- int main(void)* ?4 ]) \: x) E' H
- { - N5 \2 v& C3 X( c% r0 m( r
- char status[5] = {0,0,0,0,0};//LED1 LED2 FAN BUZZER MODE 状态 1开 0关
5 Y% J& ^& V9 m - u8 temp,hum;//保存温湿度
+ L+ Y' s# d" `! C2 N - int light;//保存光照强度6 ]( n/ h7 m! X, I
- int key;//保存读取到的按键的值
$ t' p: U: P8 k" E - char buf[100] = { 0 };//用来保存格式化出的字符串
6 g6 N/ U9 H0 z, k - int flag = 3;//flag时刻代表当前星星的行数5 v. Q, n" @$ O
- u8 *menu[4] = {"LED1","LED2","FAN","BUZZER"};//字符指针数组
, @; D& _4 x" i# H/ M, M p+ O - int i;//循环变量
9 K4 `; W _/ _/ w7 x+ Z6 g -
1 g9 b/ _. e" } L( f - systemInit();//系统初始化
% u! V$ c/ R5 N w% n0 d/ m2 I. M0 B -
5 j0 u4 i- V& E$ ~0 ]% h - while(1)
, F6 Q" Y" t. h7 L+ X, j - {
4 ]1 T$ c- Q* Q( m, L9 w - //在第0-1行显示温湿度和光照强度- |* ~- c: k! L: c; d" @; @
- DHT11_Read_Data(&temp,&hum);//读取温湿度
" Q$ W) _5 H5 C* X - light = Get_Adc();//读取光照强度1 p8 K' ^; x# l1 q) M1 X
- sprintf(buf,"TEMP:%d HUM:%d",temp,hum);//格式化字符串
: g8 ]) U! t/ X1 k+ }' D - LCD_P6x8Str(0,0,(u8*)buf);//第0行打印温度和湿度0 o, E9 t% V6 t( ~) I$ |( n
- sprintf(buf,"LIGHT:%d ",light);//格式化字符串
" B6 P0 n" I `/ D9 N j, w - LCD_P6x8Str(0,1,(u8*)buf);//第1行打印光照强度
7 e8 ]( |+ `) r9 f6 \4 M8 s* ] - //默认就是智能控制模式 temp > 30 报警红灯闪烁 hum > 50 风扇开 0-2000开一个LED 2000-4500开两个灯- X2 U# }( Z: W: O" F* y
- if(!status[4])//status[4] 初始值是0 ' [' p7 L6 C5 _0 R3 H9 `
- {
, l: D* I$ g" E; s - //温度+ @$ ~+ h7 k( q( |
- if(temp > 30). `/ J1 H6 ~6 F- L: m6 F; e" D/ |
- {
/ Z2 C% s) B' X4 X4 Z3 s- e - buzzerSwitch(status[3]=1);//蜂鸣器响
3 s! Q0 n+ A/ n' d5 E8 T( | - ledSwitch(3,1);//红灯亮
/ V# b6 q _* d. B - main_delay(200);
' c8 ^) h) T% w* Q - ledSwitch(3,0);//红灯灭. i1 I, J! K! x5 C$ _ W
- }
) y7 ^6 p! `) I - else
: P: U9 `$ N8 e1 J - {7 D) `" k) Z( h! r+ a
- buzzerSwitch(status[3]=0);//蜂鸣器关7 d5 `) S0 _ J4 M
- ledSwitch(3,0);//红灯灭, R" M- K: O2 M7 X0 B3 G
- }. R) G7 m# O1 H
- //湿度
/ r6 H: d& _7 i% W2 ? - hum > 50 ? fanSwitch(status[2]=1) : fanSwitch(status[2]=0);. b. L0 E8 A1 t2 X
- //光照强度
+ G" ?$ y8 j T+ e - if(light > 0 && light <= 1000), Z. c1 y/ T) T0 Q
- {9 a' |; f, ?7 v' i: \
- ledSwitch(1,status[0]=0);//1号灯灭9 y( A! l1 v" X8 F1 ]5 _
- ledSwitch(2,status[1]=0);//2号灯灭
" G3 i0 g2 u5 W - }( _7 X) P" B3 S/ @
- else if(light > 1000 && light <= 2000). T- c* I7 R, f% g R5 k% y
- {
6 k. i8 ^, B% Y; V) G6 B$ r - ledSwitch(1,status[0]=1);//1号灯亮4 C+ W% W( X# Q
- ledSwitch(2,status[1]=0);//2号灯灭( F8 l9 q8 v5 Z
- }
4 {" `0 | s4 x) V: F - else if(light > 2000 && light < 4500)' w* Z4 c0 H- m. {# \ |. \* |
- {( K# k! B- W' A( x# U. m; v* ]; r. v/ ^9 Q
- ledSwitch(1,status[0]=1);//1号灯亮7 L& p7 h" k! K' \
- ledSwitch(2,status[1]=1);//2号灯亮8 z6 r' d$ [( {( h! i5 h+ k7 T
- }
5 z# ]* {' W4 H+ V: H/ j+ K& o5 J - }" V" H! S8 ~* C6 \# O" e5 q
- //在第3-6行显示菜单% n* S% L3 _8 B! m
- for(i = 0; i < 4; i++)//i == 0 1 2 3
}1 y0 |6 z: D/ J5 o. Q - LCD_P6x8Str(0,i+3,menu[i]);// i+2 3 4 5 6 行. Z6 j" l* G$ Q5 V2 @ t; j* P$ ~0 l
- LCD_P6x8Str(40,flag,"*");3 Z3 X) U- j# U8 [, s
-
5 ?/ s- F* U: f* \( e5 x) F# F - //添加按键输入+ `& ]5 ?9 M6 `+ H$ ?
- key = keyRead();
7 N; `$ ]# W2 n: [( ^" q5 k5 `; U E% ~9 u - if(key == UP)//向上键* S1 a5 M( S8 h& ^) }# H8 g
- {$ Z# I; h* d, r' J& J
- LCD_P6x8Str(40,flag," ");$ s* ]6 {$ H( l2 Z3 F1 P# i
- flag = flag == 3 ? 6 : flag-1;0 }) a. \- c! f* Y- V! I: P+ N( s+ {2 L
- }
) C( V: d- f( Z( D - else if(key == DOWN)//向下键6 [' [* X& D% B) z
- {
. m. Q# V2 f; p; q - LCD_P6x8Str(40,flag," ");& o: u" H/ q- N4 p8 T; o# i
- flag = flag == 6 ? 3 : flag+1;
# F0 ?- y, [3 a; g - }
+ } q* y2 z! v k! T - else if(key == OK)//按了OK键4 ^# L) D( g9 O9 f6 m6 d
- {: h& B9 T9 K$ m6 l$ D' ?1 p
- //判断星星在哪一行,控制哪个器件8 v! ?/ M# g4 X5 V+ O. }: L
- switch(flag)& I* p: z7 {1 N& G8 r6 N
- {1 y; k" F+ T: Y: J1 ?
- case 3://LED1
& q- w7 }" C# D) e2 H% B, ^ - ledSwitch(1,status[0]= !status[0]);& c2 U0 r) U i4 {6 O. X; c
- break;
+ {6 g5 @0 e" {( i - case 4://LED27 o: f! B" x! G' U! c% j. ?3 j
- ledSwitch(2,status[1]= !status[1]);, X) x8 B/ E7 y( Z- M x
- break;
2 d, N. o( B+ y w1 s% w - case 5://FAN
* b, l2 r1 |( O. Q( M) Q - fanSwitch(status[2]= !status[2]);
. L# A) Z! i5 V# ?4 _' r6 t6 t3 \ - break;
: M" G5 g! ]4 K& k) U - case 6://BUZZER6 k% N" V; R+ }( ~3 m* X9 i5 Y
- buzzerSwitch(status[3]= !status[3]);
& H# H3 K. X$ U6 q - break;& P4 ^8 |" Y+ m
- }$ v, z) Q9 Z* D: M* |$ a: M/ J
- }
* n( y, [) ~! {. u$ u" J+ C" d - else if(key == MODE )//按了模式切换键. p; W2 c) Y6 T# p9 c' d5 A
- {
+ U( Y; q8 p8 }# B! f5 B - status[4] = !status[4];5 g6 n% x: N1 [9 z1 {) |
- }
" \; I A2 S$ ~6 |+ q' ~( E - ) G& U- O5 Y8 |4 M2 h
- //在第7行显示 开关状态3 `8 \" Y! y) @
- sprintf(buf,"L1:%d L2:%d F:%d B:%d M:%d",status[0],status[1],status[2],status[3],status[4]);
8 Q# S9 L# V8 Y- X" H& ~" k - LCD_P6x8Str(0,7,(u8*)buf);//显示到屏幕上7 r3 T5 U2 C: Q+ s0 J5 R @" Z5 |
- 2 R9 d2 Q* M8 R
- main_delay(200);$ a* N( [- Z! F* ]* K
- }! Z. ? \5 P5 y( ~1 |
- 0 ?7 { r$ H: P% _5 W
- }
复制代码
0 x- w6 | v+ F1 Z0 G1 S4 Q1 l+ U9 f5 m8 U1 F) y
1 u. C2 y. a6 _( \" E' j/ r |
早上好啊,好东西要分享出来给大家