STM32下多串口用法


一個項目用到32下的多個串口,一般STM32C8T6型號擁有3個USART,串口的配置都很簡單,但是要使用的話就得解決他們之間的矛盾,

printf函數到底輸出在哪一個串口中?

先看這函數:

//重定義fputc函數,方便使用printf
int fputc(int Data, FILE *f)
{   
    while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE));      //USART_GetFlagStatus:得到發送狀態位
                                                          //USART_FLAG_TXE:發送寄存器為空 1:為空;0:忙狀態
    USART_SendData(USART1,Data);                          //發送一個字符
    
    return Data;                                          //返回一個值
}

在我們使用printf函數的時候,首先必須重定義fputc函數,在這個函數中,實現數據的發送,然后在     USART_SendData(USART1,Data);  中選擇需要的串口。一般是選擇串口1,所以這種情況下,

使用printf函數會打印到串口1。

 

那么我要用到串口2的printf函數該怎么辦呢 ?

配置什么的還是和串口1一樣,
1.配置usart2的串口配置,gpio,rcc enable。。。。
2.勾選usb micro lib,
3.添加頭文件#include <stdarg.h>,編寫USART2的printf函數:

void USART2_printf (char *fmt, ...)
{
        char buffer[CMD_BUFFER_LEN+1];  // CMD_BUFFER_LEN長度自己定義吧
        u8 i = 0;
        
        va_list arg_ptr;
        va_start(arg_ptr, fmt);  
        vsnprintf(buffer, CMD_BUFFER_LEN+1, fmt, arg_ptr);
        while ((i < CMD_BUFFER_LEN) && buffer)
        {
                USART_SendData(USART2, (u8) buffer[i++]);
                while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); 
        }
        va_end(arg_ptr);
}

仔細看我們會發現,其實這個函數中包含了fputc,然后吧   USART_SendData(USART1,Data);   改為  USART_SendData(USART2,(u8)buffer[i++]);   循環通過串口2發送。

 

還有一種方法就是自己實現 printf的源碼(參考秉火程序):

/*
 * 函數名:USART2_printf
 * 描述  :格式化輸出,類似於C庫中的printf,但這里沒有用到C庫
 * 輸入  :-USARTx 串口通道,這里只用到了串口2,即USART2
 *             -Data   要發送到串口的內容的指針
 *               -...    其他參數
 * 輸出  :無
 * 返回  :無 
 * 調用  :外部調用
 *         典型應用USART2_printf( USART2, "\r\n this is a demo \r\n" );
 *                     USART2_printf( USART2, "\r\n %d \r\n", i );
 *                     USART2_printf( USART2, "\r\n %s \r\n", j );
 */
void USART2_printf ( USART_TypeDef * USARTx, char * 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_TXE) == 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_TXE) == RESET );
                }
                
                Data++;
                
                break;
                
                default:
                Data++;
                
                break;
                
            }         
        }        
        else USART_SendData(USARTx, *Data++);        
        while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );
        
    }
}

然后在這里面修改串口號就可以。

 

參考資料:https://blog.csdn.net/xzongyuan/article/details/28626163

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM