终于解决了MDK 3.80a中不能使用printf()函数的问题
来源:互联网 发布:mac dock透明 编辑:程序博客网 时间:2024/05/16 15:57
初始化的方法学习了马老师的STM32_Init.h大法,自己英文还可以,加上avr的基础还不错,所以gpio和时钟配置都很顺利
碰到uart就头大了,看到各种例程里都是printf()函数,自己也想用,毕竟是avr想用却开销不了的东西。但是我自己写的程序里一旦出现printf,单片机的不干活了。查论坛首先发现要重定义fputc函数,照做了,还是不行。
后来怀疑是uart1初始化问题,用自己写的put_c函数却没问题。
后来又发现一种说法,需要避免使用semihosting(半主机模式),我也把代码加进去了(改fputc去掉了),还是不行。
再一想,重定义fputc是绝对必须的,加上了之后问题解决,成功使用printf("(敏感词0373) \n");输出了,哈哈
***************************************************************************************************
以上废话,可以不看。
简单地说:想在mdk 3.80a中用printf,需要同时重定义fputc函数和避免使用semihosting(半主机模式),
论坛里应该有完整介绍这个的帖子,但是我没搜到,也许是沉了。重发出来希望能帮上像我这样的菜鸟们。
需要添加以下代码
#pragma import(__use_no_semihosting)
/******************************************************************************
*标准库需要的支持函数
******************************************************************************/
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
/// <summary>
/// 定义_sys_exit()以避免使用半主机模式
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
_sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
//USART_SendData(USART1, (u8) ch);
USART1->DR = (u8) ch;
/* Loop until the end of transmission */
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}
return ch;
}
以上代码来自goway 和 yugen 的发言,在此表示感谢
********************************************************************************************
更新:
根据四楼的帖子,发现在Options里选上microlib之后,就不用关闭半主机模式了。
我顺便查了一下semihosting的作用,介绍如下
Semihosting is a mechanism for ARM targets to communicate input/output requests
from application code to a host computer running a debugger. This mechanism could be
used, for example, to allow functions in the C library, such as printf() and scanf(), to use the screen and keyboard of the host rather than having a screen and keyboard on the target system.
This is useful because development hardware often does not have all the input and
output facilities of the final system. Semihosting allows the host computer to provide these facilities.
Semihosting is implemented by a set of defined software interrupt (SWI) operations.
The application invokes the appropriate SWI and the debug agent then handles the SWI
exception. The debug agent provides the required communication with the host.
In many cases, the semihosting SWI will be invoked by code within library functions. The application can also invoke the semihosting SWI directly. Refer to the C library descriptions in the ADS Compilers and Libraries Guide for more information on support for semihosting in the ARM C library.
找我的理解,这个模式是用来调试的,通过仿真器,使用主机的输入输出代替单片机自己的,也就是说即便单片机没有输出口也能printf到电脑上。反过来,由于这个模式更改了printf()等的实现方式,输入输出就不走单片机的外设了,所以只重定义fputc不起作用。
用代码关闭此模式后,需要同时更新一下__stdout 和__stdin 的定义,所以有后面的语句。
以上仅为个人理解,如有错误请指正。
另外,勾选microlib之后,也许编译的时候就不把开启semihosting的文件包进去了,所以没事。
- 终于解决了MDK 3.80a中不能使用printf()函数的问题
- STM32(MDK)中不能使用printf()函数的问题
- 怎么解决STM32(MDK)中不能使用printf()函数的问题
- s60模拟器不能断点调试的问题终于解决了
- MDK中STM32使用Printf函数详细解析
- Keil MDK环境下使用printf函数的解决方法
- MDK中使用printf 直接发送汉字的方法。
- 在CCS中使用printf函数输出的问题和解决过程
- 在CCS中使用printf函数输出的问题和解决过程
- SOAP开发中遇到的郁闷问题终于解决了!
- 终于解决了在控制台不能输入中文输入法的问题了
- 不能下载的问题终于解决啦
- 终于解决了JSP中编码问题~~~~~~~
- STM32 MDK工程中使用printf
- 在MDK中使用printf及串口
- 终于解决了QWidget: Must construct a QApplication before a QPaintDevice的问题
- 问题终于解决了
- minicom不能连arm-linux开发板的问题终于解决了!
- 一个C C++ 内存的问题 和 C++继承 虚函数表的点【2013.10.15小记】
- linux根据io消耗找进程
- 自考-数据库及应用
- Oracle DB 移动数据
- 1-9 实验7 网络通信实验1 广播和单播通信
- 终于解决了MDK 3.80a中不能使用printf()函数的问题
- Tomcat源码分析 启动流程分析
- 数字格式化-----将数字格式化制定位数
- wince 注册表中修改MAC地址
- C++动态数组delete出错,求助
- 为什么IT界比较累
- 上坡起步
- AsyncTask实现的原理和适用的优缺点
- linux命令解析--cut