LAUNCHXL-F28379D自定义数据格式打印
前言
调试设备时往往需要有一个高效简单的printf函数帮助追踪错误日志、运行状态,DSP开发也不例外
介绍
自带printf如果是按照stm32的方式通过自定义fputc来实现的话,它是可以打印字符串的,但是一旦自定义数值格式输出就报错(Interrupt_illegalOperationHandler)
1 2 3 4 5 6 7 8 9
| #include <stdio.h> #include "driverlib/sci.h"
int fputc(int c, register FILE *stream) { SCI_writeCharBlockingNonFIFO(SCIA_BASE, (uint16_t)c); while(SCI_getTxFIFOStatus(SCIA_BASE) != SCI_FIFO_TX0); return c; }
|
配置SCI
使用sysconfig配置SCIA
串口引脚、参数,SCIA
对应的是板子分配的默认串口:RXD
和TXD
分别对应GPIO43
、GPIO42

自定义printf
自定义打印函数实现,分别实现dsp_putchar、dsp_puts、print_int、print_float、dsp_printf几个函数
dsp_putchar
通过SCI发送单个字符,和标准库putchar
对应
1 2 3 4
| void dsp_putchar(char c) { SCI_writeCharBlockingNonFIFO(SCIA_BASE, (uint16_t)c); while(SCI_getTxFIFOStatus(SCIA_BASE) != SCI_FIFO_TX0); }
|
dsp_puts
通过SCI发送字符串,和标准库puts
对应
1 2 3 4 5
| void dsp_puts(const char *str) { while(*str) { dsp_putchar(*str++); } }
|
print_int
将整数转换为字符并输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| void print_int(int32_t num) { char buffer[12]; // 足够保存32位整数 int i = 0; int is_negative = 0; // 特殊处理0 if(num == 0) { dsp_putchar('0'); return; } // 处理负数 if(num < 0) { is_negative = 1; num = -num; } // 转换整数到字符 while(num > 0) { buffer[i++] = '0' + (num % 10); num /= 10; } // 如果是负数,添加负号 if(is_negative) { dsp_putchar('-'); } // 反向输出字符 while(i > 0) { dsp_putchar(buffer[--i]); } }
|
print_float
将浮点数转换为字符并输出(带2位小数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| void print_float(float num, int decimal_places) { if(num < 0) { dsp_putchar('-'); num = -num; } int32_t integer_part = (int32_t)num; print_int(integer_part); dsp_putchar('.'); float fractional_part = num - integer_part; int i; for(i = 0; i < decimal_places; i++) { fractional_part *= 10; int digit = (int)fractional_part; dsp_putchar('0' + digit); fractional_part -= digit; } }
|
dsp_printf
简单的格式化打印函数 - 支持 %d, %f, %s, %c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| void dsp_printf(const char *format, ...) { va_list args; va_start(args, format); while(*format) { if(*format == '%') { format++; switch(*format) { case 'd': case 'i': print_int(va_arg(args, int)); break; case 'f': print_float(va_arg(args, double), 2); break; case 's': dsp_puts(va_arg(args, char*)); break; case 'c': dsp_putchar(va_arg(args, int)); break; case '%': dsp_putchar('%'); break; default: dsp_putchar('%'); dsp_putchar(*format); } } else { dsp_putchar(*format); } format++; } va_end(args); }
|
格式化数据
测试用例:用dsp_printf
生成sin(x), cos(x), sin(x)*cos(x), cos(x)*cos(x)波形,%f表示浮点数、%d表示整形数据,%s表示字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| dsp_printf("Angle,Sin(x),Cos(x),Sin(x)*Cos(x),Cos(x)*Cos(x)\r\n");
float angle = 0.0f; float angleRad; float sinVal, cosVal; float sinCosVal, cosSquareVal;
for(;;) { while(angle <= 360.0f) { angleRad = angle * 0.01745329f;
sinVal = sin(angleRad); cosVal = cos(angleRad); sinCosVal = sinVal * cosVal; cosSquareVal = cosVal * cosVal;
dsp_printf("%f,%f,%f,%f\r\n", sinVal, cosVal, sinCosVal, cosSquareVal);
angle += 15.0f;
DEVICE_DELAY_US(10000); } angle = 0; }
|
数据可视化
使用vofa+
工具显示FireWater
的自定义格式的串口数据流

总结
自定义dsp_printf更加高效,更加自由,依赖体积更小,无需关心stack大小限制