- int main(void)
1 v& Q1 S- n* }/ C6 E* B& w2 b" P - {
- c; f r) Q( ~0 x& q% ^1 C - uint8_t a=0;//LED高低电压控制
* x) N& j2 K) Y
7 r+ \. ?& ~) [1 p E% @; a- D- /* System Clocks Configuration */
1 b7 K! A( h5 b9 t3 P - RCC_Configuration(); //系统时钟设置- [5 O0 m) h; ]+ C
- /*嵌套向量中断控制器
4 J$ X; E! G* f& q - 说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */
- {7 L$ [4 O4 O - NVIC_Configuration(); //中断源配置% M$ `. ^! c' W! r
- /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,RX。
- [# t+ B, Z% f" {9 N% J$ u - 在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B, 因此要对这个端口的时钟
t4 c" _. B8 e; m1 Y0 ~/ C - 进行使能,同时由于用到复用IO口功能用于配置串口。因此还要使能AFIO(复用功能IO)时钟。*/
4 G4 U6 K9 _3 s - GPIO_Configuration(); //端口初始化+ H5 L6 H1 m2 _( e5 f
- USART_Config(USART1); //串口1初始化
9 I4 A/ X2 r' ? - ( q! Y2 i# N! `' a) f) J0 ], v
- while (1)/ X D- ?5 l) ^; `- u1 K7 {; F# E6 w' b+ S
- {
3 T5 }& A5 p$ v3 @ - if(rec_f == 1) ; L" h8 i# j5 |( O4 k
- {
D1 J% D. A D6 N6 R, ` - //判断是否收到一帧有效数据
S5 B" h5 M! O$ l' O - rec_f = 0;1 G" F5 Z( q D% Q, Z5 s% F
4 B# R; w2 _0 N' X1 R$ j- for(i=0; i<sizeof(TxBuffer1); i++) //发送字符串
# {; i9 j. \1 E! ]& b2 W - {+ j+ m i* P7 Y( {! X. l8 s
- USART_SendChar(USART1,TxBuffer1[i]);
2 H7 S8 G2 z2 P7 s7 e - Delay(0x0000ff0);5 @3 [, _+ ?( M$ N: {% k7 B
- }/ ?! q( y# P$ [5 n# j4 g
- /*for(i=0;i<TxCounter1;i++)//发送字符串5 v- m5 Q/ T( s* L3 W
- {* x: A0 H# g: c2 k+ f# b2 G! e
- USART_SendChar(USART1,RxBuffer1[i]);
7 }- O" B+ r' C( l, y6 c" ?+ m: D - } */
6 M" v* k0 k* B% G - if(a==0)
3 Q. H/ \% I6 b( o: Z% U$ b - {
7 o8 Z# j& K, n# o - GPIO_SetBits(GPIOD, GPIO_Pin_2); //LED1 明暗闪烁; \/ v3 c, N. f1 B: b
- a=1;9 G1 C* T* A: S) X" j0 S* W% \1 [
- }) h _7 B9 V9 {( z$ X
- else - B/ T; S- X! t6 T8 K" e7 \2 v
- {; j2 h$ Q( y" R3 S! J4 n' x
- GPIO_ResetBits(GPIOD, GPIO_Pin_2);7 c4 `) d. {) J: T: y- p
- a=0;
* z8 f8 U3 B; j0 k - }
. k) q6 c0 d1 L. _' J% q - }1 R9 L* }% n) t7 m& |" N+ h
- }2 F3 G% X& U, g. m j/ F
- }
复制代码main函数如上。 相关变量 - uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO";
' G s( T. ]4 F3 W - uint8_t RxBuffer1[], rec_f, tx_flag, i;( P0 v$ r. q- S/ q
4 \7 ?$ q% `, k9 t/ Q( s- __IO uint8_t TxCounter1 = 0x00;8 Q1 m8 ?: i4 F" `3 T3 a5 [
- __IO uint8_t RxCounter1 = 0x00;0 Y: H$ I c$ a2 A, r3 e1 A; f
4 ]& z; J- ~9 R9 K# s6 r; e- uint32_t Rec_Len;
复制代码
# M$ O! q; t7 A0 s! d串口中断函数配置如下所示: - //--------------------------------------------------------------------------------------
, ^; f8 L3 y! l+ h, }" w/ u" i; L - void USART_SendChar(USART_TypeDef* USARTx,uint8_t data)
% r2 H1 o( @3 I( s4 D1 X- I/ e - {
$ w, J. Q. d1 n; q7 } - USART_SendData(USARTx,data);
+ i! ~/ X2 b7 h1 @8 g - while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
/ P- V% M8 }/ s* q6 i0 T: I - }
& ^4 { S+ ~5 e- Q/ b) A9 ^ - //--------------------------------------------------------------------------------------
: S/ N5 @7 L3 \# V1 Q - void USART_Config(USART_TypeDef* USARTx) 3 r: P/ `9 ^2 O: k
- {5 q' l! _" b" ?- @3 z7 }$ s: z- J
- USART_InitStructure.USART_BaudRate = 19200; //速率19200bps, r; R$ b' |7 g) O- l: E* d! C/ x
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
+ i8 Z" |5 Y% H0 Q2 J( W- _ - USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位
7 S3 j% r- S' y& h( P$ ~ - USART_InitStructure.USART_Parity = USART_Parity_No; //无校验位/ P' f) n e6 s3 b% I- o& K
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
; M3 F4 N+ \! B* e# j* o( B% t4 T; M4 w - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式$ s& g" q) o4 m; c5 J
- - E5 [$ \* m+ j" [. v! Q' }
- /* Configure USARTx */
5 X, t6 c( s9 u5 ?0 e" l - USART_Init(USARTx, &USART_InitStructure); //配置串口参数函数
1 r5 ^7 n( }" f! Z
# Q( z' l* j, C2 n1 U6 N6 N2 o- 7 T4 y& ?6 o% C. h9 J" D
- /* Enable USARTx Receive and Transmit interrupts */
' |( g% c; p- B3 L/ Q; q, q - USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); //使能接收中断
4 M, B& s: H& X$ o3 K1 x; M - USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); //使能发送缓冲空中断
; R9 {+ k0 O5 _- D* i - # ?+ I* ?1 T+ k9 L" D
- /* Enable the USARTx */' f) P* J$ U- x) O1 i, _( C1 Z
- USART_Cmd(USARTx, ENABLE);
$ s' D! z+ A8 v# F1 K - }
/ X' ^9 g7 E5 @) t - //--------------------------------------------------------------------------------------9 q5 \9 k% I; R$ {* o
- void Delay(__IO uint32_t nCount)
- u: H9 v- W% l1 t0 o: p' z( D" S% N - {9 E" Y' w$ z( q8 P( K) K
- for(; nCount!=0; nCount--);' ]' B9 M7 J% R
- }& t9 X$ h6 I. v5 T
- /*--------------------------------------------------------------------------------------
Y8 e! [+ b# E+ d7 f+ Z! }+ | - 系统时钟配置为72MHZ+外设时钟配置*/5 D: q. j+ o3 a! b/ y/ E% p3 m
- void RCC_Configuration(void)
4 u. L9 j& s2 W7 j: G* |' I - {
& e: b! }& w' C% r+ S - SystemInit();5 w6 x3 q. }* H' `' z$ J3 A* p
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOA, ENABLE);2 e, ?2 O4 ?! \
- }7 A$ ]2 A$ L. G6 ]; M. G/ b
- //--------------------------------------------------------------------------------------6 `. B, i2 L6 t& v
- void GPIO_Configuration(void) / B4 Y0 ^* j! m
- {" K) s/ @* K; S+ w* H9 m+ ~1 L/ \: [
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1控制--PD28 N4 [5 [; O! l, o7 h+ F
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出% @. D( U/ t+ {( G& }5 r
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;) [8 [8 R$ U2 D
- GPIO_Init(GPIOD, &GPIO_InitStructure);
" l9 w+ Z) y: i# s- m* S - ( b3 ?5 z" p% t0 T4 u1 J
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX0 g% x* s, w& K! b
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出3 n, \ {/ C- U9 J: i/ J" b; p9 H' ^
- GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口2 K/ t P3 Z8 l
: B# w Y5 f4 `8 z- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX
' f5 {. o7 k; t - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用开漏输入
& N" w3 ~' E& l6 e9 E1 G( N - GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口
5 B4 ^0 J, `4 k0 p - }5 [+ y `! D2 c! H# O
- //--------------------------------------------------------------------------------------
0 Y% o: c0 L! E* d( U; J - void NVIC_Configuration(void) 9 C' l: j- r6 \9 z' |! r: y
- {
_9 M; m& r3 u8 j. g - /* 结构声明*/) }$ i+ h$ ]8 O2 H: {% ]6 S
- NVIC_InitTypeDef NVIC_InitStructure;
, E# k9 H; z; w H
1 g6 R h; W3 }- ] r+ w, G D- /* Configure the NVIC Preemption Priority Bits */
7 Y* L7 ^4 w8 @4 C - /* Configure one bit for preemption priority */, r% u' G5 b. k2 P
- /* 优先级组 说明了抢占优先级所用的位数,和子优先级所用的位数 在这里是1, 7 */
0 X9 g7 j+ s; w* `1 ?3 h, x0 B( S - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);8 K" A7 ^# j2 w% \; `, w, X
- 3 F+ d8 e9 F, e+ y
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //设置串口1中断
1 a( k% O+ I1 d' W - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0
: b5 B; x6 A3 j' I - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级为03 w3 `; B1 p- r [, i* k
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
f* R, S8 J8 j0 n2 N" a6 x' _3 ], ~ - NVIC_Init(&NVIC_InitStructure);4 V; d6 F' S# x" S' l' a' O6 a$ U
- }
复制代码
+ A& m. q/ v2 X/ d# X# F& \在中断服务函数中编写usart函数。 - //串口1 中断服务程序3 o. n& Y6 v* L$ n) N
- void USART1_IRQHandler(void) 2 Y0 P+ V. x0 Z& R& a: V3 q
- {$ Q: x" w' p6 _% U& l2 p
- unsigned int i;" Y4 ~9 Z* e# c
- 0 F5 V! Q1 c7 P' C$ V
- //判断读寄存器是否非空
0 e# ^' G5 G3 E, P5 F0 W4 z3 c Q - if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
# w: j A* Y" g. U1 Q" l - {5 b5 U6 l8 b2 r' I5 ~0 B( l/ H
- //将读寄存器的数据缓存到接收缓冲区里* V7 Y) q0 S" o, Z* P. `
- RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1); ! h9 M1 b0 ~( w$ R& S4 y
; s' E' i5 p- H" i- //判断结束标志是否是0x0d 0x0a
; Z0 k) p4 \6 Y% W% K - if(RxBuffer1[RxCounter1-2] == 0x0d && RxBuffer1[RxCounter1-1] == 0x0a) / _0 ^& J/ f9 f$ Q4 e+ {4 O
- {) \) i4 Z' k$ `& e
- for(i=0; i< RxCounter1; i++)
2 I6 v- ^2 E, ? C, s6 q - TxBuffer1[i] = RxBuffer1[i]; //将接收缓冲器的数据转到发送缓冲区,准备转发3 t# _3 G, j" k7 w: ]; p
- & H o# {- b& Z( e2 k* S" c; y
- //接收成功标志" t, s' S9 S/ x8 O
- rec_f = 1;
: A0 Y6 p' G& ?0 Z, D# x( } h - 5 j2 l \3 W6 e9 \
- //发送缓冲区结束符4 O: C/ {" T# B
- TxBuffer1[RxCounter1] = 0; & Z1 H3 X8 J3 s
- TxCounter1 = RxCounter1;
3 j# j [; y4 Z; D9 r - RxCounter1 = 0;
+ J: f% `" B3 Y: Y' F0 f2 K - }
. o* v2 C' L e - }. Y4 I% K* w; m5 d
- 9 O# o! N8 T- J% G9 t: k
- //这段是为了避免STM32 USART 第一个字节发不出去的BUG
6 d3 z5 P+ k/ ? n6 m2 T; R - if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
, j$ u: ^' h& m* H - {$ q2 @6 I4 F) y, a4 t+ |& P/ D+ ~
- //禁止发缓冲器空中断,
9 o. D+ z5 S4 [) h- D - USART_ITConfig(USART1, USART_IT_TXE, DISABLE); # E8 D3 L3 U+ d6 ~/ V `; F
- }: A/ E& b! X8 W! ?. |
. W% G. Q6 N3 r7 m8 {3 W- }
复制代码 * C, n, ]- m. I& U
/ D8 p5 C. t$ G7 v" \运行结果如下,在发送去不填写任何字符,直接发送,显示RT Interrupt Example: This is USART1 DEMO,说明前三个字符已经被占用替换了。 8 y0 E; y! S1 ~4 A* {( @$ X
z, E( s N# P8 U7 c) l5 H% ` |