CCS6中printf()的使用——TMS320F28335工程printf()的使用
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录*前言**1. printf重定向**1.1 若cmd文件为F28335.cmd*二、使用步骤1.引入库2.读入数据总结前言一、前言在DSP的开发过程中,printf()函数对于程序的调试具有非常重要的作用。学过STM32的都了解,STM32串口文件中重定义了printf(),使得printf()打印的内容可以通过串口显示在P
文章目录
前言
在DSP的开发过程中,printf()函数对于程序的调试具有非常重要的作用。学过STM32的都了解,STM32串口文件中重定义了printf(),使得printf()打印的内容可以通过串口显示在PC端的串口调试助手上。
在没有LCD1602、12864以及其它液晶时,我们可以通过串口打印调试程序。我使用的是普中科技的TMS320F28335,现介绍几种在开发DSP的过程中使用printf()的方法。(注意:SCI配合重定向printf()方法并不能完全实现printf()的功能,其余的方法均可以实现printf()的功能)
注意:以下内容均是我通过广泛阅读CSDN大佬的文章以及加入自己的思考和调试总结出来的,方法仅供大家参考!
1. printf重定向
大家在初始学C语言时,我们会用VS或者VC通过printf()将我们要打印的数据送到终端(CMD窗口)。所谓的printf()重定向是指:通过对printf()底层的修改,使printf()打印的数据不再送到终端,而是送到我们指定的位置,结合28335的SCI,我们可以将printf()重定向到SCI,这样printf()打印的数据就会送到SCI,再通过SCI将数据送到PC端的串口调试助手上。
对于printf()底层的修改,实际上就是对fputc()函数的修改。重定向代码如下:
#include "stdio.h"
/*
* 注意:1.我使用的是SCIA与PC进行通信
* 2.我启用了FIFO缓冲区
*/
int fputc(int _c, register FILE *_fp)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); //重定向到SCIA
SciaRegs.SCITXBUF = _c;
return _c;
}
重定向后,我们就可以调用printf()函数,通过写C的形式,将要显示的内容发送给PC并在串口调试助手上显示。
但是实际操作中,完成上述步骤后,编译会出错。此时需要我们配置工程属性以及修改原cmd文件。
这里要说明一下,有的人工程用F28335.cmd,即将程序下载到FLASH中,有的人用28335_RAM_lnk.cmd,即程序仅用于调试,这两种cmd文件的修改内容是不一样的;另外还需要注意,对于SCI的初始化以及其发送函数这里不再给出(我使用的是SCIA),我将在后续讲解SCI时,给出具体的初始化代码,这里仅提供修改工程关键的部分。
具体修改以及实现结果如下:
1.1 若cmd文件为F28335.cmd
工程属性修改为:
F28335.cmd文件修改为:
主函数程序为:
void main()
{
InitSysCtrl();
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
InitFlash();
SCIA_Init(4800); //初始化SCIA
while(1)
{
printf("Hello word! \r\n");
printf("one:%d,two:%.4f,three:%3d\r\n",10000,23.157,12345);
printf("four:0x%x,five:%o,six:%c,seven:%s\r\n",12,22,'d',"nihao");
DELAY_US(500000);
}
}
串口调试助手打印结果为:
分析:从结果可以看到只有字符串能正常打印,除%s外,所有的显示符均无效!原因未知!
1.2 若cmd文件为28335_RAM_lnk.cmd
工程属性修改为:
28335_RAM_lnk.cmd文件修改为:
主函数程序为:
void main()
{
InitSysCtrl();
SCIA_Init(4800); //初始化SCIA
while(1)
{
printf("Hello word! \r\n");
printf("one:%d,two:%.4f,three:%3d\r\n",10000,23.157,12345);
printf("four:0x%x,five:%o,six:%c,seven:%s\r\n",12,22,'d',"nihao");
DELAY_US(500000);
}
}
串口调试助手打印结果为:
分析:从结果可以看到只有字符串能正常打印,除%s外,所有的显示符均无效!原因未知!
2.自定义一个变参函数来代替printf()
函数的定义如下:
#include "stdio.h"
#define MAX_WRITE_LEN (528)
void uart_printf(char * fmt, ...) //自定义变参函数
{
char * arg_ptr;
unsigned int i , len;
static char write_buf[MAX_WRITE_LEN];
va_start(arg_ptr, fmt);
len = vsprintf((char *)write_buf, fmt, arg_ptr);
va_end(arg_ptr);
for (i = 0; i < len; i++)
{
if ( '\0' != write_buf[i] )
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); //使用SCIA
SciaRegs.SCITXBUF=write_buf[i];
}
}
}
实际操作中需要修改原cmd文件,具体修改以及实现结果如下:
2.1若cmd文件为F28335.cmd
工程属性不需要修改
F28335.cmd文件修改为:
主函数程序为:
void main()
{
InitSysCtrl();
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
InitFlash();
SCIA_Init(4800); //初始化SCIA
while(1)
{
printf("Hello word! \r\n");
printf("one:%d,two:%.4f,three:%6d\r\n",10000,23.157,12345);
printf("four:0x%x,five:%o,six:%c,seven:%s\r\n",12,22,'d',"nihao");
DELAY_US(500000);
}
}
串口调试助手打印结果为:
分析:从结果可以看到所有的显示符均可正常显示!
2.2若cmd文件为28335_RAM_lnk.cmd
工程属性不需要修改
28335_RAM_lnk.cmd文件修改为:
主函数程序为:
void main()
{
InitSysCtrl();
SCIA_Init(4800); //初始化SCIA
while(1)
{
printf("Hello word! \r\n");
printf("one:%d,two:%.4f,three:%6d\r\n",10000,23.157,12345);
printf("four:0x%x,five:%o,six:%c,seven:%s\r\n",12,22,'d',"nihao");
DELAY_US(500000);
}
}
串口调试助手打印结果为:
分析:从结果可以看到所有的显示符均可正常显示!
3.直接使用printf(),从CIO观察结果
该方法无需将printf()重定向,也无需自定义一个函数,可直接按C的方法使用printf()。printf()输出的结果将在CIO()上显示。由于printf()未进行重定向,因此不使用SCI,此时的printf()仅用作调试用,将与printf()相关的程序下载到FLASH中将无意义,故只使用28335_RAM_lnk.cmd。
注意:使用printf()之前需要添加头文件#include “stdio.h”,然后就可以在主函数以及其它函数中调用printf(),进行调试时在CIO中查看打印结果。
实际操作中需要配置工程属性以及修改原cmd文件,具体修改以及实现结果如下:
工程属性修改为:
28335_RAM_lnk.cmd文件修改为:
主函数程序为:
void main()
{
InitSysCtrl();
while(1)
{
printf("Hello word! \r\n");
printf("one:%d,two:%.6f,three:%6d\r\n",10000,23.157,12345);
printf("four:0x%x,five:%o,six:%c,seven:%s\r\n",12,22,'d',"nihao");
DELAY_US(500000);
}
}
CIO打印结果为:
分析:从结果可以看到所有的显示符均正常显示!
总结
printf()重定向输出打印会出现一系列的问题。在进行程序调试时,建议用方法3,相较于方法2来说,此时无需RS232、SCI以及串口调试助手,在CCS的CIO中就可直接看打印结果;当需要将打印结果串口显示时,建议用方法2的2.1,此时可以将要打印的程序写入到FLASH中。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)