你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8S005K6串口重定向到printf

[复制链接]
haifeng-388081 发布时间:2018-4-1 21:51
最近在学习STM8,和大家分享一个将串口重定向到printf的程序,在程序中可以直接使用pfintf打印注释,在不使用串口的情况下可以使用。开发环境是IAR FOR STM8 使用的库函数,代码有点粗糙,大家可以在此基础是进行优化,我只是做个例子。首先使内部高速16M时钟
  1. CLK_HSICmd(ENABLE);
    & T1 V# I" T9 w
  2.     CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
复制代码
# h+ R# U/ N: C4 _" G6 d7 B
串口2初始化
/ ]$ }4 [$ ~! j+ l  h
  1. /*1位起始位 8位数据位 结束位由CR3设置 不使用奇偶校验 不使能奇偶校验中断*/1 o. v3 e9 h% j1 C; m  ?
  2. /*使能发送和接收 接收中断使能 禁止发送中断*/4 ?; P# W' e1 c9 L
  3. /*设置1位停止位 不使能SCLK,波特率115200*/  
    $ J) z# g6 e5 z! G' m. D
  4. void uart2Init(), J& @4 Y7 T0 X: ]
  5. {
    ) _) \7 \2 N  Y- n4 K8 }
  6.     UART2_DeInit();) h  ?4 Y1 }8 e- O4 E7 c
  7.     UART2_Init((uint32_t)115200, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, \
    ' d+ X2 y- C9 i+ _
  8.     UART2_PARITY_NO , UART2_SYNCMODE_CLOCK_DISABLE , UART2_MODE_TXRX_ENABLE);' @+ G. [6 }# m$ P* D) @
  9.     UART2_ITConfig(UART2_IT_RXNE_OR,ENABLE  );! {/ h# o. y# C3 u, R& Q) |
  10.     UART2_Cmd(ENABLE );
    4 l6 A  x& L9 h, t
  11. }
复制代码

. ]  C# j" p7 `# Z& F& x全能中断
3 q- s" N+ Q5 b* M2 q- G$ W# S4 K: @
  1. enableInterrupts();
复制代码
关于串口发送与接收的一些函数- |' X* h$ u* f+ H+ |
  1. //串口发送一个字节
    . E( z" q( G. {* R$ l4 ]6 G
  2. void uart2SendByte(uint8_t data)
    ( ~  C1 D* a1 [0 P1 G  {
  3. {6 ^) a1 x4 K. O/ P2 o$ l; a2 ]( S2 E
  4.     UART2->DR=data;
    ; `1 ^  [+ D& G1 |# ?
  5.    /* Loop until the end of transmission */" F2 }: Y  Y$ m% @/ k
  6.    while (!(UART2->SR & UART2_FLAG_TXE));
    / I& J: N) u5 r  k2 y
  7. }; W$ ]4 ?4 C% [+ a2 T& \5 p2 B/ y
  8. //串口改善字符串
    ! Y5 l1 J8 B3 {1 D- l3 e
  9. void uart2SendString(uint8_t* Data,uint16_t len)9 Q* W! g+ M3 w4 [" L9 {2 E* b. ?! i
  10. {
    # Q- _4 t( l0 P: B/ L3 G$ R
  11.   uint16_t i=0;5 U8 d8 H6 |. E0 ~/ b
  12.   for(;i<len;i++)% e4 V, X2 l$ f8 R) V9 _% c5 q
  13.     uart2SendByte(Data[i]);4 @! W5 d* C9 d  x
  14. }* L! a. A' k8 v& }
  15. //串口接收一个字节9 U$ Y2 n& q6 ]/ n+ P
  16. uint8_t uart2ReceiveByte(void)
    & ~" Q" L) w7 \8 k! v$ t
  17. {
    4 D/ s, f2 t6 k; O; D- M0 W" j
  18.      uint8_t USART2_RX_BUF;
    ) ]3 V' x( T* C1 S! ]" R' M) l# F
  19.      while (!(UART2->SR & UART2_FLAG_RXNE));& D0 q9 `( ~2 t  H- M6 B8 ]
  20.      USART2_RX_BUF=(uint8_t)UART2->DR;4 R& n! A2 o8 R8 `
  21.      return  USART2_RX_BUF;
    * [8 v: p3 D% J5 f$ P) L* n
  22. }
    5 o4 H" l5 l3 P+ G, n+ W  [( ?# D6 k
  23. /*将Printf内容发往串口*/ # K- F* a, A( N
  24. int fputc(int ch, FILE *f)% c( [! ^3 {0 [1 K! Q
  25. {  / z9 B% S. a9 h! s2 s4 f
  26.   UART2->DR=(unsigned char)ch;
    ( D7 |: p3 r1 ]9 s5 h  m$ b2 }
  27.   while (!(UART2->SR & UART2_FLAG_TXE));" B) B4 w: h$ {1 \0 p! p+ W
  28.   return (ch);/ E( m1 C' X. g2 z) M$ K0 X
  29. }
复制代码
UART2接收中断处理函数
4 \2 u9 ~: p. d1 d
  1. INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21), Y" U% f2 ?7 r4 x3 j* F
  2. {8 G! p" M" U# q9 H7 L
  3.     /* In order to detect unexpected events during development,8 t& u, ~. D' U4 m- s8 ?1 J, u6 e
  4.        it is recommended to set a breakpoint on the following instruction.
    ; G& E- S* T  `2 W9 Q8 W/ N
  5.     */
    ! H) C& c! L( K8 }6 c( z
  6.         uint8_t Res;
    " q. l- n/ A6 H
  7.     if(UART2->SR & UART2_FLAG_RXNE)  
    * |  O7 }/ Y) J4 ?
  8.     {/*接收中断(接收到的数据必须是0x0d 0x0a结尾)*/
      L0 Z& J. O' _2 ]& s' Z  S
  9.         Res =(uint8_t)UART2->DR;1 B% ?/ G9 l* J' `
  10.         /*(USART1->DR);读取接收到的数据,当读完数据后自动取消RXNE的中断标志位*/" Z3 w& g( R! [: Z2 O
  11.         if(( UART_RX_NUM&0x80)==0)/*接收未完成*/
    8 A* \3 J1 U) W
  12.         {3 @6 }  `% p: I0 \
  13.             if( UART_RX_NUM&0x40)/*接收到了0x0d*/0 J0 k2 |+ E* Q! F2 X
  14.                 {! l$ `* T5 f; @+ s" c
  15.                   if(Res!=0x0a) UART_RX_NUM=0;/*接收错误,重新开始*/1 S- x( E; m- i+ U3 G" d
  16.                   else  UART_RX_NUM|=0x80;        /*接收完成了 */
    8 [) F. W9 I9 p' Y9 h
  17.                 }  p  V9 i  @( \" c0 E, J: K
  18.             else /*还没收到0X0D*/
    0 W( _9 d! ~1 Q+ n  @
  19.               {        " m/ I0 s2 H6 J) F' n
  20.                 if(Res==0x0d) UART_RX_NUM|=0x40;1 K! N8 l5 |% a4 o. Y
  21.                 else
    " y8 j9 d- d4 V  t6 b
  22.                   {( Z( O% M; _* P( ]1 S8 x9 g
  23.                     RxBuffer[ UART_RX_NUM&0X3F]=Res ;
    " U( ]" T3 u- ]0 M" G) s6 S5 M
  24.                      UART_RX_NUM++;, Z  w2 z$ i4 m% P( ^" Z
  25.                       if( UART_RX_NUM>63) UART_RX_NUM=0;/*接收数据错误,重新开始接收*/  
    % l% L& s! s9 A7 M% ~! `7 L4 u
  26.                   }                 
    ' l* }% U& }, f
  27.               }& s5 Z. R2 X! X0 w) T% b
  28.          }                   1 u7 L* d9 ?5 l! T
  29.       }
      z3 s- P' ?0 ?& b, G* ]& g
  30. }
复制代码
然后包涵相应的头文件,% E+ h, t, k/ Z: l7 D5 t
再将IAR设置一下+ ?: _) z  y+ ]- w% H: F, D" g" k
设置1.png
5 R9 Q/ [0 o: i# B 设置2.png 0 N  I& `7 g( E
这样就可以使用printf函数了4 w8 s% @" |+ f: P  v. }
  1.     while(1)
    % o, A1 l4 {2 v0 y; y6 p. m
  2.     {
    7 N& ?5 l+ D& C$ C9 ?
  3.         /*
    - ?7 |5 Q  v4 Y' L5 p2 \+ Y
  4.         GPIO_WriteLow(GPIOD,GPIO_PIN_2);, e: \( a, c3 b; }' ~
  5.         if(++ii>250)
    * Q5 r7 @/ Y" R% E% f
  6.                 ii=0;, O, E4 t# x( `6 J4 E8 F$ i
  7.         printf("\r\n ii=%3d",ii);6 `4 b+ s! }( @' B- P; K; v5 d; u

  8. # ?/ _: A3 Q3 R* g. Q2 w
  9.         delay(9000);+ s) v% ~1 b* F
  10.         GPIO_WriteReverse(GPIOA,GPIO_PIN_1);: ^6 D/ X, J3 T' A" v/ v
  11.         delay(9000);
    / r$ c' a8 H5 r
  12.         */2 Y! I$ W  d% ~1 l
  13.         if(UART_RX_NUM&0x80)) A& J  Y6 X& z! ?1 w
  14.         {% H. t8 F7 K) z1 F' e
  15.             len=UART_RX_NUM&0x3f;/*得到此次接收到的数据长度*/' p7 Z& Z# W. Z9 q; H  _: A7 [' f
  16.             uart2SendString("You sent the messages is:",sizeof("You sent the messages is"));& O1 ]0 u5 Y+ E, ^7 Y, S
  17.             uart2SendString(RxBuffer,len);/ L8 J3 B$ S, Y( r
  18.             printf("\r\n得到此次接收到的数据长度:%dByte\r\n",len);
    " Q+ M  w% j7 e/ z% {- i0 t# @
  19.             UART_RX_NUM=0;! V# [7 {& v1 e
  20.         }
    ( F, X# i" T+ H8 Q. T
  21.     }
复制代码
另外记得要使用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)
赞 收藏 1 评论4 发布时间:2018-4-1 21:51

举报

4个回答
lisingch 回答时间:2018-4-2 09:39:57
不错,谢谢分享!
zero99 回答时间:2018-4-17 14:48:33
感谢分享,请汇总到4月技术原创
8 ?3 e0 l# r, \( `https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html
jonecolu 回答时间:2018-4-28 17:29:03
不错不错
watershade 回答时间:2018-11-23 19:51:45
建议看一下stm8标准库附带的example。里面的printf代码比较简洁优雅

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版