1. Method 1
///Redirect c library function printf to USART1 int fputc(int ch, FILE *f) { /* Send a byte of data to USART1 */ USART_SendData(USART1, (uint8_t) ch); /* Waiting to send */ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch); } ///Redirect c library function scanf to USART1 int fgetc(FILE *f) { /* Wait for serial port 1 to input data */ while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(USART1); }
2. Method 2 (only printf)
//Need to add this header file #include "stdarg.h" static char * itoa ( int value, char * string, int radix ); /* * Function name: usart2? Printf * Description: format output, similar to printf in C library, but C library is not used here * Input: - USARTx serial port channel, only serial port 2 is used here, i.e. USART2 * -Data Pointer to the content to be sent to the serial port * -... Other parameters * Output: None * Return: None * Calls: external calls * Typical application usart2 ﹣ printf (usart2, "\ R \ n this is a demo \ R \ n"); * USART2_printf( USART2, "\r\n %d \r\n", i ); * USART2_printf( USART2, "\r\n %s \r\n", j ); // */ void USART2_printf ( USART_TypeDef * USARTx, char * Data, ... ) { const char *s; int d; char buf[16]; va_list ap; va_start(ap, Data); while ( * Data != 0 ) // Determine whether the string terminator is reached { if ( * Data == 0x5c ) //'\' { switch ( *++Data ) { case 'r': //Carriage return character USART_SendData(USARTx, 0x0d); Data ++; break; case 'n': //Newline character USART_SendData(USARTx, 0x0a); Data ++; break; default: Data ++; break; } } else if ( * Data == '%') { // switch ( *++Data ) { case 's': //Character string s = va_arg(ap, const char *); for ( ; *s; s++) { USART_SendData(USARTx,*s); while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); } Data++; break; case 'd': //Decimal system d = va_arg(ap, int); itoa(d, buf, 10); for (s = buf; *s; s++) { USART_SendData(USARTx,*s); while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); } Data++; break; default: Data++; break; } } else USART_SendData(USARTx, *Data++); while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET ); } } /* * Function name: itoa * Description: converts the shape data to a string * Input: - radix =10 for decimal, other results are 0 * -value Number of integers to convert * -buf Converted String * -radix = 10 * Output: None * Return: None * Call: called by usart2 ﹐ printf() */ static char * itoa( int value, char *string, int radix ) { int i, d; int flag = 0; char *ptr = string; /* This implementation only works for decimal numbers. */ if (radix != 10) { *ptr = 0; return string; } if (!value) { *ptr++ = 0x30; *ptr = 0; return string; } /* if this is a negative value insert the minus sign. */ if (value < 0) { *ptr++ = '-'; /* Make the value positive. */ value *= -1; } for (i = 10000; i > 0; i /= 10) { d = value / i; if (d || flag) { *ptr++ = (char)(d + 0x30); value -= (d * i); flag = 1; } } /* Null terminate the string. */ *ptr = 0; return string; } /* NCL_Itoa */
3. method three
#if 1 #pragma import(__use_no_semihosting_swi) /*The support function required by the standard library, use? No? Semihosting? SWI to avoid the use of semi host mode*/ struct __FILE { int handle; }; FILE __stdout; FILE __stdin; /*Redirect Printf function*/ int fputc(int ch,FILE *f) { return(SendChar(ch)); } /*Redirect Scanf functions*/ int fgetc(FILE*f) { return(SendChar(GetKey())); /*When calling scanf() to input data in the serial port, it must end with a space, otherwise the sending cannot be completed*/ } void _ttywrch(int ch) { SendChar(ch); } int _ferror(FILE*f) { /*Yourimplementationofferror*/ return EOF; } #endif int SendChar(int ch) { while(!(USART1->SR&USART_FLAG_TXE)); USART1->DR=(ch&0x1FF); return ch; } int GetKey(void) { while(!(USART1->SR&USART_FLAG_RXNE)); return((int)(USART1->DR&0X1FF)); }
!! Note that when using the scanf() function for input, please do not interrupt USATR, otherwise it will not be received. The printf() function has no restrictions.
The red box in the figure below doesn't appear. I just open the interrupt. Although I haven't written the interrupt function, I can't receive it by using scanf() function. It's easy to use without writing the interrupt. I don't know why or whether it's an example.