STM32嵌入式实现智能家居控制系统 ! W `0 n9 ^. f+ X2 V
1 Q) b6 ~3 k c: b2 e, A本文将讲述如何用STM32嵌入式实现智能家居控制系统,所谓智能就是实时监测自主控制一些因素,如,温度、湿度、光照强度等,当室内光线较暗时自动打开灯,根据光线亮度的不同开灯数量也不同,当室内温度过高时红灯不停的闪烁,蜂鸣器也报警提醒主人室内温度过高要打开空调,当室内湿度过高时风扇开始工作,让室内湿度降下来,那么如何实现这些功能呢?下面我们开始介绍!
8 I2 X% i. x* \9 j2 S$ C. ]/ ] a0 N8 _
4 I0 x* A4 _+ u- c+ g W0 e一、本文用到的器件有:: F6 c0 @7 g' j5 X, z1 _" i
STM32F103R6 单片机
3 G$ ?9 I9 T7 U3 i1 V, cLCD12864 液晶显示屏) H: ~" T) P2 p# O* f
DHT11 温湿度传感器
$ ~' C: E# d7 k5 V. lRETCH 光敏电阻
( f0 a2 ~4 g1 [0 N. X3 u0 _FAN-DC 直流风扇* g J, w3 I3 K$ t% S* x2 N; l4 R& Y$ }
BUZZER 蜂鸣器
& i$ U) K. U* [* [) F- Y电阻、按键等5 D/ ~+ [) T4 u4 C
& }1 m' d$ f* A1 f6 o! J4 Z3 `! \- u- p5 t4 X
二、实现的功能是:
# X# b, @% `/ ^( F3 x: r有两种控制模式,分别是默认的智能控制模式和手动控制模式,按下按键MODE可切换控制模式
/ d# c+ o; G2 _% r3 c% b. _ c+ r3 a4 ^% n$ G' d k3 g1 ]
2 j& u, o6 a4 W智能控制模式中温湿度传感器实时监测当前温湿度,当温度大于30红灯闪烁,蜂鸣器报警,当湿度大于50时,风扇工作,当光照强度小于3000时点亮一个灯,小于2000时点亮二个灯7 Y. V4 Q/ d0 i. n# L; ]
+ n1 r$ x) X" d7 P+ a3 n; X8 [' w, v( c h
手动控制模式中,按下UP键或者 DOWN键可上下移动光标,按下OK键可打开或关闭当前状态 O9 K- i# U5 q1 Z0 w4 m0 M
{ B% K1 w8 G
; V( I3 w; B% }) ]- t; L& ?1 D自动模式中手动可调节,手动模式中自动模式不能调节5 H& _. K) \% i4 A" _+ I4 s4 I& R
$ i1 ]8 I( g8 r& |$ ~* G% j8 X) ^" [+ O4 S; @0 g; N
三、原理图如下:
* Z1 _0 u( a; K+ X0 a! G. U四、代码实现:
0 l8 [! G9 U4 I% a* e) q, R) v! w7 z5 v
7 Z5 g! Y; Q) {; I$ l- #include "stm32f10x.h"
8 Q, W$ Y* Z% p - #include "LQ12864.h"9 E" C& Y* O4 @* d) A- k
- #include "DTH11.h"
; U: e6 O. j1 h- o8 R" f+ [& c - #include <stdio.h>8 L7 H7 T* G7 Q' y
- #include "adc.h"9 b. h& x! }7 ~
& K) u$ W2 z: ^. d9 P5 {! [# ]% l) Q- #define UP 1
6 K1 W6 f& \& \5 e5 w - #define DOWN 2
. I9 i7 |# f9 z8 v - #define OK 30 u2 A* @6 r& ]0 }% h$ t0 J
- #define MODE 42 a$ P0 j; w' R" V N; ^% c
- #define NONE 0* [; c- r% h1 r' S$ Y: p/ H) h8 c
3 c7 ~3 B4 I; U# U7 @+ E
8 p* n% ~1 W x y9 j- void main_delay(int time)2 M$ q" P; ^8 V# a( l
- {9 [4 m2 T. p% i1 [
- int i,j;- ~) H6 w4 A% U5 j/ Y6 _" Q
- for(i = 0; i < time; i++)" E* U& Z3 d# c( Z+ O* h3 R
- {
# M% ~+ y* q0 c# F/ C* b; y - for(j = 0; j < 1000; j++)/ U" v+ \ _" A7 \4 i) J
- {1 Q7 x# N1 E& R. G1 f- C
- j++;
& \; C) P3 d' }9 m: t8 B - j--;
6 N6 M3 z! j* v( y- v7 t) ] - }
7 ~6 c. X8 T& _, q3 G# |2 ]* C- n) I; I - }
: a4 r/ H9 {: R. o - }
: I9 d) R# N: j - 8 X. u# t$ I$ r
- //按键初始化
! k( o6 c8 `& _- t" X6 G. H9 t - void keyInit()8 P' @1 R7 Q+ b: }- o) q
- {$ p: V6 C$ B2 k8 D& `& Z
- GPIO_InitTypeDef init;; c& I0 z4 ~* h3 N9 `' U- }
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);% r* ^- m4 |# k0 t9 S
- init.GPIO_Mode = GPIO_Mode_IPU;//输入模式
" [0 ?( D' h. ?7 y% i - init.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
3 r$ Z0 o3 }+ f: Z2 G% N - init.GPIO_Speed = GPIO_Speed_50MHz;
( e3 v- U/ W/ _, i - GPIO_Init(GPIOA,&init);
( M" Y( `; s# w- M - }
# U, Y( c- H3 t2 v4 M - //读取按键的值
1 O" i0 A9 b' N2 s' X9 o3 N - int keyRead() T# w! a. U4 E( Q4 I0 r
- {
) N6 Y3 G+ K5 B- N) A- u! @/ F7 j - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0)
3 b8 z5 E4 l2 ` - return UP;//上
3 }# K# `+ [% a/ J - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0)
* u, R9 k8 E. Q1 r- Z - return DOWN;//下1 t% d$ x, d7 f$ _# f5 q
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0). ]' g) t: o: G+ Q5 A5 _
- return OK;//确定* Q8 ? E% a2 c
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0)
! ^9 ^, }$ ?. G - return MODE;//模式切换
& b% D6 z& [' G! F) X3 n+ V; m ~+ v9 O - return NONE;
/ N. _* e, O: c6 S, y - }
/ ]) ?0 o2 K* M( M; H
' `: w S3 x( h- //风扇初始化
1 s7 g4 p& N" A) K! q: C - void fanInit() [- } e( E+ P
- {0 Z, K# l5 S. Z
- GPIO_InitTypeDef init;, O6 A: k$ [2 s! Q
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
2 Y9 V" G/ x2 W+ q - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式; W( I% R/ U& m$ z1 s P
- init.GPIO_Pin = GPIO_Pin_1;/ q0 p* l8 g8 l. h+ G
- init.GPIO_Speed = GPIO_Speed_50MHz;- d9 O4 o% t+ v: v
- GPIO_Init(GPIOC,&init);1 \8 ]! F: X; ]
- GPIO_SetBits(GPIOC,GPIO_Pin_1);//置1 风扇关
# s: @& y- W; o$ W& e - }8 f/ d8 l7 u% h( ?+ ~; R: ~0 J) ~! A
- //控制风扇开关 fanSwitch(1);//开风扇 fanSwitch(0);//关风扇
1 f# J/ y2 m0 \& D - void fanSwitch(int sw)// 参数 传递1 开 传递0 关3 @2 a S- r3 M. D0 `# L
- {// 1 真 0 假 真执行:左边,开风扇,假执行:右边,关风扇
- C# E, P- |" q% ?$ v# O1 u - sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_1) : GPIO_SetBits(GPIOC,GPIO_Pin_1);. G; v2 @# P/ I4 k b& l
- }
! a: ` B1 l+ F0 f$ [/ a9 C2 Z - ' D, I; M7 a9 y) a8 c5 M4 J" y7 s
- //蜂鸣器初始化! q0 A' J; V- ?: f$ O0 U
- void buzzerInit()6 }8 C6 T6 k- J) K5 F
- {
% P9 ?0 A+ j/ X* i7 }- K - GPIO_InitTypeDef init;
0 }- Q0 Q6 ]# ~/ z - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); }$ K' Q" g M4 q7 a
- init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
: j/ h; u, l0 z- f, \6 B3 R0 r - init.GPIO_Pin = GPIO_Pin_2;
7 a2 T( R) P" K - init.GPIO_Speed = GPIO_Speed_50MHz;
4 `" J8 k& f. N$ ^# I- L9 { - GPIO_Init(GPIOC,&init);& ]' J1 j( S5 @& N. \7 K
- GPIO_SetBits(GPIOC,GPIO_Pin_2);//置1 蜂鸣器关6 q! k. ?/ D2 {6 n" S5 e$ Z. i
- }% [( y( n6 v1 ~- B& V# y' J
- //蜂鸣器开关" Q" t! m' q. w/ Y I
- void buzzerSwitch(int sw) //1开 0关
. F0 B# h3 a5 j - {+ N, r' j# O, b3 D
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_2) : GPIO_SetBits(GPIOC,GPIO_Pin_2);
& A% _7 g K% ^5 G7 i - }
4 U. B: U6 v6 X( A/ }
. ]8 L9 g! g* a7 R- //LED初始化
( w; x+ ]8 X6 B" F5 \: q* ? - void ledInit(). A, K0 E; r6 W; @9 [
- {
# b4 n' Q/ O/ j4 q - GPIO_InitTypeDef init;
: o {% ?8 O- A/ y; R - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
8 P7 k) ~2 G8 w D7 ] - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
8 v6 H7 S$ [9 D( z9 ~7 [ - init.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;
4 R# F- h8 E O- K - init.GPIO_Speed = GPIO_Speed_50MHz;
5 ^% {3 v, c, `# c - GPIO_Init(GPIOA,&init);
# g1 d9 W9 t9 e$ P! ]; l% f- J - GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7);//置1 LED关$ T5 E( g, ]" c$ y# N/ z; D+ v% P7 S
- }
# v- X6 x; f% ~+ x0 \ - 1 U0 h& P* Z" d1 i ~: N% n
- //控制LED的开关 ledSwitch(3,1);
; F8 P( `* i0 H1 \& z' N - void ledSwitch(int n,int sw)//n代表灯的编号 sw 1开 0关
' W5 I/ \4 B$ d# R - {9 w, \. T1 E x
- switch(n)- M7 V/ q2 Y9 g( @# q8 m$ d1 q! k
- {
% B! h$ O8 y% R! R! r) s+ e - case 1: //编号为1的LED5 w+ ~/ x( A2 S( O' Q. W
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_6) : GPIO_SetBits(GPIOA,GPIO_Pin_6);1 k+ W, r. C. E- U% ^( v7 Z
- break;
) d! s$ r3 ~2 v5 G - case 2: //编号为2的LED2 s/ V$ b0 H# C* b4 o
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_7) : GPIO_SetBits(GPIOA,GPIO_Pin_7);
3 S: R9 @, r% D* ^ ^ - break;% B4 g# D( g4 } J
- case 3: //编号为3的LED" z, _0 f: c4 k" [
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_1) : GPIO_SetBits(GPIOA,GPIO_Pin_1);7 r. I2 @3 r% I' x, O8 ~
- break;; }. f) N0 M. m; k
- }
, `7 ~ N& d$ I. A - }
- C {. j% \6 \) ]$ M - " @ y3 U) ^/ r# `/ J, |
- 5 G0 s. O" H; r) x$ K' z
- //系统初始化函数(相关初始化的函数)
6 r% A9 {3 d" u+ o' p2 [% x - void systemInit()
6 k7 _) \% p& _. C: T$ S& l - {
5 C' b2 ?& U' N$ [5 q - LCD_Init();//LCD屏幕初始化6 q3 T5 T4 M$ q; i9 d: V
- Adc_Init();//ADC初始化* z$ L4 f0 }3 l, L2 K* _, B% J
- DHT11_Init();//温湿度传感器初始化9 u" V; M1 \/ ?" q
- keyInit();//按键初始化
3 M5 S: N: ^& e - fanInit();//风扇初始化; U3 p' l/ I, E2 V7 M
- buzzerInit();//蜂鸣器初始化
2 U* \ F3 }$ t+ N - ledInit();//led初始化
! f! V# B+ @9 |9 r X - }( J' W4 n- t# b8 h
% g+ o4 k' J" g! g4 f- int main(void)
, F* W5 L. W3 J1 W4 z2 l - {
) P9 N1 l' S+ u8 ]# U - char status[5] = {0,0,0,0,0};//LED1 LED2 FAN BUZZER MODE 状态 1开 0关2 D# ]& l$ V6 B/ a+ ^# A+ s# H2 U
- u8 temp,hum;//保存温湿度
2 O: O* s1 f/ W0 A* e, \ - int light;//保存光照强度
/ F: u0 D" @6 a8 j' m6 \; [- @1 p - int key;//保存读取到的按键的值7 b- i/ _" Q( m9 Z% q4 c0 e
- char buf[100] = { 0 };//用来保存格式化出的字符串 Q! s; D z8 X( A2 U3 x
- int flag = 3;//flag时刻代表当前星星的行数
. F' ]# k2 M1 ~7 r( g0 h* b2 f - u8 *menu[4] = {"LED1","LED2","FAN","BUZZER"};//字符指针数组
* t+ i% @) E {5 A - int i;//循环变量0 q/ e$ H: q* Y9 l9 P" p! d
- 4 b$ E1 w; x; Q1 ]( B% b7 H
- systemInit();//系统初始化
- j8 |4 a# S i) m) A -
' W$ I' e6 O/ l! ^ - while(1)
( F6 A3 V$ J5 S' W7 ^ - {
$ V ^- x( Y7 O1 ~& K9 Q - //在第0-1行显示温湿度和光照强度
2 Z) a" _% ~' R: g# h - DHT11_Read_Data(&temp,&hum);//读取温湿度' q2 A: P) }4 \3 @8 d$ X
- light = Get_Adc();//读取光照强度8 w- J$ X2 g4 W/ c
- sprintf(buf,"TEMP:%d HUM:%d",temp,hum);//格式化字符串
6 Y- s9 Y- @2 Y& W - LCD_P6x8Str(0,0,(u8*)buf);//第0行打印温度和湿度
& K) A5 Y0 d- `( N) w* K$ H! M/ g - sprintf(buf,"LIGHT:%d ",light);//格式化字符串) ]2 {6 _8 W' B! G
- LCD_P6x8Str(0,1,(u8*)buf);//第1行打印光照强度
2 z5 ^1 f- ^1 t( ] - //默认就是智能控制模式 temp > 30 报警红灯闪烁 hum > 50 风扇开 0-2000开一个LED 2000-4500开两个灯
/ s+ j( k* \9 U4 _ - if(!status[4])//status[4] 初始值是0 % B6 ^( v1 y, Y' u' v2 I& O, g' C
- {
5 }' p9 L( O3 R% o - //温度& n# f% i$ {' ]$ S2 X1 }
- if(temp > 30)
7 n. m( A9 ]- I2 C - {8 Q8 u- ~+ w* k2 ]0 N6 Q
- buzzerSwitch(status[3]=1);//蜂鸣器响
9 B; \4 R A \9 b" N - ledSwitch(3,1);//红灯亮9 N* z: U! r. U6 Q. e; \
- main_delay(200);
& L( {5 z+ F7 E! G0 u' Y6 L1 U7 i' U - ledSwitch(3,0);//红灯灭
5 g9 a% _' J7 { - }& O8 k m0 O, C; X# y& x& P- t0 q
- else) \4 @& R4 G# h' u
- {, Y. a" N- ?1 O u3 {5 D. q$ N
- buzzerSwitch(status[3]=0);//蜂鸣器关
* m- F+ v& s$ _! N! H) ?0 R: I - ledSwitch(3,0);//红灯灭
j: t$ i k+ e0 r4 N - }. }" i7 q4 f1 f0 F8 l3 H1 [
- //湿度! v! L% Y3 o5 ?8 B
- hum > 50 ? fanSwitch(status[2]=1) : fanSwitch(status[2]=0);" \# `" U( F+ {( r
- //光照强度! D2 q) R2 q$ \+ `
- if(light > 0 && light <= 1000)
* d1 d1 _' s; Q4 M9 N, u& g - {" x) Q' `* K# f) s5 B
- ledSwitch(1,status[0]=0);//1号灯灭
4 v4 x1 S2 g9 v- Z8 n - ledSwitch(2,status[1]=0);//2号灯灭( _1 z; d: R8 b& z: j
- }/ B' e% g( W) P3 ?
- else if(light > 1000 && light <= 2000)
- n; b" t0 q) k - {
4 ?. V/ y: E0 Q% G8 ~3 V: Q0 q( | - ledSwitch(1,status[0]=1);//1号灯亮) J' D( |* f- @6 `7 v5 G$ z! i) f1 O
- ledSwitch(2,status[1]=0);//2号灯灭& H1 {( p, T; v8 k6 r% w; m
- }
4 S+ F( E! B/ c3 [2 G - else if(light > 2000 && light < 4500)8 K6 Y& x8 H' C! U& U
- {& R" M( g/ H1 V. p/ x
- ledSwitch(1,status[0]=1);//1号灯亮0 B1 T ~4 s% Y* w- \8 X
- ledSwitch(2,status[1]=1);//2号灯亮! P$ c" D- D8 h3 A# d. `5 l
- }
5 \- D% H7 }2 h6 T# @ - }1 l+ K. R) e! M# S4 Q) p- x+ s
- //在第3-6行显示菜单& f& g- [2 s4 u
- for(i = 0; i < 4; i++)//i == 0 1 2 3% j4 @( G& {( x/ |2 u( b
- LCD_P6x8Str(0,i+3,menu[i]);// i+2 3 4 5 6 行' k! b& |" `! q( Z6 U4 r
- LCD_P6x8Str(40,flag,"*");
9 J( y; x$ ^2 m1 q) g. g- i1 w. O - ! O1 F6 G1 C+ [& U2 Q6 r% n
- //添加按键输入, {3 N3 N: W+ z" X9 w- \ E
- key = keyRead();# J% w) v! [) a( f) P, X2 _( r# m
- if(key == UP)//向上键 p) `+ U# g+ c. v% D. W
- {. q7 C, o. ?% _, } U' h6 X
- LCD_P6x8Str(40,flag," ");- H& _2 P7 |" G
- flag = flag == 3 ? 6 : flag-1;
% c- m# |' ?& V8 K' ] - }, k) Q1 Y9 G6 w) \7 F: O, X
- else if(key == DOWN)//向下键
& O5 a V( s) s1 E8 A - {9 n k; a* R |( w
- LCD_P6x8Str(40,flag," ");* n1 c0 W# ^' Y. E! M
- flag = flag == 6 ? 3 : flag+1;
/ M- c- w- ~% W( [) K K, a$ `0 x - }
! k! H: r' S4 I, Y7 z) R# ~5 o D - else if(key == OK)//按了OK键
* y$ q( B0 w" d* g, z9 I0 | - {' j w$ i( J2 W( x, a( v! `
- //判断星星在哪一行,控制哪个器件( e+ W+ r4 G# s& V
- switch(flag)
' e4 D& b+ r* o" n - {& w6 |( |* ^ b4 A: k9 r! v0 a
- case 3://LED1
# Z' I' w6 H/ G6 S! G! X8 s - ledSwitch(1,status[0]= !status[0]);/ {! {) G" \8 @8 ~% e: r
- break;6 ]3 B2 K' c1 i* x
- case 4://LED2
2 O3 D0 l$ o% Q, E$ n0 ~1 `1 b - ledSwitch(2,status[1]= !status[1]);
0 `6 T& m" x; x4 {0 x3 l - break;
+ \ @6 D6 p2 t/ I7 V - case 5://FAN
9 X6 {0 j) ^& P - fanSwitch(status[2]= !status[2]);
0 X3 M, r! J: M& a - break;
& r2 x# C4 t4 }5 g. S, [) s5 S! ]: h - case 6://BUZZER9 M! _6 d# G/ x" f" c2 W
- buzzerSwitch(status[3]= !status[3]);
* Y' w1 z! c7 t - break;
) \2 T9 r6 J1 J; ^' ^7 m1 @ - }
8 l. K% R) i9 X) P - }
# V+ F& P- h4 j; X' ~" O" t - else if(key == MODE )//按了模式切换键$ C3 h3 J, J9 ^8 B% E) j
- {7 U- E# v2 U: z4 w5 r/ U" X$ U: L1 `
- status[4] = !status[4];/ t: k K0 k; g! o: B( c* |
- }
) h4 w9 \- i* u; c7 G j -
% n: B; z$ Y- w6 l+ @& {. O - //在第7行显示 开关状态7 P; }1 v$ L' N0 ^/ q
- sprintf(buf,"L1:%d L2:%d F:%d B:%d M:%d",status[0],status[1],status[2],status[3],status[4]);( D6 f* V( |1 M/ H" x* b# b
- LCD_P6x8Str(0,7,(u8*)buf);//显示到屏幕上' C; H4 q) s/ r' ?4 R+ D7 Q
-
' N7 B- U# e- V2 y1 U9 u# x - main_delay(200);
; e, d- ^8 o' a+ p9 R- j9 B. Q0 l" t - }
( n) E( Q8 N" |$ W+ C6 e8 { - - J% x" u }% A# W; Q6 ?
- }
复制代码 / q, {: m9 F5 J' h% V8 p
% H) _+ n/ r1 G. @0 P/ L0 S0 U: f' \# ]: b9 J/ i9 h! S; M
|
早上好啊,好东西要分享出来给大家