平台式网站模板,网站开发流行工具,江苏建设工程信息网准考证打印时间,如何建立一个网站并运行MCU:STM32F407VE
MDK:5.29
IAR:8.32
目录--点击可快速直达
目录
写在前面什么是RTT?RTT的工作原理RTT的性能快速使用教程高级使用教程附上测试代码2019年12月27日更新--增加打印float的功能 写在前面
本文介绍了J-Link RTT的部分使用内容#xff0c;很多地方参考和使用…
MCU:STM32F407VE
MDK:5.29
IAR:8.32
目录--点击可快速直达
目录
写在前面什么是RTT?RTT的工作原理RTT的性能快速使用教程高级使用教程附上测试代码2019年12月27日更新--增加打印float的功能 写在前面
本文介绍了J-Link RTT的部分使用内容很多地方参考和使用了J-Link的官方资料有的地方可能翻译的不太准确请见谅。
如果想了解更加准确详细的内容请点此处。 什么是RTT?
RTT(Real Time Transfer)是一种用于嵌入式中与用户进行交互的技术它结合了SWO和半主机的优点具有极高的性能。
使用RTT可以从MCU非常快速输出调试信息和数据且不影响MCU实时性。这个功能可以用于很多支持J-Link的设备和MCU兼容性强。
RTT支持两个方向的多个通道上到主机下到目标它可以用于不同的目的为用户提供尽可能多的自由。默认实现每个方向使用一个通道用于可打印终端输入和输出。
使用J-Link RTT Viewer可用于“虚拟”终端允许打印到多个窗口例如一个用于标准输出一个对于错误输出一个用于调试输出。 RTT的工作原理
RTT在MCU的存储器中使用SEGGER RTT控制块结构管理数据读写。控制块对于每个可用的信道都在内存中包含了一个ID通过J-Link或者环形缓冲结构区链表都可以通过ID找到对应的控制块。
可用信道的最大数目可以在编译时配置并且每个缓冲区都可以在MCU运行时配置和使用。上下缓冲区可以分开处理。每个通道都可以配置为阻塞或非阻塞。
在阻塞模式下应用程序将等待缓冲区写满直到可以写入所有内存为止这将导致应用程序处于阻塞状态但可以防止数据丢失。
在非阻塞模式下只会写入适合缓冲区的数据或完全不写入缓冲区其余的数据将被丢弃。这样即使没有连接调试器也可以实时运行。开发人员不必创建特殊的调试版本并且代码可以保留在发布应用程序中。 RTT的性能
RTT的性能明显高于其他任何用于将数据输出到主机PC的方式。平均一行文本可以在1微秒或更短的时间内输出。基本上相当于做一个memcopy()的时间。
RTT实现代码使用大约500字节的ROM和(n(通道数) * (24字节ID24字节))的RAM。推荐的大小是1 kByte上行信道和16到32字节下行信道这取决于输入/输出的负载。 快速使用教程
1.首先安装J-Link的软件驱动。 2.安装完成后打开J-Link的安装目录开始-SEGGR-J-Link RTT Viewer-右键打开文件所在位置-然后继续右键打开文件所在位置-此时就是安装目录了
找到如下路径SEGGER\JLink_V632f\Samples\RTT,解压路径里面的压缩包SEGGER_RTT_V632f.zip(不同的版本V后面的数字可能不一样)。 3.将解压完的文件拷贝到代码工程目录中。
4.在项目工程中加入SEGGER_RTT_V632f\RTT目录下的全部四个文件。工程添加文件方法请自行百度。
5.工程加入文件后在想要用到RTT的文件中包含#include SEGGER_RTT.h,然后直接调用SEGGER_RTT_printf()就好了
例如SEGGER_RTT_printf(0,hello world!)这个和C语言的printf的格式差不多就是前面加了一个端口0的参数。详细信息请看高级使用教程
6.然后点击开始-SEGGR-J-Link RTT Viewer打开J-Link RTT Viewer 选择好你的芯片型号后点击确认。 7.然后就能看到我们打印的内容了。 高级使用教程
1.部分函数介绍
(1)void SEGGER_RTT_Init (void) RTT初始化函数应放于程序开始阶段。 (2)int SEGGER_RTT_GetKey (void); 从RTT终端获取一个按键字符。Return Value
ValueMeaning0返回按键字符0-255 0缓存区中没有有效的字符
示例代码: int c;c SEGGER_RTT_GetKey();if (c q) {exit();}(3)int SEGGER_RTT_HasKey (void);检测缓存区中是否还有字符。Return Value
ValueMeaning1缓存区中至少有一个字符是有效的0缓存区中没有有效的字符
示例代码: if (SEGGER_RTT_HasKey()) {int c SEGGER_RTT_GetKey();}(4)int SEGGER_RTT_printf (unsigned BufferIndex, const char * sFormat, …)格式化输出字符串Return Value
ValueMeaning0已经发送的字符数 0发生错误
附加信息: 转换规范具有以下语法 %[标志][字段宽度][.精度]转换指定程序 支持的标志 -在字段宽度内左对齐 始终打印有符号转换的符号扩展名 0用0代替空格。使用“-”标志或精度时忽略 支持的转换说明符 c将参数打印为一个字符 d将参数打印为有符号整数 u将参数打印为无符号整数 x将参数打印为十六进制整数 s打印参数指向的字符串 p将参数打印为8位十六进制整数。 ps.似乎官方没有给float类型格式化输出方式。
示例代码:
SEGGER_RTT_printf(0, SEGGER RTT Sample. Uptime: %.10dms., /*OS_Time*/ 890912);
同时可以使用SEGGER_RTT_printf()来设置字体颜色还背景颜色
例如:
SEGGER_RTT_printf(0,RTT_CTRL_BG_WHITE);
SEGGER_RTT_printf(0,RTT_CTRL_TEXT_BLUE);(5)void SEGGER_RTT_SetTerminal(char TerminalId);设置虚拟终端ID。Return Value
ParameterMeaningTerminalId虚拟终端的ID
示例代码:
//
// Send a string to terminal 1 which is used as error out.
//
SEGGER_RTT_SetTerminal(1); // Select terminal 1
SEGGER_RTT_WriteString(0, ERROR: Buffer overflow);
SEGGER_RTT_SetTerminal(0); // Reset to standard terminalSEGGER_RTT_WriteString中的0参数是通道号不是终端号。 (6)int SEGGER_RTT_WaitKey (void);检测缓存区中是否还有字符。Return Value
ValueMeaning≥0等待返回一个按键值
示例代码: int c 0;do {c SEGGER_RTT_WaitKey();} while (c ! c);附上测试代码
/*terminal 0: if you press any key in the keyboard ,terminal 0 will show the key value witch you press.terminal 1: show the dateterminal 2: show the time
*/
if (SEGGER_RTT_HasKey())
{int c SEGGER_RTT_GetKey();SEGGER_RTT_SetTerminal(0); SEGGER_RTT_Write (0, c, 1);SEGGER_RTT_printf(0,\n);
}
//GET DATA
HAL_RTC_GetTime(hrtc,_current_time,RTC_FORMAT_BIN);
//GET TIME
HAL_RTC_GetDate(hrtc,_current_date,RTC_FORMAT_BIN);
//Printf
SEGGER_RTT_SetTerminal(1);
SEGGER_RTT_printf(0,%d . %d . %d \n,_current_date.Year,_current_date.Month,_current_date.Date);
SEGGER_RTT_SetTerminal(2);
SEGGER_RTT_printf(0,%d : %d : %d \n\n,_current_time.Hours,_current_time.Minutes,_current_time.Seconds);代码的下载链接https://download.csdn.net/download/xue745146527/12045381 工程包含了Keil 和 IAR
2019年12月27日更新--增加打印float的功能
因为官方的RTT View不能打印出float类型的数据因此我简单写了个float转字符串的函数。
unsigned char *out_float(double value, unsigned char decimal_digit, unsigned char *output_length)
{unsigned char _output[20];unsigned long integer;unsigned long decimal;unsigned char _output_length 0;unsigned char _length_buff 0;static unsigned char *return_pointer;unsigned char signal_flag;if (value 0)signal_flag 1;elsesignal_flag 0;value fabs(value);integer (unsigned long)value;decimal (unsigned long)((value - integer) * pow(10, decimal_digit));unsigned long integer_buff integer;unsigned long decimal_buff decimal;while (1){if (integer / 10 ! 0)_length_buff;else{_length_buff;break;}integer integer / 10;}for (int i 0; i _length_buff; i){if (i _length_buff - 1)_output[_output_length] integer_buff % 10 0x30;else{//_output[_output_length] integer_buff / 10 % 10 0x30;_output[_output_length] integer_buff / (unsigned long)pow(10, _length_buff - i - 1) % 10 0x30;integer_buff integer_buff % (unsigned long)pow(10, _length_buff - i - 1);//integer_buff integer_buff % 10;}_output_length;}_output[_output_length] .;_output_length;_length_buff 0;while (1){if (decimal / 10 ! 0)_length_buff;else{_length_buff;break;}decimal decimal / 10;}for (int i 0; i _length_buff; i){if (i _length_buff - 1)_output[_output_length] decimal_buff % 10 0x30;else{_output[_output_length] decimal_buff / (unsigned long)pow(10, _length_buff-i-1) % 10 0x30;decimal_buff decimal_buff % (unsigned long)pow(10, _length_buff - i - 1);}_output_length;}_output[_output_length] 0x00;_output_length;return_pointer (unsigned char *)realloc(return_pointer,_output_length);*output_length _output_length - 1;if (return_pointer 0)return 0;else{if (signal_flag 1){return_pointer[0] -;memcpy(return_pointer1, _output, _output_length);}elsememcpy(return_pointer, _output, _output_length);}return return_pointer;
}
Parameter
ValueMeaningvalue想要打印的数据decimal_digit数字小数部分的位数_output_length输出字符串的长度
Return Value
ValueMeaningunsigned char*返回一个字符串指针
示例代码: float value 3.1415unsigned char length;SEGGER_RTT_printf(0,value %s \n,out_float(value,4,length));