keil里面骚气的printf

本文介绍如何在KEIL C51环境中正确使用printf函数进行串口通信。重点在于初始化UART时将TI标志置1的重要性,避免程序死锁,并确保数据正确发送。

今天,在浩哥的无意之谈下。提到了keil的printf函数,当时即震惊,keilC51还能用printf。
立即google一波,还真有!!! 学习了,简直666。 分享一下心得!

注意:直接调用函数时候,初始化UART时切记要把TI置1

#include <stdio.h>
#include <reg52.h>

void ConfigUART(unsigned int baud);

void main()
{
    ConfigUART(9600);
    while(1)
    {
        printf("Hello World\n");
    }       
}

void ConfigUART(unsigned int baud)
{
    SCON = 0X50;
    TMOD &= 0x0F;
    TMOD |= 0x20;
    TH1 = 256 - (11059200/12/32)/baud;
    TL1 = TH1;
    TR1 = 1;

    TI = 1;
}

原理:其底层是调用putchar函数实现的,工作方式为中断。 于是缺点就来了,此函数调用中断时会翻车。

在keil中printf默认是向串口中发送数据的,所以,如果应用该函数,必须先初始化串口,否则可能引起死机的情况,并且在printf之前应该先将TI置位,摘抄原因如下:

1.printf函数是调用putchar函数输入的,而putchar应该是先判断ti是否为1,不为1则等待为1。 如果为1则清0,然后送出一个字符。因此
你如果直接使用printf函数,你的程序就会在putchar函数中等待ti为1。这时你的程序就相当于直接死掉了。你可以通过改写putchar函数
实现自己的目的。TI相当于是初始化~不给赋初值就不干活

2.Keil的串口处理比较巧妙的,我的分析如下: putchar.c里面,是先检测TI再发送。这样做的目的是把尽可能多的时间留给2次串口操作之间的程序,而不是把等待字节发送的时间白白空等待浪费
掉。所以,在系统初始化的时候,一定要令TI=1; 就可以顺畅的使用printf函数了。sbuf=” “的办法,其实就是令TI=1.
另外要特别注意,printf函数执行完毕后,最后一个字节并未发送完毕,例如在485通讯中,此时如果切换为收模式,会丢失最后一字节.

3.一般串口发送都是等TI(字节发送完标志)为1就马上发送下一字节,由于不管是中断还是查 询TI标志的方法,都会检测TI,因此首次发送必须置位TI标志,使串口开始发送你的“在程序的初始化部分往串口数据寄存器SBUF里放一个字符来起用终
端显示;”方法最终作用也就是把TI置1,改成TI=1;来启动发送也是一样的(当然,不会发出那个’ ‘字符了)。

4.stdio中定义,调用底层的putchar()来实现.底层发送数 据到串口时,先查TI=1是否成立,死等直到TI=1时将新数据写入SBUF,函数返回,所以要先将TI置1,启动第一次传输操作.可查看反汇编相关代码理解其工作机理!

5.自己理解:在多机通讯中,应该也要形成像 putchar()函数的机理,要有串口中断服务程序,并且是在该程序中判断TI,根据TI是不是该发送下一组数据~同样对于接收的一方..

另外

如果只进行软件调试的话,与波特率无关。可以不配置定时器T1。
只需要加一个stdio.h的头文件,以及TI = 1这个命令即可

<think>好的,我需要帮助用户了解如何在Keil中使用_dbg_printf函数。首先,我应该确认用户提到的这个函数的具体用途背景。根据用户提供的引用内容,尤其是引用[1]提到的“ST Debug (printf) Viewer for Jlink”,这可能与Keil的调试功能相关。 接下来,我需要检查用户提供的引用资料。引用[1]链接到Keil的文档,说明_dbg_printf可能与串行调试窗口有关。引用[2]提到了RT-Thread在Keil环境下的使用,可能涉及调试输出。引用[3]是关于添加STC芯片到Keil,可能与当前问题关联不大,但需要留意。 用户的问题是如何使用_dbg_printf函数以及相关文档。我需要回忆或查找Keil中该函数的用法。通常,在嵌入式开发中,类似printf的函数需要初始化调试端口,比如ITM(Instrumentation Trace Macrocell)或通过J-Link的SWO接口。可能需要包含特定的头文件,并配置调试器设置。 根据引用[1],ST Debug Viewer可能用于捕获通过特定通道发送的调试信息。因此,使用_dbg_printf可能需要启用ITM并配置相应的通道。另外,在代码中可能需要重定向输出,或者使用Keil提供的库函数。 可能存在一些步骤,比如在工程选项中启用调试视图,配置ITM端口,并在代码中使用_dbg_printf函数。需要确保用户正确设置硬件连接,例如SWO引脚连接正确。 还需要考虑用户是否在使用特定的中间件或RTOS,如RT-Thread(引用[2]),其中可能有自己的调试输出机制,可能与_dbg_printf集成或有不同的函数。 此外,需要验证_dbg_printf的语法参数是否与标准printf类似,是否需要额外的初始化代码,比如启用ITM时钟或配置SWO速度。 总结步骤可能包括:包含必要的头文件,初始化调试硬件,调用_dbg_printf,配置Keil的调试环境,以及查看输出。同时,用户可能需要参考Keil的文档(引用[1])来设置Debug Viewer。 需要提醒用户检查硬件连接,比如J-Link的SWO引脚是否正确连接,工程配置中是否启用了ITM,以及是否正确设置了跟踪时钟频率等参数。此外,可能需要指导用户如何在Debug模式下查看输出窗口。 最后,生成相关问题,帮助用户深入理解调试方法、常见问题解决性能优化等。</think>关于Keil中$ \_dbg\_printf $函数的使用方法,以下是分步说明: ### 一、函数功能说明 $ \_dbg\_printf $是Keil MDK-ARM调试环境中用于输出格式化调试信息的专用函数,需要通过SWO(Serial Wire Output)接口配合J-Link调试器使用[^1]。该函数不会占用串口资源,可实现实时调试信息输出。 ### 二、配置步骤 1. **工程设置** ```c #include <rt_dbg.h> // RT-Thread调试库 #include <rtthread.h> // 若使用RTOS需包含 ``` 在代码开头添加头文件引用[^2] 2. **硬件连接** - 确保开发板SWO引脚(PB3)与调试器连接 - 使用USB线连接开发板USB转串口到PC[^2] 3. **调试器配置** ```markdown [Debug] -> [Settings] -> [Trace] 勾选 Trace Enable 设置 Core Clock = 72MHz(根据MCU实际频率) 选择 ITM Stimulus Port 0 ``` ### 三、代码示例 ```c void Debug_Test(void) { _dbg_printf("System Clock: %dHz\n", SystemCoreClock); _dbg_printf("ADC Value: 0x%04X\n", ADC_Read()); } ``` ### 四、查看输出 1. 进入调试模式(Ctrl+F5) 2. 打开View->Serial Windows->Debug (printf) Viewer 3. 添加观测变量: ```python # 在Watch窗口输入 (int)__get_IPSR() // 监控中断状态 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值