STM32嵌入式实现智能家居控制系统
4 W, o& O' \+ k& ~& L; ^$ X! E
6 O7 ~5 r- f$ _0 R, K本文将讲述如何用STM32嵌入式实现智能家居控制系统,所谓智能就是实时监测自主控制一些因素,如,温度、湿度、光照强度等,当室内光线较暗时自动打开灯,根据光线亮度的不同开灯数量也不同,当室内温度过高时红灯不停的闪烁,蜂鸣器也报警提醒主人室内温度过高要打开空调,当室内湿度过高时风扇开始工作,让室内湿度降下来,那么如何实现这些功能呢?下面我们开始介绍!5 Z- h& H5 {4 W+ p, u+ M! Z' g
/ ]5 `, W2 ?6 B; Q* ~# B7 {
一、本文用到的器件有:" s6 _8 Y) N+ _. w. J0 k0 U% M
STM32F103R6 单片机
9 S3 f1 v/ C5 b7 n- BLCD12864 液晶显示屏: F% n& H" S9 Y2 E
DHT11 温湿度传感器
0 S3 C {2 @4 W" `0 W$ ERETCH 光敏电阻2 `& m1 V6 Z) y7 [$ G# o6 X) q
FAN-DC 直流风扇- B) p3 _) L* |
BUZZER 蜂鸣器! F3 h( K, i! Q0 j% }
电阻、按键等
" k' K1 C# _/ K' D. m( K7 Y6 N) ^; u& H1 x( F% E7 d
! B6 o, Q* d, e二、实现的功能是:) S" e5 A6 {1 S, C; l
有两种控制模式,分别是默认的智能控制模式和手动控制模式,按下按键MODE可切换控制模式% O# ^9 n* U$ T4 G. v6 \
- J. G" k" F. q
4 ?$ S- ]* z! A. n
智能控制模式中温湿度传感器实时监测当前温湿度,当温度大于30红灯闪烁,蜂鸣器报警,当湿度大于50时,风扇工作,当光照强度小于3000时点亮一个灯,小于2000时点亮二个灯
1 S( ^$ A2 d( I! h
o! i; y! i# M: i; W, S8 E' X, t8 _7 f
手动控制模式中,按下UP键或者 DOWN键可上下移动光标,按下OK键可打开或关闭当前状态
) z: y& U( M7 N1 j+ T, c3 F$ Q/ w' |# s- R7 z7 U
9 D* B/ T' g/ k0 B5 A7 M自动模式中手动可调节,手动模式中自动模式不能调节
2 `2 H! _ a% I+ [/ \2 g1 W
* g# Z$ T/ d* B7 u8 S+ ]* `3 _
1 p) z5 x+ _6 x; ^: t. T& h三、原理图如下:
* j$ v; d, M: C9 `四、代码实现:
A9 F, U* `0 x" [6 k- / z# `! _7 C3 t% b8 t* c
- #include "stm32f10x.h") T/ f! n" u% U
- #include "LQ12864.h"' |/ H3 _# J% w* H4 T' P& E2 L1 j
- #include "DTH11.h"
* v& o# X. n# E( E0 h* S - #include <stdio.h>$ S( M4 X: X! V8 p+ P
- #include "adc.h"
+ w4 F* m9 D" H8 \& g* n. w
s$ Z t3 c, y/ M: B3 z7 o4 V* H- #define UP 1& f$ Z# h% f0 ^2 X7 ~% C
- #define DOWN 2* V0 I/ O$ D* z# e
- #define OK 3; V+ F; f5 m. I% X8 P/ R! d
- #define MODE 4
% K3 P) ^( }0 } F/ s5 `- ~1 R* E. \ - #define NONE 0
& R6 P. I( {, R( ?! M0 @ - , E% J8 Y# f4 m% m k9 V
" D4 H! q% \" R1 p# B7 x% N9 L: h- void main_delay(int time). k9 w+ h( m6 _/ Z) P# b" d
- {' x, J, @7 C: f7 T, q! \
- int i,j;" I$ ]. f, a$ X8 ?; x: n/ Z
- for(i = 0; i < time; i++)
1 w- H, u: W+ U8 ^/ ]9 b - {
0 r6 z7 k! G" K - for(j = 0; j < 1000; j++)
& M6 V7 ]. B: e u# k; h/ g! l- y - {
0 N) a% L, a+ o+ B - j++;* `! ~/ W7 P7 h; J. U& y6 {' e( h0 S/ O
- j--;, v7 C: {% C& K2 I C' r7 p( V' Q* Y2 M
- } q6 O' v3 b; U3 C
- }! g/ a' l) ~7 X
- }
* ]0 `+ w. q: v3 t/ [( y) v - ' {- E9 O4 h; ?% L3 n U2 c1 t) u
- //按键初始化
+ |" _+ V' z# A1 Z' ] - void keyInit()
* {% W, h& t }! P. _ - {
2 Q! p( \& g( r" A" C6 i - GPIO_InitTypeDef init;! n+ S4 B( Q, ~* ~3 ^
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);" N- X, B9 I4 ~1 o: _; W) v& }1 p
- init.GPIO_Mode = GPIO_Mode_IPU;//输入模式
! j1 O6 E- Y& M8 B2 | - init.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;4 D! {. `2 o2 x" `( F: p6 l" g
- init.GPIO_Speed = GPIO_Speed_50MHz;
* R5 }1 w* y7 L8 k8 O; S$ D8 I - GPIO_Init(GPIOA,&init);
, S# n: o. ?$ S9 k+ d: l - }
) S; k( W: J* k) q" y+ Z - //读取按键的值
5 A; D+ l# }3 R% ~4 | - int keyRead()
1 K1 m( a+ v% }! z - {
( H4 J* P: z* H: A9 i: l: l& q9 { - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0); p& Y, [5 c4 G+ c4 _/ @
- return UP;//上* P! w6 g) r N) Y
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0)4 z; k" Q. t. ?+ [& e4 F
- return DOWN;//下7 ?; U4 h. _3 l3 w& E& s9 z
- if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0)9 L" p/ [* S) J
- return OK;//确定
% A0 I3 r5 S8 t- y% l" B' g% T. m0 T1 B' z - if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0)
3 k1 F4 ~* R& h+ L" M - return MODE;//模式切换) j: I- n8 R2 t: q
- return NONE;
`3 X. Z S& g - }
9 ?7 @# {. E' r1 b4 D1 f - ' P+ T& c; a& T( m+ A
- //风扇初始化
- j7 K" n: e! s! j - void fanInit()
+ p! A; v' L( x - {/ J# R3 i. G$ x$ a2 A- U1 D
- GPIO_InitTypeDef init;" G; E6 v; F8 H6 g) P
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);1 W; q! ?. f1 _1 |
- init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
+ `1 Y0 |- F. P2 Z0 y$ H - init.GPIO_Pin = GPIO_Pin_1;4 [5 c0 j% e4 [0 |) h5 a, j- J
- init.GPIO_Speed = GPIO_Speed_50MHz;6 e- |0 a( a/ B
- GPIO_Init(GPIOC,&init);: e h8 N4 P" _
- GPIO_SetBits(GPIOC,GPIO_Pin_1);//置1 风扇关1 _* d- p; ^1 F/ W, ]6 E$ ~3 {9 U
- }
& B- x+ V" t$ ^5 E3 X( k6 N- D - //控制风扇开关 fanSwitch(1);//开风扇 fanSwitch(0);//关风扇
3 ?9 X. ]3 L( d& c - void fanSwitch(int sw)// 参数 传递1 开 传递0 关
) y: w& r* Z$ T% z; q - {// 1 真 0 假 真执行:左边,开风扇,假执行:右边,关风扇6 M ^% ~4 {7 A. }8 A
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_1) : GPIO_SetBits(GPIOC,GPIO_Pin_1);/ V5 {9 D# \: j
- }
5 i( b/ F: P: J# I - }: {' H' c3 q. C. d% C
- //蜂鸣器初始化) _$ P6 l* v2 ^2 A
- void buzzerInit()
4 S5 R- ?- `0 v0 b- A - {
' m4 s* R; H N3 R& ~% g - GPIO_InitTypeDef init;, ?0 x: L; U0 J. _0 \7 A) j
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);8 B7 y; o( j( G! {
- init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
6 {% M) D. U$ d Y" l - init.GPIO_Pin = GPIO_Pin_2;
; {6 S+ Q% V; i& ?* T& B+ ? - init.GPIO_Speed = GPIO_Speed_50MHz;
" o: t, ]1 [, J7 q7 @ - GPIO_Init(GPIOC,&init);" }- F7 | I* y/ c2 I. \# ?
- GPIO_SetBits(GPIOC,GPIO_Pin_2);//置1 蜂鸣器关9 u5 N% m& x% }' @& E# w
- }" s7 T& w% S- |$ y) U- U4 h
- //蜂鸣器开关" q- l- D) s; k' ]" G
- void buzzerSwitch(int sw) //1开 0关
1 c8 M. F3 [1 g - {/ p$ ?3 y8 b% A+ M$ J: H6 i4 l+ I
- sw ? GPIO_ResetBits(GPIOC,GPIO_Pin_2) : GPIO_SetBits(GPIOC,GPIO_Pin_2);0 s% M8 A% h1 D/ D7 D
- }
+ J! n: n* b+ T: v. j; T h. f: ^
! m& R' Y5 _& F C; ~% @, W- //LED初始化
, q( n- p: s; N* P+ l8 A7 @, ]# f8 m - void ledInit()
3 t% h; |/ R2 \6 |+ P( _7 S) V1 i3 y8 M - {5 j" ~2 T8 [5 E7 E0 k6 x
- GPIO_InitTypeDef init;
1 E/ `$ @5 N6 s; Q; f) Q/ N - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);) n9 I7 u6 j4 n7 E# v/ r
- init.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
- d8 T- {7 T( x3 ]9 I: S( T - init.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;
& G' z9 a' J2 {. U# _ - init.GPIO_Speed = GPIO_Speed_50MHz;
; y- P2 u G5 M! Q' ^6 G8 B: l - GPIO_Init(GPIOA,&init);* V. F& `: U3 h+ g
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7);//置1 LED关
& p/ l0 b9 }( A4 V - }
) Z: \! R( D/ [$ \7 \
. Y$ L N' ]1 }# I- x) Z8 @- //控制LED的开关 ledSwitch(3,1);6 h# ]6 O, b/ X
- void ledSwitch(int n,int sw)//n代表灯的编号 sw 1开 0关
) b' [+ T7 |# R: a - {
t! r1 x; A* t9 `7 b5 u2 T - switch(n)
5 o* `% ` ~4 y6 r8 V* o4 i/ m% K - {
) Y& I3 |2 R5 o ] - case 1: //编号为1的LED" k5 p3 E4 h& |( d
- sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_6) : GPIO_SetBits(GPIOA,GPIO_Pin_6);
; M+ `. |& k4 W) j; n - break;; R2 e/ l% }5 D/ a# E* L
- case 2: //编号为2的LED
9 D U* O* z1 O8 }6 z0 y - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_7) : GPIO_SetBits(GPIOA,GPIO_Pin_7);
8 s$ U+ S& s0 I/ r2 ? - break;
, Q% ^/ M" `1 z# K$ D" g - case 3: //编号为3的LED
+ c- ^5 c# l' F& K - sw ? GPIO_ResetBits(GPIOA,GPIO_Pin_1) : GPIO_SetBits(GPIOA,GPIO_Pin_1);# Y [. N; k: Q: y4 X6 s
- break;4 T+ t- D- O+ y' n$ J d
- }- B* e/ a, v* q3 {6 S- c9 A$ _7 c
- }
9 T5 j; }; i8 ?0 U& N, @3 e/ y - 9 d; v$ H" T! r8 `# n! V
- 2 D3 Q3 b+ A1 N2 s: |
- //系统初始化函数(相关初始化的函数)
3 S8 f f# I- c, m; w* ?- Q - void systemInit()
( B2 f3 D( v" Z - {) @$ V0 l8 T* E' r
- LCD_Init();//LCD屏幕初始化+ u$ R0 E" {$ _ V3 Y% G
- Adc_Init();//ADC初始化
2 x5 i) c3 M- `; \% Q$ Y - DHT11_Init();//温湿度传感器初始化
t1 \' Q1 J# n5 Z* Q - keyInit();//按键初始化, i% @" r' w. d1 F: H% x7 y0 r
- fanInit();//风扇初始化
; g4 K3 G7 B+ h; x4 Y" } - buzzerInit();//蜂鸣器初始化& Z: \) t' ]' j6 ^7 L
- ledInit();//led初始化
8 Z) x8 I# R% E: s+ A - }0 w# P0 y4 g, J
- 4 r( t6 M% i1 w. y: P
- int main(void)
" w& {4 _& _# E$ c6 X - {
/ b `; L0 M3 B5 K2 B- Y/ l - char status[5] = {0,0,0,0,0};//LED1 LED2 FAN BUZZER MODE 状态 1开 0关
2 K8 m- d, i8 c9 u - u8 temp,hum;//保存温湿度% `( g$ k7 ~6 { J- }
- int light;//保存光照强度0 J* X; G7 y( m: _) ^
- int key;//保存读取到的按键的值3 ]8 v9 ]1 ~$ o
- char buf[100] = { 0 };//用来保存格式化出的字符串8 L" d4 _6 ?2 L: o K6 Q
- int flag = 3;//flag时刻代表当前星星的行数2 x% q z! o/ Y; T' {
- u8 *menu[4] = {"LED1","LED2","FAN","BUZZER"};//字符指针数组8 \" t& J/ p$ v& A2 A
- int i;//循环变量
2 V) a1 h; t1 W! \/ n -
1 N. K6 k/ T$ ^0 T9 X; N: z: i( y - systemInit();//系统初始化! j9 B* x6 ?( m& B. }" I
-
) Y( x; {# U8 |0 i' y5 H - while(1)
( l$ ]' [$ L# B3 ?" G - {& O3 ~. b( k3 I3 R) Q- }( C, o
- //在第0-1行显示温湿度和光照强度
1 U( P( o4 s Q - DHT11_Read_Data(&temp,&hum);//读取温湿度0 a9 v" Y u" i! C
- light = Get_Adc();//读取光照强度6 U6 P5 ]8 D2 W" s
- sprintf(buf,"TEMP:%d HUM:%d",temp,hum);//格式化字符串0 `/ h* n/ F) x; C( ]$ g" N
- LCD_P6x8Str(0,0,(u8*)buf);//第0行打印温度和湿度
$ k3 s+ ?, ], H0 d - sprintf(buf,"LIGHT:%d ",light);//格式化字符串! e f. q/ w5 g7 u6 m: f0 @- y1 l
- LCD_P6x8Str(0,1,(u8*)buf);//第1行打印光照强度
* C$ t$ y2 U: k8 q - //默认就是智能控制模式 temp > 30 报警红灯闪烁 hum > 50 风扇开 0-2000开一个LED 2000-4500开两个灯
2 P6 C. O- k3 ^9 t& @" v - if(!status[4])//status[4] 初始值是0 & _1 w" _6 B+ a6 }- W7 b- L
- {
7 o& i( v0 e! L }* L0 t- ` - //温度3 O) c& K1 u4 {/ p, q! ^4 `
- if(temp > 30)1 N c& P" t* s( j
- { X2 w7 j% q) d+ @3 T7 K; w% Q. A
- buzzerSwitch(status[3]=1);//蜂鸣器响
6 i% E' \; N+ q+ v; } - ledSwitch(3,1);//红灯亮
. q: j( I$ S9 v - main_delay(200);
$ V+ Q( \7 o; d& Y - ledSwitch(3,0);//红灯灭
( J- k! w$ q( t2 G0 j8 T" } - }- q+ o' C1 p2 ^4 D; ~/ i5 {3 B
- else
6 ~0 b3 i! v3 ]. U% e, s1 r - {
9 z2 B4 R6 L9 X4 ^5 V6 v - buzzerSwitch(status[3]=0);//蜂鸣器关
% q4 _; A9 j! Y$ ~ - ledSwitch(3,0);//红灯灭5 R3 g( d8 N6 N1 `* y5 F
- }1 \( g# S! ^6 E! q$ E+ H' k$ R( ?" B
- //湿度
4 L, V% h V8 ~" a T8 P - hum > 50 ? fanSwitch(status[2]=1) : fanSwitch(status[2]=0);5 V9 q; n1 F" _5 w
- //光照强度8 s, _5 b, P0 J, V* I
- if(light > 0 && light <= 1000)
9 N' t! K2 X: S) u, ?. V - {
7 S( w, o2 L# K* \, r - ledSwitch(1,status[0]=0);//1号灯灭
9 D) D3 g. G; y1 U& w - ledSwitch(2,status[1]=0);//2号灯灭
0 m; h( W6 w6 D r7 O0 X5 P; z - }$ \( U- x- P; x6 C/ t; P" ^* s
- else if(light > 1000 && light <= 2000); e! c' h A" h" r
- {: c- i( f; I# M6 W* d3 k& r
- ledSwitch(1,status[0]=1);//1号灯亮; G" J. J+ a/ a1 p/ I; q5 i4 w
- ledSwitch(2,status[1]=0);//2号灯灭
0 n" q. D5 s; V' j/ y - }; v7 ?# X: O, {4 w" E
- else if(light > 2000 && light < 4500)
: t2 k- a( g% D1 D: C; ` - {
- F% z1 e; S" |% E2 M - ledSwitch(1,status[0]=1);//1号灯亮- ]4 |* B: ?# r+ [
- ledSwitch(2,status[1]=1);//2号灯亮
# z7 A8 |( e/ E/ V- a) z8 ] - }
7 O7 ^4 `* L- |0 \ - }/ ]% e9 R* S9 G+ U1 }# c
- //在第3-6行显示菜单
' o I& b0 M* |9 B0 _$ s - for(i = 0; i < 4; i++)//i == 0 1 2 3) E' V7 l2 I0 ^+ {
- LCD_P6x8Str(0,i+3,menu[i]);// i+2 3 4 5 6 行: t& |8 P$ g+ \4 \% p
- LCD_P6x8Str(40,flag,"*");
: w( D. p( h" H3 n& l - . O5 {2 _" G( t# O7 d9 l0 u# ]
- //添加按键输入
% S% c% H) e9 j& _4 b7 C3 c - key = keyRead();
% L, i5 J7 x( a" c! R - if(key == UP)//向上键: }% ]% [5 N% `. o1 m4 s
- {
3 g. T7 r. s" V; W7 Z - LCD_P6x8Str(40,flag," ");
g1 O6 A% [& `, y& V" l - flag = flag == 3 ? 6 : flag-1;! d6 m6 J2 d' `
- }; A( o! Y( x! m3 s7 O8 f6 N
- else if(key == DOWN)//向下键. {* H3 @! `7 `7 u
- {+ y# l) c! {& w! D1 J% Y+ K! r
- LCD_P6x8Str(40,flag," ");
9 C8 H; A6 T; i$ n- { - flag = flag == 6 ? 3 : flag+1;
, q. c" B0 p) U% q& g6 O - }
" h! @% B9 Y( Y# }1 R- I/ } - else if(key == OK)//按了OK键4 I' b- X8 \6 V0 e8 C% [/ \
- {& C: Z4 ^) f3 \- w; x( U
- //判断星星在哪一行,控制哪个器件
w$ _! f x, m& g3 d5 g" K4 g: [! c - switch(flag)$ I7 x! \3 ^/ q; x% B/ j8 l
- {& c, }4 ?" T, W
- case 3://LED1
$ K1 z; W" }9 s' H7 G. [ - ledSwitch(1,status[0]= !status[0]);
4 [3 Y* c, p4 L - break;! w9 R: }1 a4 E# x1 ?: b/ |0 v
- case 4://LED2
9 p1 c& }4 I- `5 [- |% e* d6 K - ledSwitch(2,status[1]= !status[1]);6 W* b2 m k2 c2 A- _! Y( B, F. d
- break;+ s J# Y, l2 G! t# J
- case 5://FAN# }' A: z b2 R3 ~5 z: u
- fanSwitch(status[2]= !status[2]);3 V W {; t* H, `3 o8 R
- break;' Z7 {6 H! i: F6 l) R
- case 6://BUZZER2 d# J# W Z8 T
- buzzerSwitch(status[3]= !status[3]);( _+ R9 @4 S/ K
- break;
: z0 t# ? e6 k5 Z. [ - }4 s/ K/ {& `7 }
- }
% Y4 m6 ~( Y$ k. C0 B - else if(key == MODE )//按了模式切换键
; u& {. U0 n: U' Y - {
8 Y% ^5 m. w! v" i& x7 V/ i1 N - status[4] = !status[4];% M, ^0 B5 `- w! P
- }
& y8 }+ ?) w/ `$ O8 P+ P/ @ - ) u4 ~$ z, Q. ~, a4 _3 j, h# G
- //在第7行显示 开关状态
4 q: q5 v& p; B! o( @6 y - sprintf(buf,"L1:%d L2:%d F:%d B:%d M:%d",status[0],status[1],status[2],status[3],status[4]);
; |( C& \5 I8 ~1 F; |$ _ q - LCD_P6x8Str(0,7,(u8*)buf);//显示到屏幕上! u* _( \/ a# z: N/ ~- s: K! ]
-
0 z, K e3 J3 `: S& b w - main_delay(200);, o# n% F9 r# K
- }
% P% ]" ]6 Y6 V - : W$ U, X/ n: h$ v
- }
复制代码 ' _" g) U1 f, I4 k9 z) P" G
( h9 q$ F0 }5 x# e; E9 p( J
/ T4 a% `, m+ |+ V, P& C
|
早上好啊,好东西要分享出来给大家