写在前面; X4 X" y, {7 Z/ ~6 H) Q
芯片型号:stm32f030c8t6
% G% m6 L0 @0 X/ r/ t说明:便宜,用量大
) E6 V7 O1 T! ?/ q) q! T+ l要点说明:初始化、主函数调用串口接收callback、串口接收空闲中断,串口接收中断
5 b- E! O1 w; ?8 ^: [( W4 J& D这种API封装方式可以拓展到其他单片机,但需要注意单片机是否支持接收空闲中断
9 h' b$ b/ {* ^: L. d本文注意介绍空闲中断的应用,这样就不用在定时器中计时来检测接收超时中断了
5 W# ?& \, x3 S# N9 c. C
; M" S! f: G/ ?5 N2 o0 I一、应用
* [0 D: O. `$ ^外部定义串口接收回调1 L3 v f8 U8 z* f5 V
当串口数据接收完成后,在该回调中处理串口数据即可
* [$ @; {1 S8 y9 U; F- void Uart_recvCallBack(void *buf, int len)3 a% }( U! ~/ _
- {+ N/ k4 F7 O. N% Y. \% X, T
0 Z2 R" d$ S" H% I7 G- }
复制代码
8 O7 R1 L9 J+ k: a+ T外部初始化串口1 H$ r! b2 v# D& s. T' r: N
- myUart_initialize(115200,+ G' v5 x8 \' p# y
- USART_WordLength_8b,6 ]; [3 |# k! t7 _ [# L* u
- USART_StopBits_1,
3 N; h" o/ K+ E& c0 ^: v! I" I - USART_Parity_No,
2 L& ?' }+ f7 D& l9 ?- H" \( `0 g - Uart_recvCallBack);
复制代码
/ c) K7 g3 f! A' l' F二、源码
) I% b3 e1 B% [1 K9 K+ J9 ZmyUart.h
0 ]9 n7 d4 U( Y! h4 _* x2 j3 W7 e- #ifndef __myUart_H
) y o& J/ p9 }1 L& U) L6 N% a - #define __myUart_H
. `$ {" A- _5 j& G" V0 S! ?
* K5 h2 h' Q; y. e6 [- #include "stm32f0xx.h"
/ b8 t9 W* E$ B0 I - #include "stm32f0xx_usart.h"! h# G- f- P F) G; e
- #include "stm32f0xx_gpio.h"
' I8 N1 Y$ e. L: @ - #include "stm32f0xx_rcc.h"
7 ?2 K5 c+ m9 n7 |% _1 C - #include "stm32f0xx_misc.h"9 F! G/ q* j- ^) v3 e
- 3 q7 C/ n& h+ A( ~! s( H
- #define USART_REC_LEN 200 //定义最大接收字节数
3 O* Y$ y: T0 Z3 F" k5 B$ t - 3 R ]2 R$ U, @
- typedef void (*myUart_cb)(void *buf, int len);$ `1 U; o9 R2 r
) A' W A! z/ u3 B3 S- y- void myUart_initialize( uint32_t USART_BaudRate,7 ^- W# h. `) E- i! ^
- uint32_t USART_WordLength,
% \5 b9 j+ i0 L( q - uint32_t USART_StopBits,
0 p: }" s, ^: y9 D/ c - uint32_t USART_Parity,
0 ^) u0 l6 K: a$ S2 y6 N$ z0 _ - myUart_cb cb);
' E+ S0 B& b" L" o$ a) e& T - void myUart_setBaudRate(uint32_t USART_BaudRate);; s# b; [) z1 B$ I
- void myUart_sendByte(uint8_t byte);
. u' q- F; ]% ?2 c. ? - void myUart_sendBytes(uint8_t *Buffer, uint32_t Length);0 R( C1 E* A- N6 |( L* ]5 U$ W
- uint8_t myUart_recvByte(void);4 l9 _( K1 |6 g% x5 i
- int fputc(int ch, FILE *f);% |% t6 ]6 Y- r3 s2 V% m
2 \7 D7 K7 r) { o8 y- j- #endif /* __UART_H */8 f. I$ V- Y6 [, Z2 h/ O
复制代码 . R3 S% g# _" _% a; g( T7 C
myUart.c5 \) U1 \/ v; [, }4 h# e
- #include "myUart.h"
/ R+ T. I) I7 j3 {% m - 3 z7 j" Y5 t" B5 Q
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)9 s* H9 h3 |. {4 x, A4 U
$ K8 q0 F! O6 F; u" S- uint8_t USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. H1 W- D+ |1 d0 e2 X
- uint16_t USART_RX_count = 0; //接收状态标记
7 b# z. `1 D0 c1 _0 {% e - myUart_cb myUart_callBack;
3 I# D! I+ ~2 ~5 p8 c" B& x! m7 G2 }- a - /* Private functions ---------------------------------------------------------*/5 G! f2 i% _0 A8 s, H5 ?1 V! P. f
; o' i3 G2 _! I1 E- USART_InitTypeDef USART_InitStructure;, ~0 X1 ^$ F- [& a4 I. l5 t
- 6 O( X. a+ Q% U; U1 Y2 @- U1 M
- void myUart_initialize( uint32_t USART_BaudRate,
" Z& @$ L$ o" ]6 B - uint32_t USART_WordLength,0 E C7 {: l8 y+ C# r% G
- uint32_t USART_StopBits,$ V( T1 O/ x/ Q
- uint32_t USART_Parity,
2 k7 ], U- N( C4 `0 b. x6 ? - myUart_cb cb)9 i4 `) S, w1 Q' r o: Q6 s
- { * S( r5 ~) J6 J9 ^8 [% f: O! n
* X4 Z% r* b* v6 m2 @0 G3 P+ D) I7 q- GPIO_InitTypeDef GPIO_InitStructure;3 b4 }/ l- p+ Q* l. I9 k- V
- NVIC_InitTypeDef NVIC_InitStructure;
* k: C; J0 t& V( i# `0 M/ S - ! g& M: w7 ?: W' x' F+ \
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );/ q, q1 K7 s5 a( T! j
- , \# l+ U3 f, V) r+ W
- GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
$ ]; N: [( x g9 l" i - GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
& h/ Z" B X. W3 E! q- s& z - /*6 i, J/ y/ I' b, ?/ \+ U2 {6 |
- * USART1_TX -> PA9 , USART1_RX -> PA100 c) B! @; k/ M; [) f
- */
s) z3 p; C+ [7 m - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
/ ~, B/ p) g( m6 ?3 |/ K P1 d - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
6 T. B$ A' k& w% z2 U - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;7 x; i, R. G W* `) G$ \& f
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;1 ]% `$ Q4 K7 R
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 0 a" A* ^, y1 H) Q [+ x
- GPIO_Init(GPIOA, &GPIO_InitStructure); 1 p# Z0 q* Z7 s+ G
- 1 R% E5 @6 D# i g1 O
- //Usart1 NVIC 配置
" k& a K' c3 s# J6 A - NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;/ u( v' ^ S* X
- NVIC_InitStructure.NVIC_IRQChannelPriority=1 ;//抢占优先级3 c+ Q5 r1 \! j& V" G
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
; P4 A5 t. ~, |; A# \ - NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器5 x: v9 p4 w2 u! e+ z' B
- 2 I* ]9 `9 e' V3 w) Y9 R
- USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率
% [- P, `$ l3 w$ [) a$ ?& E - USART_InitStructure.USART_WordLength = USART_WordLength;//设置数据位' z$ K/ d0 l; U) g: X9 n
- USART_InitStructure.USART_StopBits = USART_StopBits;//设置停止位3 [ ?0 q' w4 n+ \% M% a
- USART_InitStructure.USART_Parity = USART_Parity;//设置效验位
& Q1 ]) f* w1 J" r* c9 R - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制: _; D0 K- Z. z. U+ |
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式
7 [2 ?9 r [! Q/ i) ?% @! \ - USART_Init(USART1, &USART_InitStructure); //配置入结构体
5 k/ V% o) {! @ - % X" M$ l9 e$ F/ p# R- k
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
8 W( [& d H9 F% S ~ - USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接受超时中断( y8 A6 a. ?2 t! H
- USART_Cmd(USART1, ENABLE);//使能串口1
! |" H L/ @# R c
: }7 d2 X0 f1 T& I- myUart_callBack = cb;
( r6 i, F3 D% r3 _8 u - }
8 s% T/ ~ Y8 J3 B. c - void myUart_setBaudRate(uint32_t USART_BaudRate)
' F& h! J i, o7 H - {
9 N& e1 \" I4 g5 { - USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
. X6 F' {+ W( C0 S, X - USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
V2 ^% H$ {4 `# y9 ~* P - USART_Cmd(USART1, DISABLE);9 U1 i) K! k: [3 T1 _6 w
- 1 A2 O+ n- v4 P4 \
- USART_InitStructure.USART_BaudRate = USART_BaudRate;//设置串口波特率4 f* N# B, N. F% V) c) S
- USART_Init(USART1, &USART_InitStructure); //配置入结构体9 v' b9 g$ e+ B# B
2 L' [) y) Z6 H% x3 c8 W5 F- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断' C. P$ }# D5 P( }$ f* s9 M
- USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口接收超时中断7 m3 B: x/ h9 K% D
- USART_Cmd(USART1, ENABLE);//使能串口1
, B" A, {& E! H- G1 z2 q' a - }
% Z, ^+ Z9 j0 o* k - void myUart_sendByte(uint8_t byte) //发送1字节数据$ `% d0 o2 T, a, q* b2 u/ q
- {2 L( W+ s. s8 _& m% W
- while(!((USART1->ISR)&(1<<7)));
+ ~4 s! N7 ~. e, \6 H - USART1->TDR=byte;
) ?. S+ O' ?" ~( r' `& L+ K - } ; z6 w2 v5 @* {
- h$ `$ l: ]! [9 J- void myUart_sendBytes(uint8_t *Buffer, uint32_t Length)
+ W; s J; b3 r - {$ d! q7 B/ r& m" M, k* I
- while(Length != 0)
* }9 g) |# m( X; o( Y7 z7 y - {
: t$ a0 d! K6 K( ^4 I' i3 G8 `2 W - while(!((USART1->ISR)&(1<<7)));//等待发送完$ u! l% Y, t% p' Q8 r- L4 s0 Y
- USART1->TDR= *Buffer;/ X& `% `1 u: j) m" u, O/ S- e1 S* z
- Buffer++;
9 F2 o1 a4 ]4 \% F! I6 W3 G6 [! u - Length--;
1 i1 l, a# Z# ~( |. i - }; ~3 X: M! b M) S+ s
- }
% X$ B' i. k, U' G8 @ f - 3 ?. G1 V' r9 G
- uint8_t myUart_recvByte(void)
8 o) i8 J- E, t, N5 o0 ? - {
! `& o, Q0 b5 g! Y" ~ - while(!(USART1->ISR & (1<<5)));//等待接收到数据
/ F8 M2 `) D8 a" ^ - return(USART1->RDR); //读出数据
' M* K- y7 B* f) F$ Y: D4 D - }9 L" E1 ]3 f! R) U) g
$ b# s* O' _! E$ Q/ x5 K& Y- + k, B0 R! I# B' q6 `9 V* ]7 e
- PUTCHAR_PROTOTYPE ) ?# t9 `" a/ v1 l: Z4 `
- {
1 t0 o" Q. v, u( M - /* 将Printf内容发往串口 */# j' @: n# y X4 |% Z4 v
- USART_SendData(USART1,(uint8_t) ch);* L8 s$ t' \5 n. Q6 S
- while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
. Q0 J/ d5 Q4 M* \4 e7 F* F) W. Q) E - {}; T% e1 y# R- k7 e+ D5 j
, _7 V4 Q7 X. b! U1 L- return (ch);
4 l/ Y& H9 g$ ^ n+ C7 ^ - }# s* b: u4 o% c% ~# Y* S! S- m
5 g1 H) R$ d- h7 Y! K8 ]9 ]% t- void USART1_IRQHandler(void) //串口1中断服务程序+ P- }, W- k& K P1 s" ]
- {* m" q9 _' u7 {4 n' k* c! }
- uint8_t Res;
6 N* i/ Y* E* T5 n' k% {
& `* K& E8 e) E4 N2 c2 O9 H- if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)4 ^8 W d. q0 e8 \
- {, b+ ?7 Y. ` a6 H O2 G
- USART_ClearITPendingBit(USART1, USART_IT_IDLE);//USART_IT_IDLE需要手动清除
. H9 h) e$ x% K4 x8 D. t - if (USART_RX_count)
6 G8 Q/ [1 t! Y$ X - {/ ~. G% {1 b+ F$ _
- if (myUart_callBack)
+ {5 }$ ?" }% H. l - {) x6 Y6 _3 @! u
- myUart_callBack(USART_RX_BUF, USART_RX_count);5 ] m# M1 G( X' ^) t
- }( o# q t, K, J6 H4 C
- }- t( x) |1 Y# \* g
- USART_RX_count = 0;/ q! K* T& {+ r. o8 n; @7 V1 p
- }
/ b0 P' N7 z O6 o' x3 N - if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
) @$ V8 A: c) ~4 ? - {
- t; h7 _& M) I; P% x6 }1 K$ E2 m8 H: q - USART_RX_BUF[USART_RX_count] = USART_ReceiveData(USART1); //读取接收到的数据,自动清除USART_IT_RXNE中断标志
: B# L* h& l& v* q! U) J - USART_RX_count ++;5 m1 v; u& }% n4 d' V) }
- } * b/ Q! ?( r( u& B/ m
- }
4 v/ U$ {! [8 u' ]# Z0 j& n - 4 o8 T! A: F. ]3 Q. |' N
复制代码
& V. r, a+ }9 C4 h9 M; a |