STM32嵌入式实现智能家居控制系统 ) D3 }# r: U! _1 e7 F: y v
) V% |' h$ n2 F$ j' M% i
本文将讲述如何用STM32嵌入式实现智能家居控制系统,所谓智能就是实时监测自主控制一些因素,如,温度、湿度、光照强度等,当室内光线较暗时自动打开灯,根据光线亮度的不同开灯数量也不同,当室内温度过高时红灯不停的闪烁,蜂鸣器也报警提醒主人室内温度过高要打开空调,当室内湿度过高时风扇开始工作,让室内湿度降下来,那么如何实现这些功能呢?下面我们开始介绍!7 ^3 U# B( G9 P9 b5 U8 z; b
! o) D/ ~& D% J& R一、本文用到的器件有:9 ^6 v, z4 j, v% Z" T# d
STM32F103R6 单片机 ~% e4 c* b0 H( c' O& Q
LCD12864 液晶显示屏* H% g! [1 g- P3 p' A# t. e
DHT11 温湿度传感器
; u" Q0 t! S* I LRETCH 光敏电阻: R- M$ W, m: C7 h
FAN-DC 直流风扇9 e) u# {7 N- O/ q0 B% I
BUZZER 蜂鸣器, w9 |8 X* a. ?- p
电阻、按键等
4 Q) `) x C: D- h# Q: r
6 w; U: z8 \5 F, T2 j6 k
$ u9 f' h+ U) @% `8 \; W' p$ t7 y二、实现的功能是:
2 z4 t) }- T! s9 J% H# S有两种控制模式,分别是默认的智能控制模式和手动控制模式,按下按键MODE可切换控制模式8 k+ @) Y8 K# k( q
& L2 J0 S/ I" g* M7 L$ V5 \! }
3 i+ p+ T' o8 i# G' o智能控制模式中温湿度传感器实时监测当前温湿度,当温度大于30红灯闪烁,蜂鸣器报警,当湿度大于50时,风扇工作,当光照强度小于3000时点亮一个灯,小于2000时点亮二个灯
. B5 Y1 p( B8 _; ]
6 `7 E3 [& J" z: j' f; J( D s$ _- z# A+ y) F! J+ o- g' E
手动控制模式中,按下UP键或者 DOWN键可上下移动光标,按下OK键可打开或关闭当前状态
2 U" P6 N- `1 @2 j6 U6 g4 ^. C* c
, m# ~" m( Y, @
自动模式中手动可调节,手动模式中自动模式不能调节
4 Q0 c( a. c3 Z+ I! g: k% A3 i
( u( a( ?, V Z8 _7 b- c, a8 X
' Z) Y" g9 [8 b. [* @3 y* p6 _三、原理图如下:8 o0 r% S9 p" L" x- |
四、代码实现:
5 N* L$ h' h2 F7 ~- ! @1 S6 |) l6 e8 ~$ d3 p
- #include "stm32f10x.h"; E# D! X' R; Q# r
- #include "LQ12864.h"
, K9 d6 Z" C4 _* ^ - #include "DTH11.h"3 H5 }6 F' s: g( `6 |
- #include <stdio.h>
: {" \- b0 X- F3 P8 Y2 `! y5 X - #include "adc.h"
2 n+ N4 T( L0 h3 t0 k1 A" H4 b - 5 W/ E/ m( e1 W- ?
- #define UP 1
& E1 l; u8 O/ o) P" i" [2 v - #define DOWN 2% f* m! o# L0 j2 [7 q; O4 `
- #define OK 3
, I; i( i: o* `( F+ V# H - #define MODE 4
: C" l; N1 ]0 Y x3 W7 @2 `# } - #define NONE 0' ^1 K2 g- w, a* s8 O& }
- " z* m+ Z8 U1 q3 S
- * L% ]" W! v: k5 |7 m( q4 u
- void main_delay(int time)
# Y9 t4 M) j# f3 e! I - { @( l/ P! H% s9 J1 O. \* N: T
- int i,j;
8 t0 j( c! {' [6 u, r- q7 h - for(i = 0; i < time; i++)
& X) T( {& }: ?( L% h - {) r. r9 R [) O; x
- for(j = 0; j < 1000; j++)
2 P# W- F, D) q6 h. V7 J - {* D9 S# d: M# I, W6 y' Q
- j++;
0 H$ J% e2 f( ]: t - j--;
5 S6 `2 R7 B. K# m2 x3 v - }
: ]- R* c, ^+ h0 u - }; p: X* F! u9 u$ _, J/ W/ [
- }
2 o) w5 L t1 W* u, J - ( ], V1 I+ t+ V0 N
- //按键初始化
1 v" T, f; h0 n( G' J2 J( e - void keyInit()8 v8 Q4 l2 J% \# t- |% ?: I+ {1 E* {7 v
- {4 M8 A+ {0 v# `' h' C
- GPIO_InitTypeDef init;! |4 q" H9 d3 O4 m5 ^
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
) X! i- r8 C" I" a3 M7 v2 s1 `& u' Z - init.GPIO_Mode = GPIO_Mode_IPU;//输入模式
, \! q6 c6 h- D( w - init.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;; k' v, u* O& O. w( U {
- init.GPIO_Speed = GPIO_Speed_50MHz;! G* d! a2 \9 V& _; B% d( A8 U
- GPIO_Init(GPIOA,&init);- G0 ]1 y) r4 D% \) r3 U' G
- }
7 e& x- g" Q- V" Q - //读取按键的值
. o5 l+ V- X/ h# ?* J/ d* i; F - int keyRead()" T2 q7 t) T( R6 n. K
- {9 v* V" D7 z3 T8 B& b# q
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0)- o7 |: R3 ^ k; }% o
- return UP;//上
" A8 s" _/ \6 d - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0) i9 O2 C0 }2 c& r! K4 T5 a
- return DOWN;//下, l p. u. [. m% _5 @( A
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0)( O- I2 h# u4 b3 B+ q# l4 l$ Q
- return OK;//确定 g9 k0 r o, h$ N' Z* ~% k5 R$ m
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0)
& d! {7 v! o5 G/ `% ?1 j! M - return MODE;//模式切换% R% G5 F0 `, J3 \
- return NONE;
5 G' t# a6 W! W5 u9 r - }
, d0 @! t5 I5 ?; I7 t - 3 H9 l; X1 B& Z# `! _0 k6 B
- //风扇初始化
0 R7 o! I' q! j. A7 t, F" z, @& ~ - void fanInit()8 h, c6 i0 ?! \- C" C* d
- {& z1 }4 Q9 Z; p# D/ T, S: J+ Q7 N
- GPIO_InitTypeDef init;
! d; ^0 l: R/ i7 F - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
9 A+ g/ d! Z: L% y- H - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式1 h0 d2 W7 {: i: v; W# W Z- F
- init.GPIO_Pin = GPIO_Pin_1;
: I& k8 ?( X. _ - init.GPIO_Speed = GPIO_Speed_50MHz;
9 q; s& z; ^9 {/ [$ N" l7 U - GPIO_Init(GPIOC,&init);
6 u' S: y9 N( N, d) m8 b - GPIO_SetBits(GPIOC,GPIO_Pin_1);//置1 风扇关: M% @4 n/ V* a1 R# o9 h2 z ~
- }0 h F* T1 w1 N( U! z# S; P& T3 \4 m* p
- //控制风扇开关 fanSwitch(1);//开风扇 fanSwitch(0);//关风扇2 x0 ^; z- N' ^+ {: V7 z
- void fanSwitch(int sw)// 参数 传递1 开 传递0 关$ ~ l: B7 \4 j2 {0 N
- {// 1 真 0 假 真执行:左边,开风扇,假执行:右边,关风扇) S' m- m4 b- c3 D& J2 N" L
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_1) : GPIO_SetBits(GPIOC,GPIO_Pin_1);" q) Y' O8 G! h" _# c$ [; M+ i
- }% f6 U' |. x- V7 Y) d
9 Z! e9 X* N; t2 t) B2 Q- //蜂鸣器初始化1 q6 f5 g9 \( S- h, V
- void buzzerInit()/ b# ^4 a5 _% z& A& P
- {
" { l2 p6 a0 ~+ p) k - GPIO_InitTypeDef init;" U5 B( z$ L$ E4 j' Q. N
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
3 Z( A m$ t" H. j - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式4 e, J- e5 p6 V: Q
- init.GPIO_Pin = GPIO_Pin_2;; W& }$ k; M/ E: X+ C
- init.GPIO_Speed = GPIO_Speed_50MHz;
+ B L: p3 M" r( b4 E/ q3 h/ X% e& K - GPIO_Init(GPIOC,&init);; H: Q1 G2 r- t
- GPIO_SetBits(GPIOC,GPIO_Pin_2);//置1 蜂鸣器关
+ v2 @' o" W# V# A! p1 S2 n+ x4 P - }
, j/ U/ z! _5 [7 ` - //蜂鸣器开关
7 F" e' k- s; I6 Z - void buzzerSwitch(int sw) //1开 0关
1 ~4 @3 t/ E, F' S, K - {$ k6 Y0 W/ T8 f- o/ o
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_2) : GPIO_SetBits(GPIOC,GPIO_Pin_2);2 o! N; a5 Q( l$ f4 G" M
- }
, m: d! J; F- q$ R% {
0 v$ c n! S/ ?1 s; @ s- //LED初始化9 S- B& T# I% I
- void ledInit()
7 _& [1 a3 D1 t& c: e - {
" j( w6 B1 d* q8 V5 |, w# { - GPIO_InitTypeDef init;
1 l2 e, ?2 }+ ` V5 S3 Q - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
( S, w. d3 w* ] u - init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式' S7 O" F. P" ?7 X, z& m
- init.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;
3 d2 z: B9 r% v5 v V - init.GPIO_Speed = GPIO_Speed_50MHz;
9 ^$ W% M% q8 n7 I+ C - GPIO_Init(GPIOA,&init);
2 d3 L4 _+ {% r6 a, U - GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7);//置1 LED关
" w$ r" s% u. c7 z3 Q3 ~ - }
/ r, a: i8 ?3 @* n, z6 j' x - # e/ f8 I; S! @( T( F
- //控制LED的开关 ledSwitch(3,1);
$ j8 ] s, T& c. A1 U A8 f - void ledSwitch(int n,int sw)//n代表灯的编号 sw 1开 0关
. S9 j( E, A0 B- J - {
( b5 X0 \: _9 i& I9 U' W& E& G$ ?$ c - switch(n)1 r0 O7 d+ x' H! g
- {
( m& |6 a6 R/ I3 C8 W! B* z - case 1: //编号为1的LED4 n5 _0 f/ V% q& b6 n6 `
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_6) : GPIO_SetBits(GPIOA,GPIO_Pin_6);
; Z2 X/ R/ W, I; x8 m - break;
& L% o/ L. C8 `% N% y( V2 n - case 2: //编号为2的LED
) a8 Q$ H, \3 Q+ }- }( x! Z3 W - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_7) : GPIO_SetBits(GPIOA,GPIO_Pin_7);
% y* f- k. }% p- {! I8 Y: ~4 r& V - break;
$ O( z4 u |1 A% R - case 3: //编号为3的LED1 K" t' p3 \3 r- b
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_1) : GPIO_SetBits(GPIOA,GPIO_Pin_1);
6 w1 H" k* ~5 v/ q6 m* B - break;; y) H# F5 C- \: r
- }7 Z M: O! T0 W) @
- }. o3 P5 f& j# k9 o
l9 G1 x% Y: D& E \; u6 U
$ V/ `' T% ~' ^3 M+ e6 Y- //系统初始化函数(相关初始化的函数)
$ Y' T8 _/ A- G6 L1 _! _ - void systemInit()
' c5 \2 `1 A; E6 l2 L5 ?& E - {& C. X, O$ a+ @" |2 i
- LCD_Init();//LCD屏幕初始化# m* E U- O, p0 V, l& m+ w
- Adc_Init();//ADC初始化
" d- C' c+ @0 Z2 G" C - DHT11_Init();//温湿度传感器初始化' E, S& u% J4 c
- keyInit();//按键初始化
2 s/ ?. z' _$ }( [7 s4 y' O - fanInit();//风扇初始化) L: W% \4 E' a. w. R
- buzzerInit();//蜂鸣器初始化; Z) G" d0 r! O( g2 F2 J2 e
- ledInit();//led初始化
+ h7 x: X! `+ H+ i! `& s - }
7 I9 k" l% s1 H, H1 ]% q0 K e
) @; ]1 d; z5 \9 S) H% b- int main(void)
" m* u% Y8 L2 c1 f5 A/ f6 Y - {
0 O5 ]8 E: ^0 b& L3 `; f - char status[5] = {0,0,0,0,0};//LED1 LED2 FAN BUZZER MODE 状态 1开 0关4 N8 X& A: ?8 {* G0 \) ?
- u8 temp,hum;//保存温湿度+ V x- R# `' d
- int light;//保存光照强度
F6 R: [5 V/ l - int key;//保存读取到的按键的值
3 a/ Z1 B3 x7 i0 ]) i+ Z - char buf[100] = { 0 };//用来保存格式化出的字符串6 r# j/ [ ?% j& v% I2 Q4 d
- int flag = 3;//flag时刻代表当前星星的行数
0 d7 L1 q# i+ w8 y: n2 U - u8 *menu[4] = {"LED1","LED2","FAN","BUZZER"};//字符指针数组5 A6 m( J' [$ c; c' d
- int i;//循环变量" v- X2 E: P7 n# c
-
7 k4 K& P5 X" |2 a' i - systemInit();//系统初始化3 a- O: L2 h$ b6 i$ z( d4 m
- 8 v; z. J! |: R# V% |8 `+ g4 ~
- while(1)0 n) X! l) Q& K8 X* e
- {
9 k3 Y8 b8 u0 o9 @) i9 X - //在第0-1行显示温湿度和光照强度
. s) J& D! t2 T. h - DHT11_Read_Data(&temp,&hum);//读取温湿度
+ C ?: K+ x% n" z1 P$ o7 t* f - light = Get_Adc();//读取光照强度
V+ |" h2 r0 X# X- c - sprintf(buf,"TEMP:%d HUM:%d",temp,hum);//格式化字符串
. W" Q1 Y! W- A+ |8 W/ o - LCD_P6x8Str(0,0,(u8*)buf);//第0行打印温度和湿度6 L, }" O! R, ~3 i2 l. G# q
- sprintf(buf,"LIGHT:%d ",light);//格式化字符串
: c& W3 S% U" d3 X: z0 e - LCD_P6x8Str(0,1,(u8*)buf);//第1行打印光照强度& N& ]% l, y/ n4 w4 i
- //默认就是智能控制模式 temp > 30 报警红灯闪烁 hum > 50 风扇开 0-2000开一个LED 2000-4500开两个灯$ z( k( t# c( h) v+ J. |. [
- if(!status[4])//status[4] 初始值是0 $ y3 g$ i' I0 Y$ [& [
- {# G# A2 S9 j! T- i) p# u
- //温度% |6 Q. y; l( }9 ] ?
- if(temp > 30)$ p/ ]: o# I! k1 [8 O2 s& A" h. q
- {
3 B+ M ^) ~5 b - buzzerSwitch(status[3]=1);//蜂鸣器响
; X4 g& N. W* i5 l/ v* e7 k# }3 b/ N - ledSwitch(3,1);//红灯亮0 I) ]6 Q, N/ R+ k7 ^& d) y
- main_delay(200);3 z' ^% a: F' A3 \
- ledSwitch(3,0);//红灯灭: `2 ?! M- i8 Y
- }. L8 r; H/ Q1 S* h2 I9 n
- else2 e3 j5 J+ \/ ]
- {
) Y7 X2 z& D$ W/ J - buzzerSwitch(status[3]=0);//蜂鸣器关
( G6 M" b# o. v- m5 G1 {: c5 e( T0 X - ledSwitch(3,0);//红灯灭0 w. ~0 ]& S+ b
- }# M1 }4 a9 R, d U1 A [6 j
- //湿度
; l d7 [1 o. N5 E! `5 w7 U' ~ - hum > 50 ? fanSwitch(status[2]=1) : fanSwitch(status[2]=0);# P8 _$ J* }6 G% P: v1 l& t
- //光照强度2 M3 E- A/ u3 ^: h. P" X N4 }. l; D
- if(light > 0 && light <= 1000)( Y, y9 y2 G' ] c- G% W3 ?7 {
- {) c9 z7 c. j% A/ r6 ]6 `5 p- q9 e
- ledSwitch(1,status[0]=0);//1号灯灭
& w6 ]& U: g0 a, W( g+ k2 K$ M7 U - ledSwitch(2,status[1]=0);//2号灯灭0 |" \4 U$ O( K
- }
0 e+ u. m O! Y" H3 b( l3 _7 S& _ - else if(light > 1000 && light <= 2000)
0 F6 @& r: [7 a) c - {* U. Q: I6 _! k+ M! L! o0 |
- ledSwitch(1,status[0]=1);//1号灯亮! ] T O7 G0 l/ U5 n% k- u
- ledSwitch(2,status[1]=0);//2号灯灭
8 @* R/ [5 j9 l, [8 s - }
3 i% \+ _3 ?/ n - else if(light > 2000 && light < 4500)
4 \; V& w/ L, | - {
3 `' {. q) n/ S0 {: e - ledSwitch(1,status[0]=1);//1号灯亮
( H- u4 P$ p0 s% w - ledSwitch(2,status[1]=1);//2号灯亮
# W. i" `$ N [$ ~* g9 |1 V - }
9 c) g& e! ~0 R( P - }& n& h6 O K0 ]# S
- //在第3-6行显示菜单
% V2 p' t1 n6 F - for(i = 0; i < 4; i++)//i == 0 1 2 3
! O- a7 }7 Z! I" A7 T - LCD_P6x8Str(0,i+3,menu[i]);// i+2 3 4 5 6 行: r7 j. I. ]0 P, o! L
- LCD_P6x8Str(40,flag,"*");
n" O/ M( u( [! R. d0 C/ c -
% E! x' q/ {4 @7 @2 c. U) x - //添加按键输入6 s4 R$ Y4 J z& F. O
- key = keyRead();
" t( q1 F r+ b9 n8 A* X8 o) t. z; N - if(key == UP)//向上键6 p( Y. {+ B& o# p5 z" h
- {
# X" ] ^0 b$ q) P0 K - LCD_P6x8Str(40,flag," ");
9 G. |: V) p. r8 Q - flag = flag == 3 ? 6 : flag-1;, }$ S7 _. ]: l* e6 ~* B
- }. E& L4 { ?6 _" M$ O+ C
- else if(key == DOWN)//向下键
9 Q9 ~$ f2 V$ @- w - {% [' _; b; _' z
- LCD_P6x8Str(40,flag," ");
" O* {5 {; X! u) M) |4 A5 r5 z) d - flag = flag == 6 ? 3 : flag+1;5 e/ ?- z5 [" S6 z7 g8 \; A/ b, N
- }
7 x9 E% m: d, r: w, R - else if(key == OK)//按了OK键
/ Z5 Z. Q+ ^$ J& w. ^! S - {- b) l. o; F9 I% M7 Y, w0 B0 t, M
- //判断星星在哪一行,控制哪个器件
/ m, ?! F4 Z* t) x' @; [% ~7 R - switch(flag)
+ p+ Q7 e P5 w7 `1 a% S - {
6 v% g; n- L0 h0 Q, ^2 O' [3 W - case 3://LED1, r: i* c& p. V4 U2 R6 L K. ?* y8 t
- ledSwitch(1,status[0]= !status[0]);+ ]/ k) }, G8 h7 F7 w) _7 D& w
- break;2 B0 B4 E3 o9 `* q" r/ C
- case 4://LED2
/ }3 i6 {6 ?2 p ]" V - ledSwitch(2,status[1]= !status[1]);
# U6 h( c3 g) F, F) X j3 o# J - break;
& \, e' x# ]* \1 k9 C# D: `& l - case 5://FAN& |. v$ Z) p7 q/ Q+ z/ E$ P) {
- fanSwitch(status[2]= !status[2]);- n6 r# M1 J$ z# z% }
- break;
' b: d3 n: o ?; Q - case 6://BUZZER
1 K Y& W+ [) n* L+ |: y - buzzerSwitch(status[3]= !status[3]);- E4 ^2 h# }* A2 h4 @1 N4 s1 Y
- break;3 U2 N1 b- z% e9 ^
- }
, z* z3 P; G, i; p# m' a) I - }6 d8 T( v+ ?9 P8 Z" }
- else if(key == MODE )//按了模式切换键
9 ]4 M3 Z- v$ d; a - {
, K5 B+ L6 p3 m2 d! O) o - status[4] = !status[4];. j6 I2 K5 c$ {. u# u
- }' i3 B9 B/ A# Z- U' W
- , J: `: o9 f' O) \- m' l
- //在第7行显示 开关状态
9 x5 c9 ?- l# O) [- r0 l# l; Q" T! [5 Z - sprintf(buf,"L1:%d L2:%d F:%d B:%d M:%d",status[0],status[1],status[2],status[3],status[4]);
% C% e+ y! P, H; x ^ o - LCD_P6x8Str(0,7,(u8*)buf);//显示到屏幕上
* H2 G3 y6 m0 D -
; W" } J3 m2 E! `7 { - main_delay(200);
$ R( Y |) e9 D$ [) C - }
+ t- A2 Y3 d: N3 W! T1 `/ P -
) \! O3 n7 g h* p5 } - }
复制代码 % u2 h M. P8 {. c( m
G% w" I! Y7 C
( y' t6 [' o8 P" c6 R: j+ M c
|
早上好啊,好东西要分享出来给大家