变参函数是C语言中经常用到的一类函数,例如常见的printf、scanf等都是变参函数
C库中有一个stdarg.h文件,其中包含有各个编译器的va_start、va_arg等函数,可以实现对变参的解析。
#defineva_start(v,l) __builtin_va_start(v,l)#defineva_end(v) __builtin_va_end(v)#defineva_arg(v,l) __builtin_va_arg(v,l)#if!defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L || __cplusplus + 0 >= 201103L#defineva_copy(d,s) __builtin_va_copy(d,s)
在MC3172的例程中有串口输出的函数
voidGPCOM_UART_EXAMPLE(u32 gpcom_sel){ INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV4)); GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_RXD_IS_P2)); GPCOM_SET_OUT_PORT(gpcom_sel,( \ GPCOM_P0_OUTPUT_DISABLE|GPCOM_P3_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE| \ GPCOM_P0_IS_HIGH |GPCOM_P3_IS_TXD |GPCOM_P2_IS_HIGH |GPCOM_P1_IS_HIGH \ )); GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_UART_MODE); GPCOM_SET_COM_SPEED(gpcom_sel,12000000,115200); GPCOM_SET_OVERRIDE_GPIO(gpcom_sel, ( \ GPCOM_P2_OVERRIDE_GPIO|GPCOM_P2_INPUT_ENABLE | \ GPCOM_P3_OVERRIDE_GPIO \ ));#ifdef TEST_ONLY_UART_TXwhile(1){while(GPCOM_TX_FIFO_FULL(gpcom_sel));for(u32var=0;var<90; ++var) { NOP(); } GPCOM_PUSH_TX_DATA(gpcom_sel,0x31); }#elseu8 rx_data_rp=0; u8 rx_data=0; rx_data_rp=GPCOM_GET_RX_WP(gpcom_sel);while(1) {if(rx_data_rp!=(GPCOM_GET_RX_WP(gpcom_sel))){ rx_data=GPCOM_GET_RX_DATA(gpcom_sel,rx_data_rp); GPCOM_PUSH_TX_DATA(gpcom_sel,rx_data); rx_data_rp++; rx_data_rp&=0x0f; } }#endif}
把配置GCOM0的代码复制到main文件的thread1中
voidthread1_main(void){//usercode sectionu32gpcom_sel = GPCOM0_BASE_ADDR;INTDEV_SET_CLK_RST(gpcom_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK_DIV4));GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_RXD_IS_P2));GPCOM_SET_OUT_PORT(gpcom_sel,(\ GPCOM_P0_OUTPUT_DISABLE|GPCOM_P3_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE| \ GPCOM_P0_IS_HIGH |GPCOM_P3_IS_TXD |GPCOM_P2_IS_HIGH |GPCOM_P1_IS_HIGH \ ));GPCOM_SET_COM_MODE(gpcom_sel,GPCOM_UART_MODE);GPCOM_SET_COM_SPEED(gpcom_sel,12000000,115200);GPCOM_SET_OVERRIDE_GPIO(gpcom_sel,( \ GPCOM_P2_OVERRIDE_GPIO|GPCOM_P2_INPUT_ENABLE | \ GPCOM_P3_OVERRIDE_GPIO \ ));while(1){}thread_end();}
发送一个字节的函数如下
voidputch(u8 ch){while(GPCOM_TX_FIFO_FULL(GPCOM0_BASE_ADDR)); GPCOM_PUSH_TX_DATA(GPCOM0_BASE_ADDR, ch); }
在此之上,编写printf函数对%d、%x、%s、%c、%o的解析和输出
voidputch(u8 ch){while(GPCOM_TX_FIFO_FULL(GPCOM0_BASE_ADDR)); GPCOM_PUSH_TX_DATA(GPCOM0_BASE_ADDR, ch); }voidputstr(u8 *str){while(*str !='\0') { putch(*str); str++; } }charnum_to_char(intnum){if(num>=0&& num<=9)return(char)('0'+num-0);elsereturn(char)('A'+num-10);}voidputnum(i32 num, i32 carry){ u8 i, num_arr[10];if(num <0) { putch('-'); num = -num; }for(i =0; i <10; i++) {if(!num)break; num_arr[i] = num % carry; num /= carry; }while(i--) { putch(num_to_char(num_arr[i])); } }voidprintf(constchar*fmt, ...){ va_list ap; va_start(ap, fmt);for(; *fmt !='\0'; fmt++) {if(*fmt !='%') { putch(*fmt);continue; } fmt++;switch(*fmt) {case'd': putnum(va_arg(ap,int),10);break;case'x': putnum(va_arg(ap,int),16);break;case'o': putnum(va_arg(ap,int),8);break;case'c': putch(va_arg(ap,int));break;case's': putstr((u8 *) va_arg(ap,char*));break;default: putch(*fmt);break; } } va_end(ap); }
再写一个毫秒的延时宏
do{ \ unsigned int i=0,j=0; \ for(i=0; i
在thread1函数中调用printf和DELAY_MS函数
while(1) { tick++;printf("tick:%d,hex:%x,oct:%o,char:%c,str:%s\r\n", tick, tick, tick,'A',"hello"); DELAY_MS(500); }
把USB转串口的RX连接到开发板的PA3管脚,使用串口助手查看输出
PS:在MC3172中调用stdio.h的printf函数、定义_write函数到串口输出,但是仍然会报错,如果有知道解决办法的大佬还请不吝赐教。