1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
原子哥的USART代码中,有一部分感觉看得不是很懂
#if 1 #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; //定义_sys_exit()以避免使用半主机模式 _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; } #endif 下面分析代码: 1. #if 1 相当于一段废话,就是永远判断为正 2. #pragma import(__use_no_semihosting) 要理解这一句话,要先了解半主机的概念以及如何构建用于非半主机环境的应用程序 2.1 半主机的概念 半主机是用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求 传送至运行调试器的主机。 例如,使用此机制可以启用 C 库中的函数,如 printf() 和 scanf(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕 和键盘。 这种机制很有用,因为开发时使用的硬件通常没有最终系统的所有输入和输出 设备。 半主机可让主机来提供这些设备。 2.2构建用于非半主机环境的应用程序 如果不想使用任何半主机功能,则必须删除对半主机函数的所有调用,或者使 用非半主机函数重新实现它们。 要构建不使用半主机功能的应用程序,请执行以下操作: 2.2.1 创建源文件以实现与目标相关的功能。 例如,使用半主机调用或依赖于目标内存映射的函数。 2.2.2 将 __use_no_semihosting 符号添加到源文件中。 要确保应用程序中不包含任何使用半主机的函数,请使用以下任一方法: • 汇编语言中的 IMPORT __use_no_semihosting • C 中的 #pragma import(__use_no_semihosting)。 IMPORT __use_no_semihosting 只需添加到一个汇编源文件中。 同样, #pragma import(__use_no_semihosting) 只需添加到一个 C 源文件中。 不需要将这些插入添 加到每个源文件中。 2.2.3 将新对象与应用程序进行链接。 2.2.4 在创建与目标相关的应用程序时使用新配置。 从2.2.2可以看出,这句话确保应用程序不包含任何使用半主机的函数 3. 重新实现printf() printf()这一高级函数通过调用与目标相关的函数来执行,重新实现printf(),需要重新定义低级函数 重新实现有此需要的函 数 __FILE: 文件结构 __stdout: __FILE类型的标准输出对象 fputc():将一个字符输出到文件中 ferror():返回在文件 I/O 期间累积的错误状态 3.1 demo() 《RealView编译工具-库和浮点支持指南》中的demo #include 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; int fputc(int ch, FILE *f) { /* Your implementation of fputc(). */ return ch; } int ferror(FILE *f) { /* Your implementation of ferror(). */ return 0; } void test(void) { printf( “Hello worldn” ); } 3.2 __FILE; __stdout; fputc() 通过之前的分析,可以理解原子哥关于 __FILE; __stdout的代码是什么意思了 重定义了 __FILE; __stdout; 3.3 重定义fputc() 3.3.1 状态寄存器(USART_SR) 位7: TXE:发送数据寄存器空 (Transmit data register empty) 当TDR寄存器中的数据被硬件转移到移位寄存器的时候,该位被硬件置位。如果USART_CR1 寄存器中的TXEIE为1,则产生中断。对USART_DR的写操作,将该位清零。 0:数据还没有被转移到移位寄存器; 1:数据已经被转移到移位寄存器。 3.3.2 数据寄存器(USART_DR) 位31:9: 保留位,硬件强制为0 位8:0 DR[8:0]:数据值 (Data value) 包含了发送或接收的数据。由于它是由两个寄存器组成的,一个给发送用(TDR),一个给接收 用(RDR),该寄存器兼具读和写的功能。 3.3.3 fputc() int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; } 相当于先等待之前的字符通过USART1发送完成后,通过USART1将一个字符发出 3.3 __sys_exit() __sys_exit()是库函数退出函数,所有从库中的退出最后都会调用__sys_exit() 在这里重新定义,避免使用半主机模式。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
732浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
557浏览 3评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 07:43 , Processed in 1.559961 second(s), Total 76, Slave 60 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号