Today, I encountered the implementation of variable parameters, and suddenly I found that I was not so clear. Oh, the study is not rigorous. So this time you must completely understand.
This article has been very clear about the number of variable parameters of the first phase of 9CBS C / C Electronic Magazine, so I will take the code that I saw today.
/ ************************************************** ******************************** @Func void | formatString | Simple formatted output string routine ** @rdesc returns length @RDesc Returns Length of formatted String ** @parm unsigned char * | PBUF | * Pointer to string to return formatted Output. User Must Ensure * That buffer is large enough. ** @parm const unsigned char * | SZ, ... | * Format string: * * @Flag format string | type * @flag u | unsigned * @flag d | int * @flag c | char * @flag s | string * @flag x | 4-bit hex number * @flag b | 8-bit hex number * @flag H | 16-bit hex number * @flag X | 32-bit hex number ** @ comm * Same as OutputFormatString, but output to buffer instead of serial port * / unsigned int FormatString (unsigned char * pBuf,. Const unsigned char * sz, ...) {unsigned char C; VA_LIST VL ; // State a variable VA_Start (VL, SZ) of a VA_LIST (CHAR * or VOID *); // Get the address of the last fixed parameter Szsprintf = Pbuf; // char * szsprintf; a global char * while (* SZ ) {C = * sz ; switch (c) {case '%': c = * sz ; switch (c) {// switch (* SZ) case 'x': // 4-bit hex number PoutputNumHex ( VA_ARG (VL, UNSIGNED Long), 0); Break; Case 'B': // 8-Bit HEX Number PoutputnumHex (VA_ARG (VL, Unsigned Long), 2); Break; Case 'H'
: // 16-Bit HEX Number PoutputNumHex (VA_ARG (VL, Unsigned Long), 4); Break; Case 'x': // 32-Bit HEX Number PoutputNumHex (VA_ARG (VL, UNSIGNED Long), 8); Break; Case 'D': // INT {LONG L; L = VA_ARG (VL, LONG); if (l <0) {PoutputByte ('-'); L = - L;} PoutputNumDecimal ((unsigned long); } Break; Case 'u': // unsigned poutputnumdecimal (VA_ARG (VL, UNSIGNED Long); Break; Case 's': // String OutputString (VA_ARG (VL, Char *)); Break; Case '%': // Directly print the% POUTPUTBYTE ('%'); Break; Case 'C': // CHAR C = VA_ARG (VL, Unsigned Char); PoutputByte (C); Break; default: poutputbyte (''); break;} Break; Case '/ R': if (* SZ == '/ n') SZ ; c = '/ n'; // Fall Through case '/ n ': PoutputByte (' / r '); // Fall Through default: PoutputByte (c);}} PoutputByte (0); c = szsprintf - pbuf; szsprintf = 0; VA_END (VL); // Good habits, VL = NULL to prevent future misoperation RETURN (C);
/ ************************************************** ******************************* @func void | PoutputByte | sends a byte out of the monitor port. ** @rdesc None ** @parm unsigned int | c | * Byte to send. ** / static voidpoutputByte (Szsprintf) * szsprintf = C; else OemWriteBugbyte (C);} / ******* *********************************************************** *********************** @func void | Poutputnumhex | Print The Hex Reperesentation of a Number Through The Monitor Port. ** @rdesc none ** @parm Unsigned long | n | * @parm long | depth | * minimum number of digits to print. ** / static void PoutputnumHex (unsigned long n, long depth) {if (depth) {depth--- } IF ((N & ~ 0xF) || DEPTH) {PoutputNumHex (N >> 4, Depth); N & = 0xF;} if (n <10) {PoutputByte ((unsigned char) (N '0') )));} Else {PoutputByte ((UN) Signed char) (n - 10 'a');}}
/ ************************************************** ****************************** @func void | PoutputNumDecimal | Print The Decimal Representation of a Number Through The Monitor Port. * * @Rdesc none ** @parm unsigned long | n | * The number to print. ** / static void poutputnumDecimal (unsigned long n) {if (n> = 10) {PoutputNumDecimal (N / 10); n% = 10 PoutputByte ((unsigned char) (N '0'));
/ ************************************************** ******************************* @func void | OutputString | sends an unformatted string to the monitor port. ** @rdesc none ** @parm const unsigned char * | s |. * points to the string to be printed ** @ comm * backslash n is converted to backslash r backslash n * / static void OutputString (const unsigned char * s) {while ( * s) {if (* s == '/ n') {OemWriteDebugbyte ('/ r');} OemWriteDebugbyte (* S );}} / ************************ *********************************************************** ************** @func void | OEMWriteDebugString | Display string to the monitor port ** @parm unsigned short * |. str | * Points to the receiving buffer * / void OEMWriteDebugString (unsigned. Short * Str) {// Loop THROUGH TEXT STRING, Sending Characters. // While (Str && * Str) {OemWriteDebugbyte ((unsigned char) * STR );}}
/ ************************************************** ******************************* @func void | OemWriteDebugbyte | Output Byte to the Monitor Port. ** @parm unsigned char * | STR | * Points to the output buffer. * / void iemwritedebugbyte (uchar ch) {Volatile Uart0REG * S2410UART0 = (UART0REG *) UART0_BASE; // Turn register settings
// Wait for transmit buffer to be espty. // while (! (S2410uart0-> rutrstat & 0x2)) {}
S2410UART0-> RUTXH = CH; // "Assignment" on the register}
intOEMReadDebugByte () {unsigned char ch; volatile UART0reg * s2410UART0 = (UART0reg *) UART0_BASE;? (! (s2410UART0-> rUTRSTAT & 0x1)) // Any receive data for us // if {ch = OEM_DEBUG_READ_NODATA; // No data Else {CH = S2410UART0-> RURXH; // read character.} Return (CH);
Keywords: variable parameter function, principle, implementation, UART register operation