基于FreeRtos温湿度采集+蓝牙% n8 D; {$ W' w0 X9 r
本次分享的是基于FreeRtos的温湿度采集并且将所采集的数据通过蓝牙每隔1s发送到手机一次。
" M7 U4 o6 u" J3 t7 V/ {
5 [# O( P1 U9 a硬件说明9 {2 ^) F% b! r/ T
& f2 g' Z# D& L- Y' Y使用的是DHT11温湿度模块,蓝牙使用的是HC-05,具体的使用方法就不做介绍了。! M1 L% X6 U9 z5 ~* D
2 c6 Y; u% E) V6 r
# z& b+ Z) l4 K4 X5 R: n5 U
( L8 c3 s! j$ \
& n8 Q5 P8 v5 s/ T下面直接进入主题
$ c0 h) w {& X8 o- Y- {% L1 N0 |# j
) ~2 G, Y# S- Z7 iusart.h //这个头文件里面宏定义了三个串口 可根据自己需求进行使用3 d# w0 [' Y7 f8 i9 L7 V) `# i' P
" d2 }/ c# O7 O
- #ifndef __USART_H' ^8 \1 J; W% W4 X9 M9 C+ J
- #define __USART_H- ]7 S7 M* z" K, d# C8 k+ B
- #include "stdio.h" . U c- W! N0 J# |. c. h; _3 O4 c! V
- #include "sys.h" , K5 X x* I$ I+ c
5 v' b# \) r5 g% M# @- #define USART_REC_LEN 200 //定义最大接收字节数 200
" \9 b: M: o- b/ d4 o J% ?. A' V5 [ - #define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
& ]- u, E% |! P( E - #define EN_USART2_RX 1 //使能(1)/禁止(0)串口1接收9 x5 J0 r5 H" T3 y$ `
- #define EN_USART3_RX 0 //使能(1)/禁止(0)串口1接收
' S9 ]: z! K) {. t
7 \5 K: e! e4 u1 b" G) V
! @7 ~; Q6 n' o6 Q- #define DEBUG_USARTx USART1
$ Y8 U8 o7 p( z& Q2 P9 Y, r - //串口1" _: l7 P) H3 L6 B8 [* u
- #define USART1_GPIO_PORT GPIOA! X7 J, N: L9 y5 Q' [
- #define USART1_GPIO_CLK RCC_APB2Periph_GPIOA
" \) B( L9 G+ p+ f2 ] - #define USART1_TX_GPIO_PIN GPIO_Pin_9% I8 x, L; ]3 [; Q5 \# w$ H, l
- #define USART1_RX_GPIO_PIN GPIO_Pin_106 s* ]* w; Y. I9 M' ?$ @
- //串口2
, z! L+ i( K' [ - #define USART2_GPIO_PORT GPIOA
7 W* V. N% Q% ^ a' K$ Z' y - #define USART2_GPIO_CLK RCC_APB2Periph_GPIOA/ Q/ r1 t- |) A# }3 p
- #define USART2_TX_GPIO_PIN GPIO_Pin_2
3 o: u0 m( k" i6 Q% @ - #define USART2_RX_GPIO_PIN GPIO_Pin_30 v9 w# M* B6 y4 D( S
- ( N G# N) n) ^! C% ]
- - M. f0 }1 Z3 Y; P# B
- //串口3
2 E$ q5 _4 f& Q - #define USART3_GPIO_PORT GPIOB' V* [4 C0 D; R7 i8 ?5 j/ G) j Z
- #define USART3_GPIO_CLK RCC_APB2Periph_GPIOB
! @4 z/ `( E" M" x - #define USART3_TX_GPIO_PIN GPIO_Pin_10$ U' G: I- n' X. V% x$ w5 n
- #define USART3_RX_GPIO_PIN GPIO_Pin_116 ^4 t4 U1 x+ O9 K# X4 w
- #define USART3_RX_EN 1 //0,不接收;1,接收.
( N' U! w& a) F: f - #define USART3_MAX_RECV_LEN 600 //最大接收缓存字节数- _! i, |. E' C& ]- ?& E& A; Q0 i
- extern vu16 USART3_RX_STA; //接收数据状态
# K3 Q7 M% C# y - extern u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN字节
; n0 S. C1 U; w5 d& R3 V - B: {& K3 W, W' d5 O t
-
* q: Q9 {1 _) b) m" g - extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
9 D9 C" G$ ]& l - extern u16 USART_RX_STA; //接收状态标记
4 Q- W6 Z. @! T - //如果想串口中断接收,请不要注释以下宏定义
7 q/ W, z3 d5 ^( w. _1 U - void uart_init(u32 bound);1 V: H$ [" w. K4 q F
- void usart_init2(u32 bound);% a% q" F Z1 M/ f( y( B( k
- void usart_init3(u32 bound);
# K& K' q. u# S% z- E8 m1 ^: _ - void u3_printf(char* fmt,...) ;. S) ^/ H- Y, G4 `
- void USART_Send_Byte(USART_TypeDef* USARTx, uint16_t Data);
* ]+ w- B1 `6 j: S - void USART_Send_String(USART_TypeDef* USARTx, char *str);
8 C Q# p# d, F9 t$ {0 s8 F - #endif
复制代码
) |+ N% g( ~! u! u+ N2 musart.c
5 S0 P0 B j/ `- z3 n. S
" E' T) c; M9 E2 m- #include "sys.h"! B+ b2 {, v3 p; y& r7 p- D4 }
- #include "usart.h"
# C7 a8 V% }/ V2 Z - #include "stdarg.h"
7 P6 G2 y: C2 h3 j/ Y4 ` - #include "string.h"
$ D/ @; [: K, D- c7 r5 P - // , a4 p! y7 X, T( |
- //如果使用ucos,则包括下面的头文件即可.
/ |: t% X2 ^2 ^7 _4 H$ g - #if SYSTEM_SUPPORT_OS
- ~0 }2 l, G J, |8 w8 q - #include "FreeRTOS.h" //FreeRTOS使用 % C$ Y) G( U2 b- u
- #endif7 U5 d, X7 }) z& p3 b
- : i/ _! A5 u N6 L
! {/ N% J8 R. u( h- #if 1 {# {/ t; K8 }; q4 ]0 v
- #pragma import(__use_no_semihosting)
/ E; L" x- t3 p( X" G - //标准库需要的支持函数
: f# T9 `$ q- T2 U# T% z - struct __FILE 3 f5 d/ L) _5 l# \2 D" M3 J
- { : J9 h; v% u3 C4 P4 g$ @1 K) M
- int handle; 7 E( A% v3 n) k' q7 [1 [
- - c8 m" g9 ?4 U* J) d
- }; ! F) @+ U L; f) C) Y
- - {, l2 e: Y( G. w8 J
- FILE __stdout; + U. O" E6 n3 b8 o5 y3 V- [
- //定义_sys_exit()以避免使用半主机模式
5 R1 A1 U" k ] m - void _sys_exit(int x)
0 H. h3 J' S$ S* @- h- _ - { ' i$ ?1 ]" @4 c% ?2 b8 ]2 R# G
- x = x;
# q. W% x) u9 r0 g - } 8 C0 R( B& _0 F2 u9 v9 E
- //重定义fputc函数
, _; k1 J" Z! k0 G. ?6 N3 ^! u0 Z - int fputc(int ch, FILE *f)8 X+ `/ l2 N" W! c
- { " ?! [1 a) L }" {7 k
- while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
z2 K: Q0 a) O' T W: Y6 ? - USART1->DR = (u8) ch;
' _9 z- O$ b) J - return ch;; {8 [. g, H- B; d; [+ U
- }
2 [+ A0 k. Q' R* G - #endif ( T1 P. o% \* ?
- ( J. t0 x1 ^+ O- e0 m; k
- /*使用microLib的方法*/3 ?0 R6 B) g+ p. {# m
- /*
3 p; ~. ] m) T, @% Z$ ]7 m7 r - int fputc(int ch, FILE *f)
: H9 ?" @) a. [4 y* @: x - {" A6 H4 X4 s( {1 F- h C8 c/ v; l
- USART_SendData(USART1, (uint8_t) ch);/ m$ R& r3 [: \0 ^* A) Z" p
- ; t; i5 @' c) J6 @# ?
- while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {} 4 Z. c$ @' ~- ~; t# ^$ |
$ u% S6 ~* _7 Z# I( R# c# G9 P- y- return ch;
?# d3 ~5 z6 M* B! L$ a6 c - }" _, L9 r# r4 U" P' k6 e/ T: T
- int GetKey (void) { w. C; S0 C6 |$ i- c2 R& l( x
- 7 u! B/ S9 {6 ?" B+ i! J$ I
- while (!(USART1->SR & USART_FLAG_RXNE));
0 ~1 x+ \# a' o$ ~$ J. f* L. | - ) b# l+ x: t/ Y6 o$ Q
- return ((int)(USART1->DR & 0x1FF));% Q4 Y- s! C; C
- }
" c; D( n$ x: {1 }' R - */
$ k9 @0 H% ~6 y0 J0 ^% f
& `; v: S3 ]/ ~+ H: z: c
- ?3 e# ^( `& R m3 m: m- 8 n- O. U; |6 i$ n9 s
- /*===============================================================================================*/
$ b0 l, m3 w% _ t$ i- M7 R% u - u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
# j% o" ~, q9 G7 p% a# {7 ~ - //接收状态
9 Z6 `3 X# B" f. D9 a6 ? - //bit15, 接收完成标志8 h3 V( q) h! T6 w, t1 P b
- //bit14, 接收到0x0d
) F9 X# o+ V6 K - //bit13~0, 接收到的有效字节数目
7 f& y" t$ t' v$ h! t - u16 USART_RX_STA=0; //接收状态标记
; ]# `6 p! p# N# Q: [. A - /*================================================================================================*/
% N3 Q' K3 K5 [! T0 p/ M - 1 L" e) o" G0 N) |/ ?$ |- T
; M6 g$ N ]4 ?, e; f) t ^8 a1 e8 M; _- #if EN_USART1_RX //如果使能了接收3 Y2 Z6 P$ t3 K' |# n) }' ^
- //串口1中断服务程序# m) ]0 o: {; n& m7 F
- //注意,读取USARTx->SR能避免莫名其妙的错误
# A) \7 V$ S1 r - $ ~5 C: _0 p: A+ l; `
- P; u' G( ^8 M" y& K" v4 F
- void uart_init(u32 bound){& M* ]9 O* g: ]# H
- //GPIO端口设置
+ R+ Q! c: Q$ W% t/ o - GPIO_InitTypeDef GPIO_InitStructure;" L; v7 \% g9 j6 W7 O. y: b( O
- USART_InitTypeDef USART_InitStructure;# [+ ^0 F( y4 k6 r( c( X
- NVIC_InitTypeDef NVIC_InitStructure;
3 b/ R3 }/ \5 ]2 N1 j& n -
% _0 Q3 {; l. f2 y' W, `5 l - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟3 q2 V9 E& p5 v
* @' r7 `% w6 H" F( J7 B. Y- //USART1_TX GPIOA.90 _# Y1 n0 j) O& e' [
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.99 L8 T4 O$ q" B3 `3 f8 u& X/ Q9 j
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;% ~) i5 H* y. n% t E
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出7 j6 L# [6 {7 B! h
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
) M* K1 y/ _: i! a. k. O
* i, K" ^3 e4 z/ m7 T- //USART1_RX GPIOA.10初始化
. s" m* Q V" p - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
8 R/ t7 `1 v$ x) ~' r - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
8 _& F) ~7 C0 F H- N" h - GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
9 o% }, A/ l0 h; D, ^6 X) t% ] - ! a& U# j- b2 X2 a6 x0 L; r
- //Usart1 NVIC 配置" W0 b Q8 z! c4 N) `
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;) V3 x7 ^! [4 R
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=4 ;//抢占优先级3$ c9 ^4 R/ K& H p
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级3" _! o! e8 O$ I4 z! d% n2 }
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能3 u0 {2 Y5 E% p3 v+ C S1 I
- NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器( a" M& h+ ^/ ~( Y9 B
7 b) l1 k# _# p6 s. P- //USART 初始化设置6 K% ?* l% I. N; a
- ) M/ @# B: m, `6 h. Y; X
- USART_InitStructure.USART_BaudRate = bound;//串口波特率$ W) m [$ ]+ r4 J
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
+ ^7 H0 n0 ^# _; j! q9 w - USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
) O7 s! E4 L9 S# b - USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
6 [+ X8 G9 {9 G3 C* u, W: O - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制8 v4 x. a3 B# d/ L
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
$ l5 b/ D5 {0 m- Y/ j) L. v4 g - ( ^% \- `% y8 T
- USART_Init(USART1, &USART_InitStructure); //初始化串口1' G- I$ X4 P7 |8 f* j1 _
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断) e9 i2 ~' r4 m) |/ M* J# Y
- USART_Cmd(USART1, ENABLE); //使能串口1 ; l$ q# X1 Z ?9 A$ w. {! Y
- }
`. A; K) L# A9 E* x) B
$ B# [# M# y. W* f4 _8 n- void USART1_IRQHandler(void) //串口1中断服务程序. h/ g5 u. C% k
- {
. f' L) F9 D4 ^/ w0 i - u8 Res;2 g$ [. u: B1 F. C8 p' z$ m
- 2 B3 D# @2 W. Y. @
- if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾); y( E, L2 C0 i; I. G5 h
- {
. N% g/ [5 |5 _7 e6 f - Res =USART_ReceiveData(USART1); //读取接收到的数据# A0 h# n. f: X8 |; w: _2 {/ e d
- 6 }! m) x8 c7 ], t
- if((USART_RX_STA&0x8000)==0)//接收未完成
# p1 x. [* q2 m5 T a$ @# k - {
" ]7 R0 z; z/ U+ _, Z! J+ v - if(USART_RX_STA&0x4000)//接收到了0x0d
' ~# v2 ^6 d9 [& v% o - {( m6 O0 }$ {7 {! X" U. Y9 a, B, s- O
- if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始5 @$ l( Q7 X+ u% L- I# \6 f
- else USART_RX_STA|=0x8000; //接收完成了
) ~ @# q2 K3 P/ m+ W& n - }
8 U* ~; U2 n2 t9 E& L - else //还没收到0X0D3 Z) K5 S8 _0 C/ a2 Z
- { 3 z! z% W8 l3 c3 v1 {/ \" f
- if(Res==0x0d)USART_RX_STA|=0x4000;: M$ R. w, U5 l" A" ~2 W3 Y
- else1 q' Y0 u& ]" O8 k; ]+ m D
- {7 z& e$ {, E* ^. Z7 [7 m$ t2 s8 n
- USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;2 a% J* ^* e, h
- USART_RX_STA++;
+ `$ Z2 c8 H- U8 [1 a4 F1 m - if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 2 S6 Q2 d; W3 S; R9 e9 F1 i
- }
y4 E% w0 }, t5 T$ x - }
+ ^( j/ b7 ?1 W# u( W, `; H - }
) j2 y; v% _3 c" @ H - }
! b# h1 X5 p% ]) i o& g/ D - }
& ^. @7 }0 Q3 v2 F - #endif
3 y) V6 t; F# s" r3 J - + |0 {, a9 t" J6 T0 {, Q" O7 ~
- /*=======================================================串口二===========================================*/" I, J) z( a5 ]( A$ i
3 N( x* Y/ h: x- #if EN_USART2_RX
, L8 g, c7 i. e/ ?
+ X$ ~" A0 _" h p+ G+ J2 k- void usart_init2(u32 bound)
' M: V& {' {4 T. u1 w; [ - {
- u7 |5 X; p2 h! F3 s - GPIO_InitTypeDef GPIO_Init_Structure; //定义GPIO结构体
) h6 Q7 ?( c d - USART_InitTypeDef USART_Init_Structure; //定义串口结构体
/ u5 x4 f' `3 P0 m& X6 k T: c - NVIC_InitTypeDef NVIC_Init_Structure; //定义中断结构体
4 t' X0 [1 y/ N2 E, b1 Y - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
4 `, w ?! o9 E# X3 E I# f - ; ]* T/ v N3 R7 S9 D' k
- RCC_APB2PeriphClockCmd(USART2_GPIO_CLK, ENABLE); //开启GPIOA时钟
: o* C/ R' Y- `$ l R - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启APB2总线复用时钟
6 z' j$ t4 S) M' O; E7 b$ Q1 n* b* S - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //开启USART1时钟
0 ]1 f! }4 C Z+ x* Z
, p1 b% b7 p' y" }- //配置PA2 TX" z. S: C! M& q6 O: I$ q
- GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
% a; K. j9 J5 m8 d9 ?; `9 q - GPIO_Init_Structure.GPIO_Pin = USART2_TX_GPIO_PIN;
" W! Q( n% w6 a9 \+ [! O( R# F2 h - GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_10MHz;! Q) I) ^+ Q" L" q/ ]' Y) {3 |
$ K. C( p; P$ k" d, w+ ~4 [# O- GPIO_Init( USART2_GPIO_PORT, &GPIO_Init_Structure);! F# {7 V3 H. V( G% ~ w# I' x4 z5 }: i) ]
6 J$ }2 ^2 S7 M2 X* i6 _8 G3 w- //配置PA3 RX
' I) j! Z* G. Q" t0 ~. ~8 J - GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用推挽
# V! A" q, E( ^( a1 L9 z - GPIO_Init_Structure.GPIO_Pin = USART2_RX_GPIO_PIN;
" ?3 z& x8 C1 ^% K6 `" ~2 r9 ` - GPIO_Init( USART2_GPIO_PORT, &GPIO_Init_Structure);
. G+ H& }6 i2 Z: { -
. y7 n7 c9 Q3 y" n) K0 G; u - USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
6 ?5 B; g7 M$ o3 c. m - USART_Init_Structure.USART_BaudRate = bound; //波特率设置为115200
' o2 S. z3 e( S x# X/ ? - USART_Init_Structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制为无
& @7 D2 m& n& m) k) a - USART_Init_Structure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //模式设为收和发
7 |( Q( \5 j1 B' J; Z. ^$ i - USART_Init_Structure.USART_Parity = USART_Parity_No; //无校验位
; W" D' O) l# H9 M+ v4 N - USART_Init_Structure.USART_StopBits = USART_StopBits_1; //一位停止位
. c# F. q& P1 ^; x" i: O) W - USART_Init_Structure.USART_WordLength = USART_WordLength_8b; //字长为8位 8 f5 S8 h5 h) [4 B5 L, x
- USART_Init(USART2, &USART_Init_Structure);
( x, s3 g# b w% g8 s - USART_Cmd(USART2, ENABLE);
" H" h/ t* g+ I9 m% M - 0 g8 g% F" ]( K+ f- ^
- //中断结构体配置) E, u) `0 _* o Z* f/ a0 u5 ^
- NVIC_Init_Structure.NVIC_IRQChannel = USART2_IRQn;9 d6 m; c6 m8 K `: F, u
- NVIC_Init_Structure.NVIC_IRQChannelCmd = ENABLE;
5 X4 D9 g/ S: ^ - NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority = 5;
5 T* j* o$ W3 e, c& g2 e - NVIC_Init_Structure.NVIC_IRQChannelSubPriority = 0;# E1 Y0 l( @8 G; g" p1 ^! G+ d
- NVIC_Init(&NVIC_Init_Structure);! L4 x/ H, a( L0 G2 @
- 3 M2 H" {: Y; j1 R' y. O; p
- . c H; ^( {! i. ]
- }6 A- |" Z3 }- p9 q. W. X1 Y" R
5 y$ O' b: d3 E6 ?5 {% G
; K8 f. y, O2 V6 t7 R5 ~& b- void USART2_IRQHandler(void) //串口1中断服务程序. T' o/ q7 f4 P1 {4 k" \( S5 i
- {
/ x& X9 a0 ^8 o - u8 Res;: G. g8 p& [% e0 U5 e
" W; S' H2 j+ v9 B7 [/ p: u- if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
' g1 }: `! p l1 l* C - {
/ z" q. i8 a1 h1 e( q4 j - Res =USART_ReceiveData(USART2); //读取接收到的数据
) g) W. F& a& a6 F1 J6 B7 X - : N9 G& K5 V% D3 i9 q& ]9 N
- if((USART_RX_STA&0x8000)==0)//接收未完成$ c' E2 T9 [9 a% B; A3 J- {
- {% H& a- F+ A6 w2 a3 \9 w' p
- if(USART_RX_STA&0x4000)//接收到了0x0d
( K2 z! e8 u$ P' H* m! M - {* f; c1 [. i1 o& q: w2 s+ q! ~4 Z3 w6 \6 W
- if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
6 U- X5 P3 c! A. h" H9 n: F - else USART_RX_STA|=0x8000; //接收完成了 ' w @# B: F( v
- }
; s0 A. Z7 q1 |1 n; V" |- y* E& ~ - else //还没收到0X0D
6 U! f5 m3 s1 E* X2 P2 v$ ?7 X( ^! a - { # I5 M4 q# p) y6 Q
- if(Res==0x0d)USART_RX_STA|=0x4000;
) _, x0 w$ U* s& R - else
. ?1 e" V8 X; P5 i- F* D - {6 P* d+ w6 J k7 H: w2 o" F
- USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
2 d# B8 D! \8 w) C4 Z' ] - USART_RX_STA++;# K" g4 _ C* c# X# Q
- if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 5 i5 }" s; N4 Q3 g& ]* U" o. H& v1 ?
- } 7 g) c! Y4 t2 F& x( h/ r
- }9 z: k7 V$ m2 V5 s- H5 y+ G
- }
- h5 i2 @, {4 }% F- A4 S - }
" X8 G- z c& `/ S! q! f& @: T - }
0 L" k+ _- w. U7 g2 R1 o
; h" |1 E7 b4 t- E! P( {5 C# f- #endif2 g/ ?' m" q; [
- # V9 u+ S* P* v
- 8 F% [% }& J& r
- 4 u& B1 r6 M/ A% i% F7 u/ O
- /*==================================================串口三============================================== */
9 S: h) _9 |! H& G( |4 h5 s# C: n - 5 t& `' e' ^7 m; m
- #if EN_USART3_RX
?1 i/ w! ~/ I$ \ r' O0 l B! f - 0 e* @7 @ F: d* U) n
-
6 p. P" h! q) s4 t( } - u8 USART3_RX_BUF[USART3_MAX_RECV_LEN];
# W4 u% g2 A- P7 p& t) \ - //接收到的数据状态( ^2 n. y3 k0 f: k$ h
- //[15]:0,没有接收到数据;1,接收到了一批数据.# R' r4 K, s' o/ z* Z2 Y
- //[14:0]:接收到的数据长度* Q& q$ L# `2 b+ r& Y* J
- vu16 USART3_RX_STA=0;
" h2 o4 K+ K: K4 \
1 ` I9 s$ g# x; \8 N" m( z' O- ! U5 e' }' Q( K2 q
- void usart_init3(u32 bound)
' \$ ^& y P& q. z9 h7 T - {9 d" A& i" I+ L+ K. h
- GPIO_InitTypeDef GPIO_Init_Structure; //定义GPIO结构体" ?: U# M' |. {7 ^( R; y _
- USART_InitTypeDef USART_Init_Structure; //定义串口结构体9 Z% v; W; |2 f8 M/ Z
- NVIC_InitTypeDef NVIC_Init_Structure; //定义中断结构8 M& {1 `+ g- P& o, F) ^
- 8 B- d/ u/ I l( W; L
- RCC_APB2PeriphClockCmd(USART3_GPIO_CLK, ENABLE); //开启GPIOA时钟
3 X4 i1 M+ o) H* m5 k4 Z4 Z - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启APB2总线复用时钟! A. }7 W; R3 L* [$ ]: F
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //开启USART1时钟# k+ [: f0 q0 Z& G8 S! w, |
- 0 i+ [% _3 }. I7 z& t
- //配置PB10 TX
& A. g* c: m! C - GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽' Z e$ d; K1 {4 @! f: \2 D* C
- GPIO_Init_Structure.GPIO_Pin = USART3_TX_GPIO_PIN;
8 T1 d r& X: K0 K+ ~" { - GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_10MHz;( G) q/ r' r1 J1 G2 P% H
- GPIO_Init( USART3_GPIO_PORT, &GPIO_Init_Structure);
4 t/ n0 y7 r* L# v8 B2 M5 Z1 k - 9 U" f& H2 w Z/ I6 ~0 d" Y2 q
- //配置PB11 RX
' n" Y4 |; C" T3 ^3 s - GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用推挽
, o8 f: `8 Z$ [& F1 ^% V3 H: g1 R - GPIO_Init_Structure.GPIO_Pin = USART3_RX_GPIO_PIN;% x" V" v( p' b# v* e- w% U& x! d t
- GPIO_Init( USART3_GPIO_PORT, &GPIO_Init_Structure);% Z/ t6 Z3 J- ]4 m3 j+ h8 m: @
- - c+ r' `& m2 n. o Y2 D$ w
- USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
) m1 E. m: r6 R- |$ u6 b - USART_Init_Structure.USART_BaudRate = bound; //波特率设置为115200: J$ K0 _& }7 d
- USART_Init_Structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制为无( C1 H/ R' i( @8 P& _
- USART_Init_Structure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //模式设为收和发
6 ~) B# h6 ?0 Z# w3 ^2 U - USART_Init_Structure.USART_Parity = USART_Parity_No; //无校验位
9 {1 N0 C' K3 @7 o. r - USART_Init_Structure.USART_StopBits = USART_StopBits_1; //一位停止位% d; D8 a) p% b% u7 z) t
- USART_Init_Structure.USART_WordLength = USART_WordLength_8b; //字长为8位 % n: w; j* U+ o. r: a* K
- USART_Init(USART3, &USART_Init_Structure);
! F8 M2 r. E6 r - USART_Cmd(USART3, ENABLE);. g2 f" m1 G( X
- 5 h/ G; Q( c/ R" F! d; c1 V$ c# t
- //中断结构体配置
$ o6 w2 K% x& Z& W, Y$ [) [ - NVIC_Init_Structure.NVIC_IRQChannel = USART3_IRQn;
4 V5 Y. R2 B( ?# w5 y - NVIC_Init_Structure.NVIC_IRQChannelCmd = ENABLE;
: c5 L( Q& H7 N4 ? - NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority = 6;& k& V4 I# x4 n2 Z) q, ~1 i
- NVIC_Init_Structure.NVIC_IRQChannelSubPriority = 0;, c5 d3 ~" T, s1 @7 v
- NVIC_Init(&NVIC_Init_Structure);
$ E# E! h$ P4 Z9 C" H% E - }
; z1 V8 S1 T6 F- D+ O5 ] - + F7 s- P6 L, S0 v( y. i; y$ n3 |$ }
- 7 K) G m/ ]; k" {& w
) \$ n4 _+ l0 Y' C; i( M( G% @" p- % C- B# }5 d/ {: ?
- void USART3_IRQHandler(void) //串口1中断服务程序7 R4 X2 w8 T9 H
- {, D2 g$ w1 {8 |! f3 W, J
- u8 Res;/ m5 R/ {# _5 h, U8 R
( d7 l9 ~! d! y& s+ {6 F* U- if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)0 S/ L+ c8 j% d9 L' ^. H( t
- {/ R' w5 z* J+ S4 U. ^; _4 K; ~ x
- Res =USART_ReceiveData(USART3);
7 @ j6 m" B1 Z( L. \( P4 \2 X - USART_SendData(DEBUG_USARTx,Res); //这里是把ESP8266发送到串口3的消息发送到电脑端串口调试助手,便于调试" r0 h3 r9 M' W, d. b5 j% M
-
! |; c4 f2 {8 I - if(Res != 'A') //以‘A’为结束位,收到‘A’表示一次接收消息完成2 }, Y5 ?* t, p5 K; Y* a1 ?2 [
- {: m" E( V" K4 ]9 I7 e
- if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
" t V8 Z# n! l - { _+ h$ ^5 P% @8 O
- USART3_RX_BUF[USART3_RX_STA++]=Res; //记录接收到的值
) s, e! R% m( v, a+ i; P - }5 }' k) A" W4 {! b$ b" o
- else , X( T U# p6 \# M! r" m
- {' @- @* N7 w. _4 p
- USART3_RX_STA|=1<<15; //没有收到结束符‘A’,收到的字节数>=0x80,强制标记接收完成7 r1 I2 b Y; Q4 \
- }
( r" G* X( L- {7 v. i( f -
" M, G& n. B( E3 W0 f - }
c+ S" e, c. q5 b& Z: | r0 H) |6 a -
) N. L4 B ?( X& ]7 r o - else
Y/ S# A0 X$ J" s8 o - {
* E# v: @4 ^# H N" I - USART3_RX_STA|=1<<15; //接收消息完成 H& k n0 X+ h) Q- \$ b
- }
~& ?1 h o; T4 Q2 t5 ^ - % r2 e4 ?3 H$ z
- }
" ?5 k/ l/ J" y# U8 C - * u w; T0 v5 L, G* O7 x! T ]- [. y
- } 8 K3 M" C% Q h. H' m4 S* K
2 w6 N- N/ V5 @* @- void u3_printf(char* fmt,...) 4 S, F- ]3 @/ a# U8 H
- { $ i2 M3 J/ t9 ~ F
- u16 i,j;
9 [: d2 Z5 b) L7 J2 {# ? U - va_list ap; / e* [/ i& K3 u' J- S
- va_start(ap,fmt);
( f9 M) w( Y- `+ T( U& l - vsprintf((char*)USART_RX_BUF,fmt,ap);% e' \! d8 u) F' T+ W
- va_end(ap);7 D) n8 `6 V( i0 ~' ]% M9 c
- i=strlen((const char*)USART_RX_BUF); //此次发送数据的长度
; X7 X% Q0 Q0 J& k @/ ]- ~8 t) | - for(j=0;j<i;j++) //循环发送数据' D' w. Q" V6 |
- {4 k5 s0 e+ f2 I2 _
- while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
$ s( Z6 y% g; y! U6 p - USART_SendData(USART3,USART_RX_BUF[j]);
- B+ m* y/ y4 C+ V+ r; j" o; w7 Y - } 3 J4 f/ [5 m1 W5 I' c7 N. g; u0 k
- }# n- Y. [( E# m1 }
- $ G# B( ?) d1 z# g1 x
- #endif
6 M3 y" n8 Z4 s1 b/ Q - - v4 ]9 L: x/ Q! \/ n( t$ L
% `8 {9 J0 i; E( G0 H
; r5 c: m6 K2 T* _- /*=============================通过发送函数==============================*/4 U% N. z$ j9 L% t3 X" c+ J2 Y
- /**
. V* _! y6 @8 \) ^( f" j2 i - * 功能:串口写字节函数
0 V0 O$ H. Q* @ D4 y - * 参数1:USARTx :串口号6 E: a5 t/ T0 S1 V$ U R
- * 参数2:Data :需写入的字节
1 j9 P7 F/ Q9 w! V' W - * 返回值:None, v. L+ ~+ Y) @! b8 j
- */
# s! Z& S2 S' b. `2 Q5 G; g: q - void USART_Send_Byte(USART_TypeDef* USARTx, uint16_t Data) G. A% z" S0 a
- {
+ {' s& j) ~( I - USART_SendData(USARTx, Data);
# j; A2 [3 T, Z+ X - while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)==RESET);5 l, W: M; `8 k/ m
- }
+ b7 h" @* g; s0 I: v - /**
" t$ I9 H2 g+ k3 `0 P+ N - * 功能:串口写字符串函数
# v: Z( \; o" p- B0 ^3 @ - * 参数1:USARTx :串口号" L& y2 B/ _3 E# t2 ~ V* k2 e
- * 参数2:str :需写入的字符串
/ w' C2 ?' ?. I4 g" F2 e, J5 I - * 返回值:None
& C# _4 a4 H5 U' @" n - */6 _0 H/ a- [; m* P
- void USART_Send_String(USART_TypeDef* USARTx, char *str); S! H& y" f& a+ V# z
- {: ^& F9 p/ W. A
- uint16_t i=0;
( Y/ B# U! |# D1 K. q - do
7 e9 o! { o+ x3 N. [; b# b$ z6 [ - {3 y3 x+ |) b0 S1 I5 i: ^9 X/ f
- USART_Send_Byte(USARTx, *(str+i));& O* Q* R. U j9 S/ T8 t$ Q
- i++;
# D" [1 K7 r- s' O0 U8 A - }
* m; z9 R* N$ k. D" W9 x) D! N* U - while(*(str + i) != '\0');; Z$ P' H: x2 G0 |' S0 C; d6 I
' M6 h* ?' T4 z) ?/ X) m: \4 m- while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
, d0 I' O% X7 |5 | - }
复制代码
; u! q0 D; E- Fmain.c, {0 n( T: P$ H0 v
1 i H, S% i4 [$ u- #include "sys.h"9 Z% g- s- Y" _
- #include "delay.h"' [/ `& P* D* Y0 R+ a# X6 H
- #include "usart.h"/ m, }' j, L) Q" `7 b% e) v
- #include "led.h"
$ Z( T: I4 O& @; A - #include "FreeRTOS.h"
" F" B& |, w `8 c - #include "task.h"4 l+ a1 N' x0 J( W d+ v3 d% f
- #include "key.h"
4 p& s0 k4 X' K) z/ V( L$ F - #include "string.h"& u9 z5 C7 T/ ]" x2 _ G
- #include "dht11.h"- d7 j7 g6 D' [! }
# E# i$ x6 e# i; h- /*========================FreeRtos读取温湿度=======================
+ C/ ?( z1 c5 n F3 G+ M& L - *Author:小殷同学- B9 W8 h$ t5 k; j0 r" y! g
9 r( {* r' r6 E5 ~" Y$ R- *Date:2022-5
; L& S- s1 H+ X7 I
" Y. Z- d1 ]& g& i" @- *Description: 通过蓝牙将获取的温湿度数据每隔一秒发送一次到手机. r! H1 \# m. G! C! E4 k
- ==================================================================*/
4 O/ B, n. ~5 N5 p: h+ }& X
5 w6 i7 x! g' x4 k- : @* |& z* `# U8 U' m
1 m; U* T% i6 M: s8 h. G- |6 C- //任务优先级
1 @( d( w; Y, R0 N# E. g - #define START_TASK_PRIO 1
2 i) y8 t4 U* H - //任务堆栈大小
) s& r% q% j) U( R9 f8 h; c$ \% q - #define START_STK_SIZE 250 ; E. p! I0 _; _7 j9 b6 C
- //任务句柄$ k. x- A+ p5 l; c$ I( j! F
- TaskHandle_t StartTask_Handler;
% g! d# h( V _& _ - //任务函数
4 l4 U% w ]+ }" X, a. L5 r2 \2 F h! p - void start_task(void *pvParameters);& \4 b7 r v( j' @
- : v" Y( l* b& ?% }# D% A
- //任务优先级
7 C9 D9 W: i, v. `/ u - #define LED0_TASK_PRIO 2' Y; Z. x- n: M& @$ H; {) n3 Z' |0 V
- //任务堆栈大小 $ W9 N4 k* T' z7 m
- #define LED0_STK_SIZE 50 ! `$ x: V/ t' Q: {. n- i
- //任务句柄
/ `. _! f+ W4 T - TaskHandle_t LED0Task_Handler;" u7 ?* w2 T8 L( E$ Y4 S e. _ A
- //任务函数. P/ e5 p" b) C3 k' M+ L7 K: K
- void led0_task(void *pvParameters);
9 Y* d" M( T1 e: M5 r
% R4 G! d, N" H+ I+ K$ w- //任务优先级6 D n' h4 b4 C5 ^3 o0 t( x
- #define UsartControal_TASK_PRIO 3
+ F& C5 ?5 x& e4 o- U - //任务堆栈大小
9 E6 l% K. ?2 \, R0 O0 M/ Q - #define UsartControal_STK_SIZE 120
7 N& ?' c, _0 N' t; { - //任务句柄. z! ]+ x- w* `: `7 G- v
- TaskHandle_t UsartControalTask_Handler;" Y2 b, n/ c) J
- //任务函数7 s9 Y& i* m9 ? u! h$ v+ w' j
- void UsartControal_task(void *pvParameters);
* r8 C% v, _' b - # o1 l0 d/ @) x* A6 g
: m! N9 @2 W. I* Z8 H/ H; G: H- * G0 Y% O4 s. t
- int main(void)
- G6 Z- r# l) q9 f - {6 B5 y/ q/ s! H( ?$ g
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 0 Z. @( h7 ~. j- [5 a
- delay_init(); //延时函数初始化
' g- R' c2 x$ Z, ~4 Q5 u; B6 X# B# j) f) q - uart_init(115200); //初始化串口+ z8 y a$ r4 R
- usart_init2(9600); //蓝牙使用
3 U" U) y1 T1 l7 |" c - # D% O5 n& ?. L
- LED_Init(); //初始化LED; D! D* m/ R4 a. G3 p% E
- 3 Q* \$ _8 G# H: ~' X
-
3 t/ D9 j! O1 V, t+ w - printf("初始化完成Start Test\n");5 x( n5 u+ o% S v5 s- l) B8 E W, N
-
* d7 `+ j7 f* f/ _+ G0 g3 g8 b - //创建开始任务. Y, l% n' @5 E3 ?; c
- xTaskCreate((TaskFunction_t )start_task, //任务函数
$ H$ d0 d& j3 z0 D8 c3 S8 p - (const char* )"start_task", //任务名称# {3 @: j# ~4 R/ q
- (uint16_t )START_STK_SIZE, //任务堆栈大小
1 A, k/ E- `' Q$ O" @. N2 ^ - (void* )NULL, //传递给任务函数的参数' D, O2 s+ U( j7 r# n! g
- (UBaseType_t )START_TASK_PRIO, //任务优先级
2 {$ o9 r$ t. W5 u5 P/ f* n - (TaskHandle_t* )&StartTask_Handler); //任务句柄
1 ~! j `% E- d/ K - vTaskStartScheduler(); //开启任务调度8 c, n8 U6 z% N! l9 X
- }5 v+ q% B& \7 l/ X$ r- B# N
~& q" C% w9 {' f& _
# _ D! ]+ F6 t5 O- //开始任务任务函数1 V0 k% L1 }( U: @' \5 Y; A
- void start_task(void *pvParameters)
2 q4 z5 j ^ Z. v% P3 k - {
& |8 z6 w, X i4 E. A1 o* H$ i - taskENTER_CRITICAL(); //进入临界区
7 z0 }6 J% h( \. H. H: G - //创建LED0任务: v' L) y1 o+ D
- xTaskCreate((TaskFunction_t )led0_task, 4 [$ f- a. e0 O8 w g0 w
- (const char* )"led0_task",
& b2 G" ^1 j' t3 m( U. F0 w! o/ b - (uint16_t )LED0_STK_SIZE, " b! y( l. R+ h+ H
- (void* )NULL, 3 k7 ^0 n# @" i% r$ `$ t( T" K) @
- (UBaseType_t )LED0_TASK_PRIO, & t9 C8 \1 y7 g/ _6 G- a
- (TaskHandle_t* )&LED0Task_Handler);
/ y5 ^- q0 T5 R- j - //蓝牙串口控制/ O. J/ w3 T) T! n
- xTaskCreate((TaskFunction_t )UsartControal_task, . u* r! X4 p1 O. J2 C
- (const char* )"UsartControal_task",
/ X- C+ W5 k$ y: Q6 k - (uint16_t )UsartControal_STK_SIZE,
# v: J/ n3 l# A; ^# B% R# f - (void* )NULL, t( B- a* Y' Z- L
- (UBaseType_t )UsartControal_TASK_PRIO,
; q' p" S$ L! E/ r j5 {& R - (TaskHandle_t* )&UsartControalTask_Handler); + w- b. O+ S* K: [& t
- , k3 Q- y/ [' F& h) I
- vTaskDelete(StartTask_Handler); //删除开始任务' {+ \6 a; |+ R7 I' q
- taskEXIT_CRITICAL(); //退出临界区: V; ^5 k/ p1 R, {' ^
- }% {. E5 B7 Z! A) _* J: }& p
- ' t }5 n& y/ z6 G& K# U# \
- //LED0任务函数
+ z! N& N5 \' r# W! S+ K - / J4 d' F& G b* u" \
- void led0_task(void *pvParameters)) x+ O" P7 {. m5 N t4 C6 F
- {$ k7 f$ V t5 d5 S. d
- while(1)
' J( [1 B J: _4 H - {$ h b3 x5 h1 Y
- LED0 = ~LED0;5 q8 m* E) j" Y$ Z! A
- vTaskDelay(1000);
9 \) H( L$ N- o4 u% X - printf("led0_task Running\r\n");
' C1 F8 C0 G7 X0 q! H& v - }
# f* J- k- j8 ^% O* D - }
# d" A3 j* e- c8 Q$ z% B - 5 I. I- f' y# Q/ l' Y: |2 ]
2 q! x5 R) P: a% W2 N- 9 h$ f" O, o+ \8 |: j! N8 L Q
- //温湿度数据读取 将获取的数据每隔1s通过蓝牙发送到手机
( [( l9 ]" {( X! o$ i" n! N - void UsartControal_task(void *pvParameters)
. I7 q( L+ o- x1 K: e# f - {- v7 l9 ~% x+ `) `2 l. E
- uint16_t i;
! C0 @/ B E2 E& M1 ~4 r5 [9 }! j - uint8_t k;
. I ]6 b' s2 t2 x1 K - uint8_t kk;' q4 ~, C: L* `1 o
- uint8_t kkk;
6 T) c( w) L0 i3 q - uint8_t Temp_Buffer[20]; //发送数据缓存
( ^ }' j% W$ f: ~( c: h - while(1)& k; K3 }. T4 v1 m" ~) n& Z
- {/ Q3 V. G' e( w& Y/ m
- ' W, z$ m% l2 _5 S
- DHT11_UpdateData(); //读取温湿度5 e |- r4 ^7 p8 N) @, k# T1 O* {: i
- i = Rxbuff[0]+ Rxbuff[1]+Rxbuff[2]+ Rxbuff[3];
+ b; G; i6 e/ D5 o% m - if(Rxbuff[4] ==i) //进行效验判断
+ I$ y% j& ]# @& L6 J - {
# b/ f1 I5 L3 F; o- p! u5 ^ - k=Rxbuff[2];
/ N% O# E1 z- ~" z - kk=Rxbuff[0];5 O, Y6 J) B$ Z. D
- kkk=Rxbuff[3];& P0 u' i3 ~+ p2 h0 _! o3 h
- sprintf((char *)Temp_Buffer,"当前温度为:%d 当前湿度为:%d\r\n",k,kk);
% d- M' [" [& i: e - USART_Send_String(USART2,(char *)Temp_Buffer);
1 c. \/ F. I/ V1 r+ w& i z - }* _8 P; n: f! F+ T, s) r# w" l
- memset(Temp_Buffer,0,sizeof(Temp_Buffer)); //清空缓存! a6 K4 Q* g5 H4 {; a2 V
- delay_ms(1000);* R; n, R6 z6 |! ]2 B' K o0 m) b
-
* [4 B+ Z7 [, t% Q3 z8 o - ( m2 C, ^- ^+ D. T+ K
- }! E: _ ?( H' P+ w! t
-
5 o& @6 P I5 s9 c0 u. F) u - }
复制代码 3 l, G ~" y" l8 b& m( A+ c8 w
实验结果
w* ]% \* X; @- H8 |1 o
2 W R, I4 W+ E' r
3 F. |- k6 r3 g6 m: v) ]$ v8 P. B
- j% }6 Y& P! _/ B, B' t2 y! n————————————————4 u! h6 l, v7 ~* o% K
版权声明:@slow-walker
: i9 Z2 Y0 R& _+ L" M/ w# R" b
( x6 [% q, S( W- _7 W
0 h$ x( z7 o3 p. A6 q# i, @ |