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 = 115200;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 = 115200;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 =2;NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}/*printf()函数重定向*/
int fputc(int ch, FILE *f)
{//将printf()内容发往串口1USART_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 = 0;char    *ptr = string;/* This implementation only works for decimal numbers. */if (radix != 10){*ptr = 0;return string;}if (!value){*ptr++ = 0x30;*ptr = 0;return string;}/* if this is a negative value insert the minus sign. */if (value < 0){*ptr++ = '-';/* Make the value positive. */value *= -1;}for (i = 10000; i > 0; i /= 10){d = value / i;if (d || flag){*ptr++ = (char)(d + 0x30);value -= (d * i);flag = 1;}}/* Null terminate the string. */*ptr = 0;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[16];va_list ap;va_start(ap, Data);while ( *Data != 0)     // 判断是否到达字符串结束符
      {                                                          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, 10);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 );}
}

转载于:https://www.cnblogs.com/codingmengmeng/p/5488551.html

stm32学习笔记----双串口同时打开时的printf()问题相关推荐

  1. STM32学习笔记-USART串口通信+与野火STM32F407板载ESP8266进行通信

    文章目录 STM32USART介绍 STM32USART框图 第一部分 第二部分 第三部分 发送器 时序图 接收器 第四部分 软件部分: STM32通过USART与板载ESP8266通讯实验 板载WI ...

  2. STM32学习笔记(三)丨中断系统丨EXTI外部中断(对射式红外传感器计次、旋转编码器计次)

    本篇文章包含的内容 一.中断系统 1.1 中断的定义 1.2 中断优先级 1.3 中断的嵌套 1.4 STM32中的中断系统 1.4.1 STM32的中断资源 1.4.2 嵌套中断向量控制器 NVIC ...

  3. STM32学习笔记之OLED屏

    STM32学习笔记--OLED屏 OLED屏的特点: 1.  模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2.  显示尺寸为0.96寸 3.  分辨率为128*64 4.   ...

  4. STM32学习笔记(13)——模数转换ADC

    这个月一直忙于准备考试,已经考完一半科目了,偷闲写了这篇文章.因为还没考完试,估计还得咕一段时间了. STM32学习笔记(13)--模数转换ADC 第一部分:ADC功能框图 一.输入电压 二.输入通道 ...

  5. STM32学习笔记(八)丨ADC模数转换器(ADC单、双通道转换)

    本篇文章包含的内容 一.ADC 模数转换器 1.1 ADC简介 1.2 逐次逼近型ADC工作原理 1.3 STM32中的ADC基本结构 1.4 STM32中ADC的输入通道 1.5 STM32中的AD ...

  6. STM32学习笔记:FLASH读写之二

    因为关于STM32的Flash相关的知识点比较多,所以该内容的学习我们分为以下4个部分 1.RAM和ROM的一些基本概念 -- STM32学习笔记:FLASH读写之一 2.STM32的Flash寄存器 ...

  7. 《STM32学习笔记》2——开发环境的建立

    接上文,文中的图片知识,大多数来自视频的截图(来自洋桃电子). 欢迎大家批评指正! STM32学习笔记-专栏 文章目录 一.接口定义 1 芯片引脚整体简介 2 各部分引脚介绍 二.开发板简介 三.IS ...

  8. KEIL 5.38的ARM-CM3/4 ARM汇编设计学习笔记3——串口Stdio实现

    KEIL 5.38的ARM-CM3/4 ARM汇编设计学习笔记3--串口Stdio实现 一.介绍 任务目标 二.工程创建 三.软件设计 第一步,BSP构建 1, 添加前面的pll_config文件 2 ...

  9. 【K210】K210学习笔记五——串口通信

    [K210]K210学习笔记五--串口通信 前言 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口接收相关定义 K210串口发送接收测试 完整源码 前言 本人大四学生 ...

最新文章

  1. R语言plotly可视化:plotly可视化箱图、基于预先计算好的分位数、均值、中位数等统计指标可视化箱图、箱图中添加缺口、可视化均值和标准差(With Precomputed Quartiles)
  2. oracle11g 启动报错 缺少系统参数
  3. 内嵌资源html,内嵌元素(HTML)
  4. ML:MLOps系列讲解之《基于ML的软件的三个层次之03 Code: Deployment Pipelines》解读
  5. 全球及中国速冻菠萝市场消费潜力及供需前景调研报告2021-2027年
  6. autocad.net中判断当前被激活的空间
  7. LuoguP1268树的重量【构造/思维】By cellur925
  8. Windows 下 Python 环境搭建
  9. gridsearchcv参数_Python机器学习库Sklearn系列教程(21)-参数优化
  10. 一、auto_test_base
  11. 美团技术leader:写给工程师的十条精进原则
  12. linux centos 网易云音乐,Centos7.4安装网易云音乐教程
  13. 小程序软件有必要申请软件著作权登记么?
  14. Laravel Eloquent:API资源
  15. ThreeJS - 动态更换fbx模型的某个子Mesh现有的纹理贴图为指定的纹理贴图
  16. myeclipse优化配置指南、myeclipse常用功能设置、 myeclipse快捷键
  17. (转载)视频采集学习笔记
  18. 亚马逊鲲鹏系统:批量注册亚马逊买家号软件
  19. Promtail报错处理
  20. 宁波栎社机场停车场怎么收费,栎社机场停车场收费标准

热门文章

  1. 采用个hook技术对writefile函数进行拦截(2)
  2. 算法复习——虚树(消耗战bzoj2286)
  3. MySQL之如何删除重复数据只保留一条
  4. 如何安装部署秋色园QBlog站点
  5. php数组使用json_encode函数中文被编码成null的原因和解决办法
  6. Android拍照流程
  7. tomcat手动发布
  8. tail实时监控日志qps
  9. getReadableDatabase() 和 getWritableDatabase()的区别
  10. 项目管理在企业发展中的作用及未来的发展方向—— 来自项目管理群的讨论