在网上找资料时找到一篇介绍在keil中使用printf()函数的文章,copy到这里,作为备忘。
在keil中printf默认是向串口中发送数据的,所以,如果应用该函数,必须先初始化串口,否则可能引起死机的情况,并且在printf之前应该先将TI置位,摘抄原因如下:
1.printf 函数是调用putchar函数输入的,而putchar应该是先判断ti是否为1,不为1则等待为1。如果为1则清0,然后送出一 个字符。因此你如果直接使用printf函数,你的程序就会在putchar函数中等待ti为1。这时你的程序就相当于直接死掉了。你可以通过改写 putchar函数实现自己的目的的。
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.中定义,调用底层的putchar()来实现.底层发送数据到串口时,先查TI=1是否成立,死等直到TI=1时将新数据写入SBUF,函数返回,所以要先将TI置1,启动第一次传输操作.可查看反汇编相关代码理解其工作机理!
下面举一个简单的例子:
//===========================
#include
#include
//-------------------------------
int main()
{
Uart_init(); //初始化串口,这里就不写具体代码了。
TI = 1; //keil 调用stdio.h中printf函数前要置位。
while(1)
{
printf("Hello world!\n");
delay_ms(800); //延时程序,这里也不写具体代码了。
}
return 0;
}
关键字:keil printf()函数
引用地址:
在keil中使用printf()函数的要点
推荐阅读最新更新时间:2024-03-16 13:53
使用Keil MDK以及标准外设库创建STM32工程
1.1 使用Keil MDK以及标准外设库创建STM32工程 通过上一节对标准外设库的介绍,想必各位读者对标准外设库已经有了基本的认识,然而由于标准外设库中文件众多,很多初学者在开始很长一段时间内甚至都无法完全自己建立一个工程,很多人只是依赖标准外设库或给定的工程模板。本节就介绍怎样利用Keil MDK开发环境和标准外设库来搭建自己的工程。 建立一个基于标准外设库其实并不复杂,网络上也有很多关于怎样在Keil MDK下建立工程的教程,方法也各异,本节所介绍的方法本着少改动、便于使用、方便更换器件等原则,给大家介绍怎样在Keil中创建一个工程,并以一个最简单的例子来说明怎样下载和调试程序。 1.1.1 开发工具与开发环境 1. 软件
[单片机]
keil c51是如何启动c程序的
汇编是从org 0000h开始启动,那么keil c51是如何启动main()函数的?keil c51有一个启动程序startup.a51,它总是和c程序一起编译和链接。下面看看它和main()函数是如何编译的; //主函数如下; void main(void) { while (1)这是个无条件空循环。 { } } 把上面的main()函数编译后的汇编程序和反汇编代码整理后对照如下; ?C_C51STARTUPSEGMENTCODE ?PR?main?TESTMAINSEGMENT CODE ?STACKSEGMENTIDATA RSEG?STACK DS1 CSEGAT0 ?C_STARTUP:LJMPSTARTUP1 C
[单片机]
proteus与keil Cx51的单片机仿真(测量脉冲宽度)
利用门控位测试INT0引脚上出现的脉冲的宽度,并以机器周期数的形式通过发光二极管显示。 电路图: U1源程序: #include reg51.h sbit P1_1=P1^1; void main(void) { TMOD=0x02; EA=1; ET0=1; TH0=256-250; TL0=256-250; TR0=1; while(1); } void Time0(void)interrupt 1 using 0 {P1_1=~P1_1;} U2源程序: #include reg51.h #include intrins.h void main(void) { TMOD=0x0a; EA=1; ET0
[单片机]
proteus与keil Cx51的单片机仿真(定时器方式2应用)
用定时器1方式二计数,每计满100次,将P1.0取反。 电路图: c源程序: #include reg51.h sbit P1_0=P1^0; void main() { TMOD=0X61; TL1=0X9C; TH1=0X9C; TR1=1; for( ; ; ) { do {}while(!TF1); P1_0=!P1_0;TF1=0; } }
[单片机]
GD32F303标准库开发:Keil5新建GD32标准库工程
新建GD32工程 步骤1:创建工程模板文件 新建一个文件夹,命名为:GD32 在文件夹GD32里面新建四个文件夹 (1)CMSIS: 存放内核驱动程序和启动引导文件 (2)FWLIB:存放库函数文件 (3)Project:存放工程文件 (4)User: 存放用户程序(主函数) 具体效果图如下: 步骤2:导入GD32固件库 GD32标准固件库下载链接 1. 打开GD32F30x固件库文件 其中需要用到的两个文件:Firmware 和 Template。 2. 导入文件到 CMSIS 文件 (1)导入内核驱动程序 GD32F30x_Firmware_Library_V2.1.3FirmwareCMSIS 中的 4 个
[单片机]
51学习历程-第二章keil软件的使用以及流水灯
第二章 keil软件的使用以及流水灯的实现 2.3 while语句 在程序的最后加上“while(1);”这样的语句就可以让程序停止。 单片机是无法停止工作的,只要它有电,有晶振在起振,就不会停止工作,每过一个时间周期,它内部的程序指针就要加1,程序指针就指向下一个程序 完整的点亮第一个发光二极管的程序 #include reg52.h void main() { P1=01fe; while(1); } 2.5 keil仿真以及延时语句的精确计算 #include reg52.h #define uint unsigned int sbit led1=P1^0; uint i,j; void main() {
[单片机]
【STM32F103攻城笔记】STM32之MDK(Keil)环境搭建(二)
继续上面的操作,我们打开keil,是空的! 点击project - New uVision Project 选择工程的位置并命名工程名字 保存后,选择你对应的芯片, OK后,一个空的环境搭好了! 下一步建立一个代码文件夹, 先说明我们要用的文件有哪些: 然后将上面的文件分配到建立的文件代码,分配方式为 CORE 文件夹: LIB文件夹: 最后在APP里建个main.c文件! 这样我们基本完成了代码的分配! 下面我们只需要将这代码加载到上面keil搭建的环境里就可以了! 打开刚才的环境,为了方便区分,和代码建立相同的文件结构,如图 下一步,我们通过加载文件,将代码文
[单片机]
keil提示仿真器SWD/JTAG Communication Failure的问题解决
问题现象 在使用CMSIS-DAP仿真器的时候,经常出现连不上仿真器,很烦人,就算你重启MDK或者重启电脑,插拔主板的电源或者仿真器的usb连接线都无济于事。错误提示: 问题分析: 把可能出现硬件问题都一遍遍排除了,剩下就是软件问题了,莫非是MDK的配置问题,打开仿真器的设置 ,上面的设置似乎也没啥问题,只提示仿真器通讯错误。心里想:莫非是工程配置文件的问题?于是打开其他工程,下载,仿真,果然没问题。再打开刚才出问题的工程,问题依旧。这样可以确定是项目配置文件的问题,可能是之前仿真出错,强制关闭Keil导致项目配置文件出错了。 问题解决 最后定位到一个以“uvoptx”后缀的配置文件,把它拷贝到有问题的工程项目里,替换原
[单片机]