1. 程式人生 > >STM32下多串口用法

STM32下多串口用法

sdn 什麽 ron 情況下 pla case npr start audio

一個項目用到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

STM32下多串口用法