历史上的今天
今天是:2025年06月10日(星期二)
2018年06月10日 | STM32输出调试信息-printf重定向到串口
2018-06-10 来源:eefocus
在STM32调试过程中常常需要将调试信息输出到串口,然后通过串口助手查看输出的调试信息。一般来说,串口输出的是指定长度的十六进制字节,对于想打印的调试信息来
说,略显灵活性不足。这时候如果可以将printf重定向到串口输出,则能很好的解决这个问题。
关于printf重定向的方法有很多种,这里只讨论一种我认为相对简单实用的方法。其主要方法步骤如下:
1、配置STM32的串口,确保STM32能输出数据到串口调试助手。
void USART5_Init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOD |RCC_APB2Periph_AFIO , ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// Configure the USART1_Rx as input floating
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING ;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); //Enable rx enable,
USART_ClearFlag(UART5, USART_IT_RXNE);
/* Configure the USARTx */
USART_Init(UART5, &USART_InitStructure);
/* Enable the USARTx */
USART_Cmd(UART5, ENABLE);
}
2、添加printf头文件#include
3、点击Keil中小魔术棒Target页勾选Use MicroLIB。
注:这个步骤必须有,否则代码编译通过后,进行仿真时会卡住,进入不了Main函数。printf、malloc等标准库函数在工程建立时,不勾选Use MicroLIB就会引起这类问题。
至此,就可以通过printf打印调试信息到串口助手了。
接下来关于输出调试信息再补充两点。
1、printf输出指定长度的字符串。
格式为printf("%.*s\n",strlen,str);
printf("指定长度字符串:%.*s\n",strlen,str); //打印指令长度字节串
2、打印十六进制数据。
当我们使用串口调试助手查看输出信息,如果我们查看的数据是十六进制类型,我们会勾选调试助手中的Hex显示选项。这时当数据量很大时,我们可能需要附加一些可见字符的说明,比如英文或者中文,这时在Hex显示下,这些字符辨识度比较低,甚至是乱码,printf辅助打印调试信息目的作用不大。这里可以选择一种方法,电脑串口助手不勾选Hex选项,而将要显示的十六进制数据转为可见的ASCII码格式。
如下为指定长度的十六进制数据转化为字符串的函数:
/**********************************************************
*函数功能:将十六进制数据转为字符串格式
*参 数:In,十六进制数据;Len十六进制数据长度
* Out,输出字符串
*返 回 值:无
**********************************************************/
void HexToString(char *Out,char *In,char Len){
long i;
char Temp;
for(i=0;i Temp = In[i]>>4; if(Temp>9)Out[2*i] = Temp + 'A' - 10; else Out[2*i] = Temp + '0'; Temp = In[i] & 0x0F; if(Temp>9)Out[2*i+1] = Temp + 'A' - 10; else Out[2*i+1] = Temp + '0'; } Out[2*i] = 0; } 此时再调用printf即可打印出清晰的调试信息: HexToString(DebugData,(char *)buffer,bufferlen); printf("NTP发送:\n%s\r\n",DebugData); 以上步骤根据调试成功后的结果总结。
史海拾趣
|
做个记录 只列出几个例子 Load / Store Load Immediate p3 = 12 (z) ; r0 = -344 (x) ; Load Pointer Register p5 = [ p0 ++ ] ; p2 = [ sp -- ] ; Load Data Register r7 = [i3 ++ m0] ; r1 = [ p0 ++ p1 ] ; r0 = [ i0 ++ ] ; ...… 查看全部问答> |
|
1. 目前国家提倡节能减排,发展低碳经济。变频调速,改善工艺是目前工艺领域节能减排的主要方向。开发制作这些大型的工况设备,嵌入式设计技术应用不可缺少。欢迎大家讨论嵌入式技术在工业领域应用的心得和技巧。… 查看全部问答> |
|
Yokogawa’s New DL850 ScopeCorder Yokogawa’s New DL850 ScopeCorder Third generation of best-selling combined oscilloscope and data recorder family I had the opportunity to talk with Terry Marrinan, Sales & Marketing Director for Europe & Africa with Yokogawa’s ...… 查看全部问答> |
|
LED电子显示屏的亮度计算方法: 以全彩屏为例,通常红、绿、蓝白平衡配比为3:4:1 以P16(2R1GB)5000 CD/平方为例: 红色LED 灯亮度:亮度5000(CD)/M2÷点数/M2×0.3(白平衡配比占3 ...… 查看全部问答> |
|
首先,承认错误,小版14日那次点评做LCD and TOUCH BoosterPack去了,然后21日的也漏掉了,导致这次盘点几乎成了月盘点,对不起各位坛友。 3周的变化是很大的,下面开始这次的盘点! 不知道大家有没有注意到MSP430版块新增一位版主qinkaiabc,欢 ...… 查看全部问答> |




