lib_printf.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /***************************************************************
  2. *Copyright (C), 2017, Shanghai Eastsoft Microelectronics Co., Ltd
  3. *文件名: lib_printf.c
  4. *作 者: Liut
  5. *版 本: V1.00
  6. *日 期: 2017/07/14
  7. *描 述: 串口打印库函数
  8. *备 注: 适用于 ES8P508x芯片
  9. 本软件仅供学习和演示使用,对用户直接引用代码所带来的风险或后果不承担任何法律责任。
  10. ***************************************************************/
  11. #include "lib_printf.h"
  12. #include <stdarg.h>
  13. /***************************************************************
  14. 函数名:fputc
  15. 描 述:重定向c库函数printf到UART
  16. 输入值:。。。
  17. 输出值:。。。
  18. 返回值:。。。
  19. ***************************************************************/
  20. /*使用printf()函数需要调用微库:Use MicroLIB*/
  21. int fputc(int ch, FILE *f)
  22. {
  23. FlagStatus Status = RESET;
  24. uint32_t Count=0;
  25. #if defined __PRINTF_USE_UART3__
  26. UART_SendByte(UART3, (unsigned char) ch);
  27. do
  28. {
  29. Status = UART_GetFlagStatus(UART3,UART_FLAG_TXIDLE);
  30. Count++;
  31. }while((Status == RESET)&&(Count != 0x1CE2));
  32. if(Count == 0x1CE2)
  33. return (EOF);
  34. #elif defined __PRINTF_USE_UART2__
  35. UART_SendByte(UART2, (unsigned char) ch);
  36. do
  37. {
  38. Status = UART_GetFlagStatus(UART2,UART_FLAG_TXIDLE);
  39. Count++;
  40. }while((Status == RESET)&&(Count != 0x1CE2));
  41. if(Count == 0x1CE2)
  42. return (EOF);
  43. #elif defined __PRINTF_USE_UART1__
  44. UART_SendByte(UART1, (unsigned char) ch);
  45. do
  46. {
  47. Status = UART_GetFlagStatus(UART1,UART_FLAG_TXIDLE);
  48. Count++;
  49. }while((Status == RESET)&&(Count != 0x1CE2));
  50. if(Count == 0x1CE2)
  51. return (EOF);
  52. #else
  53. UART_SendByte(UART0, (unsigned char) ch);
  54. do
  55. {
  56. Status = UART_GetFlagStatus(UART0,UART_FLAG_TXIDLE);
  57. Count++;
  58. }while((Status == RESET)&&(Count != 0x1CE2));
  59. if(Count == 0x1CE2)
  60. return (EOF);
  61. #endif
  62. return (ch);
  63. }
  64. #ifdef __clang__ //当使用的是idesigner编译器时,则不调用微库
  65. /***************************************************************
  66. 描 述:将整形数据转换成字符串
  67. 输入值: -radix =10 表示10进制,其他结果为0
  68. * -value 要转换的整形数
  69. * -buf 转换后的字符串
  70. * -radix = 10
  71. 返回值:无
  72. ***************************************************************/
  73. static char *itoa(int value, char *string, int radix)
  74. {
  75. int i, d;
  76. int flag = 0;
  77. char *ptr = string;
  78. /* This implementation only works for decimal numbers. */
  79. if (radix != 10)
  80. {
  81. *ptr = 0;
  82. return string;
  83. }
  84. if (!value)
  85. {
  86. *ptr++ = 0x30;
  87. *ptr = 0;
  88. return string;
  89. }
  90. /* if this is a negative value insert the minus sign. */
  91. if (value < 0)
  92. {
  93. *ptr++ = '-';
  94. /* Make the value positive. */
  95. value *= -1;
  96. }
  97. for (i = 10000; i > 0; i /= 10)
  98. {
  99. d = value / i;
  100. if (d || flag)
  101. {
  102. *ptr++ = (char)(d + 0x30);
  103. value -= (d * i);
  104. flag = 1;
  105. }
  106. }
  107. /* Null terminate the string. */
  108. *ptr = 0;
  109. return string;
  110. }
  111. /***************************************************************
  112. 描 述:格式化输出,类似于C库中的printf,但这里没有用到C库
  113. 输入值: -UARTx 串口通道,
  114. * -Data 要发送到串口的内容的指针
  115. * -... 其他参数
  116. 返回值:无
  117. 典型应用: UART_printf("\r\n this is a demo \r\n" );
  118. * UART1_printf("\r\n %d \r\n", i );
  119. * UART1_printf("\r\n %s \r\n", j );
  120. ***************************************************************/
  121. /* 未调用C库的时候可以使用此函数代替C库中的printf,但功能无printf全,
  122. 只支持\r \n %d %s */
  123. ErrorStatus UART_printf(uint8_t *Data,...)
  124. {
  125. UART_TypeDef *UARTx;
  126. const char *s;
  127. int d;
  128. char buf[16];
  129. ErrorStatus RET = SUCCESS;
  130. FlagStatus Status = RESET;
  131. uint32_t Count=0;
  132. va_list ap;
  133. /**
  134. **
  135. **使用宏定义选择使用哪一个串口
  136. **
  137. ***/
  138. #if defined __PRINTF_USE_UART3__
  139. UARTx = UART3;
  140. #elif defined __PRINTF_USE_UART2__
  141. UARTx = UART2;
  142. #elif defined __PRINTF_USE_UART1__
  143. UARTx = UART1;
  144. #else
  145. UARTx = UART0;
  146. #endif
  147. va_start(ap, Data);
  148. while ( *Data != 0) // 判断是否到达字符串结束符
  149. {
  150. if ( *Data == 0x5c ) //'\'
  151. {
  152. switch ( *++Data )
  153. {
  154. case 'r': //回车符
  155. Count=0;
  156. UART_SendByte(UARTx, 0x0d);
  157. do
  158. {
  159. Status = UART_GetFlagStatus(UARTx,UART_FLAG_TXIDLE);
  160. Count++;
  161. }while((Status == RESET)&&(Count != 0x1CE2));
  162. if(Count == 0x1CE2)
  163. RET = ERROR;
  164. Data ++;
  165. break;
  166. case 'n': //换行符
  167. Count=0;
  168. UART_SendByte(UARTx, 0x0a);
  169. do
  170. {
  171. Status = UART_GetFlagStatus(UARTx,UART_FLAG_TXIDLE);
  172. Count++;
  173. }while((Status == RESET)&&(Count != 0x1CE2));
  174. if(Count == 0x1CE2)
  175. RET = ERROR;
  176. Data ++;
  177. break;
  178. default:
  179. Data ++;
  180. break;
  181. }
  182. }
  183. else if ( *Data == '%')
  184. {
  185. switch ( *++Data )
  186. {
  187. case 's': //字符串
  188. s = va_arg(ap, const char *);
  189. for ( ; *s; s++)
  190. {
  191. Count=0;
  192. UART_SendByte(UARTx,*s);
  193. do
  194. {
  195. Status = UART_GetFlagStatus(UARTx,UART_FLAG_TXIDLE);
  196. Count++;
  197. }while((Status == RESET)&&(Count != 0x1CE2));
  198. if(Count == 0x1CE2)
  199. RET = ERROR;
  200. }
  201. Data++;
  202. break;
  203. case 'd': //十进制
  204. d = va_arg(ap, int);
  205. itoa(d, buf, 10);
  206. for (s = buf; *s; s++)
  207. {
  208. Count=0;
  209. UART_SendByte(UARTx,*s);
  210. do
  211. {
  212. Status = UART_GetFlagStatus(UARTx,UART_FLAG_TXIDLE);
  213. Count++;
  214. }while((Status == RESET)&&(Count != 0x1CE2));
  215. if(Count == 0x1CE2)
  216. RET = ERROR;
  217. }
  218. Data++;
  219. break;
  220. default:
  221. Data++;
  222. break;
  223. }
  224. } /* end of else if */
  225. else
  226. {
  227. Count=0;
  228. UART_SendByte(UARTx, *Data++);
  229. do
  230. {
  231. Status = UART_GetFlagStatus(UARTx,UART_FLAG_TXIDLE);
  232. Count++;
  233. }while((Status == RESET)&&(Count != 0x1CE2));
  234. if(Count == 0x1CE2)
  235. RET = ERROR;
  236. }
  237. }
  238. return RET;
  239. }
  240. #endif
  241. /*************************END OF FILE**********************/