STM32嵌入式实现智能家居控制系统
# L7 n a' T" A# ^$ z" v- D7 P' ]$ {
2 i5 ~/ H, L$ Y9 b; N. D* z本文将讲述如何用STM32嵌入式实现智能家居控制系统,所谓智能就是实时监测自主控制一些因素,如,温度、湿度、光照强度等,当室内光线较暗时自动打开灯,根据光线亮度的不同开灯数量也不同,当室内温度过高时红灯不停的闪烁,蜂鸣器也报警提醒主人室内温度过高要打开空调,当室内湿度过高时风扇开始工作,让室内湿度降下来,那么如何实现这些功能呢?下面我们开始介绍!- w/ T7 E# a3 y* y( e- q
2 D. S5 e" S1 Z4 P } X0 {" l& [5 G一、本文用到的器件有:7 N# `) ]6 j$ l" |
STM32F103R6 单片机
$ l* W# ?+ }+ y5 L" d3 \9 W' ILCD12864 液晶显示屏
9 b6 z" p# k/ }& r) l P+ `DHT11 温湿度传感器' O1 Z* n! c1 r1 w. D2 H7 i
RETCH 光敏电阻
3 P1 a4 i/ x ^1 K* k WFAN-DC 直流风扇
. g8 v, ?& e& l, }6 uBUZZER 蜂鸣器
9 W4 P$ W b/ s2 I电阻、按键等
3 B1 u& m9 _3 j
+ N5 ^) ~6 G: }5 _
Y/ F$ e+ q- V+ X二、实现的功能是:$ ?$ l$ C$ C( ?6 S! s8 }
有两种控制模式,分别是默认的智能控制模式和手动控制模式,按下按键MODE可切换控制模式
1 ?% N- I8 |7 I0 h# ?0 L& K6 K, i9 e/ K6 U5 q U( m" p
8 I2 s' h2 Y! t% @5 N智能控制模式中温湿度传感器实时监测当前温湿度,当温度大于30红灯闪烁,蜂鸣器报警,当湿度大于50时,风扇工作,当光照强度小于3000时点亮一个灯,小于2000时点亮二个灯# k" f- x' T; `: @5 ~% A6 S2 Y
9 r# s, |9 B7 C! Q
$ j+ p# d9 I- f3 d- O+ s7 R! n手动控制模式中,按下UP键或者 DOWN键可上下移动光标,按下OK键可打开或关闭当前状态0 u! r$ e7 ~; U5 A/ y' o! I
. [- w/ U0 C, D+ Z
- h% `. m0 w( R6 J: _ @; t自动模式中手动可调节,手动模式中自动模式不能调节
9 I9 J, f+ K _/ k5 U) }9 V, J- f. X! {! h
# N, @# |# N; K; S, R+ q3 Y6 [2 [三、原理图如下:
# l7 G' N; }: _& T+ S+ n& _- d& V R3 w四、代码实现:0 S: b6 k4 p/ i% g0 ]/ X$ v
2 N. c8 s1 [3 V- #include "stm32f10x.h"
k, b: q' C! k4 X3 o - #include "LQ12864.h"/ w/ @. @ j: _
- #include "DTH11.h"1 K- u% B$ p% N
- #include <stdio.h>" H9 T+ x" I, U" ~1 O
- #include "adc.h"' M/ I @9 ?3 G- N e4 M" H/ ]
8 u" m: U$ Y9 _3 R- #define UP 1
$ y) W0 K0 H* o6 T5 A V - #define DOWN 2/ o+ O0 G# a% y: b7 E
- #define OK 3
7 d+ ]# }. y# Q4 x0 a) K - #define MODE 4. C; W( t& {$ t3 e/ @$ S
- #define NONE 0
: w) c, t8 `1 k% S# S& K; p4 l' K6 I
- T. E# s$ s6 p. v% f5 ]9 A
: }1 t& f9 M' U: b9 E- void main_delay(int time)) X) K6 o+ l, n* X8 J3 c' r
- {
, _' Z# }9 _# X% \& M - int i,j;
! ]- m* ?5 ]* m& l - for(i = 0; i < time; i++)' O8 P7 K- C& B" i( R% ^
- {
3 \/ L0 Q, n4 k5 _" p% f$ r+ e) L - for(j = 0; j < 1000; j++)
4 K; y! {1 e5 h3 `/ s - {
- |1 Z3 \3 S% d) o! c2 g - j++;9 \" G1 I- b) y/ E5 c4 R
- j--;! a+ Q6 Y: A* L; x. J# D1 d4 y
- }- \; B# c+ x" y+ p( |; b( K$ a
- }% x9 T2 ]2 @9 O9 _. X9 i: b5 o
- }! g0 z+ S, c. [
7 b, ?, V9 a* ^4 r& B; h- //按键初始化
) i2 d' s! l/ j8 G4 } - void keyInit()7 u. [2 L5 s) w4 ~
- {
- Z0 O/ j9 `# Q% y( u - GPIO_InitTypeDef init;/ X* _: ?/ b6 I
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);5 d; q' q# M ^8 r7 m
- init.GPIO_Mode = GPIO_Mode_IPU;//输入模式
; v X j4 b4 v O$ ^! i - init.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;& q! i4 U4 h* K& H* b
- init.GPIO_Speed = GPIO_Speed_50MHz;
3 i4 u) ^, Z* H% F* k! a - GPIO_Init(GPIOA,&init);
: L8 T/ ^# p" b5 V - }
- G% R- c9 {- [/ O6 F( s - //读取按键的值
: g/ ^4 Z$ B, W9 I/ H5 q - int keyRead(); }2 U- z. u7 e! B* f
- {, u# x' g! K& o% e1 W8 i/ f
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0)
5 O' \! T8 _9 S H% ?+ u - return UP;//上
6 ?# F. @! H$ \1 [0 B9 j7 j - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0)
: L' s' B# x5 G- K1 D- ~ - return DOWN;//下
8 L! }- f9 ]+ B0 N# P H - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0)3 M$ @1 ?0 h8 s8 d1 ^. H+ t2 b$ F
- return OK;//确定2 ^! Q' `& y5 u8 M) V( n$ n$ z
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0)
6 f9 N7 [4 _$ D$ B1 v# l; G7 ` - return MODE;//模式切换
; R9 @( \* W# N4 T5 {" q - return NONE;5 Y' M" V$ q [5 _6 j# |
- }8 _, Z* j% R2 d8 l
* j4 w7 Y: L9 X/ z8 @% b- //风扇初始化) F- a7 B0 M0 j$ U8 P Q
- void fanInit()3 E- @+ T+ i! ?/ D4 p
- {9 ^2 q- P6 T0 t
- GPIO_InitTypeDef init;
" p1 {+ \3 T, O7 S6 l# k8 E - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
# o9 m# R$ `2 n' ~ - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
8 O$ r, X& \- ~+ b/ G - init.GPIO_Pin = GPIO_Pin_1;+ ]7 W/ T' N/ g. z, L
- init.GPIO_Speed = GPIO_Speed_50MHz;
. o5 @6 x% W( u7 Q - GPIO_Init(GPIOC,&init);* X* g4 h) r5 [; R' D
- GPIO_SetBits(GPIOC,GPIO_Pin_1);//置1 风扇关
2 n) s" J. s" ~* y+ i. K - }
- y! ~+ ~$ V2 N. u! R6 ? - //控制风扇开关 fanSwitch(1);//开风扇 fanSwitch(0);//关风扇
6 D* H8 f+ a5 h2 y3 D' L - void fanSwitch(int sw)// 参数 传递1 开 传递0 关/ `* N- R2 d" o# z
- {// 1 真 0 假 真执行:左边,开风扇,假执行:右边,关风扇( l6 b; [. J! g) [# S# V
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_1) : GPIO_SetBits(GPIOC,GPIO_Pin_1);
& B( h; _2 V6 B5 v6 W - }$ _+ f( K3 Z d3 U& X
+ D# K1 f4 u1 J. ]9 q5 |- //蜂鸣器初始化2 h. E- f+ x; \, i
- void buzzerInit()
& H$ K7 l/ ^' Z9 H - {
* X, |4 `' o1 s2 X2 p - GPIO_InitTypeDef init;" U: ^2 }! ^ B: J- N
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
, b3 ~, E R3 l. ^' g& }, o - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式6 z: D0 E7 k4 m9 X
- init.GPIO_Pin = GPIO_Pin_2;
* y" }. R3 F, H+ S% e' F$ h - init.GPIO_Speed = GPIO_Speed_50MHz;
0 J" u8 |7 e7 i# T! L+ U - GPIO_Init(GPIOC,&init);8 m: N( F9 c: x! A( r" m
- GPIO_SetBits(GPIOC,GPIO_Pin_2);//置1 蜂鸣器关
/ B. a/ D2 X/ t% Z7 q - }
{7 h: M0 I" J0 E% s - //蜂鸣器开关
! g* S+ l: L2 P, Q - void buzzerSwitch(int sw) //1开 0关7 g# e9 o( D/ k1 y. u% _+ V- ?( `
- {( a: h( {& k6 R0 B7 p; e. [+ o) G: \
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_2) : GPIO_SetBits(GPIOC,GPIO_Pin_2);. ]9 \2 c0 l( {/ g) x
- }: @8 \: ?% l, M, A" @% V
- - w$ U( y; }- i$ x* y. c* Y
- //LED初始化
1 \* {* x( D; X - void ledInit()7 { P9 }* L2 X; c
- {
' I# r$ n, H8 K7 r- Q - GPIO_InitTypeDef init;1 g }' r6 S* q: x. b: b
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
& f; F4 x/ u3 f) u4 w" B - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
2 W& F( @# V4 t+ C0 p& P" {" L5 d6 X - init.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;
0 q- d& Y- y- J - init.GPIO_Speed = GPIO_Speed_50MHz;+ L S5 b" N5 h. }/ Q# i/ }8 H; {
- GPIO_Init(GPIOA,&init);* P' @0 i5 J* r; g
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7);//置1 LED关- p( K/ p; i$ a3 D3 m
- }: g1 _( Q I( P2 E) c9 ]
6 t% I# x; a2 c( o- //控制LED的开关 ledSwitch(3,1);3 P9 ~: ?2 f0 x5 _+ k- t
- void ledSwitch(int n,int sw)//n代表灯的编号 sw 1开 0关: j0 |7 K- j m4 { O9 Y( m5 a
- {
" W+ x) K# J+ J: T; b7 z - switch(n)
% H8 S( j( H. s! z - {
8 O4 u: J+ s4 x6 o - case 1: //编号为1的LED
1 C5 y$ u4 d9 C# k$ ~) x/ u* J9 w - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_6) : GPIO_SetBits(GPIOA,GPIO_Pin_6);
& Q5 Z3 n6 {! ], f7 O- Q - break;! w$ X% S7 k7 h/ s
- case 2: //编号为2的LED
$ P& E1 ~) y; N! m - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_7) : GPIO_SetBits(GPIOA,GPIO_Pin_7);( J& }( j9 V1 |4 y
- break;
2 c- l$ c2 X" n9 p - case 3: //编号为3的LED
0 M8 r! g8 C2 X - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_1) : GPIO_SetBits(GPIOA,GPIO_Pin_1);
+ h8 K- m- D) o3 W: ~ - break;3 u" H) Q; @- P' {# c" U0 o1 ?
- }* z$ a* R, E8 `/ u% N, W
- }
E& U/ _4 J$ m. z+ _6 P: L - * M; ~, k" E7 s3 v" h- g
& R7 U* h6 I5 R! c- //系统初始化函数(相关初始化的函数)' a1 m* n, c/ [# A: y [
- void systemInit()/ d0 y7 j# i, j) T! A
- {
! h* O- P3 x2 n2 V - LCD_Init();//LCD屏幕初始化
, q5 V9 v" \7 }, C$ O' w8 a - Adc_Init();//ADC初始化
: g' ~* E4 o" g& T1 ~$ A; B2 d - DHT11_Init();//温湿度传感器初始化
0 }$ G+ a) g! b; C; J( k+ q - keyInit();//按键初始化4 M! \) e7 {; h1 |
- fanInit();//风扇初始化
" m0 n' Q- f3 G( I6 f5 z) a - buzzerInit();//蜂鸣器初始化5 s) e# s; V; p5 P
- ledInit();//led初始化
* z; M" X, }" f" W# a - }# T9 X0 {/ x6 h9 d. E4 b& \
- 8 B" u% O; P6 [+ I
- int main(void)
; d/ S8 o3 F2 l5 n# a8 E, I - { + b |6 ^5 |5 B; Y: N; `! x$ L
- char status[5] = {0,0,0,0,0};//LED1 LED2 FAN BUZZER MODE 状态 1开 0关
a) i" f$ H6 X x0 \7 U" K# D: y - u8 temp,hum;//保存温湿度1 l+ I6 t) i% A! |/ g; w) m2 b7 i
- int light;//保存光照强度7 `. t5 ^% I6 M# Y! L
- int key;//保存读取到的按键的值
) R, i* z. J# l( x* ~/ ^ - char buf[100] = { 0 };//用来保存格式化出的字符串* p4 a, ?+ m1 f6 X- r/ k
- int flag = 3;//flag时刻代表当前星星的行数" C' p- \! V% q5 V- `' x
- u8 *menu[4] = {"LED1","LED2","FAN","BUZZER"};//字符指针数组
8 e9 F; k7 S- @% C: c - int i;//循环变量
1 l- d* }+ d3 L - $ u; B# e/ c; Y: y* ]
- systemInit();//系统初始化
. ^$ ?: X! ^" R) { - % Z/ a$ k& X1 ]$ z) w
- while(1)
' L5 q/ }+ ^9 c# g6 u - {: W1 T7 q) Y( }3 @- H! n
- //在第0-1行显示温湿度和光照强度& ]5 C* b$ k) d, V
- DHT11_Read_Data(&temp,&hum);//读取温湿度
5 N+ L2 s. D( C/ W: A/ ?% A - light = Get_Adc();//读取光照强度3 ^* |' c2 {, W$ ~" p3 G
- sprintf(buf,"TEMP:%d HUM:%d",temp,hum);//格式化字符串
# n" y& I: S$ u - LCD_P6x8Str(0,0,(u8*)buf);//第0行打印温度和湿度
/ {5 O$ F7 J# L/ s - sprintf(buf,"LIGHT:%d ",light);//格式化字符串
$ s( l2 ]2 Q% F$ M - LCD_P6x8Str(0,1,(u8*)buf);//第1行打印光照强度. `4 ?* T' k9 \3 V4 t9 w1 \8 b, @
- //默认就是智能控制模式 temp > 30 报警红灯闪烁 hum > 50 风扇开 0-2000开一个LED 2000-4500开两个灯; b. |0 O' ]( p% y* K) b% o
- if(!status[4])//status[4] 初始值是0 . ?9 `! ~9 P8 y/ S& p/ [8 B7 }7 D7 G
- {" q& X" ~, R; M% \+ k# G! L
- //温度6 V/ N+ \5 ^" U
- if(temp > 30)
, v: U5 |) r7 N! L0 G- r5 W/ z3 ] - {! ]; s7 H* p# j
- buzzerSwitch(status[3]=1);//蜂鸣器响
* g i$ E& u, m) q& w - ledSwitch(3,1);//红灯亮
+ _+ G- j* b% K8 Y2 A) r - main_delay(200);
: K4 f h Q2 B* C" g0 G( i: k - ledSwitch(3,0);//红灯灭; W% |' h) B# ]5 M# L9 t7 _/ J5 k, L
- }( Y% p1 M$ j5 x/ ?' Z: L0 J
- else3 L7 a; S& x5 g/ l U: o1 p' y
- {4 n3 w/ S& d C6 v) o
- buzzerSwitch(status[3]=0);//蜂鸣器关
" F0 ~" a/ d+ }3 f! a( o& ~9 f# I - ledSwitch(3,0);//红灯灭3 f- M }3 ?. L, a/ [: I
- }1 d" x- }- X8 E9 F6 n
- //湿度
8 t# f$ }. E2 y4 \6 B1 I - hum > 50 ? fanSwitch(status[2]=1) : fanSwitch(status[2]=0);
+ q) g- o$ ?7 u8 o - //光照强度4 `6 L1 L! a H( l2 K
- if(light > 0 && light <= 1000)3 v- _# ~, X3 N( E
- {
3 B X- a; V7 W3 E# M+ J* h - ledSwitch(1,status[0]=0);//1号灯灭
$ E( T! d5 \. n) a& R - ledSwitch(2,status[1]=0);//2号灯灭7 q' `5 u0 s& E* e. F: z y- ?$ s
- }
& Y5 {" x9 T6 z ~ - else if(light > 1000 && light <= 2000)
" [1 O, G2 _' ]; T! z/ l# q - {, i" p+ ~. h6 w7 o7 I+ I, i
- ledSwitch(1,status[0]=1);//1号灯亮
" S$ W# Y0 A& n& w - ledSwitch(2,status[1]=0);//2号灯灭; l0 t3 F2 y8 w- O2 h! W! C
- }: y3 I( M; d5 A1 T, ~- |0 Z
- else if(light > 2000 && light < 4500)" {) g7 F z' L" e
- {& ]7 d' r" c! t% q* O
- ledSwitch(1,status[0]=1);//1号灯亮
) k8 N0 d) }- L/ ?) B( k6 X - ledSwitch(2,status[1]=1);//2号灯亮5 i& Q+ g; C1 L2 |" r* {% w
- }
* S* c* X* N$ L8 H - }, \; `: ^) n" H0 ?4 E/ H
- //在第3-6行显示菜单9 q4 W, M* N( D1 X/ z: ]$ L1 t
- for(i = 0; i < 4; i++)//i == 0 1 2 3( \! \2 N# p8 a3 t6 o: x% q
- LCD_P6x8Str(0,i+3,menu[i]);// i+2 3 4 5 6 行
% c3 I X9 y% Z7 d% H - LCD_P6x8Str(40,flag,"*");
- w2 c; m7 l7 u1 e - 0 K1 E+ E7 M) O3 h& E1 w& Y# g( y
- //添加按键输入, q8 `9 o* L2 X$ j
- key = keyRead();
3 ?" _7 r# K2 i. V9 w - if(key == UP)//向上键
+ W9 A( q2 u+ E4 E- M; c e - {3 `6 ^/ M% p% i/ R: ~
- LCD_P6x8Str(40,flag," ");3 b$ F. B! A7 y& `/ ~0 }
- flag = flag == 3 ? 6 : flag-1;
" f5 z% n+ W. i" A% K O - }! o; r# \ Y9 m
- else if(key == DOWN)//向下键& l7 ^: h7 i- B) X& x$ I+ f
- {# l7 P9 t9 |8 R: S0 `1 o
- LCD_P6x8Str(40,flag," ");8 `! |0 \: J2 `
- flag = flag == 6 ? 3 : flag+1;
- x& b& }& k) x2 D - }
, @ `# f2 `) X$ j, U& h - else if(key == OK)//按了OK键8 u/ V, M- j: [5 y7 W% m) ^
- {" v p' x& O; K- H* F* B: c, d
- //判断星星在哪一行,控制哪个器件
% n7 R! k. J8 e- T/ Q# s3 h - switch(flag)- w' I; c$ R7 D" F
- {
# [( V! o) Q2 D4 f. V - case 3://LED1: z+ ?7 z3 {2 [! I+ b: K: a
- ledSwitch(1,status[0]= !status[0]);
% C( J' Y) [( a# I" U - break;/ u) }! p& ~. J/ j0 h/ V) d, |( n
- case 4://LED2
" R7 l) \/ ~9 E& T* b4 W% P( t6 | - ledSwitch(2,status[1]= !status[1]);
* H1 h; M! T; h+ d9 n$ k& z - break;
# D) C5 |$ q& C1 J- H7 | - case 5://FAN5 E; L+ b1 z% T$ W$ W& y* ^
- fanSwitch(status[2]= !status[2]);5 s6 R1 z2 i4 q! R5 V' \: P6 p3 d
- break;
* r, f, a( S* A% B: J% z - case 6://BUZZER
$ E! l. F. v! S2 m- T - buzzerSwitch(status[3]= !status[3]);: R, J, d3 X$ v( F+ A
- break;
2 T* t' @8 A/ ` - }: x* A- v5 t8 p5 @0 J
- }; T( a- f9 M( A& @5 p9 P7 R8 Q
- else if(key == MODE )//按了模式切换键- Y9 m2 U) `2 u& @4 e6 x4 ~' C" v7 @
- {
- j3 i2 y! J; @! o - status[4] = !status[4]; z; W- k# H; P8 L
- }
+ |/ H5 S5 `( d* H+ u' z) [: C - / Z. |! \5 r; D% d( P j' M. [
- //在第7行显示 开关状态
, a& w; m/ n, Z. y2 A - sprintf(buf,"L1:%d L2:%d F:%d B:%d M:%d",status[0],status[1],status[2],status[3],status[4]);
' L7 _6 M5 o/ r+ h3 v# n% r - LCD_P6x8Str(0,7,(u8*)buf);//显示到屏幕上
& B# [7 r/ {7 h4 m) I) a2 K - * s4 t0 m4 h3 c0 o. B+ Z9 R2 W
- main_delay(200);- _9 l7 D& ~6 ^: ]! o$ i, q3 _
- }; V: a3 x. r! o8 i- w
-
5 R k4 t/ Y! l4 a6 o/ K% D/ L! w - }
复制代码
1 B! L; Q$ O$ M' m& ]' O2 S' i- N) J2 K B
8 A5 Z; f% \3 k
|
早上好啊,好东西要分享出来给大家