STM32的串口介绍
4 I& e' z# `0 SSTM32 芯片具有多个 USART 外设用于串口通讯,它是 Universal Synchronous Asynchronous Receiver and Transmitter 的缩写,即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。有别于 USART,它还有具有 UART 外设(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是 UART。- `- U8 @7 |( m& O6 x( B. @# g
% d }. z( B4 z- E7 u( B0 l
USART 满足外部设备对工业标准 NRZ 异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率,使得它的应用更加广泛。USART 支持同步单向通信和半双工单线通信;还支持局域互连网络 LIN、智能卡(SmartCard)协议与IrDA(红外线数据协会) SIR ENDEC 规范。USART 支持使用 DMA,可实现高速数据通信。' ~0 e1 q; Y' H7 Y7 L' ]
) ~; }- ?0 F# ~% N. s- A* Y U" Y* NSTM32F103与STM32F407的串口使用方法基本相同。* ^: {! ~0 U! M4 @; ~1 J4 K
F103有3个USART(USART1~3)与2个UART(UART4~5)
" P6 x$ p; w6 }$ Z' [3 P4 `: mF407有4个USART(USART1~3, USART6)与2个UART(UART4~5)。
3 w2 A: y! q1 b9 C1 o" I( X以下两表分别是这两种单片机串口的管脚(部分)映射与时钟说明。6 n) k+ C$ o% w; ~2 i
9 [, @$ ]1 Y2 p3 ^. s @& A
/ X/ f, Z$ r; h+ B! z- l0 m6 {7 M- N
# U V8 U2 C; v! G! `
3 W7 w) T; k A% a" {
; y& \+ R# B0 Z. V' T3 n
( @: L& K: Y/ M! v, F串口配置的模板函数' Q0 R) S. V+ z1 x3 c
以STM32F103平台为例,开发了三个核心的串口配置函数,在串口初始化和需要修改参数时可直接调用。这些串口配置函数可以满足大多数应用场景的需求,但需要注意的是为了减少函数的参数个数、提高函数的易用性,部分串口参数直接采用了默认配置(例如收发使能、中断使能、流控禁用等),在一些特殊场景下需要重写部分函数的实现才能修改默认配置。
& h& F5 h$ z( G4 o" C X! b3 ]2 b! P! D. i( a" Z
配置GPIO7 A1 y1 m- W* x0 e) |+ h
- /**
B" a, i& g5 r - * @brief 配置串口的引脚端口" I" P: S' k% x7 `+ ]8 ~
- * @param TXD_Port: 'A'~'G'
' U+ i \" _7 b6 `$ s% K% q - * @param TXD_Pin: 0~159 p: R& `% o; D( M8 L p2 D
- * @param RXD_Port: 'A'~'G'
7 x- S' I+ E; U - * @param RXD_Pin: 0~15
' ^1 t+ v! s) I9 l6 s5 E - */
. Z/ p6 ?, T# J% {; g& E) i - void USART_ConfigGPIO(char TXD_Port, uint8_t TXD_Pin, char RXD_Port, uint8_t RXD_Pin)5 v$ P# H* I* _4 G3 y4 d0 c
- {
* O$ @& @" q0 U - uint16_t txdPin;& K/ P' j; d' I5 B
- uint16_t rxdPin;
3 ^$ G6 f! _: |/ Q5 U% y# _ - GPIO_TypeDef *txdPort;3 f3 r% w$ p6 @* f7 c8 {
- GPIO_TypeDef *rxdPort;! c8 {, [7 P; N5 u% t% m. Q
* A1 \$ s2 E, ]; b9 {; l' t5 M# D* H- GPIO_InitTypeDef GPIO_InitStructure;, V |" }& K. i( F
- " S3 k) j$ e% p" \
- switch (TXD_Port)5 R; S: c& ?% K$ u# I! T4 V& G! Y2 p
- {$ K+ B5 @$ M/ I4 `5 G
- case 'A':
4 C& ? Y& M2 E - txdPort = GPIOA;
. ~. {- q+ g0 Q5 q4 b. K& `1 V - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
0 {/ M6 T" p, I - break;
: }- \% c5 v6 a. v9 J - case 'B':
; |# y1 `4 h U) _ - txdPort = GPIOB;
8 b* h9 @$ p j. R% i& h( l8 k - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
( k6 Y5 d; d. q8 @: |7 @; M - break;
* X' j) H) Z; J- x& e3 p0 m - case 'C':5 m' @9 c9 W: x/ v
- txdPort = GPIOC;7 r+ f$ g; }) r2 X- p
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
& P( F& B6 C: f( X( e, u K - break;
% {2 U& N, n0 V3 `9 D9 X v - case 'D':
) B2 d9 u. ]4 m. n- e - txdPort = GPIOD;
+ z- w8 D% V8 Z2 E - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);+ N3 \# c S/ p) b8 D) a
- break;
T6 a4 @5 y" S) x - case 'E':
% K6 J- \7 ^/ ?+ |0 c/ l/ p3 { - txdPort = GPIOE;# Q; \' [ e$ D* {( l
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);* X: R4 _& h( R! E" `' ]+ Y# j
- break;
. Q1 q/ }0 W" [* p& e j - case 'F':7 x' {- \: p; N/ u
- txdPort = GPIOF;. b' X' Q$ l3 a6 {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);$ Y5 z1 q( H& a. b" c/ K0 ]0 T, W, h: \
- break;, L1 K) u2 y. S6 I4 U
- case 'G':
9 u: N. D% {6 p4 ~. a - txdPort = GPIOG;
4 M2 u/ Z) X) Z+ V* O) p0 n/ i7 i# E - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);$ V7 F f( H2 W! A" K& [
- break;) Z/ }% g G9 v9 _8 P9 c
- default:
6 i+ W4 v7 {/ L' h7 `3 ~ - break;; c/ x* p4 a3 o5 V
- }7 h U! E* m9 Z
& d( t( B5 L4 D3 X M- txdPin = (uint16_t) (0x0001 << TXD_Pin);+ v% N4 {$ F5 S0 C
& j3 Q! E$ [4 w) K9 N: y6 R- switch (RXD_Port)1 x4 m! \& d" {4 b8 J
- {. y5 M8 |6 H7 H& f) V7 E# [
- case 'A':7 a% L( `5 e4 H* m7 \& o
- rxdPort = GPIOA;4 e; u7 h q7 i# S' k7 i% b
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
1 S9 x& I3 I* K. @1 H- j - break;& _+ z5 b/ ^3 v( ~9 d: }: H
- case 'B':
% b" _) c9 q4 h5 u4 F+ \' e! E - rxdPort = GPIOB;
- R0 F9 }; B/ ^! h - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
2 s! d( Z% V1 C4 \" i y8 Y6 D - break;
! g* {& S6 C: [# K4 X& P" Q - case 'C':. I9 c8 o* t9 G
- rxdPort = GPIOC;* J' r8 w0 q7 t, e9 P9 g( U$ c
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);7 z4 p6 R: U, m: A* P6 L6 e
- break;. y. e) ~; r D% N
- case 'D':
. ^0 b& @% B6 q7 x# Q9 @6 W# Y - rxdPort = GPIOD;
; F4 |# ?* \% Y, d; K/ J. ] - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);" r% W# P; c1 k9 c _ _' V
- break;
5 A8 ^0 h6 o" W# h( U4 L' z1 S - case 'E':& Y" m a3 O2 Y/ \1 m
- rxdPort = GPIOE;+ @1 [( f }9 q8 a* t0 {, \
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
/ C; \. n0 U! V- k - break; j2 N6 \8 }. D. ]0 L; t `# O
- case 'F':5 h6 F. M7 v3 |1 U
- rxdPort = GPIOF;. C& ~% P. {9 W& h
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);$ Y: A& Q- T. L- I5 I; ^1 Q
- break;
1 l! B9 I8 E3 Q1 G - case 'G':
9 k7 F( H2 w3 |& _ - rxdPort = GPIOG;
6 Y# H8 M, h4 o) K - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);+ z) l0 \* ~* R) M
- break;+ o+ T* l# C6 p" A% D; v" {, ?
- default:
/ G9 B; [- d! e9 X+ H6 _% [ - break;0 r* G- u0 Q* R0 o# ~0 o
- }
6 T( d9 Z% c% X Y - 7 X d! r% |- Y( ?8 Q& I
- rxdPin = (uint16_t) (0x0001 << RXD_Pin);
3 `+ a5 N+ v3 K$ u" T5 L( K - , S4 L8 m9 W/ K! f
- GPIO_InitStructure.GPIO_Pin = txdPin;) x7 a M( Q$ L. @) o* [5 k
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;5 N1 a9 } Q r! w- X$ }% u
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;! e5 k9 {4 O2 c N1 D8 u
- GPIO_Init(txdPort, &GPIO_InitStructure);$ F/ c4 E3 H" G! M. X( `
- 6 L$ |0 w: T- z. U- d" h% l
- GPIO_InitStructure.GPIO_Pin = rxdPin;
6 s2 T# ?: o: ~& h7 B - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;) ^/ }" q" R0 ^5 M1 n7 s. ?
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
# t) f! t6 Q' `& J5 p: R - GPIO_Init(rxdPort, &GPIO_InitStructure);
8 u( L$ s, Z3 Z - }1 P+ E5 P: w" u
复制代码 2 y% U3 l+ d% [, k; @7 M/ Q% ?
配置NVIC
0 x* b' A( _2 T0 M$ S( J+ r- /**+ @" E7 L# S; |6 U6 \# U4 }4 Z. |
- * @brief 配置串口的中断向量控制器
5 j7 ~0 x1 P& a - * 注意,此函数中未设置中断向量控制器的优先级分组。* W6 L/ X! z7 k4 r! A
- * 中断向量控制器的优先级分组应当先在程序其他地方被设置后,再调用此函数。+ w- E3 D6 H; Y( T% ~) c/ S, n
- * 在运行FreeRTOS的系统中,一般情况下采用分组4,即四位都被配置为设置抢占优先级。1 ?" k% c7 R* T( l: f
- * @param portNum: 串口序号1~56 Z2 S2 O2 V( u7 o
- * @param preePriority: 主优先级(抢占优先级)
. N6 }+ N; K1 _ - * @param subPriority: 从优先级: w* c# E G+ Z" x
- */
- X) G1 s( p' Y - void USART_ConfigNVIC(uint8_t portNum, uint8_t preePriority, uint8_t subPriority): Z0 ?# p+ z5 x5 {) z; x! i' g
- {8 ]+ g( J" R r/ r
- NVIC_InitTypeDef NVIC_InitStructure;
|0 C7 g. I5 [, \7 Z; Z& _4 A
4 N1 {6 [) w2 [/ u- }, Z4 j- switch(portNum)4 C+ k9 ^' A# E9 M) u
- {! M' C' r: J- q7 e' H5 k/ o# L
- case 1:# l' j1 O! C. Y6 d2 f6 A0 h
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
/ D& R$ V4 ^5 n C5 u# ^6 Y; | - break;. ], c6 u# i% q6 _; a* i
- case 2:( ^( n$ |, k6 Z4 M
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;5 Q1 q0 Z$ a% ]" P% K
- break;
- W$ f. ?( e' _$ D! Z0 c @4 d9 @ - case 3:
6 T! O2 i0 ?. E/ |4 G - NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;& }3 Z5 w5 I5 Z$ I. e# |+ W
- break;
- ~0 ^% C* x; a1 B7 b: J( p, T - #if defined(STM32F10X_HD) || defined(STM32F10X_HD_VL) || defined(STM32F10X_XL) || defined(STM32F10X_CL)
' O* L1 E: i! F- V3 B. M$ U - case 4:
8 \3 a" h5 ~# l5 Q* F# ]$ c- V# n5 w4 k* M - NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;$ A1 p4 n. Q. t" e& q/ x5 c
- break;# S @ z2 n4 ^
- case 5:8 c5 v( `. l; Z' Z: @* ]0 j
- NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;* N- }8 k4 l- J2 u! b, B4 X; X
- break;9 q$ U$ k3 g2 M7 Q/ W
- #endif
" E/ V! A& J. V/ ? - default:
& _& j+ V* C* H' c3 P) b7 \/ B9 r - break;
" G+ K4 V2 y* t% Z8 h3 t; X - }4 Q, [/ D) {( V& I6 S
0 b* \8 E9 S H/ J5 G, U- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = preePriority;
' [! _ b- `. q" \2 W - NVIC_InitStructure.NVIC_IRQChannelSubPriority = subPriority;3 S3 b/ r! z& D
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
# Z) E4 h- o7 t1 O- A - NVIC_Init(&NVIC_InitStructure);
' Y2 u, P6 v( E! v) m! J - }
复制代码
% ~3 q# T7 g( P; z, C* k {6 z; x& p0 K3 {( O
配置USART- /**
( X$ F& d) }2 j; Z7 W - * @brief 配置串口外设& h7 l- z" Y c8 q' M) [1 q; d
- * 注意,函数参数列表中没有列出的配置参数采用默认的配置:
$ z5 R0 m$ L3 T4 w4 c9 y: h - * 1. 无硬件流控 2. 双向收发 3. 使能接收中断 4. 开启串口
$ j6 |* r2 y- \1 T8 _ - * 如果需要修改默认的配置参数,则不能直接调用此函数完成串口外设的配置。9 U% F" ^5 {0 K2 _- e0 A0 \
- * @param portNum: 串口序号1~5
, b8 v( t% X$ {# X4 b' w4 { - * @param baudRate: 波特率
5 p+ d$ t+ e/ N+ c: |. h: p - *
$ d( s7 P* D( ~9 i7 N* G - * @param wordLength: 数据位长度(枚举变量)
1 q* l0 m) [6 t' c' Z: \ - * @arg WordLength_8b: 数据位8
4 \- m; w' ^, a- f. G - * @arg WordLength_9b: 数据位9 X6 j# X9 q0 D" ^! f
- *% ^" Z) V( L* K/ o# w
- * @param stopBits: 停止位(枚举变量)' h0 C1 q2 o$ y
- * @arg StopBits_1: 停止位11 {* r0 B2 F4 ^6 [# C9 n1 \
- * @arg StopBits_0_5: 停止位0.5
& Y, e' V! ~! q) D7 X ~- J9 x - * @arg StopBits_2: 停止位2) L( ?# ^' ?* g& e) {+ y
- * @arg StopBits_1_5: 停止位1.5/ {/ S/ X. ]& I) D* |
- *0 [$ E' f, G) c4 y1 B0 I
- * @param parity: 校验类型(枚举变量)
+ A9 `" `& I5 x* Q4 V, M - * @arg Parity_No: 无校验$ _4 E8 _) E5 u t5 D
- * @arg Parity_Even: 偶校验8 m9 @5 p# M. T+ ^2 O
- * @arg Parity_Odd: 奇校验% b' d* c% C. Q( C
- */; ~! A9 Y3 [9 F
- void USART_ConfigPort(uint8_t portNum, uint32_t baudRate, USART_WordLength_Enum wordLength, USART_StopBits_Enum stopBits, USART_Parity_Enum parity)
; X9 A5 _: N$ b H( K7 b - {# }" H5 z- j+ N7 C3 ]) g6 S3 M
- USART_InitTypeDef USART_InitStructure;; d, O6 _( G. q. y
- USART_TypeDef* USARTx;
; z: H* p9 C B - . t. T: l/ l6 y! ^9 d2 ~+ q( E
- //开启外设时钟* u( k0 K+ H0 u& [
- switch (portNum)
% W0 _% M# D! g$ Z+ C; {7 S - {2 y; Z& \; Y& n/ ~
- case 1:
; W: F& y) z8 f - USARTx = USART1;5 n3 ~( }% q5 }
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);2 @0 D8 \& m5 `5 b' y
- break;' c9 _( q" e7 ?
- case 2:
3 A6 f v0 F2 \. ]: I - USARTx = USART2;
q( L2 ~* f/ p$ u4 S - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
: [ r7 g3 {# r4 h - break;% I. z' w& r' l+ A& y9 X4 q
- case 3:
0 P7 A4 z0 f4 ~/ ^ - USARTx = USART3;
( k: n: v4 J% D3 X0 k( x3 c - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
( ^( U9 J" ~0 ?) I - break;9 t. A7 V, `1 K: p `& J
- case 4:
* h6 o9 u4 E" s% |& `1 k! E1 t - USARTx = UART4;
9 b1 L' W4 |4 b$ a - RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
' U5 \( m6 ~8 u - break;
2 H8 i5 H! H1 o7 H+ J/ B/ w1 U - case 5:# e* l3 l) I: b: N* v. p3 h3 z
- USARTx = UART5;
, M' X6 q9 D+ \4 ] j$ i4 R7 o - RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);9 t/ N g' `( D0 o$ q
- break; M( |# D( s* s; Q4 h- f
- : H% R* W% \3 d& @( S9 `+ g9 N
- default:
2 U, P) o! Y t& H$ _9 N' | @9 L - return;
$ s3 i L. H2 O4 Z - }
' }( ?' c) t; f8 A2 K K
7 u0 ^4 d# j$ k0 e- ?* H- //设置波特率) h8 H: `1 Q0 h, K/ y% }
- USART_InitStructure.USART_BaudRate = baudRate;
6 z: y7 _( g/ h7 G
* N2 m R# C* y; H0 ~. h! |& X- //设置数据位长度(一般情况下无校验时,为8位数据;有奇偶校验时,为9位数据)+ H1 d; F; T1 @: n0 N
- USART_InitStructure.USART_WordLength = wordLength;
: P: X: W; U+ K - 4 y. s5 |! c( [8 w0 u7 A
- //设置停止位" h, {: G" V6 s* \% p9 u6 N/ f
- USART_InitStructure.USART_StopBits = stopBits;; C# `4 q+ y% E
- ' O9 i6 c, N0 B9 E3 V
- //设置校验位7 L# ~7 h+ g( B* F3 |( p1 f& ~
- if (parity == USART_Parity_No)+ i* n& V$ P; y
- {
1 P& u1 `$ N( P2 @0 B6 A - USART_InitStructure.USART_Parity = USART_Parity_No;
: z4 c" v1 y# W. n: F6 W1 \ - // USART_InitStructure.USART_WordLength = USART_WordLength_8b;
& Z1 m& o6 n6 a - }, a( z. B1 X7 G3 c" e" } d2 u
- else if (parity == USART_Parity_Even)
2 G3 Q0 K& A& w - {
% E3 q: W2 P# m( @) M: A4 Y" D - USART_InitStructure.USART_Parity = USART_Parity_Even;8 ^2 M* C6 O) R. d0 H6 i% C
- // USART_InitStructure.USART_WordLength = USART_WordLength_9b;, t6 t& c9 K; ?# T6 Q& ]+ ~
- }
- j, E# \; j) D! G4 b: a - else if (parity == USART_Parity_Odd)
$ w6 G' u K) w8 H& l1 N# q( ] - {
0 O2 a8 ], R4 I+ H' v* @2 v$ D, f* @ - USART_InitStructure.USART_Parity = USART_Parity_Odd;% b. V5 I- |) E& z2 K" ^
- // USART_InitStructure.USART_WordLength = USART_WordLength_9b;
0 {5 y k) a$ c) }" I - }& P. k u+ u" i6 u6 ]7 z
- else5 K* ^$ G Y& i) P0 z) G
- {' {2 P& ?1 O! G5 G. b2 j
- return;
& k6 a, M, ~( y) [% X! ?3 a- \# V - }
/ u+ b& F8 s9 j- E - 8 g: q- E( n$ M' z
- //设置硬件流控
3 |% M' m2 T9 F5 | P5 ]; S - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
! `% T6 w, G9 `5 p! p+ o! }- a: t - * n" `! V0 Y1 m3 j9 V) j
- //设置收发模式# Y9 T; M9 Z" v( U0 e
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;: V5 ^( P) j$ P
" w' J4 ?7 H1 K# D, R5 i& y- USART_Init(USARTx, &USART_InitStructure);' W) F: o3 l5 ]( ^) \6 ^8 R
- - t. ~( p& ]$ J3 ~
- //设置中断模式0 C% d0 X* X' H3 o, Q0 W
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
1 m; J& F9 B$ H' q# L/ B
4 S) j. Q# A& B# i+ X7 H. J- //使能外设
' @) o) h- I1 S8 ~ - USART_Cmd(USARTx, ENABLE);
# }9 u- A+ j) i- r1 H: O0 R - }2 O( D( q1 {- {" Z7 ]8 l! A. L
复制代码 9 W" T4 q- M7 N
扩展库的特性
l5 s7 k! W. K. m, }本串口扩展库的核心是构造了多个循环FIFO队列作为接收数据的缓存。通过向接收数据处理函数传递一个具体的处理函数,可以实现本扩展库较好的封装。开发者设置了合适大小的接收缓冲区之后,仅需要在合适的位置调用接收数据处理函数void USARTx_RevBuffer_Handler(void (*USART1_RevBuffer_HdlPoint)(uint8_t* _Data, uint16_t Count))即可获取缓冲区中保存的串口接收数据,而不必考虑这些数据是如何入队、如何出队的。7 K" O2 h/ c& d
: f* B5 z5 a5 q本串口扩展库函数采用中断的方式接收串口数据,利用系统空闲处理串口接收数据,采用查询等待的方式发送串口数据。如果需要发送的数据较多,可以考虑利用中断或者DMA传输发送数据,否则系统将会等待较长的时间。同时库函数可以与FREEModbus库配合使用,通过FREEMODBUS_ENABLE宏定义的值可条件编译不同的串口中断服务函数。: A" @) n# u/ R+ d1 g1 g" Z8 _- g
. ?+ c4 \; c7 W2 {
需要特别注意的是为了使函数名称与功能更加准确的对应起来,本扩展库中的连续数据发送函数名USART_SendData与标准串口外设库函数中的单字节发送函数名重复了。因为需要将标准库函数中的函数名USART_SendData改为USART_SendByte。当然,也可以修改本扩展库的*连续数据发送函数名,使之区别于标准库的函数名即可。' B' J" a+ E2 H Y4 t4 s5 g6 M4 y9 m
0 y- ] V4 i( }
在"stm32f10x_usart.h"与"stm32f10x_usart.c"需要修改的标准库函数如下:5 T, L" \8 _) y4 [. a
/ [) u# w+ F* M2 _; b1 R
- /**
h. z L; D4 i$ W - * @brief Transmits single data through the USARTx peripheral.
8 ~ B& \$ s. v6 F+ V - * @param USARTx: Select the USART or the UART peripheral.
4 a: s$ v+ _$ n3 r! n! ^+ } - * This parameter can be one of the following values:/ ^; `* f0 N" o: @. r. l
- * USART1, USART2, USART3, UART4 or UART5.
( H% U4 s2 S5 W6 o+ L) F9 D - * @param Data: the data to transmit.
# W6 a2 |1 y6 k& j) `9 M& ^6 ^ - * @retval None
]3 y; v2 w8 W# R f - */. |8 g3 o v6 b) v8 r% c/ l3 y9 b
- void USART_SendByte(USART_TypeDef* USARTx, uint16_t Data)& K/ X) B# F. U+ J* \
- {
# ^* ?6 p2 g7 q* @. ]# m( l" h - /* Check the parameters */
8 u2 R \5 v1 J. ^1 r; ^ - assert_param(IS_USART_ALL_PERIPH(USARTx));
) M4 [% n3 S+ S! S2 q - assert_param(IS_USART_DATA(Data)); ' o" y# b* N+ i- Z& Y* M
0 u5 e9 ^' J0 ^- /* Transmit Data */
$ S) t- |" s6 J8 z; V1 G - USARTx->DR = (Data & (uint16_t)0x01FF);
$ @0 _) L( ]' _7 C - }
复制代码
( R. ^" }, Y% U+ y3 n) i& f( U4 q$ ?/ d源码% \ N& p# n8 `
头文件
9 S! h6 i) j0 a1 K, d9 O& T- #ifndef __USART_EXT_H__" [) \4 m. {9 K2 K: g X0 V! F- m
- #define __USART_EXT_H__
. g- [4 J8 Y; V# s8 Q% e - # m) j# G8 I7 A$ G
- #include "stm32f10x_conf.h"
/ L- B& d" ?# I: w' p! f2 F - #include "stm32f10x.h", A- N% ~0 }1 J7 t, S
" j$ o! o& a6 j6 @* Y- #define USART_Count 54 w: K* F, x$ R
: t! Y1 f n- d# ^' A- #define USART1_BufferSize 50# B1 }3 r2 d& L; Q2 p# @# R! ~
- #define USART2_BufferSize 50
) ^4 e* Z q- K( p3 _' \& l4 V - #define USART3_BufferSize 50
" Q& g2 F1 F4 Y6 L - #define UART4_BufferSize 503 O, J- c8 L2 c$ u9 Q9 B7 M; t
- #define UART5_BufferSize 50' B0 `/ Z2 }4 ?) F
: f: Z2 v# M j" M: E6 h4 n5 ]- typedef enum{
/ W3 a! S T# z4 h: X - WordLength_8b = USART_WordLength_8b,, y- Y2 i0 ]- T- K; c
- WordLength_9b = USART_WordLength_9b,
) g3 ]! t$ I$ ?% h) @! k) r+ ] - } USART_WordLength_Enum;& G4 [. K( L! g# R5 P( a. L \
1 r, }0 O: R6 z# y4 c3 L- typedef enum{$ e v( I, [0 C4 u- K. s I
- StopBits_1 = USART_StopBits_1,- x& j$ t0 V F u7 o
- StopBits_0_5 = USART_StopBits_0_5,
* ~$ L3 I' e D. `9 k! i - StopBits_2 = USART_StopBits_2,* K3 J+ v8 |" c C3 F
- StopBits_1_5 = USART_StopBits_1_5,; b3 f" g2 S3 Y# ~6 N
- } USART_StopBits_Enum;( c, K0 ~4 b0 Q, u, z3 m
- 2 V1 |' z* u4 R+ D% y! @7 Z
- typedef enum{
+ [- R/ d7 f6 T' V( Z. Q - Parity_No = USART_Parity_No,& l, F0 O: I2 H! U& h, w
- Parity_Even = USART_Parity_Even,
7 a8 D2 O& z9 @) E( j; e, p3 s - Parity_Odd = USART_Parity_Odd,, W O" K6 H% D3 q
- } USART_Parity_Enum;
, t" t3 B- _+ g8 R$ ` - 5 K \; W5 ~$ `% q! M* S, c/ Z
- void USART_ConfigGPIO(char TXD_Port, uint8_t TXD_Pin, char RXD_Port, uint8_t RXD_Pin);. J# M9 W- Q! x
- void USART_ConfigNVIC(uint8_t portNum, uint8_t preePriority, uint8_t subPriority);
. }3 a4 m" c6 a O# ^ - void USART_ConfigPort(uint8_t portNum, uint32_t baudRate, USART_WordLength_Enum wordLength, USART_StopBits_Enum stopBits, USART_Parity_Enum parity);
6 k/ u& J% @: O5 |- Y
) I3 c; `. I* H- void USART_RevInitAll(void);
2 Z6 h: O* C" h0 f9 Q/ c - void USART_RevInit(USART_TypeDef* USARTx);
6 F' D% y7 e0 t" A) ^
~& C8 Z1 V8 }7 v- p- void USART_SendByteData(USART_TypeDef* USARTx,const uint8_t byteData);6 l1 r+ b/ Y3 ~, X: R
- void USART_SendData_Bit16(USART_TypeDef* USARTx,const uint16_t *Data, uint16_t Count);6 b& ^' b) v" ^3 q% E% A8 I
- void USART_SendData(USART_TypeDef* USARTx, const uint8_t *Data, uint16_t Count);4 j a3 Q: d. `9 C% X+ c* P3 A4 v
- uint16_t USART_SendString(USART_TypeDef* USARTx, const char *String);
4 X1 J* L8 @6 k7 b
$ e5 n9 s( I% M8 h- void USART1_RevBuffer_Handler(void (*USART1_RevBuffer_HdlPoint)(uint8_t* _Data, uint16_t Count));5 V, `3 [4 P' Z; b& H- {
- void USART2_RevBuffer_Handler(void (*USART2_RevBuffer_HdlPoint)(uint8_t* _Data, uint16_t Count));0 A p5 s9 a3 ^8 Q! ?
- void USART3_RevBuffer_Handler(void (*USART3_RevBuffer_HdlPoint)(uint8_t* _Data, uint16_t Count));) B5 G6 V2 n2 u ?* I
- void UART4_RevBuffer_Handler(void (*USART4_RevBuffer_HdlPoint)(uint8_t* _Data, uint16_t Count));2 V6 f d$ u$ d, q3 O3 d
- void UART5_RevBuffer_Handler(void (*USART5_RevBuffer_HdlPoint)(uint8_t* _Data, uint16_t Count));
3 o4 D# h6 X" w5 @ B3 G6 P# O8 r
8 w$ g% \0 O" r9 q4 t- #endif
" c+ [0 j# v$ L9 u4 C& x
复制代码 ! I" O) q& H8 r
源文件
7 d# z) F Q: }% y! P9 g& b- #include "usart_ext.h"
! [+ S0 j3 G7 V - #include "mb_user.h"' {2 G, h0 c9 t
- - }% F. c& h$ g5 A0 O
- /**
2 [2 ~. B9 I3 |$ Z! l/ I: G - * 本串口扩展库函数采用中断的方式接收串口数据,利用系统空闲处理串口接收数据,采用查询等待的方式发送串口数据。8 f6 S$ |6 V" _2 J$ z3 C# \) K% [% s
- * 如果需要发送的数据较多,可以考虑利用中断或者DMA传输发送数据,否则系统将会等待较长的时间。2 ^% P" M8 F F. ^2 \! Q4 a. [2 s' ^/ e, ]
- * 同时库函数可以与FREEModbus库配合使用,通过FREEMODBUS_ENABLE宏定义的值可条件编译不同的串口中断服务函数。
3 {2 e+ y- }$ b( j - *// Y! q# R4 |2 C; m: P' D- ^' [
- * P+ ~( H% L+ a! t9 r. C! W
- /**
. L: ^0 j/ Y7 K: S( t1 y - * 定义串口接收的缓冲区大小,根据串口的应用需求,可以为每个串口设置不同大小的缓冲区
n$ Y& S# x; `- z. p: l; w/ j6 }$ b - */
+ b4 k! t' {8 L+ a0 p0 P - const static uint16_t USART_BufferSize[USART_Count] =
9 q4 T7 n; D- q2 X' a) y - {
5 m5 b& [! x1 G - USART1_BufferSize,& C3 ^- ^5 f1 U
- USART2_BufferSize,
- M- T& V7 Y% T - USART3_BufferSize,
. @: Y6 U3 o6 j1 I - UART4_BufferSize,! K M+ f+ Z7 t4 M, M" V, J, h
- UART5_BufferSize,' q* H, z( w+ Y9 F5 p) u
- };
9 T7 ]/ V1 t# `: |! ^, T; Y - 7 f) Z& O; H, R+ r6 E1 }
- /**
8 u: c: u. x; b9 ]# a5 w: q- e - * 将各串口接收的缓冲区声明为静态数组变量,防止外部修改
5 V8 f7 F; t( J. T) p$ f3 R - */- f$ A$ P) O2 L
- static uint8_t USART1_RevBuffer[USART1_BufferSize];
; z5 Y( ~+ X& ^$ g0 w; k& d! a - static uint8_t USART2_RevBuffer[USART2_BufferSize]; Y! ?" f; e3 V# N
- static uint8_t USART3_RevBuffer[USART3_BufferSize];% e& C, @9 c6 Y$ i' U7 F; W
- static uint8_t USART4_RevBuffer[UART4_BufferSize];
6 ?0 {+ c8 l# }3 `6 e - static uint8_t USART5_RevBuffer[UART5_BufferSize];
( a4 D- q# F0 A# {/ v9 Z& z+ q
: I/ _/ _0 I. _4 v* {& T( ~0 E- /**. b. L4 n; r- L
- * 指针数组,将各串口接收缓冲区的首地址作为数组的成员,以方便程序操作
! |: l! N2 V$ Z1 \+ Y - */
: @- i, e! H# P - static uint8_t* USART_RevBuffer[USART_Count];
' g2 ^ O* m; a5 g d& d# @
5 y2 Q# I- u! l4 K3 w# W% e+ c- /**
) t; ]( z1 s; S1 Q5 {9 B; R2 s - * 指针二维数组,用于管理缓冲区的读写指针
1 q4 Y9 C4 ^9 _. ^3 q9 ], a - */; O( ^- ?% @3 p$ J/ `" I' O( K
- static uint8_t* USART_RevPointer[USART_Count][2];
4 M( h# W, [4 m' P3 I# h9 N - 1 _* S6 K" K# `/ O. q
- /**% X: h& w h' l: i
- * 缓冲区接收数据计数1 f- U/ G3 Y) V
- */
* S0 R# X. L3 A" o8 G3 U - static uint16_t USART_RevCount[USART_Count];$ e- W0 g' }. R
' B. p, R" a1 o* _2 ~- /*** ?% y; `5 Q0 {
- * @brief 配置串口的引脚端口3 G5 y6 J2 g# C/ b& S
- * @param TXD_Port: 'A'~'G'
6 E" v# w2 U2 ~6 g, m2 | - * @param TXD_Pin: 0~152 [! h( Y: y" f
- * @param RXD_Port: 'A'~'G'" q; _: Z: d' ]7 p! f* a+ g1 y8 ^& x
- * @param RXD_Pin: 0~150 y0 G8 }7 P& y# \ x' m* q
- */
3 F5 \! T6 i: H1 p P4 x - void USART_ConfigGPIO(char TXD_Port, uint8_t TXD_Pin, char RXD_Port, uint8_t RXD_Pin)
* F& M! A1 I' d- H - {; g& |2 p5 ^* z% m- ~- b
- uint16_t txdPin;& z" a h1 t3 F# V% }) {$ o
- uint16_t rxdPin;
" {( [4 c' y( p, M+ \ - GPIO_TypeDef *txdPort;
8 o m$ \; h9 u+ v; _0 x& C. N0 z: b - GPIO_TypeDef *rxdPort;3 u) n1 N' D. ~' q" ^
" D5 {! }+ I3 N# {5 J- GPIO_InitTypeDef GPIO_InitStructure;
1 W/ W: n7 U$ R7 h- R+ h/ u
) N) z' f: x {+ T" E: ^8 y- switch (TXD_Port)$ \% |/ W/ b) ^) c! Z* z
- {, B5 `9 |% u6 s5 s( K
- case 'A':! F. O6 A; @5 ^8 _1 r- V p
- txdPort = GPIOA;
1 F- E/ d: h" K" R3 H - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);1 }/ g* z2 T" F3 ~4 y p& k
- break;
$ ?% V) L) B" K; J - case 'B':4 M( y7 ]& m H+ J- x' e* @
- txdPort = GPIOB;0 m& a( Z6 O/ W V* O2 `
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);& b" o2 X% r8 X+ x$ q0 U. r
- break;
4 Z% f4 C: q2 e3 Z# q - case 'C':/ E) a8 k0 Y" I, z$ P1 E/ H6 F
- txdPort = GPIOC;& c% _: [% T6 `4 D( w! j
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
8 `8 T( q7 E+ y( R0 c - break;# @6 w/ k. D' g) p4 n. W
- case 'D':: k: u0 V. C8 _8 ^; ]
- txdPort = GPIOD;+ N& b2 W7 V# G
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);, }2 a0 ]& h _( C" }9 e5 [/ d
- break;
9 K. P* X! t2 q: U' U& t- [5 i - case 'E':
: t ]6 U% O c6 Q8 ^# X4 J/ u9 W0 e - txdPort = GPIOE;& N! }$ ^: T0 g" y
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);, n) z/ V4 \+ h, X; A- K$ y
- break;4 Y9 `7 A! C8 M$ G. V/ @8 R. L/ g
- case 'F':% R2 D# ]$ B& ]1 a) x6 d x
- txdPort = GPIOF;8 f. R* { }3 ?+ Z! r' V
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);+ o8 _$ @/ q) u; \; a4 s* j
- break;
: ^& G6 j, c+ [/ M7 _' o" d - case 'G':
- d9 y, r% H, ^. ? \ - txdPort = GPIOG;
4 e, P0 j. `* D5 _; i& ^8 ` - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);9 f+ q- w+ k/ r0 ~& `6 f7 W
- break;9 }, E& _5 }; [! V0 H4 |, a6 m5 l# }
- default:6 c1 @! e7 z' o( j1 w( Z4 a$ h
- break;
" e9 q. q; G6 H p' B4 t9 D: P - }: S8 V# { f) `3 K& G& h( ] O1 G3 D
- 6 m- `, N# F9 B
- txdPin = (uint16_t) (0x0001 << TXD_Pin);
, T$ F8 n5 g, L% t' m
2 E% v0 i4 ?0 @ }( I- switch (RXD_Port)
! |! @. k I0 d: E - {
6 z# z) o$ K A) s3 e& {6 Q - case 'A':" U2 [( ~) u$ M5 W+ h( o% z6 M4 A
- rxdPort = GPIOA;' W& D( \' D3 a+ m. d+ {. O8 u$ ?
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);) G8 I3 I; @) z( ]5 v
- break;) g+ s3 C; t( Q2 l
- case 'B':/ `. A$ f6 a: _. ~2 P* w4 D; h
- rxdPort = GPIOB;
, s6 Y1 R% }, E% T$ @* Y3 S8 {0 k - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);1 M! i2 V% \3 J
- break;& H) g8 }) t2 i* S( q( E3 x
- case 'C':: O# ?( K8 D; O
- rxdPort = GPIOC;
/ x" N5 T, ]$ f- v - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);% Z7 \& D; ?- ^& F
- break; C6 K3 C* r0 Y
- case 'D':9 I+ y% A' _; x+ G
- rxdPort = GPIOD;: U9 s$ n: m, [+ j# L0 S
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);: a, g9 _7 y# b/ a+ R: B5 |
- break;6 j! g( a7 Q# `9 U
- case 'E':% L( _, g$ J# {, o$ r3 n/ p( D- `
- rxdPort = GPIOE;/ B5 M9 f" G' ~. l0 r( A4 G$ R2 P8 `
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
) z; }" l- G) ?& @# J9 ` - break;
+ s7 [1 y& e; }" j7 t# L" A; }' @0 z - case 'F':* t A9 ]+ X( w7 O! [. Z9 u
- rxdPort = GPIOF;
5 [& q+ ?8 i1 m v - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);
# g# V4 ]9 z( W" a" P* u - break;$ C# D4 F+ r( w9 ?7 b0 k' t7 B
- case 'G':/ k4 n9 R1 G' L. h m5 G) e' Q
- rxdPort = GPIOG;' {( Q9 p) y3 {! D
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);
1 w i8 f: R, x$ F7 T9 P - break;
4 o, W+ }" D) _9 }, W5 g9 d - default:, y0 Y3 Z" @4 O
- break;
: g6 V: f8 v0 h6 i6 ? - }
" o1 |/ J( x" L+ A# ? - & M: G+ t4 C/ d+ a* Z/ h
- rxdPin = (uint16_t) (0x0001 << RXD_Pin);# C* t; i+ ?; Q
- ; n6 _5 I# I# Y6 e" W4 I2 I. ^5 Y
- GPIO_InitStructure.GPIO_Pin = txdPin;
9 Q- [( {9 c9 ?9 G6 c - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
# n( \7 M/ H3 u4 S; @* H. u - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
! Y) O- ?0 I# ` - GPIO_Init(txdPort, &GPIO_InitStructure);' _2 S, g8 `1 ^1 }; ]
# ?: @+ m7 q7 v# r. L7 s- GPIO_InitStructure.GPIO_Pin = rxdPin;
1 D+ q6 P( Q0 \+ s/ x2 Z+ x - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
: T( @) Q9 o% I& }9 @! K - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
, _" p9 R0 m- F+ x$ _# } - GPIO_Init(rxdPort, &GPIO_InitStructure);
6 f0 U5 x4 o) k& ~% w @. L - }
# |6 `7 b! ^9 t
) U1 H7 m% e* V0 b D' q- 1 E+ M, Y8 o! H0 D
- /**
( x+ A4 [9 K& w9 b9 A! c) P4 S - * @brief 配置串口的中断向量控制器
/ r- x7 D$ G& T6 w& _# k - * 注意,此函数中未设置中断向量控制器的优先级分组。
7 J. p$ Y) R+ G6 i# V - * 中断向量控制器的优先级分组应当先在程序其他地方被设置后,再调用此函数。
' F, ~- z' o$ |3 u+ ~$ B; P - * 在运行FreeRTOS的系统中,一般情况下采用分组4,即四位都被配置为设置抢占优先级。
" v E. x8 v* q+ U w - * @param portNum: 串口序号1~5
4 f% `+ U9 S. S g* r1 V+ H, A - * @param preePriority: 主优先级(抢占优先级)# u% _7 d5 ^$ p7 O) p8 G5 l
- * @param subPriority: 从优先级5 _& K5 ]. m- ~, j" t
- */2 U0 F: m6 x3 L2 P4 P' g9 W+ ~
- void USART_ConfigNVIC(uint8_t portNum, uint8_t preePriority, uint8_t subPriority)
$ `, P& j9 p8 c - {) r3 B& ]# e( r5 E2 u
- NVIC_InitTypeDef NVIC_InitStructure;
; d t8 p) q+ O5 S0 M r5 o - ) ]7 K5 ]; o- w) G. e0 l1 n
- switch(portNum)
8 }. p( T/ o! ^- _, S( ~) s: r - {7 p! R4 ? ?% t" q
- case 1:
+ `* u' R4 E% p4 m6 u& U: I - NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
7 D1 S6 ^, h& | - break;/ p7 l9 P6 F7 n ^& J5 x, g
- case 2:2 D4 Y3 l7 t* {- A- o
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
! h( O- D. r9 O ]2 H1 ~ - break;7 x: D( L5 @+ ^8 O# {- C
- case 3:
. A5 k" y, L I- m* z& {7 k - NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
! x) b/ p0 t& X2 p* H6 f3 k1 H - break;% {4 j6 Z. N# k+ U; ~ t
- #if defined(STM32F10X_HD) || defined(STM32F10X_HD_VL) || defined(STM32F10X_XL) || defined(STM32F10X_CL)
3 c1 U- K6 i8 D" ^ - case 4:
3 [6 ?7 ]- J8 K8 F; R8 A - NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
1 G+ J" w6 e" @2 [ - break;1 ]# Y! ]& K+ S, t( \* U7 c" G- Q' w% h
- case 5: h: E% k: n( H; _4 B) Z4 W
- NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;5 X' O0 _9 ~6 u0 H5 V" t: u
- break;
* U n! E: n4 | N - #endif- w$ {! [0 H ^; D/ L! ], [& B7 m3 L
- default:
' X9 L* [. e# _0 s# L. ~ - break;( P) d( U% o% ^) P; w) I+ M$ o" E( Q
- }
/ M1 V# b# v3 n, f) G - * V) X* j! A& N: [! Z' f
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = preePriority;
( Y9 B ?2 r$ c" j0 T6 j - NVIC_InitStructure.NVIC_IRQChannelSubPriority = subPriority;7 Z3 K% V1 b6 b9 D+ E) U
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
: n) n8 S+ |+ z5 z - NVIC_Init(&NVIC_InitStructure);
: I* A! _2 O3 h* i - }4 r; v; }6 _2 i. u
: |8 P( A7 x. M! V$ X7 t# S8 b
+ w- E- t( o& H) B/ X! H- /**
/ C! x* w" a/ X4 M - * @brief 配置串口外设, D& X0 T# Y7 D/ E9 V
- * 注意,函数参数列表中没有列出的配置参数采用默认的配置:% z1 C: i- P* O, d4 d9 s
- * 1. 无硬件流控 2. 双向收发 3. 使能接收中断 4. 开启串口. a8 W- e) Q( X
- * 如果需要修改默认的配置参数,则不能直接调用此函数完成串口外设的配置。
4 Q- T1 _$ h9 e( f' X7 p. s - * @param portNum: 串口序号1~54 N& e0 r& d$ ~+ s5 @8 D c1 ?& S3 s
- * @param baudRate: 波特率
* s" n' @5 l& W/ l3 Z! w' L - *
; ?" j+ R: l- z: K. O! k o - * @param wordLength: 数据位长度(枚举变量)
$ b/ |9 D$ u7 D' @& x% `# g - * @arg WordLength_8b: 数据位82 ^3 F! O" m* U3 k# z, I- X8 F
- * @arg WordLength_9b: 数据位9
: U" s3 z5 l9 l( [( W4 p% i' ?; J - *
# ?$ ~ ]0 T) q) ^5 g! ?9 `- l6 ` - * @param stopBits: 停止位(枚举变量)) k1 `, t1 t5 N
- * @arg StopBits_1: 停止位1' x% L8 l( }, F7 f6 }$ K7 |. }
- * @arg StopBits_0_5: 停止位0.5
0 z9 a& }# E1 m& [# ^- {3 y+ x9 F - * @arg StopBits_2: 停止位2. \/ X* \* b0 w6 P! I6 @
- * @arg StopBits_1_5: 停止位1.5) ~/ ?" W6 o7 i, a* J2 b
- *
. H, Q# M V7 U: n) {, m( f - * @param parity: 校验类型(枚举变量)
6 A7 @+ ~1 _) `; [/ ~. | - * @arg Parity_No: 无校验
4 Y5 x% m5 p5 @ - * @arg Parity_Even: 偶校验
. x" {) `5 l0 P8 t. Y5 C - * @arg Parity_Odd: 奇校验% N. p( j* z; q
- */& T% ?: C, q8 p5 R+ f7 o
- void USART_ConfigPort(uint8_t portNum, uint32_t baudRate, USART_WordLength_Enum wordLength, USART_StopBits_Enum stopBits, USART_Parity_Enum parity)4 r9 ]& F6 N6 Z, u/ A% G
- {
3 T8 U* P+ c7 m& T0 D8 P - USART_InitTypeDef USART_InitStructure;
+ Q" q1 L) C. d# | - USART_TypeDef* USARTx;3 b" R7 i4 U' |1 w
- ( s) D( V/ H! O& f. M" Y+ }6 p
- //开启外设时钟2 u' M* C( t5 s, J3 O9 u& |
- switch (portNum)
. F( \* L: n6 C1 t* ? - {
5 N/ f; C) {- S( Q: Z" k - case 1:
& u/ G3 B- w8 g y& y3 v - USARTx = USART1;# Q Z t% H( P
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
9 U) x, f7 _ s7 b C0 p - break;$ H' Y5 u `2 |- r
- case 2:# a8 k& n0 F! I
- USARTx = USART2;
5 p7 _- C, M! H3 m9 P - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
, Z5 g, M, @1 Y8 g& D: _! X& Q: I* q - break;
. Y. [- D$ r1 |# V& L - case 3:& ]) p4 W# D9 g- {3 R$ ?: m
- USARTx = USART3;
1 Q- @& i' c' [# O4 w) k - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);5 Y0 w V. `& {9 d; q
- break;
[( I8 K; q& c - case 4:3 x- r5 t% ~' _" O. W
- USARTx = UART4;' d" }* |8 z/ ~
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);* t( g5 h, {7 d
- break;8 w- V; {* G. l, @* u# T4 n
- case 5:
# T# F$ z" y& G - USARTx = UART5;
! z8 H1 V4 t/ M2 E, x - RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);9 Y8 N- i0 I0 u6 N, Q# W& e
- break;; ]2 L7 e' E, v3 [1 q% t* W" R) S
( q3 ^0 s" E: H3 \& V: k0 S' v8 c+ |, O- default:
, S* j- C. W6 G7 c; a4 |8 q - return;
7 i+ P( N# D2 o5 B) X - }- _- k1 r! F: H3 _" N2 ?- r
; E/ u4 b0 B. c; c# o- //设置波特率
6 Y! L2 v/ B; k+ C- W1 N7 { - USART_InitStructure.USART_BaudRate = baudRate;
. J; I) ^" ]% ]8 D' S - " g% [4 ~. |; J! T! K! O) h
- //设置数据位长度(一般情况下无校验时,为8位数据;有奇偶校验时,为9位数据)* t7 @ e& x# K J8 c
- USART_InitStructure.USART_WordLength = wordLength;
0 C8 C' V$ z/ X - 8 x& _+ D+ f' ]; F7 i0 I& f) E
- //设置停止位
1 j. W/ L1 S2 B9 V9 t/ G( C - USART_InitStructure.USART_StopBits = stopBits;$ X# j# U0 B0 }7 E+ H) |2 W1 }
- % L# z" [/ c `" M3 j% n: z" G
- //设置校验位
5 L0 d4 A$ V" b# Q" R - if (parity == USART_Parity_No)! }% t, D; N! t- }/ ]; Q! Y
- {9 u9 ]+ J" S" l: G. e9 O7 r
- USART_InitStructure.USART_Parity = USART_Parity_No;- Q; _9 ^" U3 c2 d
- // USART_InitStructure.USART_WordLength = USART_WordLength_8b;' Z% p+ f5 B Q y$ {
- }( e0 Z5 x6 u O0 }! X/ f
- else if (parity == USART_Parity_Even)1 O/ g o% N, r$ @$ w
- {4 B' W4 E3 M* w
- USART_InitStructure.USART_Parity = USART_Parity_Even;
5 H- J1 M; V' i( A ^) g# ` - // USART_InitStructure.USART_WordLength = USART_WordLength_9b;0 u9 M' ?2 r2 g5 l8 \7 z+ d
- }
4 g* p3 ~0 U& l# ]5 q* S - else if (parity == USART_Parity_Odd)
& G/ N& |; ?$ k# ~/ ~0 t( [# v: L - {7 u8 c& e& A( d+ C2 p
- USART_InitStructure.USART_Parity = USART_Parity_Odd;$ u" G1 Y3 B* w# O6 E
- // USART_InitStructure.USART_WordLength = USART_WordLength_9b;
# P$ h- c$ @/ C+ z* M1 A - }
0 d+ v1 x* W: m# ~3 M - else
8 ? _ p. i" y- e - { [+ }- f2 s# t1 Z6 M
- return;
% q$ w' N* G* \ - }
* L! E U9 W9 b2 a# ?5 W# l0 k
. E/ m5 s3 b& W) P- //设置硬件流控
; l9 f Z q8 O. E3 f) M - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
5 k- d4 P9 L: i. i" k. W$ A
G4 a& S* k( p' s, r) N7 @0 H- //设置收发模式
4 W! a0 ]6 ^( a9 B, e1 B - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;. F, f6 l% \4 ^% f/ K( }/ {
- . `* T9 R7 K2 B+ m
- USART_Init(USARTx, &USART_InitStructure);8 |- j% O6 \0 O/ S- p
( J3 E, `2 G. ^. H0 H7 H3 N- //设置中断模式% u" ?/ o ~3 M7 D% K
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
7 u$ a7 ]# ^5 V6 L - ! v9 E& a c" N L/ S
- //使能外设
& `7 g$ \: d( r+ V1 ]- u - USART_Cmd(USARTx, ENABLE);
% x. u2 I! N7 h; Z! U7 l$ v - }
' k1 V7 H6 A/ V @ - . _. o- |) g- c- r" [
; M! \" k& s: z# j( A- /**
5 n1 `( u: i& @( H, m% R0 b0 L9 W5 A - * @brief 初始化全部串口缓冲区及其管理变量
/ e+ t" B( I( P8 D: \ - */
" J/ T- {$ |' x- S1 P9 A - void USART_RevInitAll(void)
' L/ I% {* e8 G7 E! B. B, G - {1 f. G. ~. A1 S7 v3 }( |
- uint8_t i;
. W: d# W8 Q5 P: L/ i/ e# | - ///: n' z% i$ T B* d& @/ `& L3 b9 x5 Q
- USART_RevBuffer[0] = USART1_RevBuffer;
4 V$ `# C0 z0 Z5 J9 w - USART_RevBuffer[1] = USART2_RevBuffer;
/ ], N' }+ W. R1 ^8 C1 a7 A- n - USART_RevBuffer[2] = USART3_RevBuffer;
5 J d8 P6 G/ k% W9 f% G* l
9 D: B; w( x. [9 L B$ e6 T- USART_RevBuffer[3] = USART4_RevBuffer;
* ?) p" o1 s$ V+ m - USART_RevBuffer[4] = USART5_RevBuffer;
) D0 e- R7 t8 @0 J& t - ///
& Z) C, d8 Y# o c - for (i = 0; i < USART_Count; ++i)
, I/ Y7 i( k( ~- e( X - {
9 `' @, A$ _8 q* } z - USART_RevCount<i> = 0;( f5 z$ P0 t! W j( x
- USART_RevPointer<i>[0] = USART_RevBuffer<i>;$ R. b% t F. y+ c
- USART_RevPointer<i>[1] = USART_RevBuffer<i>;& J: \4 |) e* u" m
- }
. j( n) p9 m, |7 n) @4 Y - # N1 R' a! Y" e, z
- for (i = 0; i < USART_BufferSize[0]; ++i): W; J2 ~# L: Z8 O) ]/ z
- {
8 v3 x6 U# c8 e0 b0 F+ C - USART1_RevBuffer<i> = 0;
; z& I" t" a! Y& j8 g- F" j- w5 L - }" Y! T, H; K- E# J+ s
- 2 g h/ y/ `. P4 O. P, V
- for (i = 0; i < USART_BufferSize[1]; ++i)* A& i9 B$ `2 D# c/ v) }" M* {
- {( [) B- g0 ~$ Y/ h/ h* t
- USART2_RevBuffer<i> = 0;4 W$ A" Z$ Y- M. g! G" i6 F
- }/ S' q9 `* M! ?2 K) g5 z2 `+ f( h: P
- ; {0 c! U$ K+ a7 f- g6 P4 S, N6 T
- for (i = 0; i < USART_BufferSize[2]; ++i)
- C% K- s- f% ] - {
, G5 |" L# e* ?0 i2 I( H - USART3_RevBuffer<i> = 0;
4 W0 p/ e# Z1 S' u6 O" T2 Q$ r( Y- @ - }( ?' Z$ z9 T, i4 g" I$ e, F
- }
5 k, y+ D! V6 u% P4 `* v - . }; q2 h. P! H9 A+ U' O
* u ~% E$ O- H) l7 e: x9 E- /**" S+ M# M E4 U& E7 y
- * @brief 初始化指定串口缓冲区及其管理变量
& H! `) s9 [% X( K- Y; @5 z: f6 u - * @param USARTx: 需要初始化的串口
/ s9 X6 [1 w2 w9 i& p6 ? - */1 T p* j. \1 h4 K
- void USART_RevInit(USART_TypeDef* USARTx)
6 O4 {, {4 x: W - { c# |' K5 c! F
- uint8_t i;
: j/ v7 i$ t/ b/ L: w& Q* C
6 L1 S9 c+ S1 C( K# W9 ]4 ^- if (USARTx == USART1)
, H) k7 a w2 ?. o. e, j% V - {5 V6 P) a3 a1 {) z6 g8 F3 U! C: M
- USART_RevBuffer[0] = USART1_RevBuffer;
4 \7 n0 r3 G, F- d, c q - USART_RevCount[0] = 0;
9 w# [1 e( t V - USART_RevPointer[0][0] = USART_RevBuffer[0];+ x# ~5 O7 A7 b L( X1 x% C$ X
- USART_RevPointer[0][1] = USART_RevBuffer[0];
# H- J0 X% i! x: V% I, o3 _5 m
6 }* B, a' a( ?$ B- for (i = 0; i < USART_BufferSize[0]; ++i)
1 {8 M5 q: X+ n - USART1_RevBuffer<i> = 0;
* X( L( c0 b! d/ r - }& S. w6 g. O7 h, R, i/ G r# l
- else if (USARTx == USART2)1 l# i2 }9 E3 R. S# B
- {
/ W. T# t0 H# D3 D& d - USART_RevBuffer[1] = USART2_RevBuffer;, {6 T" l D9 S% e) @
- USART_RevCount[1] = 0;( b/ n8 r$ `1 ]; D( }4 K/ ?
- USART_RevPointer[1][0] = USART_RevBuffer[1];4 V2 l- p d3 Z4 U4 `. a$ d, `
- USART_RevPointer[1][1] = USART_RevBuffer[1];
+ I" I3 ~! K/ k8 w( L - ! {$ |4 R# O, } t" i
- for (i = 0; i < USART_BufferSize[1]; ++i)
0 p. Z) g5 G9 A7 b+ P- p - USART2_RevBuffer<i> = 0;
- F5 R0 I. w% Q& w2 ^$ G$ P - }% k5 j5 z, g5 U7 O) }2 }
- else if (USARTx == USART3)# X, V( O/ k2 p/ q- V, A0 i1 g
- {
5 D" ` q) M. Y7 C2 j E - USART_RevBuffer[2] = USART3_RevBuffer;
7 U% {! l. g5 e4 R$ |3 F - USART_RevCount[2] = 0;3 X( g6 t5 e+ E, F
- USART_RevPointer[2][0] = USART_RevBuffer[2];
2 ~& a P! Z6 @; @5 o - USART_RevPointer[2][1] = USART_RevBuffer[2];- O' }5 g5 Z$ d, r
7 g* \! Y$ x6 S& B$ ^* d- for (i = 0; i < USART_BufferSize[2]; ++i). _* j( M/ v. s+ k
- USART3_RevBuffer<i> = 0;, T' V2 u. n E% u
- }
* D- N) U. e' h/ V: m; |. E - else if (USARTx == UART4)
4 f% k' v! G; B. i+ R - {' n7 q* [2 O5 C: F) ]* {
- USART_RevBuffer[3] = USART4_RevBuffer;
9 m; K4 E1 @2 \. t - USART_RevCount[3] = 0;
: Q4 E4 e1 g0 I - USART_RevPointer[3][0] = USART_RevBuffer[3];1 S# K6 h+ G8 K( j
- USART_RevPointer[3][1] = USART_RevBuffer[3];
?$ _# L2 k) L# y+ q( U1 e3 \
$ Q3 s/ N( n4 f& N* ]" Q) Y0 Q. ~- for (i = 0; i < USART_BufferSize[3]; ++i), P! `- Y$ m& q$ P
- USART4_RevBuffer<i> = 0;
' I1 C+ b! V* {8 B* ~ - }
0 U& d/ |; g- r& c - else if (USARTx == UART5)3 m4 A) x# z* o' ?
- {3 C% G; k9 r2 D1 W: m! {
- USART_RevBuffer[4] = USART5_RevBuffer;3 s6 | E' {) H4 J# A2 v$ B5 r1 x2 J
- USART_RevCount[4] = 0;0 ~' |* r' o8 [2 S1 v4 }
- USART_RevPointer[4][0] = USART_RevBuffer[4]; q* V7 ]! r, Z
- USART_RevPointer[4][1] = USART_RevBuffer[4];
3 d8 h/ A, b) e! {% x4 T% L# L q
! s( j |' ~ H( v# n- for (i = 0; i < USART_BufferSize[4]; ++i)
% |# \& ~- o. z2 T+ t8 v! E' g - USART5_RevBuffer<i> = 0;
, A) N6 X9 a! n3 p' i; ~ - }
% L+ E+ d) L+ O - else' F* X; q N- u8 U
- {# W& u1 P- k; c9 G' C
- ;
+ d3 K+ N4 c: d; o+ c- p - }/ H# Z, l2 d4 U# `1 H" p
- }
1 g+ y4 g4 D; A1 O' b# b - 4 T+ U/ B5 ^; }7 D) `
- 2 U, q$ H! Y! K- j( q, s$ p6 N' f- j
- /*** B3 B( m. @3 d% r. ~9 X1 ^
- * @brief 通过指定串口发送字节数据; @: ]* G( p: k/ ]
- * 通过查询的方式确认发送结果,如果发送失败,此函数会阻塞- r' {6 V7 n9 D; G; v+ @9 T
- * @param USARTx: 发送数据的串口 F s( p) ]: N7 \: }
- * @param byteData: 发送的字节数据1 |$ e. @7 Y! t/ @9 O# N4 m% h
- */& q9 _3 R( ~- f3 \" ^
- void USART_SendByteData(USART_TypeDef* USARTx, const uint8_t byteData)0 R+ c& s" q9 H. X
- {4 F6 l* K5 t1 S! G
- USART_SendByte(USARTx, (uint16_t) byteData);
) ]8 M. X a0 s - while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
1 w% o& E% }7 t0 k - ;1 i: z* o' P6 z+ H+ \4 r
- } R: b. a. v' A" d
2 P _+ {1 e( Q& K- 1 J8 A$ @( @9 y4 S
- /**
* S$ B6 W/ m& ~2 U' A9 h - * @brief 通过指定的串口发送连续16位数据5 j2 e2 }# [ Z' T
- * 单个16位数据的传输通过发送两次8位数据,高位先发送,低位后发送- Z5 E" [5 d2 L4 j% U3 u8 r
- * 通过查询的方式确认发送结果,如果发送失败,此函数会阻塞 n; H6 ?$ n: ?2 U! f2 A' J
- * @param USARTx: 发送数据的串口" r& w, s9 L: M! }& V2 G* N# ~
- * @param Data: 发送16位数据的起始地址
" Y; N+ f1 }/ p8 p! [1 c+ B" f! q - * @param Count: 发送数据的数量
: p% k/ f R( X* m: q& ^3 w - */- ^" F- p; t0 d
- void USART_SendData_Bit16(USART_TypeDef* USARTx, const uint16_t *Data, uint16_t Count)
" ]3 A# d4 `( ` - {2 G: _; D' s( l
- for (uint16_t i = 0; i < Count; i++)
( h6 M5 M6 H% @7 o" t6 x' k. E - {
* P( A. E& N. P J7 L* n0 l - USART_SendByte(USARTx, (*Data) >> 8);
0 V) q# ]8 J* I9 T - while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)7 p4 i: Y0 t6 `9 ?$ A( X/ G0 w
- ;' p! a/ [: G7 F# X
- USART_SendByte(USARTx, *Data);
: Q+ L$ I3 L+ ]3 t6 o - while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)% H' A: i8 H G, `; `! n7 M
- ;
( C- w; @5 c; Y9 W - Data++;
* [# f' |6 A Y9 h - }; e" R' M: b+ g; F
- }0 h6 G }# l8 g0 f6 H9 L% P
- 3 i& C& Z. r, l5 t: N! K) O. Z
- " ~& i6 i8 N6 M1 x) e, d
- /**
0 d/ c7 O/ ?! N3 E - * @brief 通过指定的串口发送连续8位数据+ c+ x, s# _9 x6 X' H( X& E
- * 通过查询的方式确认发送结果,如果发送失败,此函数会阻塞( x3 t; T4 |% f) a
- * @param USARTx: 发送数据的串口- _ E/ M. R2 R& E
- * @param Data: 发送8位数据的起始地址
0 ^- |3 n4 K' d1 q" k - * @param Count: 发送数据的数量
3 Q$ F& l$ s5 l5 O, y- R2 P( U - */2 X1 X& k! S6 |3 h' v
- void USART_SendData(USART_TypeDef* USARTx, const uint8_t *Data, uint16_t Count)( v( w+ ]; h% O' f- u7 | C
- {
9 u$ l' y5 \$ W8 W! T* N - uint16_t i;
2 P' B3 c X/ L5 J$ I
& x% g+ s( ]0 |; {! Q: k- for (i = 0; i < Count; i++)
$ G5 D5 T* `4 Y; W4 W7 x2 M - {
# D& r r/ C4 Y - USART_SendByte(USARTx, (uint16_t) *Data);
0 ]/ S* s$ V( i* L7 x2 [ - Data++;
6 m* y3 d, O' }. X
: `, z* w" h6 l) r# p$ i- while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)% Y# z% g' Z3 T( V# y3 K
- ;1 ]$ V9 k! d5 H$ G! R7 w
- }2 ]7 Q9 r( C/ m
- }
7 |# i% W7 ~; Y& S5 t, L% o
" X0 r: v8 P8 i/ v' K0 y
& W: e6 I4 j) l& k h- /**, v8 e% J5 O; p1 |
- * @brief 通过指定的串口发送字符串
6 f" l$ o1 u4 b - * 通过查询的方式确认发送结果,如果发送失败,此函数会阻塞
: R, x9 ^& k+ J( |# y - * @param USARTx: 发送数据的串口
n3 k2 R0 m" }) d: n1 S( r - * @param String: 需要发送的字符串(检测到'\0', 自动停止发送)' N8 `; @# A c
- * @return 发送的字节数) C# L/ q8 C# t0 M/ }: e4 M: R
- */
9 H$ S1 i3 M. u - uint16_t USART_SendString(USART_TypeDef* USARTx, const char *String)
; M8 }( d2 R6 M$ S7 |8 f) [ - {% @& J8 r$ y: e/ o! f4 Z
- uint16_t count = 0;
1 s4 s9 b) o8 ^9 X% p4 f - while (*String != '\0')
, n. o8 m- t7 F/ w+ B- U5 O# [ - {2 w9 F3 B" P) |; s
- USART_SendByte(USARTx, *String); j. A9 \* b+ l4 R& K0 x1 W
- String++;* E9 X$ W* _6 M6 ]: f7 ~: d
- count++;
: g1 M9 n- h! j) i - while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
1 X/ v& v" X3 b6 p. q. z - ;. D. D2 ]$ N) u7 w3 F8 S" I# r9 x
- }! v6 b! a/ e* C# J2 K
- return count;
; X: a) ^/ x4 K. L - }$ e% O. B0 }% _" h
. p: {3 F5 |# M+ h2 ], R9 {* T( D- 6 ?/ W# P3 x3 z* J5 R
- /**
1 ]) N/ \! T2 p5 m8 w s" W - * @brief 串口1数据接收处理函数
9 V! h$ v3 f0 H, G6 o: x) L - * 在系统空闲时轮询或者在需要的时候调用此函数即可处理串口缓冲区中已经接收到的数据 D+ C# I8 E* r8 @- ~- z
- * @param USART1_RevBuffer_HdlPoint: 需要注册的数据处理回调函数
6 m! q+ ^& m% [! c$ N - */5 s. E4 j4 ^7 @
- void USART1_RevBuffer_Handler(void (*USART1_RevBuffer_HdlPoint)(uint8_t* _Data, uint16_t Count))
* Y+ a6 ~5 t/ S$ `1 n: A3 q* E - {
+ q5 A9 b6 _% i* y. r: Y! m' T3 j - uint16_t count = 0;
7 W1 ?! u/ y, E% g$ b2 I - uint8_t _data[USART1_BufferSize] =
9 ?" W# N0 j) c$ K1 Z - { 0 };2 d# [, S+ A6 n, j. i
1 C/ p. \$ s& b' K: d) S- while (1)
5 s5 e g. H# o% ~, Q - {) ?) G" l( _9 j# P- K. p
- if (USART_RevPointer[0][1] == USART_RevPointer[0][0])- q' |$ f6 p1 R6 W; q6 Q2 o
- break;1 @, W# ^3 |8 m8 C {* V
- ) \; D( n2 S [6 X! X5 e4 N
- _data[count] = *USART_RevPointer[0][1];/ l6 l+ q& X# ~5 O
- count++;" K* x. f" O; y% b+ c
- USART_RevPointer[0][1]++;
, f( J; ?; K. p; T( I# G3 a - + C* z9 Y# _( {' h' Q
- if (USART_RevPointer[0][1] >= USART_RevBuffer[0] + USART_BufferSize[0])0 [9 m9 `6 Q2 z3 Y. w3 ~8 ^
- USART_RevPointer[0][1] = USART_RevBuffer[0];$ M* P0 F$ N [* o, M* h8 w' [0 ~7 Q
- }) O6 g+ p, q% _' @
- 0 E1 v, a6 q% i; ?, o
- USART1_RevBuffer_HdlPoint(_data, count);2 u* w; X' z$ Z
- }
7 C6 X) h5 n4 z0 A# n( i
* s9 E# d2 M' p# |: F* d
' _: K" ^9 `9 w/ k' y! m1 x5 o3 V$ ^- /**
5 Q% C" Q* u8 c4 ?9 `9 x - * @brief 串口2数据接收处理函数* L. X$ v e$ q
- * 在系统空闲时轮询或者在需要的时候调用此函数即可处理串口缓冲区中已经接收到的数据 m8 i. X3 d5 P& M
- * @param USART2_RevBuffer_HdlPoint: 需要注册的数据处理回调函数 T1 g* m3 t1 d7 ~$ E8 R
- */
( w9 p' h9 c( {5 L - void USART2_RevBuffer_Handler(void (*USART2_RevBuffer_HdlPoint)(uint8_t* Data, uint16_t Count))" v5 H2 _) V1 y* t$ K
- {6 b4 E9 t' L% t3 h- h0 V
- uint16_t count = 0;+ m c2 C" J3 Z
- uint8_t _data[USART2_BufferSize] =, L. f+ e7 F. S. O4 P( {; V
- { 0 };2 }) O9 U4 _) D. B+ \7 m
- : F- C# N4 C+ R) f: d1 A! t1 ^$ E
- while (1)
4 e% q1 G. `- X - {5 M4 H, R$ g |+ U! o. H
- if (USART_RevPointer[1][1] == USART_RevPointer[1][0])
# D7 P. d2 L7 L" F8 o5 {) u - break;# _* E/ I! U' O
- z* V. ]% L& G8 A+ K, U
- _data[count] = *USART_RevPointer[1][1];
& h& }- N, _4 j* c+ Q! R - count++;
8 V; \% e$ A* S* }. W2 P. { - USART_RevPointer[1][1]++;
' O; c! p% I4 ?' M B) e% v4 @ - ( s( S) _3 v5 R; ^8 f
- if (USART_RevPointer[1][1] >= USART_RevBuffer[1] + USART_BufferSize[1])1 I% v$ [: i, u% q6 y+ ?: q; d! a
- USART_RevPointer[1][1] = USART_RevBuffer[1];$ d3 i; @2 d" U3 L/ s
- }
" V% |- y* a! e$ y# i+ F, O# P
- O3 C. a* @% d I* z. @; X- \& I; g- USART2_RevBuffer_HdlPoint(_data, count);- L3 O# {0 J3 Q7 t) \3 T! j9 F
% d x* w# j+ q) v( \, z- }
: `2 |/ R) U# K0 f6 `! \
) s3 H u; d. \7 \* Y. P! m8 N) Z- 3 G6 h5 Y( C* h- k: N" o, {' c
- /**8 A" x0 d% X# o
- * @brief 串口3数据接收处理函数
7 o, R6 z: f. f2 a# Z" z/ A! V - * 在系统空闲时轮询或者在需要的时候调用此函数即可处理串口缓冲区中已经接收到的数据
2 |8 f0 G) @+ T+ J6 N; Z - * @param USART3_RevBuffer_HdlPoint: 需要注册的数据处理回调函数
$ q5 i1 B9 U/ c+ P4 `0 A9 r - */7 X: |+ m3 w4 p9 Y% t8 ?* ?
- void USART3_RevBuffer_Handler(void (*USART3_RevBuffer_HdlPoint)(uint8_t* Data, uint16_t Count))- ~7 ^4 j3 k- f4 K$ B+ N& n: n
- {
7 J& E- N+ b- y+ U$ t" }/ V - uint16_t count = 0;
- A: p$ X9 u3 X1 K - uint8_t _data[USART3_BufferSize] =
7 c: [3 D! v1 d9 f$ p# b - { 0 };/ x, P" h3 g2 `; n1 S) B/ M& R
) U* t7 O9 x1 k$ H- while (1)
$ X2 ~8 P R- a, X! ]1 U/ d( C - {
3 Z1 i* }" B0 G, f; T0 n - if (USART_RevPointer[2][1] == USART_RevPointer[2][0])
5 Y1 s, p3 |4 a0 ^ - break;
7 [! R# @, G, g - 4 B3 a/ K8 K; y5 W3 e
- _data[count] = *USART_RevPointer[2][1];
* }- O2 o0 a! G8 c* _7 @ - count++;. ^0 X- h$ t( Y! |! M1 u) r
- USART_RevPointer[2][1]++;4 F5 W6 \- n) D8 y' D
- ; G4 o& ?$ ]- `" v. @- `, l
- if (USART_RevPointer[2][1] >= USART_RevBuffer[2] + USART_BufferSize[2])
% q5 r' ~0 a @: P* j - USART_RevPointer[2][1] = USART_RevBuffer[2];
7 R$ E6 b0 ]: I' V6 \1 c5 H5 i/ E6 M - }
9 F" H0 F- ~! V3 [0 v) ] - ' S. J* d# g* f! a. V
- USART3_RevBuffer_HdlPoint(_data, count);
{* M2 p/ ~1 D. z - }
7 d; y$ N8 e0 x* @/ L: _ - ) G) l6 B3 g2 w* n4 [
& x% Z: _ ~# z$ X! t+ a- /**
) n7 a4 ]# g* C. ?6 ~) x# f - * @brief 串口4数据接收处理函数6 R+ s @5 z9 w, i8 @- @
- * 在系统空闲时轮询或者在需要的时候调用此函数即可处理串口缓冲区中已经接收到的数据! D/ e+ C! U. c) j C8 r7 {# i
- * @param UART4_RevBuffer_HdlPoint: 需要注册的数据处理回调函数! p# @ `; D. o
- */
' r, l$ c6 {4 ~8 y! w8 Q) J - void UART4_RevBuffer_Handler(void (*UART4_RevBuffer_HdlPoint)(uint8_t* Data, uint16_t Count))
9 P9 {7 d% m8 T W# [/ J - { {2 B: \0 W4 o) ^# T3 K' t
- uint16_t count = 0;8 j0 ^2 b6 c4 P! |8 q
- uint8_t _data[UART4_BufferSize] =# @) T4 t1 g/ w1 ^/ S
- { 0 };
0 l( F* T7 [& [9 ^& V' {: { - " {! }& x6 G: z9 E* o
- while (1)
, g6 C" a0 k2 W e: s* X - {
: t1 k! ]! q. L* R - if (USART_RevPointer[3][1] == USART_RevPointer[3][0])
7 M# p6 ]$ [, F; P/ J/ i& V6 M4 P - break;
+ A% g+ Y- N& w+ R q& D
8 R8 W- H+ G; {2 G- _data[count] = *USART_RevPointer[3][1];
9 L" M5 I3 I$ U* }) o, m9 ` - count++;
1 l+ Y; F5 P+ u5 b - USART_RevPointer[3][1]++;+ O- |6 }$ W/ r! [. w% I
- u) T0 w$ X6 ?
- if (USART_RevPointer[3][1] >= USART_RevBuffer[3] + USART_BufferSize[3])
) S* g7 ]4 y/ P" {4 `4 t K2 V - USART_RevPointer[3][1] = USART_RevBuffer[3];% I7 C% o5 C* W
- }+ n) ^( T" l3 M6 q$ X
3 O4 U* Z/ I( _8 ]6 P- UART4_RevBuffer_HdlPoint(_data, count);! J" R: \+ m8 d) ~, M
5 |2 W$ D: @0 @7 k- ?- }% m1 L% _; d, p/ x( f4 U7 V
6 d0 a4 J" V. F8 Y% z+ Y
* z4 J7 Q5 q- s- /**
$ a" `) M- b8 B" J ] - * @brief 串口5数据接收处理函数
! B7 G: h" w, m - * 在系统空闲时轮询或者在需要的时候调用此函数即可处理串口缓冲区中已经接收到的数据$ g' |$ @5 i9 E
- * @param UART5_RevBuffer_HdlPoint: 需要注册的数据处理回调函数
q; g( m& \2 F - */
: x0 t- P: V6 b3 E - void UART5_RevBuffer_Handler(void (*UART5_RevBuffer_HdlPoint)(uint8_t* Data, uint16_t Count))) \0 b; ]2 V8 A+ I. @) G/ m
- {8 C, z0 L9 N5 z
- uint16_t count = 0;
/ F. i" e! @" n - uint8_t _data[UART5_BufferSize] =
1 R8 {7 u4 t P. U; n - { 0 };
/ M g7 c3 i }
) Y9 ~) z; h& y2 F, K- while (1)
9 C4 E* b# p { - {; t: Q' Y2 y- z
- if (USART_RevPointer[4][1] == USART_RevPointer[4][0])
- L3 H0 h2 J4 ?, B2 L, U2 V - break;5 n9 J- f- n" n& B2 Y6 E
. O. _' m0 g1 g% I- _data[count] = *USART_RevPointer[4][1];0 L0 a2 j( |* b/ E( w5 u" f
- count++;/ c5 h) x/ |) `( b% L+ B+ M4 ^: l
- USART_RevPointer[4][1]++;* ]0 @0 H' ~! N2 w3 f
- 8 }* {) H# x4 h& V0 e
- if (USART_RevPointer[4][1] >= USART_RevBuffer[4] + USART_BufferSize[4])3 ^9 c! X. p$ b& F1 v; I
- USART_RevPointer[4][1] = USART_RevBuffer[4];
3 S# l' _7 I, ]( E: v Z - }& F' a# [0 Y7 n! M
& ]0 O# [( ?+ _- UART5_RevBuffer_HdlPoint(_data, count);
6 n/ x' u" k1 A$ H* x - }
7 Z! L8 ]8 D' L" i! s
; f2 {& Y* g& H$ H# Q; W/ n- 8 |. l7 T: m: G+ ?2 l+ n
- /*************************以下是串口中断服务函数*********************************/1 m" g; G" X: `/ c9 Y
- /****************根据是否启用modbus,会启用不同的服务函数********************/$ d/ o5 ]9 l! S4 Q* n
- #if FREEMODBUS_ENABLE==0
; N& ]6 l) C+ y( @ - void USART1_IRQHandler(void)
, Q" S! {: @# K - {3 ^2 n* v! k: h6 X* Y2 T3 {$ `1 A* g
- /**3 c! ~2 o! s9 X- v: l* q4 I
- * 如果使能串口接收中断,那么ORE为1时也会产生中断。
3 Y5 d: S% h% S& R7 `: N - * 在应用中对ORE标志进行处理,当判断发生ORE中断的时候,
' V6 m2 p" _ d- z, \ - * 我们再读一次USART_DR的值,
: @: Z$ s' Z L5 {) T - * 这样如果没有新的Overrun 溢出事件发生的时候,ORE会被清除,
' t( ~5 V e' x q# G% ~, h - * 然后程序就不会因为ORE未被清除而一直不断的进入串口中断
6 z" z% M8 ]5 s. u8 s Q - */
4 X6 k$ P; j& x$ ~6 _2 l - if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)0 p& v, D4 b; x6 `: h& T
- {- ?4 p( B; T% C
- USART_ReceiveByte(USART1);
7 a, d. H) @- e. {0 g% _ - }' P4 T+ g& E; h/ w- n! J
- / w5 r9 ]1 r' D0 S/ y6 @" |9 R
- if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)6 J5 W( ]1 T- f# ?
- {
, x; h5 x2 {: L! \" I - USART_ClearITPendingBit(USART1, USART_IT_RXNE);8 g' B: J" H9 a6 ^( T+ b0 `$ i
- *USART_RevPointer[0][0] = (u8) USART_ReceiveByte(USART1);
% D; R% r% g$ B8 r% ? ?2 t - USART_RevPointer[0][0]++;
$ C% _6 A1 o2 s- J, v - USART_RevCount[0]++;. f$ F$ }" h! q
- / I1 G) F6 A |$ ^
- if (USART_RevPointer[0][0] >= USART_RevBuffer[0] + USART_BufferSize[0])
6 `% t! R$ U8 G+ H* Q+ g8 w - USART_RevPointer[0][0] = USART_RevBuffer[0];
% I0 ^) t" X* ?0 j: [& n - }
% g8 z+ d! \5 Q - }
- `' y0 V( Y: z3 k( s$ [ - 5 n# S' R% k& o; V. [8 C D
- 8 V$ f! r% N$ X
- void USART2_IRQHandler(void)
! l( h$ F# S* V8 p - {- y c4 _7 W5 V2 j$ g/ ^
- if(USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)* m+ r M9 b# t9 z3 n1 @
- {
! C: G$ O* Z* l1 a) T - USART_ReceiveByte(USART2);
2 K/ \ ]; F/ `1 g3 L7 ]) c - }
8 h W! C0 D0 Z m' v; q
! Z/ x' w: [; T0 {$ Q7 y- if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
8 b, [% h3 ]; W8 ~2 q# \ - {, S' \& s# ~ }9 H& M
- USART_ClearITPendingBit(USART2, USART_IT_RXNE);
2 Z8 X/ C. z$ Q* L: I - *USART_RevPointer[1][0] = (u8) USART_ReceiveByte(USART2);
# ^3 w+ X/ a. J& M* u3 \. F8 ] - USART_RevPointer[1][0]++;
2 Q6 v; N9 o! u7 L - USART_RevCount[1]++;
* K4 N9 Z2 Y1 E# v
' M3 X% Z( K Y: w4 c! `- if (USART_RevPointer[1][0] >= USART_RevBuffer[1] + USART_BufferSize[1])
8 }% Y/ A% Q3 M7 W/ C" H - USART_RevPointer[1][0] = USART_RevBuffer[1];
2 t2 C2 L9 d Q0 Z! k; m - }
' ^- V$ h4 m) s7 z% d - }" B2 o5 m+ S' x6 u7 k \
) h- T% h$ _5 s1 X8 G6 Q
* k2 |5 j, t' V( Y- void USART3_IRQHandler(void)
& W3 J9 S/ u$ `+ [+ n; I - { N1 n" O: U4 J; k' m+ ^" S) _8 \
- if(USART_GetFlagStatus(USART3, USART_FLAG_ORE) != RESET)$ X! J! X& U( q" D
- {- L ~6 s! x o" L, f) B6 H
- USART_ReceiveByte(USART3);
6 I8 k6 E: X6 v - }6 W5 E( C6 p4 W1 {5 p+ M4 D
, y2 b: j4 x3 Q+ C/ H# M8 U, e- if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)5 N, c2 L8 J# b6 r$ V
- {
, K7 ]# f+ Q1 {) T3 C; s - USART_ClearITPendingBit(USART3, USART_IT_RXNE);: ?" B# R9 r) W" j
- *USART_RevPointer[2][0] = (u8) USART_ReceiveByte(USART3);) }' `' E% o' _4 t# O8 Q* {0 c; S
- USART_RevPointer[2][0]++;
8 J# K% z, s- f7 G& {8 q7 ?0 Z - USART_RevCount[2]++;
6 c5 O" x/ T3 \1 l/ [
% Q+ M& o0 u) {3 T, f! b2 Z- if (USART_RevPointer[2][0] >= USART_RevBuffer[2] + USART_BufferSize[2])
7 ~( R' t0 k" S# C - USART_RevPointer[2][0] = USART_RevBuffer[2];9 d# k7 g. i7 X i! H" `& v
- }
% p# b* a$ c9 ~- @' } - }; T& c" | [& w) {8 S9 J ]$ ]! L# I
! c. \/ v, M- |+ | R# W- ( U0 n x. v2 N+ l4 U
- void UART4_IRQHandler(void)6 ?( q, ~" U8 K) D
- {
* c$ S6 x: S" O+ T5 z - if(USART_GetFlagStatus(UART4, USART_FLAG_ORE) != RESET)# C8 X0 y* V5 I9 M/ p4 m
- {
) J- V% I- s* d% R- p2 ^ - USART_ReceiveByte(UART4);
- L: T+ E1 E( \5 T/ Z - USART_ClearFlag(UART4, USART_FLAG_ORE);
. O6 M, f& q" I: D" t. ]! s - }
, B k$ t( g2 N2 u3 N5 H
3 f% Y! S( |+ V) y2 T& N( G
& Y! a* E0 n: p" K! F- if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
: v& f% c' Q/ u - {! l$ F2 I0 p' E5 d" h4 h: G# Z% `
- USART_ClearITPendingBit(UART4, USART_IT_RXNE); \5 a/ V) t5 K" t% N
- *USART_RevPointer[3][0] = (uint8_t) USART_ReceiveByte(UART4);, m* ]- M& N, q7 f& x( y/ x
- USART_RevPointer[3][0]++;8 m" U0 ~! U2 i
- USART_RevCount[3]++;9 Z1 H# j6 Y$ T' n6 }$ @
- 3 L' c% X! \. i( c
- if (USART_RevPointer[3][0] >= USART_RevBuffer[3] + USART_BufferSize[3])* u. } `- r4 {+ `9 X) T. M% Q+ |
- USART_RevPointer[3][0] = USART_RevBuffer[3];
$ D v3 ?' Z U X! g" C - }
9 g. }$ c, m. w' j9 r* P) p* l - }
/ \" a) _! t; Q. h1 \ b
6 S0 P" O( p4 x/ ~3 S
; {, @0 p+ M: h( o2 X$ Q- void UART5_IRQHandler(void)% _5 S7 m) D1 {* l1 h
- {( w4 C: { c7 I6 A# h
- if(USART_GetFlagStatus(UART5, USART_FLAG_ORE) != RESET)% I+ a2 N# x3 V/ A
- {
5 z) q. H& w& y - USART_ReceiveByte(UART5);7 n% {* z ^" G% C5 s. j
- USART_ClearFlag(UART5, USART_FLAG_ORE);
* G8 o& e! }! {8 R - }9 w( `7 P" z9 w* u+ Y: n) n, h
( I+ @- J" u5 X, E0 q5 ?- if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)7 k; ]: b" V# {" }6 ^& q
- {
, R# h, T1 ~" R6 w' q - USART_ClearITPendingBit(UART5, USART_IT_RXNE);
- r2 Z+ P( L8 l3 Q0 m - *USART_RevPointer[4][0] = (uint8_t) USART_ReceiveByte(UART5);) @0 K! w* j) a7 f' \6 n+ \! {' n9 i/ f
- USART_RevPointer[4][0]++;
) P0 O9 t. l! W( g; W, ~+ g - USART_RevCount[4]++;
" c4 r' z# J% {) G3 I( t2 T9 I - 4 V. A& P1 i& Z+ \) c9 a2 }( R
- if (USART_RevPointer[4][0] >= USART_RevBuffer[4] + USART_BufferSize[4])
5 F- R4 O8 h! d3 N' H$ Y4 g. v$ o - USART_RevPointer[4][0] = USART_RevBuffer[4];% p' L0 ^3 V* n, p0 }+ @9 Y
- }
3 Y/ E: I8 ?% C$ t$ D& M6 ^+ a - }1 _- E" N/ Q4 N0 K: H7 u& T
- #else+ ~9 ]8 d; q+ U4 S, L* [
- void USART1_IRQHandler(void)
9 c$ J" _. [8 {# w# } - {
( D" ~* @: Z1 A- ~8 |! `# U4 ~ - /**9 S `$ K$ {( s! r2 e, l
- * 如果使能串口接收中断,那么ORE为1时也会产生中断。5 k. g( E! y/ ^. w* ^ s
- * 在应用中对ORE标志进行处理,当判断发生ORE中断的时候,
. o& @/ k" p2 |. j# y ^ - * 我们再读一次USART_DR的值,6 g: U) N3 L/ I8 N+ [; M$ B) i
- * 这样如果没有新的Overrun 溢出事件发生的时候,ORE会被清除,
& H2 t2 V' D" c) e - * 然后程序就不会因为ORE未被清除而一直不断的进入串口中断
! m* R9 s' c# \/ `, q - */# b, B" \) _" |8 O+ Y& J9 ^- H+ S' {1 O
- if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)( v6 L7 l, u# h
- {
3 x% _* ?2 ]) i/ Z8 Y - USART_ReceiveByte(USART1);
4 T C8 P9 ^) B. B: Z6 R- { - }3 h$ ~) O) H) Q5 l
4 V0 H8 `/ T2 T- if(FreeModbus_PortNum == 1)9 F ~1 S: T3 y
- {
( j3 d, O2 _0 c - if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
3 v, d7 H0 p( v0 _8 s# g# Z4 \: ` - {6 {1 H3 l4 ?, u1 Y/ [" S
- // prvvUARTRxISR();6 O: ^% J' K0 @, B3 z+ p* z
- pxMBFrameCBByteReceived();; r- j. h B; d# C4 t- G
- USART_ClearITPendingBit(USART1, USART_IT_RXNE);/ T1 j' J& z L3 ^) F
- }8 q# s& @ W$ e! g
- else if(USART_GetITStatus(USART1, USART_IT_TC) != RESET)
: | T6 v( m8 ]% s0 ^ - {) U0 m3 x+ U4 J( M+ [) ^
- // prvvUARTTxReadyISR();) w/ I* L+ r. F8 {, x: y
- pxMBFrameCBTransmitterEmpty();
8 p: }3 ^ m+ x7 Q9 o) r - USART_ClearITPendingBit(USART1, USART_IT_TC);# m& n6 i( Z' s# p5 H9 k
- }
) p' W# T2 O! a4 U# c. Z - else4 }- x& d& B5 i' w8 p6 q: l
- {
" K( _& c8 T" v6 a" ] - % [( y% E/ ^, h
- }
G# O; n% g2 K - }5 u2 E: Q0 _% h% \. ?+ {8 a$ a
- else6 l4 ^; b: V3 o! }& V9 |
- {
5 k+ y' p4 l! e3 n3 V - if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)- N5 k8 T+ u4 q' {- A1 W5 Y/ M/ R
- {
) K4 V1 e, f, G& i* o - USART_ClearITPendingBit(USART1, USART_IT_RXNE);
# N! g- K& l; r5 P% H - *USART_RevPointer[0][0] = (u8) USART_ReceiveByte(USART1);
5 _, K* B1 L3 c( {* w4 i - USART_RevPointer[0][0]++;0 I3 o% q- f0 i
- USART_RevCount[0]++;
$ t0 c3 W( s |8 x$ r8 O: @) m - / J A8 N( z; v9 l; ?
- if (USART_RevPointer[0][0] >= USART_RevBuffer[0] + USART_BufferSize[0])
: K7 J3 l+ s; ^' S/ A6 g4 k4 o - USART_RevPointer[0][0] = USART_RevBuffer[0];
& m& ]9 i4 ~- f+ G7 T# _ - }0 S1 ~" F1 V3 L+ ^* y
- }
E/ u) z" [9 _- Z' t! E4 n+ K - } W) r4 y' v1 c/ T. ~
- 0 w c7 s* U; K; p* o g9 a
/ l' n: O j8 x/ {0 y2 ]- void USART2_IRQHandler(void)
) B( f% B1 j: s F7 R - {" F+ ~" I9 g; O X, y
- if(USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)
) _ `4 u% \; v - {; j# ?( e J2 | T
- USART_ReceiveByte(USART2);) ?( b5 h/ l, ?9 d' |$ R, \6 s/ ^
- }
Y/ Q1 v& W6 F& g: M
9 y' L$ y' E, v" q# y. t- if(FreeModbus_PortNum == 2)
$ H, F* A0 B7 {6 B7 U3 d9 H0 C - {
4 o1 a; U0 n$ f; [5 E - if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
; T8 e1 m7 `% N' c - {, e0 t7 d% |. F
- USART_ClearITPendingBit(USART2, USART_IT_RXNE);
' m3 b% G( `* }( [9 b - pxMBFrameCBByteReceived( );, y$ ^5 P5 u3 q% ?
- }( z+ v8 m2 Y) z/ t. [5 e
- else if(USART_GetITStatus(USART2, USART_IT_TC) != RESET)
9 L; M1 Y( {9 u - {
6 _- [! ?! @8 m - USART_ClearITPendingBit(USART2, USART_IT_TC);$ Q1 Z f$ A0 g5 r3 g
- pxMBFrameCBTransmitterEmpty( );
$ l6 q3 Y* c/ p4 D - }! Y) a4 ^/ b p! I
- else& w+ U: X: S% s( N8 Y
- {* u% [: R; t$ i
- 1 J& y& `, ?0 f2 l* r
- }
$ K( k4 w0 m- Z' ~. }) [ - }
8 h# t& V- X: E2 L - else/ u/ B d8 U; H0 j9 c/ i
- {9 R+ i( }: Y1 Z
- if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
0 H+ M, R- h, C7 ~) M! _ - {
0 {( K( g& ^3 B5 P* F* s7 M - USART_ClearITPendingBit(USART2, USART_IT_RXNE);' z0 |/ X K& Y' B. T5 s2 |
- *USART_RevPointer[1][0] = (u8) USART_ReceiveByte(USART2); N: m- G: O5 p y/ T
- USART_RevPointer[1][0]++;* E6 |! `" j( g- M. D
- USART_RevCount[1]++; v4 ]2 p" `/ j' V& e- v
. l: y2 d8 W: s- if (USART_RevPointer[1][0] >= USART_RevBuffer[1] + USART_BufferSize[1])
* |$ s) I2 q+ g3 F& y# B* b - USART_RevPointer[1][0] = USART_RevBuffer[1];
4 e3 P" Y- f' }( P& ^# H - }
- l. ]0 x% M/ a; J6 I: b* R - }
( Z/ N6 \4 U8 ?: u - }( |0 P* p; D" N* Y$ m |- D
* C9 w, _1 Z( q, |' o5 e2 E% y+ B: T
4 d; u# N3 _# l( D3 a- void USART3_IRQHandler(void)( }9 d) U% S2 D
- {
9 r' v ^8 n6 Z( c - if(USART_GetFlagStatus(USART3, USART_FLAG_ORE) != RESET)
; |( }" w2 u- E0 e" u7 ^4 { - {
( r$ \( W& u, q* O+ x3 ] - USART_ReceiveByte(USART3);. X6 W5 @) @/ Y! @, m
- }- ~% A# r* V4 R8 ~! w R
- 4 j: A) z$ r; r) b
- if(FreeModbus_PortNum == 3)4 _3 Z) Z: |" f. F# x2 w
- {7 P/ ~) _8 A8 l. Z* y, N/ X
- if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)% H* x9 X1 q6 Z
- {) w; W: ? z4 W( h a
- USART_ClearITPendingBit(USART3, USART_IT_RXNE);% _- H z+ Y) T3 K
- pxMBFrameCBByteReceived( ); q7 j+ Y+ v. H- G
- }
& x. B1 _; R- v; U6 v1 Z; W) W0 y - else if(USART_GetITStatus(USART3, USART_IT_TC) != RESET)
7 u# M9 j' z) z* f - { N$ X; K+ v2 \7 Q- j( q
- USART_ClearITPendingBit(USART3, USART_IT_TC);, E9 D5 ^9 x6 h4 F& ?
- pxMBFrameCBTransmitterEmpty( );
" p4 n- j/ ^! l+ f, ?+ S7 i9 ~7 G& ] - }
: |. e9 P+ Z! w. s. a) C - else+ v$ Z q* K5 S$ B2 x) ^
- {
% a) I6 e( V& H* ]! u( K3 I -
4 G* \2 g8 u4 ^ - }4 e0 I4 Y; | V6 s
- }9 K$ y ~9 k! \$ C
- else
& x, ]8 n6 T4 F5 W& u% S8 N: Q - {& A: @6 u0 G7 d- o$ i7 N
- if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
0 X+ C6 N7 s1 Z - {
2 Z9 E" Q# j8 `0 l! H - USART_ClearITPendingBit(USART3, USART_IT_RXNE);
0 n+ J X* l9 t - *USART_RevPointer[2][0] = (u8) USART_ReceiveByte(USART3);- |6 a* P2 h7 f" m0 i
- USART_RevPointer[2][0]++;
' B7 K1 [+ n1 q - USART_RevCount[2]++;
7 N r3 S d9 H4 X1 D - # Y$ q+ H& }5 U* E# b
- if (USART_RevPointer[2][0] >= USART_RevBuffer[2] + USART_BufferSize[2]): x5 I# h8 G, K" o" A
- USART_RevPointer[2][0] = USART_RevBuffer[2];
1 P: q1 W# q' u' Y* j/ x0 k - }
" U2 m M- t2 @2 A - }# ~0 W0 i9 V- U9 g/ r; i' z* H' F, m+ s
- }
: o: l( E% L+ B! J- ` - % s. l0 t7 u9 b! c8 R
7 l) G! \2 P5 t6 \: P0 Q" F* V# q- void UART4_IRQHandler(void)4 i- p/ h1 b5 G, R7 K; W
- {
& v# h, i# a5 w$ o8 K2 Q - if(USART_GetFlagStatus(UART4, USART_FLAG_ORE) != RESET)( [% O* Z% }, ?! j" l
- {
% ^. M- Y* T) q; e: ? - USART_ReceiveByte(UART4);6 B4 [; L, x( Y. H9 R" N0 h3 |
- USART_ClearFlag(UART4, USART_FLAG_ORE);: {; m6 a8 E) e8 a
- }$ \" R. _- l( ?# M
- ^* j$ I' L$ l( t. q- if(FreeModbus_PortNum == 4); P) O8 g9 r* n' ^
- {
; a0 e! n1 M# B - if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
3 J1 m* g# d$ ` - {/ g ]/ _! k1 ^* \. Y$ l7 t; h$ b/ P# L, T
- USART_ClearITPendingBit(UART4, USART_IT_RXNE);
- h! Q. r7 w$ k" }7 ^/ n - pxMBFrameCBByteReceived( );
" |- F+ X5 i. k/ P4 P - }
# j3 A9 N3 j' D+ @) K- H - else if(USART_GetITStatus(UART4, USART_IT_TC) != RESET)
; y" Y' T; t+ I7 R: P- @9 y - {
& s1 O, @& {" R6 \, _7 I; X( T. [! t - USART_ClearITPendingBit(UART4, USART_IT_TC);) C1 g# `0 _5 {; Q$ o& I! j
- pxMBFrameCBTransmitterEmpty( ); ^. G4 H8 W2 G
- }
+ R r$ T$ L3 d& s8 z - else5 w" \; N2 \: M
- {3 {; M6 K' S. n
- , Y8 U! Z3 z0 J8 @
- }7 S& C& r+ w- I( q# N
- }
5 L: Z$ O/ M5 O$ Y) C: j" f+ @ - else
2 Y1 ?# ^. [* p+ n' ~% c - {
7 u5 B0 X7 h; p+ V. _4 q - if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
% r6 L( j# G6 S6 R& \ - {
5 Q. o6 y5 S$ v0 z1 A" C - USART_ClearITPendingBit(UART4, USART_IT_RXNE);
5 W! j2 y. S& S/ F$ \ D" j) L6 N - *USART_RevPointer[3][0] = (uint8_t) USART_ReceiveByte(UART4);1 c5 n, f' N3 W
- USART_RevPointer[3][0]++;8 {7 G( B+ ~: K& _
- USART_RevCount[3]++;6 E3 z3 T% o8 K. |: P" t. }2 E
, a; ]6 E( T: k* J# p- if (USART_RevPointer[3][0] >= USART_RevBuffer[3] + USART_BufferSize[3])6 K* F' d9 P% K p) ]
- USART_RevPointer[3][0] = USART_RevBuffer[3];: H- ~3 A0 B) b J; Z! R
- }6 V) `2 m8 q( D9 v! n
- }
: W N7 P: E/ r$ }# ]' U - }
* q P& h8 O8 L' J6 u k
" s$ A+ y3 F1 S% I* l3 |- 7 K' Q3 t: W& _0 Z$ C- F2 @7 u
- void UART5_IRQHandler(void) t C2 H% h& t, |# S$ W4 m
- {" k; i+ @2 Z# }! s5 \
- if(USART_GetFlagStatus(UART5, USART_FLAG_ORE) != RESET)6 l7 x9 h! W, Y7 A' g
- {
( y! J% W% K; }, @4 O4 z2 D - USART_ReceiveByte(UART5);
3 i4 G/ b$ i/ W: Z: R" A/ W - USART_ClearFlag(UART5, USART_FLAG_ORE);1 o* h& ]* C/ S( S- s0 [$ Z
- }6 L( T H1 q9 L, Q
- ; _4 v+ n3 \/ O2 R
- if(FreeModbus_PortNum == 5). u+ g/ M/ t8 N7 S. H# ?% Y+ p- g
- {
: `# ~9 F) V j$ F1 B- } - if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
& F5 D5 u1 @7 {' O% u5 J. l4 X - {9 O. S3 g2 _% L" B$ ]! l
- USART_ClearITPendingBit(UART5, USART_IT_RXNE);
' a3 N3 H0 C( k4 y5 Q - pxMBFrameCBByteReceived( );7 w0 Z4 a1 y# w: B
- }" L/ x. p' X J4 x" o# L( i
- else if(USART_GetITStatus(UART5, USART_IT_TC) != RESET)9 G7 J8 e' K* l, P$ }0 T0 T0 O
- {
L2 \* v% t$ [) p' _" I/ n - USART_ClearITPendingBit(UART5, USART_IT_TC);7 Y8 y0 N* t. q9 J
- pxMBFrameCBTransmitterEmpty( );0 J& c: \2 a0 U6 h( z
- }; e8 E6 X9 k9 n6 i7 F& V' l9 I3 T
- else
8 v5 b X) ~, B Y R1 a - {
. s# N3 j* {. c' F! h* r+ v - 5 {: {9 O) G& f) s) L" P' K
- }6 S0 n4 N5 B- W0 k l2 q
- }- C$ A( N4 I5 `2 e" B8 f* Y7 H4 S) i
- else* f l" T- ~4 n# i* K9 i
- {% S) R; k0 W& U& s
- if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
+ \9 h, k. B) a, G - {
% N" J ?+ n$ t( M+ ] - USART_ClearITPendingBit(UART5, USART_IT_RXNE);
, ?% A) `7 m1 N; z! ~ - *USART_RevPointer[4][0] = (uint8_t) USART_ReceiveByte(UART5);4 u8 `9 _7 w N2 C# @
- USART_RevPointer[4][0]++;0 }6 t1 `6 v5 ?8 m" r
- USART_RevCount[4]++;- Z1 s R- d4 b0 F+ p6 ^- q
7 g- b0 j& \% m3 I- if (USART_RevPointer[4][0] >= USART_RevBuffer[4] + USART_BufferSize[4])5 _8 x/ A. s4 x) V: a7 X
- USART_RevPointer[4][0] = USART_RevBuffer[4];
' }& [: {8 e0 H5 a - }/ W$ g; s) O1 Z( P+ f
- }
0 Y3 ?0 U p5 d* {6 n' `0 f: L* e - }
0 D2 i' j8 \5 n8 R3 k1 d x$ o* ?3 C6 l - #endif
% A( |- Y% ]; y- J - </i></i></i></i></i></i></i></i></i></i></i></i></i>
复制代码 " |4 U) i# Y) x6 \( M; I
使用指南0 w( p/ X+ t; N3 o1 A, B/ r7 I/ {
基本使用流程
" S# Q& o; Y' w G% M2 `! W% w$ O配置串口外设
' m; G1 x4 q' C2 x6 L* S配置GPIO6 B) K& D. I) E% t a1 s) n$ `
- void GPIO_Config()
, u5 S8 J$ |! D' m' _( G3 F - {
+ p! @: C8 R. ~/ b" @1 O+ E - ' G; i3 Y6 e; R
- GPIO_InitTypeDef GPIO_InitStructure;
- A0 t" H+ H" X. K9 L - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE);6 b) I0 a' {5 f9 J2 X5 E
+ n9 X( w8 I; y! [1 h3 H- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);8 y B- B, X. V. J+ H! a$ ?
- 9 U& ]( o, o9 {1 ~4 w9 ~
- GPIO_AFIODeInit();
% E1 Y$ J4 A; Q2 w - /*JTAG-DP Disabled and SW-DP Enabled, use PB3, PB4 as GPIO*/, c/ a8 O" `/ Y6 H, L, h. V
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
! n- L$ r9 I w$ k2 b* C. p
% e$ S) C1 I9 g1 h. ^+ c* C0 O' Q, I- /**$ Z" Q( `: l% E* b
- * System State LED. m7 f' P" O+ _1 |& A
- */
- I4 N c- _8 i4 ?! ^+ [ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;1 A5 t" ?' y- P% z2 C% V6 \
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;9 y' W2 A2 e, h
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
G4 P# V, u; _; T, s. J - GPIO_Init(GPIOA, &GPIO_InitStructure);
. g% u' l g/ ~- I1 x$ g R& r
1 y& f/ i# S& j- y. s" ^- GPIO_ResetBits(GPIOA, GPIO_Pin_15);# I/ h w+ w+ o5 h4 c
-
; d8 O# L+ @ F% H& a1 V4 O - /**) c( i5 _0 ]. X) h+ {9 O. y- T$ v+ F
- * Serial Port Interface7 g1 @* ~- |( g) [/ ]7 `
- */, Z9 J9 t( e" X( j$ a
- /***************USART1_TX-->GPIOA.9************/6 b4 c7 b) s+ f7 G/ N' C I
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;. n" i3 L T- X; U }
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
$ _% \' g! }) r4 \' O- w - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;0 o ?5 h* ]% h* p+ a$ o! w" J% h8 I" t0 z
- GPIO_Init(GPIOA, &GPIO_InitStructure);. W- U$ [! |- {9 m1 j! m
- 6 l8 B1 |1 F; c7 \8 u+ l; P9 U0 S
- /***************USART1_RX-->GPIOA.10***********/
3 g, b2 w$ y. I1 d - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
3 e- I- u: J/ ]% C4 _ - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;* p$ @) w- ]& o
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;" K- R; T* t: v1 I2 ?" _/ E, [
- GPIO_Init(GPIOA, &GPIO_InitStructure);' o+ M# w4 @6 y. b7 o+ y0 f
- }
) P- z* D2 }7 Q Z! p
复制代码
2 N# }. Q# u( v7 b配置USART. M6 {' m3 r4 x% L% ~6 n
- void USART_Config()
# K/ x' ^3 {) u2 `8 M { - {! X8 f1 d1 U7 X) o, e& |; b- F) n
- USART_InitTypeDef USART_InitStructure;
( m, _9 p" O, `5 V% U9 C9 J5 D - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);$ `# ^. d( [/ G0 r3 N, ^( a) Q
- # ?2 `8 U3 v' d& X8 x
- USART_InitStructure.USART_BaudRate = USART1_BAUDRATE;: K" M" E7 g0 [- B ?
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
" a4 k2 ^ q# j: Z1 m0 z - USART_InitStructure.USART_StopBits = USART_StopBits_1;6 [7 x9 K, C5 L- u7 p
- USART_InitStructure.USART_Parity = USART_Parity_No;
3 ]# u4 I, X7 z( Y" B: x - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;" Y0 o9 d9 s. ^3 V* \
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;" U' @1 M* V, l
- $ n( a# L, S- U' H. D& U
- USART_Init(USART1, &USART_InitStructure);, T8 x2 Z0 s5 j9 Z
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
) k* Y4 E" p6 J) ]/ Q0 m - }
复制代码 2 }. M6 e& j% `4 o# P% x1 G2 F1 b
配置NVIC( Z% \3 W& v& B; I
- void NVIC_Config()
; C8 _3 b- z ~! B% |3 P0 { - {
2 b# P- s( w, o! f# |+ F( x$ U - NVIC_InitTypeDef NVIC_InitStructure;6 T# H$ t# {1 d( d1 X
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); e1 w6 }% C/ H v
- % X- s% d7 D/ o6 G9 Y7 f, S
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
3 X; r, F" K: ^& c3 @ - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
. Y0 M c4 k* A, Q1 U2 W0 s; o" i8 } - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;# M9 }8 d3 y h0 C$ w4 M2 l
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- W3 S0 W$ X, `7 @1 N -
' r7 T1 h4 m9 r, V5 i1 q$ s% x - NVIC_Init(&NVIC_InitStructure);! @ c! o9 `# F7 e
- }
复制代码 * @- G/ V& o [( l
打开串口
2 w- T. {: e0 L- void User_Init()4 z& S" ^, ^! B8 u$ D
- {. s5 w8 P2 _$ @, _4 G, o
- /*省略无关内容*/
( G1 h% o7 Z k( s- J' _ - USART_RevInitAll( );. U- z3 k4 N3 X1 T9 F: V! H
- USART_Cmd(USART1, ENABLE);
- E7 v$ K2 B; m! U7 @4 b - /*省略无关内容*/
2 n9 N e v6 d2 q - }
复制代码 4 g6 A X1 b* p/ @8 I- F
定义数据处理函数
# G4 G5 Z1 H( [定义一个数据处理函数,并将其作为参数传递给接收数据处理函数。: j! P" ?' M# ]. S
) f& |3 x ^5 r. Z- void ReceiveFromPC(uint8_t *_Data, uint16_t Count)
2 c9 G5 V: }7 [5 i+ g7 D& p! s - {
; Z F7 q" D; U - //如果没有接收数据就直接返回) _5 c' x8 B" X0 z1 |' V
- if (Count == 0)
2 I/ K8 y( t6 U7 U- b - return;
( n: C# W2 @" }% Y/ P+ Y - //处理接收的数据% b5 c& m( M5 y! t2 Q$ J) P# b% T
- for (int i = 0; i < Count; i++)
3 K! j7 d- e6 y1 L; l0 H - {, H6 y* ~, _( V8 U0 V/ }* _8 \( F5 q
- shellHandler(*_Data++);1 B/ `9 F5 k8 n q! Z4 y. G
- }
) m: y4 L+ }& \. J4 j& a4 x5 o - }
复制代码 0 o0 a' N+ _/ ?
处理接收数据
% T. m4 v: E/ r+ R3 @在系统空闲时(一般在主函数的轮询中)或者其他需要的地方调用数据处理函数处理接收的数据。
0 L; x- Q2 `2 J" q' H3 H1 a
- Z" H! G% m+ { I- int main(void)
, P/ X1 `0 y% y9 L! T - {
$ \+ ^5 Q. _+ z+ j - //略初始化外设! k# w% s4 t n2 `0 O
- //初始化用户配置% W3 B( }. x7 ]
- /*省略无关内容*/
. c1 A5 x) I! s3 a% q5 v - while (1)
. Q5 y% G% n5 d3 o: `3 l5 y - {% k- g+ Q- S1 |6 @. k7 k4 c
- /*省略无关内容*/7 A; A! @3 T N, @5 L
- //ReceiveFromPC为USART1接收数据的处理函数" W7 k5 J. `5 v( e9 J5 ~8 A" i i
- USART1_RevBuffer_Handler(ReceiveFromPC);% x- d. D1 Z9 h2 J. [6 A a. l1 h5 V! D
- /*省略无关内容*/
6 i, Q8 t! O V7 N: i* y, H - }, ^! Z: l: k7 S6 ]# B9 ]8 A
- }
/ e; l8 d( y+ V
复制代码
1 I+ U5 Z# o' l7 i. m5 G. @发送数据8 O# e$ Z4 p2 p8 F# {) s E- ~
在需要的地方,根据数据内容选择适合的数据传输函数。* _$ I$ f$ I" n) f8 n
. r6 R7 ?3 n, H- X1 N( y( q
通过指定串口发送字节数据1 @( R2 ~9 G/ w3 g% ^4 x; D
void USART_SendByteData(USART_TypeDef* USARTx,const uint8_t byteData)% f3 E! Z) @ ~( t( l
通过指定的串口发送连续16位数据
, w8 W8 A1 ~/ N5 Nvoid USART_SendData_Bit16(USART_TypeDef* USARTx,const uint16_t *Data, uint16_t Count)
! J. V; l" M/ ]9 X8 c4 n通过指定的串口发送连续8位数据
+ s2 `+ G4 [; ` Q+ Bvoid USART_SendData(USART_TypeDef* USARTx, const uint8_t *Data, uint16_t Count)
1 b- B$ L0 n" }* Z2 N' _通过指定的串口发送字符串* x& Q1 K. Q- q. d
uint16_t USART_SendString(USART_TypeDef* USARTx, const char *String)6 A3 X$ \8 E0 O9 X1 k: P
1 Y" B% J) V' ^8 C) P
$ ?6 }, ]+ ~0 j- H' J4 o( a! a
4 h! ]9 w6 _& v6 P0 } |