stm32学习笔记----双串口同时打开时的printf()问题
stm32学习笔记----双串口同时打开时的printf()问题
最近因为要使用串口2外接PN532芯片实现通信,另一方面,要使用串口1来将一些提示信息输出到上位机,于是重定义了printf(),使其将打印的信息重定向至串口1。但是当在程序中调用printf()时,却发现上位机无论如何都接收不到信息,而且printf()之后的语句也不再执行,想必程序在printf()函数里面死掉了吧。当时觉得很纳闷,因为单独只使用一个串口时,printf()是没有问题的。往下说之前,先贴一下双串口的配置和printf()的书写,mark一下。
- void USART_Config()
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- //配置串口1时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
- //配置串口2时钟,使用复用功能,打开AFIO,管脚重映射到PD5,PD6
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
- /*配置串口1(USART1 Tx(PA.09))*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /* 配置串口1(USART1 Tx(PA.10))*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- /*串口1工作模式(USART1 mode)配置 */
- USART_InitStructure.USART_BaudRate = ;
- 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_Init(USART1, &USART_InitStructure);
- USART_Cmd(USART1, ENABLE);//使能串口
- /*配置串口2(USART2 Tx(PD.05))*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- /*配置串口2(USART2 Tx(PD.05))*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- /*串口2工作模式(USART2 mode)配置 */
- USART_InitStructure.USART_BaudRate = ;
- 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_Init(USART2, &USART_InitStructure);
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
- USART_Cmd(USART2, ENABLE);
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- /*串口2中断配置*/
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority =;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- /*printf()函数重定向*/
- int fputc(int ch, FILE *f)
- {
- //将printf()内容发往串口1
- USART_SendData(USART1, (unsigned char) ch);
- while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);
- return (ch);
- }
当只开串口1时,printf()是可以正常使用的,但是同时使用串口1和串口2时,使用printf()就会输出不了信息,并且程序无法往下执行;但如果不用printf()函数,而直接使用
- USART_SendData(USART1,(unsigned char) ch)时,串口1也能正常打印;但这样太麻烦辣,每次打印一个字符。
于是网上查了一下,也有人遇到类似问题,而后评论下方有一个函数,说是可以双串口同时打开时,也可以一次性打印一串信息。抱着试一试的心态,将函数程序搬到我的工程中,没想到,还真行。下面贴出代码:
- /*
- * 函数名:itoa
- * 描述 :将整形数据转换成字符串
- * 输入 :-radix =10 表示10进制,其他结果为0
- * -value 要转换的整形数
- * -buf 转换后的字符串
- * -radix = 10
- * 输出 :无
- * 返回 :无
- * 调用 :被USART_printf()调用
- */
- static char *itoa(int value, char *string, int radix)
- {
- int i, d;
- int flag = ;
- char *ptr = string;
- /* This implementation only works for decimal numbers. */
- if (radix != )
- {
- *ptr = ;
- return string;
- }
- if (!value)
- {
- *ptr++ = 0x30;
- *ptr = ;
- return string;
- }
- /* if this is a negative value insert the minus sign. */
- if (value < )
- {
- *ptr++ = '-';
- /* Make the value positive. */
- value *= -;
- }
- for (i = ; i > ; i /= )
- {
- d = value / i;
- if (d || flag)
- {
- *ptr++ = (char)(d + 0x30);
- value -= (d * i);
- flag = ;
- }
- }
- /* Null terminate the string. */
- *ptr = ;
- return string;
- }
- /*
- * 函数名:USART_printf
- * 描述 :格式化输出,类似于C库中的printf,但这里没有用到C库
- * 输入 :-USARTx 串口通道
- * -Data 要发送到串口的内容的指针
- * -... 其他参数
- * 输出 :无
- * 返回 :无
- * 调用 :外部调用
- * 典型应用USART_printf( USART1, "\r\n this is a demo \r\n" );
- * USART_printf( USART2, "\r\n %d \r\n", i );
- * USART_printf( USART3, "\r\n %s \r\n", j );
- */
- void USART_printf(USART_TypeDef* USARTx, uint8_t *Data,...)
- {
- const char *s;
- int d;
- char buf[];
- va_list ap;
- va_start(ap, Data);
- while ( *Data != ) // 判断是否到达字符串结束符
- {
- if ( *Data == 0x5c ) //'\'
- {
- switch ( *++Data )
- {
- case 'r': //回车符
- USART_SendData(USARTx, 0x0d);
- Data ++;
- break;
- case 'n': //换行符 //???
- USART_SendData(USARTx, 0x0a);
- Data ++;
- break;
- default:
- Data ++;
- break;
- }
- }
- else if ( *Data == '%')
- { //
- switch ( *++Data )
- {
- case 's': //字符串
- s = va_arg(ap, const char *);
- for ( ; *s; s++)
- {
- USART_SendData(USARTx,*s);
- while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
- }
- Data++;
- break;
- case 'd': //十进制
- d = va_arg(ap, int);
- itoa(d, buf, );
- for (s = buf; *s; s++)
- {
- USART_SendData(USARTx,*s);
- while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
- }
- Data++;
- break;
- default:
- Data++;
- break;
- }
- } /* end of else if */
- else USART_SendData(USARTx, *Data++);
- while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
- }
- }
stm32学习笔记----双串口同时打开时的printf()问题的更多相关文章
- stm32学习笔记之串口通信
在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...
- STM32学习笔记——USART串口
转载自:http://www.cnblogs.com/microxiami/p/3752715.html 一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异 ...
- STM32学习笔记——USART串口(向原子哥和火哥学习)
一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范围的波特率选择. S ...
- STM32学习笔记:【001】时钟树与RCC
导言 如果学过单片机的同学应该不会陌生,学习51单片机时最经常听到的就是“最小系统”. 最小系统里面少不了晶振,否则单片机无法工作. 单片机需要晶振(时钟源)来工作,那么对于STM32芯片同样如此. ...
- STM32学习笔记(四)——串口控制LED(中断方式)
目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...
- STM32学习笔记——OLED屏
STM32学习笔记--OLED屏 OLED屏的特点: 1. 模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2. 显示尺寸为0.96寸 3. 分辨率为128*64 4. ...
- stm32学习笔记——外部中断的使用
stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...
- STM32学习笔记-NVIC中断知识点
STM32学习笔记-NVIC中断知识点总结 中断优先级设置步骤 1. 系统运行后先设置中断优先级分组 函数:void NVIC_PriorityGroupConfig(uint32_tNVIC_Pri ...
- STM32学习笔记——点亮LED
STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...
随机推荐
- EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)
在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...
- 用requests库实现登录遇到的问题
想登录zhihu,然后总是得到403 foribidden的错误,各种谷歌百度,得到结论说是输入错误或者是url错误,用fldder发现的确是url错了,post的地址是错误的 ==. 开始以为是#s ...
- Nginx 配置文件详解
user nginx ; #用户 worker_processes 8; #工作进程,根据硬件调整,大于等于cpu核数 error_log logs/nginx_error.log crit; #错误 ...
- 本地与在线图片转Base64及图片预览
查看效果:http://sandbox.runjs.cn/show/tgvbo9nq 本地图片转Base64(从而可以预览图片): function localImgLoad() { var src ...
- JavaScript 上万关键字瞬间匹配——借助Hash表快速匹配
来源: http://www.cnblogs.com/index-html/archive/2013/04/17/js_keyword_match.html http://www.etherdream ...
- Ten Tips for Writing CS Papers, Part 2
Ten Tips for Writing CS Papers, Part 2 This continues the first part on tips to write computer scien ...
- Linux rpm 命令参数使用详解[介绍和应用](转)
RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序” rpm 执行安装包二进制包(Binary)以及源代码包(Source)两种 ...
- linux利用grep查看打印匹配的下几行或前后几行的命令
转自:http://www.itokit.com/2013/0308/74883.html linux系统中,利用grep打印匹配的上下几行 如果在只是想匹配模式的上下几行,grep可以实现. ...
- 如何测试本机的公网IP能否被Internet用户访问
声明:本机的公网IP是指ADSL拨号方式取得的公网IP,并非指固定公网IP. 一.新建IIS站点 xp系统需要有安装包才能安装IIS服务 windows7及以上与系统直接在windows->控制 ...
- Unity3D模型的细致纹理问题解决办法
http://hunterwang.diandian.com/post/2012-09-28/40039798509 也许有人也遇到过同样的问题,也许解决方式不同,我来介绍一下偶尔尝试发现的解决办法. ...