|
STM32嵌入式实现智能家居控制系统 - i W9 ]0 q# U- l
; k; t7 s9 b' Z; _' b2 K
本文将讲述如何用STM32嵌入式实现智能家居控制系统,所谓智能就是实时监测自主控制一些因素,如,温度、湿度、光照强度等,当室内光线较暗时自动打开灯,根据光线亮度的不同开灯数量也不同,当室内温度过高时红灯不停的闪烁,蜂鸣器也报警提醒主人室内温度过高要打开空调,当室内湿度过高时风扇开始工作,让室内湿度降下来,那么如何实现这些功能呢?下面我们开始介绍!
% K6 t, I2 b% p$ ?6 H5 C8 m. u+ ^# L8 x( B1 c) W; q0 N
一、本文用到的器件有:" p0 y; i3 h( d! L4 s5 ^- `$ u
STM32F103R6 单片机/ M3 k: I" a) ]6 W2 z6 v5 i
LCD12864 液晶显示屏: X* @; J6 `8 C: x. h
DHT11 温湿度传感器5 k$ _0 w0 R; x) @) r
RETCH 光敏电阻
, R$ }3 f/ E7 n1 {0 r$ qFAN-DC 直流风扇
8 y, @; g* j- t! l- A4 uBUZZER 蜂鸣器
) v4 [6 t8 k3 r+ e2 h# V2 O电阻、按键等
( u, P* L. L+ g8 T7 \0 ~3 n. B( N6 Z2 A Z$ \) a: O
* N% e. e/ O$ k& ]# e! X二、实现的功能是:8 `3 p1 x j5 w
有两种控制模式,分别是默认的智能控制模式和手动控制模式,按下按键MODE可切换控制模式
8 L; A9 n) K, E7 r+ s: l$ L9 Y W, x" [- U4 T
# `# e" f5 w8 y0 L% p" T) k1 J智能控制模式中温湿度传感器实时监测当前温湿度,当温度大于30红灯闪烁,蜂鸣器报警,当湿度大于50时,风扇工作,当光照强度小于3000时点亮一个灯,小于2000时点亮二个灯
. Z0 p) t- t; I& }4 a7 _' [8 L7 ^7 q
) j! N y0 B8 Q/ P0 ?/ M
- S, [( F f e$ g9 g手动控制模式中,按下UP键或者 DOWN键可上下移动光标,按下OK键可打开或关闭当前状态
2 i' g$ y# s$ O/ v% U7 N3 N- J. h2 |* q6 g3 A
# r0 r$ f; T6 \! D自动模式中手动可调节,手动模式中自动模式不能调节3 f# e" r2 o: P z- n1 t" |
, \! | x7 K2 c7 f+ I1 T3 N6 \7 ^- S, w4 l
三、原理图如下:* Q4 P! m" O' m/ x# Z& Q
四、代码实现:" v$ `: k2 u6 s: g2 Z
+ o1 Z# q' a' ^6 T/ N+ r- #include "stm32f10x.h"
, I3 S# R- \9 k - #include "LQ12864.h"# R) {, x4 z) @$ i
- #include "DTH11.h"
8 Z" j) M5 j6 @' N( s! a - #include <stdio.h>1 f' d6 H1 F2 z2 e) E0 [+ |
- #include "adc.h"
& o% {3 u- u/ Q+ H- C1 w - ' O" o5 `! d! n% u
- #define UP 1
8 v. l+ ~4 R4 m - #define DOWN 21 J9 I/ r# v6 E1 Q$ z. v5 K7 m
- #define OK 3+ j Q8 `" a8 ? L# [$ y G
- #define MODE 49 H' |$ f+ [! W* ?
- #define NONE 0
2 O# ]# S# i, b* H# t. B
( H6 S Q& w4 P+ z
& E7 x4 r" ^6 P- void main_delay(int time)0 e) l) N. L) f8 {: a9 Y% Y9 p
- {
! E, P# u" B N. c% A1 o4 P - int i,j;" [1 Q- L5 h- I1 e/ F" X
- for(i = 0; i < time; i++)
) K4 \1 @ s) Z) Q - {0 ?% M: } [" P: r2 _
- for(j = 0; j < 1000; j++)) m+ T) i1 c/ P' S
- {' B2 u+ P& { x! U, M3 q- a% z
- j++;
2 c. Y& D6 t+ C6 y" I* s/ c& X - j--;1 z7 W) H6 E- G9 O- f$ ^1 _: i
- }1 P# w2 H9 S5 h) O$ N% s0 G4 L K
- }8 H, k a3 _2 y! M8 M" S
- }
* k/ x4 B6 D9 r( F4 z1 _
6 J7 Q. B8 S9 D* {+ k. Q- //按键初始化
0 i( N) u% ~+ E6 I9 L8 [9 U - void keyInit()
* S1 e! r" @7 r: c0 B1 O, O; R - {
( N# N. z- H" \" E5 _5 d - GPIO_InitTypeDef init;
( ^% ?; b2 k; x1 D - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);$ S3 B) o8 c/ ~- B9 c
- init.GPIO_Mode = GPIO_Mode_IPU;//输入模式
2 G! X& p- a1 M - init.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
?+ ^/ j2 \" }% p, _% a( f - init.GPIO_Speed = GPIO_Speed_50MHz;4 g/ C; l) ]0 Q' n; _6 h/ _' t
- GPIO_Init(GPIOA,&init);; ]9 [. c/ r) ^0 U9 K! ^* i
- }
$ c- u6 n8 p2 o% x6 B3 ]0 P( z - //读取按键的值
9 v0 A' m! Z7 T, e% W( ]: t: } - int keyRead()
l2 G" q H- |' ~9 S" J8 `6 }9 o# ]8 t - {
$ `; o7 y& f5 c' Y( u1 w - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0)
* p0 o8 R, B! p( }" Y* h( J1 h - return UP;//上
, U1 _2 f% R2 K4 l. ? - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0)
, U# I T9 V! g - return DOWN;//下+ K, \6 _. N w$ |+ E$ _
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0)' S/ V1 T3 c$ v
- return OK;//确定% S% W: c$ U* Q# r
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0)2 @1 S/ D7 D3 t& |
- return MODE;//模式切换- o3 N" W# c3 {4 i6 Q8 N2 t; [
- return NONE;! u/ {6 n- S \& L- K
- }
/ ^3 F+ |$ t f* o% Y# m5 j - 7 K* l b6 u+ t% S6 P
- //风扇初始化6 @0 S l5 o# i) S% ?, W$ E7 [
- void fanInit()5 o1 A9 g. P& v2 [( t/ C
- {
3 C/ |$ \! k$ }5 r" Y2 k - GPIO_InitTypeDef init;4 j0 p4 `% g( w/ z# T# e. K
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
4 A6 V0 G/ R3 x0 s& V: `6 U$ O - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
: B) a, x2 `0 S6 g, h D( @ - init.GPIO_Pin = GPIO_Pin_1;5 A( a0 C2 V& }/ D B+ `2 h; A) {. {
- init.GPIO_Speed = GPIO_Speed_50MHz;
- U2 h) X1 W& f* I* ? - GPIO_Init(GPIOC,&init);
9 A* S# [' L8 d5 d) {. ?5 |1 r - GPIO_SetBits(GPIOC,GPIO_Pin_1);//置1 风扇关
- O5 K7 O, o2 S( S - }& v& {. J- H: C; y* ^2 R
- //控制风扇开关 fanSwitch(1);//开风扇 fanSwitch(0);//关风扇9 U |+ _0 {8 |2 @! _
- void fanSwitch(int sw)// 参数 传递1 开 传递0 关
, P; @6 F: F& A, X8 U8 `# n - {// 1 真 0 假 真执行:左边,开风扇,假执行:右边,关风扇, c0 j h6 ]3 H/ j# Y6 z- s
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_1) : GPIO_SetBits(GPIOC,GPIO_Pin_1);, D! H3 s+ _+ e/ R1 `* X" Y2 _5 T
- }" g" X# q: f, n
- 1 n4 I, d+ h. w9 a" V V( }
- //蜂鸣器初始化
# V& Z" q" r) d. a - void buzzerInit()
& P# p) Z; w C/ \7 \% z# |/ g% p; j3 z9 h - {
j$ U1 V9 E, c2 L - GPIO_InitTypeDef init;
- B5 ~% [% n! u - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
/ {4 e& M1 P2 Z5 ^) E - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式% N! k/ z# M4 L
- init.GPIO_Pin = GPIO_Pin_2;
% ?& y) z7 k0 d8 x - init.GPIO_Speed = GPIO_Speed_50MHz;
& h y0 d& k9 K, m- Q8 S1 ^ - GPIO_Init(GPIOC,&init);6 Z t7 J/ R1 A0 n
- GPIO_SetBits(GPIOC,GPIO_Pin_2);//置1 蜂鸣器关- ~, U" `5 ^" p$ m1 l" }) K
- }1 F; [! w0 d& `
- //蜂鸣器开关% C& K3 U( B& F/ k- o3 X9 H' B* Z v' } l
- void buzzerSwitch(int sw) //1开 0关. {1 }- p2 Z3 q8 F9 u
- {
( G/ v+ U- x! | - sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_2) : GPIO_SetBits(GPIOC,GPIO_Pin_2);/ y9 O$ C1 t/ B0 M7 H3 Y& S
- }( \- |! k2 }2 E) m2 B. y* ^% A" \+ K F
- : e$ d( N4 u! a1 j: c' J
- //LED初始化
# z" o m9 A; {7 B# l( a; G& ^! Z - void ledInit()& z) J. b) l% C
- {
& x9 W o+ ]5 s" i - GPIO_InitTypeDef init;7 A, {3 I7 `+ W8 ~* p! x2 ~9 ?. `* r
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);0 F/ w/ A1 r1 I% `
- init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
. A, q4 Q. l% F* W9 |$ V - init.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;
. _1 Q7 @3 v+ g5 ^ - init.GPIO_Speed = GPIO_Speed_50MHz; Y; P$ q1 b. Y8 ?& M$ h/ `
- GPIO_Init(GPIOA,&init);
$ C" F1 ?, q7 Z9 E - GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7);//置1 LED关
; a; y( F8 y& n2 c0 u - }( a( W- [# G7 v4 b9 B8 s
- : g( R8 E+ a, X2 A8 s* \1 h
- //控制LED的开关 ledSwitch(3,1);
5 d, c* e- c: h4 ? - void ledSwitch(int n,int sw)//n代表灯的编号 sw 1开 0关( V" X+ ?' Q8 g& q( o
- {7 w: B) r u* ~9 [4 \2 z
- switch(n)
9 o% g' g* X2 a3 ~1 H& J* Q. e - {" l5 G% e+ O3 ]
- case 1: //编号为1的LED+ C+ G! G5 ^! D( G
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_6) : GPIO_SetBits(GPIOA,GPIO_Pin_6);
8 e) I+ ^4 \, B1 c$ o! c - break;1 [* B- [- F. d: w
- case 2: //编号为2的LED# e2 K+ L) V; X* j: `
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_7) : GPIO_SetBits(GPIOA,GPIO_Pin_7);7 ~$ X: T: k: z
- break;
! z' d4 g/ U, h3 ?3 q) U6 { - case 3: //编号为3的LED/ g# v: t5 [4 A# _9 I) p
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_1) : GPIO_SetBits(GPIOA,GPIO_Pin_1);" W6 c! J/ X* I! M
- break;
; t' n( b5 @+ u1 ]% q2 S" q - }
/ u2 x7 K; k4 O9 H8 }* @ - }8 `2 S# R, l$ S1 X. S3 X z) ^
4 @5 @/ a7 N( E8 Y: E
8 ~, s& F3 A F; W, d1 g- //系统初始化函数(相关初始化的函数)* z3 P" u7 e* U) k
- void systemInit()
3 p7 `7 J( P# P - {3 p/ o7 X* a5 ] z: L- u' U
- LCD_Init();//LCD屏幕初始化
; o$ {" o1 T6 p5 P: Q - Adc_Init();//ADC初始化5 [8 D t. B# N* c) Y
- DHT11_Init();//温湿度传感器初始化% q9 z& t( U( l- b+ M; X
- keyInit();//按键初始化
4 ~" o1 z* V' ?, r) B - fanInit();//风扇初始化
* x8 j( g7 Q( r8 h% o" V, {# U - buzzerInit();//蜂鸣器初始化
6 E4 R* R7 V8 A3 M" F$ B! C: e! T - ledInit();//led初始化
; a5 C: V8 r: g) r - }
, |& J9 W1 _8 ~' D: k - + ?7 i3 E/ y0 D" ^# P- x7 i. `* U, e
- int main(void)
! P' W: k" O* z, l! e0 ~ - {
0 [2 @6 z% C6 _' W' n- s9 s - char status[5] = {0,0,0,0,0};//LED1 LED2 FAN BUZZER MODE 状态 1开 0关
: k* [* |9 [" Q$ J1 z3 i+ Z3 F - u8 temp,hum;//保存温湿度
" j; C/ j* s( L; t# T - int light;//保存光照强度
3 @! h- ]8 d" m6 [ - int key;//保存读取到的按键的值
$ ^6 ]/ G1 U% s - char buf[100] = { 0 };//用来保存格式化出的字符串
" p) a. J( @/ G - int flag = 3;//flag时刻代表当前星星的行数1 _, ?6 {% J( k( R8 k
- u8 *menu[4] = {"LED1","LED2","FAN","BUZZER"};//字符指针数组
4 J" W+ u) n& ^' M - int i;//循环变量
3 e5 {+ X A, H# I6 j! y - 4 I* j0 G" S/ o# g9 `, y' r
- systemInit();//系统初始化/ B+ E. L* m0 W- v4 k) v# x' u2 y
- $ L: {0 ^6 @6 o
- while(1)* u- H G. |, L) B; E
- {/ l, z4 f( L: [5 Q$ b; Z. O8 w
- //在第0-1行显示温湿度和光照强度
# R; S7 R# k$ Z& {; X0 ^) F - DHT11_Read_Data(&temp,&hum);//读取温湿度
( i' j( I( ]# [) c; { - light = Get_Adc();//读取光照强度: ?" A5 X6 k) G
- sprintf(buf,"TEMP:%d HUM:%d",temp,hum);//格式化字符串
x' j6 s! b5 _$ l! n) r" Q: S - LCD_P6x8Str(0,0,(u8*)buf);//第0行打印温度和湿度/ N0 L) }- I6 R. |+ d
- sprintf(buf,"LIGHT:%d ",light);//格式化字符串/ ^1 z/ X* ]* v0 _7 `
- LCD_P6x8Str(0,1,(u8*)buf);//第1行打印光照强度' F; Q% `2 _6 r0 X
- //默认就是智能控制模式 temp > 30 报警红灯闪烁 hum > 50 风扇开 0-2000开一个LED 2000-4500开两个灯2 |$ p v% @( U5 G
- if(!status[4])//status[4] 初始值是0
5 `7 { |! f. V - {
( I& c8 G) I) l; a, l4 D - //温度
4 D" i0 {7 ~4 G0 G - if(temp > 30)/ \ @/ G. ]7 I5 |; U L4 R3 t
- {: w' O2 r9 D* `/ |6 R2 q
- buzzerSwitch(status[3]=1);//蜂鸣器响1 Y* @' m3 U( T7 D! m. f1 B
- ledSwitch(3,1);//红灯亮; G9 {" Y3 M0 n+ W3 O( ~9 e
- main_delay(200);
0 w" _8 i1 P& Z1 @6 P. v - ledSwitch(3,0);//红灯灭
- q- g6 Q0 _9 \0 {$ F. n - }" B) `8 y' g0 v
- else1 `7 B! `5 n) s) O) {5 E
- {, U6 i1 \& {7 Q4 y3 Z
- buzzerSwitch(status[3]=0);//蜂鸣器关# }. U7 Y- O+ n, j2 K* E. U
- ledSwitch(3,0);//红灯灭
1 U; B9 f! [+ \9 b) A - }6 Y: H& K( u4 @; `, v, P: x
- //湿度+ t* q/ R: `5 u7 R8 j
- hum > 50 ? fanSwitch(status[2]=1) : fanSwitch(status[2]=0);1 T; G2 X2 i/ r% j! j
- //光照强度
5 v5 [/ m+ V) @8 v1 K2 e - if(light > 0 && light <= 1000)
0 Y9 j/ m* m) ?; N$ H' W5 P7 ? - {
! G2 [6 k3 q% G- D7 D3 w - ledSwitch(1,status[0]=0);//1号灯灭
8 d! L& G2 E7 Z$ n( q% m - ledSwitch(2,status[1]=0);//2号灯灭! G) U* H7 G" X9 E& J
- }
0 \# P' l$ V) O- Z7 E1 V9 U - else if(light > 1000 && light <= 2000)
+ r# l" G& d& n2 ~ o - {
( f4 O. h( ]- T5 b) k - ledSwitch(1,status[0]=1);//1号灯亮/ t5 J1 e7 F; [
- ledSwitch(2,status[1]=0);//2号灯灭3 h' u( e+ p2 d) r+ @5 M; V t
- }5 ~! z+ r% e$ U0 N' p7 B# k
- else if(light > 2000 && light < 4500)
+ Q' w% _5 A2 s4 i - {
8 @. U! \; n v8 k) C5 g - ledSwitch(1,status[0]=1);//1号灯亮
+ b3 D: F4 m% r- J9 }1 j N G - ledSwitch(2,status[1]=1);//2号灯亮 Q& ~1 g3 w. T4 x! T7 [/ U. z
- }: K: j, U& O: ?1 i, a. L0 J4 k" w
- }$ A8 K6 T9 R9 K) Q; `3 E
- //在第3-6行显示菜单
- t6 I) C# p& v8 d! U% |) W& m - for(i = 0; i < 4; i++)//i == 0 1 2 3! K0 f; m2 ^/ ]4 p/ v
- LCD_P6x8Str(0,i+3,menu[i]);// i+2 3 4 5 6 行6 Z: d7 j& g: }' R4 J/ R" r
- LCD_P6x8Str(40,flag,"*");
) Q8 t1 i( k3 S2 a -
, e& i# j, l& F# f, b - //添加按键输入
# ^! L2 ]4 n- h" |5 q8 G$ P - key = keyRead();! [- P z: C: x4 L
- if(key == UP)//向上键
- k; ~; P( _& g# G1 ^7 V - {
6 e4 J/ x, D! i3 d, @ - LCD_P6x8Str(40,flag," ");9 \! v/ p( O2 T+ K$ X
- flag = flag == 3 ? 6 : flag-1;
) ~; C0 d f5 q' j4 W3 {) m - }
. p) w' i% m2 Z2 C: [# e - else if(key == DOWN)//向下键
4 B7 t0 I: E* y' L9 r - {" a- V$ m( t& B7 F& I! t$ U; `0 l- B
- LCD_P6x8Str(40,flag," ");
" P3 j F6 O/ m - flag = flag == 6 ? 3 : flag+1;
7 Y: @$ i, x! f* Q" i. ^ - }2 @: U1 q) D, @) @% b. }4 _
- else if(key == OK)//按了OK键& |: Q i. V. Q1 L H
- {
' O$ K: L+ Z" }* i - //判断星星在哪一行,控制哪个器件0 E# `& K0 t% I" j7 ]% A' ~4 c
- switch(flag)0 \* s; ~9 t5 z- e
- {
1 |: a% e8 Q6 J6 c6 [ - case 3://LED1
4 _2 c$ h" @4 W& K. Y7 i - ledSwitch(1,status[0]= !status[0]);
/ s$ k1 b# ^( b9 i* f( U: v - break;1 A1 i3 z3 s. `% X) K
- case 4://LED2
7 U; H( E/ [1 h L y6 h. l - ledSwitch(2,status[1]= !status[1]);9 t( Z3 V; `, v8 C
- break;
; @, }+ V8 v. J: j3 C% C1 p" D5 S" B - case 5://FAN
+ v: Y* T) u& ]* @% A - fanSwitch(status[2]= !status[2]);
" y0 I& t h Q - break;
0 n w; s9 `2 S) v- B( H0 M - case 6://BUZZER) ~% s3 Q7 x$ c: @
- buzzerSwitch(status[3]= !status[3]);- Z7 d5 V) S8 o) D! O: b
- break;
9 [# c: p8 G; R0 k+ z! Y- m% C - }2 d8 @- w) ]9 x T1 Z9 z. ^
- }3 x( ]1 G* a& p# D
- else if(key == MODE )//按了模式切换键+ v7 u8 z+ v6 W" P- {" i0 o
- {
% N5 g5 ]9 B- s! k - status[4] = !status[4];; ]+ a4 N/ b$ x% k/ b
- }
7 g3 H o) e. r3 [$ w -
5 V) c$ W4 t5 M! f4 u. R9 Z - //在第7行显示 开关状态
4 X; \6 D6 s. P9 K( u* P% u# Y - sprintf(buf,"L1:%d L2:%d F:%d B:%d M:%d",status[0],status[1],status[2],status[3],status[4]);
; R* F* T, i1 X* W) p$ Y, X3 R* s - LCD_P6x8Str(0,7,(u8*)buf);//显示到屏幕上
9 y$ C( z3 I. m% X, \ -
0 o) }" C2 ~' p( j - main_delay(200);, I r. n) Z8 g
- }
& C5 T, ~) I. h0 s! V) `- K9 H -
y0 t0 D# N. j$ J - }
复制代码 1 j' r( Q4 ] _ e% o& h
0 l1 |7 c& V0 |) _/ o
, ~3 e$ _ M1 t% r+ U. D$ f' v |
早上好啊,好东西要分享出来给大家