stm32学习笔记----双串口同时打开时的printf()问题
生活随笔
收集整理的這篇文章主要介紹了
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()问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java内部类的使用
- 下一篇: Angular中ngModel的$ren