Common.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include "common.h"
  2. #include "stm32f1xx_hal.h"
  3. #include <stdarg.h>
  4. static char * itoa ( int value, char * string, int radix );
  5. /*
  6. * 函数名:USART2_printf
  7. * 描述 :格式化输出,类似于C库中的printf,但这里没有用到C库
  8. * 输入 :-USARTx 串口通道,这里只用到了串口2,即USART2
  9. * -Data 要发送到串口的内容的指针
  10. * -... 其他参数
  11. * 输出 :无
  12. * 返回 :无
  13. * 调用 :外部调用
  14. * 典型应用USART2_printf( USART2, "\r\n this is a demo \r\n" );
  15. * USART2_printf( USART2, "\r\n %d \r\n", i );
  16. * USART2_printf( USART2, "\r\n %s \r\n", j );
  17. */
  18. void USART_printf ( USART_TypeDef * USARTx, char * Data, ... )
  19. {
  20. const char *s;
  21. int d;
  22. char buf[16];
  23. va_list ap;
  24. va_start(ap, Data);
  25. while ( * Data != 0 ) // 判断是否到达字符串结束符
  26. {
  27. if ( * Data == 0x5c ) //'\'
  28. {
  29. switch ( *++Data )
  30. {
  31. case 'r': //回车符
  32. USART_SendData(USARTx, 0x0d);
  33. Data ++;
  34. break;
  35. case 'n': //换行符
  36. USART_SendData(USARTx, 0x0a);
  37. Data ++;
  38. break;
  39. default:
  40. Data ++;
  41. break;
  42. }
  43. }
  44. else if ( * Data == '%')
  45. { //
  46. switch ( *++Data )
  47. {
  48. case 's': //字符串
  49. s = va_arg(ap, const char *);
  50. for ( ; *s; s++)
  51. {
  52. USART_SendData(USARTx,*s);
  53. while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
  54. }
  55. Data++;
  56. break;
  57. case 'd':
  58. //十进制
  59. d = va_arg(ap, int);
  60. itoa(d, buf, 10);
  61. for (s = buf; *s; s++)
  62. {
  63. USART_SendData(USARTx,*s);
  64. while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
  65. }
  66. Data++;
  67. break;
  68. default:
  69. Data++;
  70. break;
  71. }
  72. }
  73. else USART_SendData(USARTx, *Data++);
  74. while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );
  75. }
  76. }
  77. /*
  78. * 函数名:itoa
  79. * 描述 :将整形数据转换成字符串
  80. * 输入 :-radix =10 表示10进制,其他结果为0
  81. * -value 要转换的整形数
  82. * -buf 转换后的字符串
  83. * -radix = 10
  84. * 输出 :无
  85. * 返回 :无
  86. * 调用 :被USART2_printf()调用
  87. */
  88. static char * itoa( int value, char *string, int radix )
  89. {
  90. int i, d;
  91. int flag = 0;
  92. char *ptr = string;
  93. /* This implementation only works for decimal numbers. */
  94. if (radix != 10)
  95. {
  96. *ptr = 0;
  97. return string;
  98. }
  99. if (!value)
  100. {
  101. *ptr++ = 0x30;
  102. *ptr = 0;
  103. return string;
  104. }
  105. /* if this is a negative value insert the minus sign. */
  106. if (value < 0)
  107. {
  108. *ptr++ = '-';
  109. /* Make the value positive. */
  110. value *= -1;
  111. }
  112. for (i = 10000; i > 0; i /= 10)
  113. {
  114. d = value / i;
  115. if (d || flag)
  116. {
  117. *ptr++ = (char)(d + 0x30);
  118. value -= (d * i);
  119. flag = 1;
  120. }
  121. }
  122. /* Null terminate the string. */
  123. *ptr = 0;
  124. return string;
  125. } /* NCL_Itoa */