最近在学习STM8,和大家分享一个将串口重定向到printf的程序,在程序中可以直接使用pfintf打印注释,在不使用串口的情况下可以使用。开发环境是IAR FOR STM8 使用的库函数,代码有点粗糙,大家可以在此基础是进行优化,我只是做个例子。首先使内部高速16M时钟- CLK_HSICmd(ENABLE);
& T1 V# I" T9 w - CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
复制代码 # h+ R# U/ N: C4 _" G6 d7 B
串口2初始化
/ ]$ }4 [$ ~! j+ l h- /*1位起始位 8位数据位 结束位由CR3设置 不使用奇偶校验 不使能奇偶校验中断*/1 o. v3 e9 h% j1 C; m ?
- /*使能发送和接收 接收中断使能 禁止发送中断*/4 ?; P# W' e1 c9 L
- /*设置1位停止位 不使能SCLK,波特率115200*/
$ J) z# g6 e5 z! G' m. D - void uart2Init(), J& @4 Y7 T0 X: ]
- {
) _) \7 \2 N Y- n4 K8 } - UART2_DeInit();) h ?4 Y1 }8 e- O4 E7 c
- UART2_Init((uint32_t)115200, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, \
' d+ X2 y- C9 i+ _ - UART2_PARITY_NO , UART2_SYNCMODE_CLOCK_DISABLE , UART2_MODE_TXRX_ENABLE);' @+ G. [6 }# m$ P* D) @
- UART2_ITConfig(UART2_IT_RXNE_OR,ENABLE );! {/ h# o. y# C3 u, R& Q) |
- UART2_Cmd(ENABLE );
4 l6 A x& L9 h, t - }
复制代码
. ] C# j" p7 `# Z& F& x全能中断
3 q- s" N+ Q5 b* M2 q- G$ W# S4 K: @关于串口发送与接收的一些函数- |' X* h$ u* f+ H+ |
- //串口发送一个字节
. E( z" q( G. {* R$ l4 ]6 G - void uart2SendByte(uint8_t data)
( ~ C1 D* a1 [0 P1 G { - {6 ^) a1 x4 K. O/ P2 o$ l; a2 ]( S2 E
- UART2->DR=data;
; `1 ^ [+ D& G1 |# ? - /* Loop until the end of transmission */" F2 }: Y Y$ m% @/ k
- while (!(UART2->SR & UART2_FLAG_TXE));
/ I& J: N) u5 r k2 y - }; W$ ]4 ?4 C% [+ a2 T& \5 p2 B/ y
- //串口改善字符串
! Y5 l1 J8 B3 {1 D- l3 e - void uart2SendString(uint8_t* Data,uint16_t len)9 Q* W! g+ M3 w4 [" L9 {2 E* b. ?! i
- {
# Q- _4 t( l0 P: B/ L3 G$ R - uint16_t i=0;5 U8 d8 H6 |. E0 ~/ b
- for(;i<len;i++)% e4 V, X2 l$ f8 R) V9 _% c5 q
- uart2SendByte(Data[i]);4 @! W5 d* C9 d x
- }* L! a. A' k8 v& }
- //串口接收一个字节9 U$ Y2 n& q6 ]/ n+ P
- uint8_t uart2ReceiveByte(void)
& ~" Q" L) w7 \8 k! v$ t - {
4 D/ s, f2 t6 k; O; D- M0 W" j - uint8_t USART2_RX_BUF;
) ]3 V' x( T* C1 S! ]" R' M) l# F - while (!(UART2->SR & UART2_FLAG_RXNE));& D0 q9 `( ~2 t H- M6 B8 ]
- USART2_RX_BUF=(uint8_t)UART2->DR;4 R& n! A2 o8 R8 `
- return USART2_RX_BUF;
* [8 v: p3 D% J5 f$ P) L* n - }
5 o4 H" l5 l3 P+ G, n+ W [( ?# D6 k - /*将Printf内容发往串口*/ # K- F* a, A( N
- int fputc(int ch, FILE *f)% c( [! ^3 {0 [1 K! Q
- { / z9 B% S. a9 h! s2 s4 f
- UART2->DR=(unsigned char)ch;
( D7 |: p3 r1 ]9 s5 h m$ b2 } - while (!(UART2->SR & UART2_FLAG_TXE));" B) B4 w: h$ {1 \0 p! p+ W
- return (ch);/ E( m1 C' X. g2 z) M$ K0 X
- }
复制代码 UART2接收中断处理函数
4 \2 u9 ~: p. d1 d- INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21), Y" U% f2 ?7 r4 x3 j* F
- {8 G! p" M" U# q9 H7 L
- /* In order to detect unexpected events during development,8 t& u, ~. D' U4 m- s8 ?1 J, u6 e
- it is recommended to set a breakpoint on the following instruction.
; G& E- S* T `2 W9 Q8 W/ N - */
! H) C& c! L( K8 }6 c( z - uint8_t Res;
" q. l- n/ A6 H - if(UART2->SR & UART2_FLAG_RXNE)
* | O7 }/ Y) J4 ? - {/*接收中断(接收到的数据必须是0x0d 0x0a结尾)*/
L0 Z& J. O' _2 ]& s' Z S - Res =(uint8_t)UART2->DR;1 B% ?/ G9 l* J' `
- /*(USART1->DR);读取接收到的数据,当读完数据后自动取消RXNE的中断标志位*/" Z3 w& g( R! [: Z2 O
- if(( UART_RX_NUM&0x80)==0)/*接收未完成*/
8 A* \3 J1 U) W - {3 @6 } `% p: I0 \
- if( UART_RX_NUM&0x40)/*接收到了0x0d*/0 J0 k2 |+ E* Q! F2 X
- {! l$ `* T5 f; @+ s" c
- if(Res!=0x0a) UART_RX_NUM=0;/*接收错误,重新开始*/1 S- x( E; m- i+ U3 G" d
- else UART_RX_NUM|=0x80; /*接收完成了 */
8 [) F. W9 I9 p' Y9 h - } p V9 i @( \" c0 E, J: K
- else /*还没收到0X0D*/
0 W( _9 d! ~1 Q+ n @ - { " m/ I0 s2 H6 J) F' n
- if(Res==0x0d) UART_RX_NUM|=0x40;1 K! N8 l5 |% a4 o. Y
- else
" y8 j9 d- d4 V t6 b - {( Z( O% M; _* P( ]1 S8 x9 g
- RxBuffer[ UART_RX_NUM&0X3F]=Res ;
" U( ]" T3 u- ]0 M" G) s6 S5 M - UART_RX_NUM++;, Z w2 z$ i4 m% P( ^" Z
- if( UART_RX_NUM>63) UART_RX_NUM=0;/*接收数据错误,重新开始接收*/
% l% L& s! s9 A7 M% ~! `7 L4 u - }
' l* }% U& }, f - }& s5 Z. R2 X! X0 w) T% b
- } 1 u7 L* d9 ?5 l! T
- }
z3 s- P' ?0 ?& b, G* ]& g - }
复制代码 然后包涵相应的头文件,% E+ h, t, k/ Z: l7 D5 t
再将IAR设置一下+ ?: _) z y+ ]- w% H: F, D" g" k
5 R9 Q/ [0 o: i# B
0 N I& `7 g( E
这样就可以使用printf函数了4 w8 s% @" |+ f: P v. }
- while(1)
% o, A1 l4 {2 v0 y; y6 p. m - {
7 N& ?5 l+ D& C$ C9 ? - /*
- ?7 |5 Q v4 Y' L5 p2 \+ Y - GPIO_WriteLow(GPIOD,GPIO_PIN_2);, e: \( a, c3 b; }' ~
- if(++ii>250)
* Q5 r7 @/ Y" R% E% f - ii=0;, O, E4 t# x( `6 J4 E8 F$ i
- printf("\r\n ii=%3d",ii);6 `4 b+ s! }( @' B- P; K; v5 d; u
# ?/ _: A3 Q3 R* g. Q2 w- delay(9000);+ s) v% ~1 b* F
- GPIO_WriteReverse(GPIOA,GPIO_PIN_1);: ^6 D/ X, J3 T' A" v/ v
- delay(9000);
/ r$ c' a8 H5 r - */2 Y! I$ W d% ~1 l
- if(UART_RX_NUM&0x80)) A& J Y6 X& z! ?1 w
- {% H. t8 F7 K) z1 F' e
- len=UART_RX_NUM&0x3f;/*得到此次接收到的数据长度*/' p7 Z& Z# W. Z9 q; H _: A7 [' f
- uart2SendString("You sent the messages is:",sizeof("You sent the messages is"));& O1 ]0 u5 Y+ E, ^7 Y, S
- uart2SendString(RxBuffer,len);/ L8 J3 B$ S, Y( r
- printf("\r\n得到此次接收到的数据长度:%dByte\r\n",len);
" Q+ M w% j7 e/ z% {- i0 t# @ - UART_RX_NUM=0;! V# [7 {& v1 e
- }
( F, X# i" T+ H8 Q. T - }
复制代码 另外记得要使用printf的文件中包含头文件#include "user_uart.h" 要么会出现一些问题,比如:输出的数字不正确。我就在这儿花费了好长时间,1秒钟加1 然后输出,可输出的数字一直是3。后来才发现没有包含头文件。
* w4 D' F. u7 K- O: }; L( Q下面附上工程代码。8 R3 ~& o) H; n4 b! O% w
STM8S005K_printf.zip
(5.11 MB, 下载次数: 76)
|
https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html