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 = 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()问题相关推荐
- STM32学习笔记-USART串口通信+与野火STM32F407板载ESP8266进行通信
文章目录 STM32USART介绍 STM32USART框图 第一部分 第二部分 第三部分 发送器 时序图 接收器 第四部分 软件部分: STM32通过USART与板载ESP8266通讯实验 板载WI ...
- STM32学习笔记(三)丨中断系统丨EXTI外部中断(对射式红外传感器计次、旋转编码器计次)
本篇文章包含的内容 一.中断系统 1.1 中断的定义 1.2 中断优先级 1.3 中断的嵌套 1.4 STM32中的中断系统 1.4.1 STM32的中断资源 1.4.2 嵌套中断向量控制器 NVIC ...
- STM32学习笔记之OLED屏
STM32学习笔记--OLED屏 OLED屏的特点: 1. 模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2. 显示尺寸为0.96寸 3. 分辨率为128*64 4. ...
- STM32学习笔记(13)——模数转换ADC
这个月一直忙于准备考试,已经考完一半科目了,偷闲写了这篇文章.因为还没考完试,估计还得咕一段时间了. STM32学习笔记(13)--模数转换ADC 第一部分:ADC功能框图 一.输入电压 二.输入通道 ...
- STM32学习笔记(八)丨ADC模数转换器(ADC单、双通道转换)
本篇文章包含的内容 一.ADC 模数转换器 1.1 ADC简介 1.2 逐次逼近型ADC工作原理 1.3 STM32中的ADC基本结构 1.4 STM32中ADC的输入通道 1.5 STM32中的AD ...
- STM32学习笔记:FLASH读写之二
因为关于STM32的Flash相关的知识点比较多,所以该内容的学习我们分为以下4个部分 1.RAM和ROM的一些基本概念 -- STM32学习笔记:FLASH读写之一 2.STM32的Flash寄存器 ...
- 《STM32学习笔记》2——开发环境的建立
接上文,文中的图片知识,大多数来自视频的截图(来自洋桃电子). 欢迎大家批评指正! STM32学习笔记-专栏 文章目录 一.接口定义 1 芯片引脚整体简介 2 各部分引脚介绍 二.开发板简介 三.IS ...
- KEIL 5.38的ARM-CM3/4 ARM汇编设计学习笔记3——串口Stdio实现
KEIL 5.38的ARM-CM3/4 ARM汇编设计学习笔记3--串口Stdio实现 一.介绍 任务目标 二.工程创建 三.软件设计 第一步,BSP构建 1, 添加前面的pll_config文件 2 ...
- 【K210】K210学习笔记五——串口通信
[K210]K210学习笔记五--串口通信 前言 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口接收相关定义 K210串口发送接收测试 完整源码 前言 本人大四学生 ...
最新文章
- R语言plotly可视化:plotly可视化箱图、基于预先计算好的分位数、均值、中位数等统计指标可视化箱图、箱图中添加缺口、可视化均值和标准差(With Precomputed Quartiles)
- oracle11g 启动报错 缺少系统参数
- 内嵌资源html,内嵌元素(HTML)
- ML:MLOps系列讲解之《基于ML的软件的三个层次之03 Code: Deployment Pipelines》解读
- 全球及中国速冻菠萝市场消费潜力及供需前景调研报告2021-2027年
- autocad.net中判断当前被激活的空间
- LuoguP1268树的重量【构造/思维】By cellur925
- Windows 下 Python 环境搭建
- gridsearchcv参数_Python机器学习库Sklearn系列教程(21)-参数优化
- 一、auto_test_base
- 美团技术leader:写给工程师的十条精进原则
- linux centos 网易云音乐,Centos7.4安装网易云音乐教程
- 小程序软件有必要申请软件著作权登记么?
- Laravel Eloquent:API资源
- ThreeJS - 动态更换fbx模型的某个子Mesh现有的纹理贴图为指定的纹理贴图
- myeclipse优化配置指南、myeclipse常用功能设置、 myeclipse快捷键
- (转载)视频采集学习笔记
- 亚马逊鲲鹏系统:批量注册亚马逊买家号软件
- Promtail报错处理
- 宁波栎社机场停车场怎么收费,栎社机场停车场收费标准