- int main(void) ) ?% ^/ Z$ @2 x* a2 [
- {# v Q) a; C' e$ Y% T: f
- uint8_t a=0;//LED高低电压控制
x' b( O1 I4 c0 M- `2 \: O3 N3 ^( h
! C6 p! ~( _# M, W( W+ @' D- /* System Clocks Configuration */
0 q4 F/ ~1 _4 S8 Q& I; T n( }% ^ - RCC_Configuration(); //系统时钟设置
+ x2 g& W8 ~: U* ^% n) X% U - /*嵌套向量中断控制器- n& w) h# x/ c3 G/ [
- 说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */! c( a$ d6 k! w7 h7 N7 k, L
- NVIC_Configuration(); //中断源配置
4 z- I% w( w: ~* a6 _ - /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,RX。
" U- W. x( c3 z) B3 T! C* q - 在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B, 因此要对这个端口的时钟
4 I; x) i5 E& P! w9 h+ _: W - 进行使能,同时由于用到复用IO口功能用于配置串口。因此还要使能AFIO(复用功能IO)时钟。*/* a$ o/ p0 N/ P) y
- GPIO_Configuration(); //端口初始化! O, s% J$ U5 L3 J6 e5 F6 F. m6 a
- USART_Config(USART1); //串口1初始化0 Z0 {# |. h, ]& D$ B6 O. M2 v
9 T8 s7 I5 y" j; w- ]- while (1)
& B: Y4 Y! M7 p7 } - {
6 B% X+ Z) P* c2 i- l6 \5 s - if(rec_f == 1)
" K( D, r3 l+ _& k* o - { $ U# Q2 ]" B: ?: [$ l' Q
- //判断是否收到一帧有效数据 " Q8 B m! L- E2 x! D$ z
- rec_f = 0;
# y! f! u; @4 v, R8 ^& Z H- S - 0 k7 y4 T4 Q: V, L1 x
- for(i=0; i<sizeof(TxBuffer1); i++) //发送字符串
% R& a( P. j h4 }8 F5 D: c - {+ o3 p# ]4 S( Q$ Y3 j. c4 z
- USART_SendChar(USART1,TxBuffer1[i]);* X$ n+ n) ^2 u* m" o$ Z- F2 ^
- Delay(0x0000ff0);7 X) _" Z( w! P% s9 p
- }
7 N- w0 b2 w! X6 e5 R - /*for(i=0;i<TxCounter1;i++)//发送字符串
7 b( C" w3 l1 i/ ^ - {; t5 @- F: y0 o; Q/ X
- USART_SendChar(USART1,RxBuffer1[i]);* a! x) H* K5 U. T6 m
- } */
: q i# Q8 E/ p1 Y# c2 V - if(a==0)
5 y9 r# [9 F$ z1 y# h - {
$ R1 A" e2 J( b( j7 j: G0 { - GPIO_SetBits(GPIOD, GPIO_Pin_2); //LED1 明暗闪烁5 I( j$ g+ V& w) V
- a=1;+ U$ d8 t9 p0 m1 V& ?0 Z/ n; y- T
- }
; s! d$ L& L- D - else 5 ~9 \8 o/ I5 z4 [. ^+ E& j
- {
3 W/ n+ p+ f' o/ I( m$ d* A( w$ Z - GPIO_ResetBits(GPIOD, GPIO_Pin_2);# p9 G) w% B* T
- a=0;
n1 w/ D3 ]/ f5 |5 e - }
4 M7 \5 ^8 T/ U! \ - }
) X5 b1 {" R0 }& T6 o/ g - }
$ ^- a0 z- R' h+ {8 u - }
复制代码main函数如上。 相关变量 - uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO";
, R0 b! o6 X7 o, n& y - uint8_t RxBuffer1[], rec_f, tx_flag, i;
+ j$ ]& @% W. | p5 A, `# b - & v7 X' E G2 B0 J% N
- __IO uint8_t TxCounter1 = 0x00;( f& |/ t6 P2 z/ D
- __IO uint8_t RxCounter1 = 0x00;! t2 m) C7 m3 c. g6 `$ Y% [2 B
- 0 {5 S2 K& q3 s5 x4 ~3 ?$ x
- uint32_t Rec_Len;
复制代码
d# z0 a. f/ d! j串口中断函数配置如下所示: - //--------------------------------------------------------------------------------------2 h6 e# f7 a& C" Q; i: v
- void USART_SendChar(USART_TypeDef* USARTx,uint8_t data)
: ] y3 L: H; O - {6 D$ s7 G/ C3 G# g8 l
- USART_SendData(USARTx,data);. B: a5 w- q+ i @- j* ^6 F: j
- while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
- U9 [% G& L8 \- W n - }' Z; V+ k: S3 f1 o" q
- //--------------------------------------------------------------------------------------" O8 \1 w- j2 p+ ?1 p% ^: ~
- void USART_Config(USART_TypeDef* USARTx)
* m7 }- s% z7 }& G) V) |9 V! b8 G - {
s# t4 z0 l; x0 {" o - USART_InitStructure.USART_BaudRate = 19200; //速率19200bps1 {1 N- \5 u+ T, ?& N; @5 L) R
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
/ e8 V T' h. R8 J( d5 i - USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位+ n8 f: h6 r5 G' w3 M5 z
- USART_InitStructure.USART_Parity = USART_Parity_No; //无校验位
+ W+ B) q' o3 U+ T1 ] - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
6 @& I3 K% |2 p }# m - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式" Z) g2 D- ?& Y( Y" s
" Q" G+ X2 p' l6 r0 r2 @- /* Configure USARTx */) l, W/ _5 m% ?8 f& P8 y
- USART_Init(USARTx, &USART_InitStructure); //配置串口参数函数7 h) x% ~7 u+ P+ i3 s0 U
- 2 \) f% d8 g( O
- d* P7 y& D, k: S
- /* Enable USARTx Receive and Transmit interrupts */# e! k+ Q0 _5 O% `+ o% {
- USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); //使能接收中断
- J0 [; W3 z) S1 k - USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); //使能发送缓冲空中断( b/ P" c$ {' Y" y4 ?
7 p5 a0 ]( R; Q5 E- /* Enable the USARTx */& E! D, C* O# [+ y
- USART_Cmd(USARTx, ENABLE);
5 k& f! D( n" y$ h8 u2 e7 P( Z - }- e: Z6 v4 B0 O' l7 {
- //--------------------------------------------------------------------------------------% h. M: e: U& I6 S+ M; M! F
- void Delay(__IO uint32_t nCount)
* d4 i: k. j4 J$ ]: M5 s- k% M7 E5 J - {" L4 W: F' \& C- a4 L1 a
- for(; nCount!=0; nCount--);7 J7 t6 t6 n" t. c7 g0 i) }* a
- }
, \/ s3 O0 ?. U. W1 k4 @; O, z - /*--------------------------------------------------------------------------------------7 M. D l6 m3 c) d1 ^9 W" L
- 系统时钟配置为72MHZ+外设时钟配置*/$ ^( a$ @( P7 ]9 ]
- void RCC_Configuration(void)
. g! W+ s4 B) Q4 |* R1 z - {
$ N4 M' x. V' D. w& A; z7 E - SystemInit();5 d5 C- t& x- g6 l
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOA, ENABLE);
# w* j( ]" E5 X+ \3 M - }2 G" Z1 p, k( _: {) v% L2 _
- //--------------------------------------------------------------------------------------
4 }2 {. c3 f" |% g, ^* M - void GPIO_Configuration(void)
( l8 u2 A9 E# H* o0 K- w - {
' F9 ~8 y! b$ X7 A) S* F - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1控制--PD27 d# ?) B( }5 [6 k
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出) Z8 G0 ?9 s4 w: L
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
" [/ u- V$ @) y7 O0 `, E0 ~+ h - GPIO_Init(GPIOD, &GPIO_InitStructure);
9 l1 m( t- F$ \. J# ^) B) b2 v
/ m" ]9 V0 W& C# V% E9 S. F- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX
- ^# ` j e: S% W; v& J - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
" p; W! G# m* ` - GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口
5 E2 N& f( Y6 z0 V( H7 p
. ^/ v& ?) Q5 l$ o' d- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX. m' Y& e" ~6 a7 K- y d( g# h
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用开漏输入
& Q' s! L3 K3 g3 ?& o - GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口" W! S" u& j2 A- S. o, D: i
- }( L: `( B- N% ]+ d4 Z/ {
- //--------------------------------------------------------------------------------------
# Y: q% {. z' p, }5 e8 z3 r0 L9 H - void NVIC_Configuration(void)
" T# L) p# W" S$ o. j3 z! S" o - {
5 U% k0 a: N3 O% X" W+ j6 m - /* 结构声明*/
/ @, @) J+ r, E, R' w% ~9 T - NVIC_InitTypeDef NVIC_InitStructure;
0 U( }& C: D7 F7 I - 1 F& t, f" X4 n/ A" N
- /* Configure the NVIC Preemption Priority Bits */
& V o+ G, ~! | - /* Configure one bit for preemption priority */
' |' d; J6 H6 O' M - /* 优先级组 说明了抢占优先级所用的位数,和子优先级所用的位数 在这里是1, 7 */( u& W% r' X9 G
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);+ {# ]9 U3 A: r) h, @* _
9 n$ ]6 { |. T& g$ N9 n- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //设置串口1中断6 x* o' d( [/ p5 }; e) x0 E4 X$ q
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0
5 J# X; g/ y( r a - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级为0
\& o, q2 C' f - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
" n+ H. v- B C1 r9 L0 r& f - NVIC_Init(&NVIC_InitStructure);; r( u8 Q- ?6 m
- }
复制代码 ) S2 J8 }; U3 S' M( b
在中断服务函数中编写usart函数。 - //串口1 中断服务程序: ^6 h2 h8 P! {. F
- void USART1_IRQHandler(void) 0 x _4 C) U$ P5 J) p" k: n
- {
5 E1 H* p' B. Z+ F: `& m3 L8 ~ - unsigned int i;1 g0 Y4 u; {& B! [1 n; v
- 3 c) k" o! u6 y7 [
- //判断读寄存器是否非空. _3 G( S8 P g1 D9 a
- if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 3 W) C- S% F6 W9 L, H3 F
- {( T5 Q; D0 S: J4 d+ [
- //将读寄存器的数据缓存到接收缓冲区里
. X" Q% ^. V( @% f% B - RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1); 6 A2 R7 Q' ` V0 w
6 e" Y1 H9 `! A+ ~' c3 G, d6 c- //判断结束标志是否是0x0d 0x0a
7 Y: f! P5 ^) J' K5 v - if(RxBuffer1[RxCounter1-2] == 0x0d && RxBuffer1[RxCounter1-1] == 0x0a) 8 N( j& \: A- e) _0 {" A
- {2 h$ C& W7 n& s% i' w. d8 u
- for(i=0; i< RxCounter1; i++)
7 K0 K. ]( U- ]5 C/ n$ J - TxBuffer1[i] = RxBuffer1[i]; //将接收缓冲器的数据转到发送缓冲区,准备转发& {9 j7 t* c$ e: |
-
! m. r1 G: x9 {9 o - //接收成功标志$ t' _/ e- u; h; X/ F, @8 I$ `+ i3 q
- rec_f = 1;
) u. v( L$ ^3 [- ~: i -
; K, T" x, L n. ^% O, ?! a' R - //发送缓冲区结束符/ Q% s- [2 o/ K( P! g7 q7 n7 h: n& z
- TxBuffer1[RxCounter1] = 0;
: `0 b7 f% f; H1 c; g0 O% Y' h* @+ H+ j - TxCounter1 = RxCounter1;
5 D* B* U- V# Y& i - RxCounter1 = 0;
$ S [/ |0 P" b! g1 W, `0 X% P# w - }5 R0 G( z. X( H& B# E* R
- }
% w6 q2 T1 A7 }" L0 D - 2 C0 R) Y2 w: P9 L
- //这段是为了避免STM32 USART 第一个字节发不出去的BUG3 F8 K8 [6 ~6 {- A
- if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) ; E; m' O4 @" T4 F% `
- {1 d, C. R' Q0 I. _2 x6 [; S
- //禁止发缓冲器空中断,7 ?: S: u o6 M# {# _
- USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
7 n4 ~4 G- n7 ~+ I! D! |6 G - }
. G l- U% D' x# W* A - 2 d8 }* R# |5 z* |2 a, a! i6 d' ]
- }
复制代码 & q, R R4 T1 D8 R6 d
, x% d! c8 l) n运行结果如下,在发送去不填写任何字符,直接发送,显示RT Interrupt Example: This is USART1 DEMO,说明前三个字符已经被占用替换了。 " x X, g9 p! _! P. k5 z9 I
& Q! E' q1 v R |