STM32標准庫_03 | 串口printf打印


本篇文章主要介紹STM32的調試利器,串口printf打印輸出,希望能給人以收獲。

1.開發環境

軟件環境

使用MDK5.25版本,芯片包為STM32F4系列。

硬件環境

開發板:STM32F407VGT6開發板,是一款大容量芯片,最高能跑168MHz。

燒錄器:STlink或者Jlink。

2.工程搭建

直接復制上一篇代碼,在工程欄加入/LIB/src文件夾下的串口庫函數文件stm32f4xx_usart.c,在/APP文件夾下加入usart.c和usart.h文件並添加到MDK工程欄。

開始編寫串口初始化函數和重定義printf打印函數。

在usart.c文件中添加串口初始化函數,F407和F103有些區別,1是串口掛載的時鍾總線,2是F103對於串口TX和RX是分別初始化為復用推挽輸出和上拉輸入的。

/*
*********************************************************************************************************
*	函 數 名: uart1_Init
*	功能說明: 串口1初始化函數
*	形    參: 1.bound(串口波特率)
*	返 回 值: 無
*********************************************************************************************************
*/ 
void uart1_Init(u32 bound)
{
        //GPIO端口設置
        GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA時鍾
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1時鍾
 
	//串口1對應引腳復用映射
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9復用為USART1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10復用為USART1
	
	//USART1端口配置
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9與GPIOA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//復用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽復用輸出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10

        //USART1 初始化設置
	USART_InitStructure.USART_BaudRate = bound;//波特率設置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
	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_Tx;	//收發模式
        USART_Init(USART1, &USART_InitStructure); //初始化串口1
	
        USART_Cmd(USART1, ENABLE);  //使能串口1 
	//USART_ClearFlag(USART1, USART_FLAG_TC);   //解決第一個字節丟失問題,如果第一個字節丟失可以加上這行
}

對於重定義printf函數有兩種方法,一種是使用微庫,一種是不是用微庫(正點原子)使用的方法。

1.使用微庫重定義printf函數

注意:printf函數依賴於"stdio.h",在使用的時候記得添加上"stdio.h"。

如果是C++文件則修改成

2.不使用微庫重定義printf函數

在原來的fputc函數的基礎上再加入避免使用半主機模式的一些代碼(參考正點原子)。

可以參考這篇對於半主機模式的理解

小結:所謂重定義就是修改fputc函數的底層代碼,修改成運行一次串口發送一個字節的數據。

3.測試

3.打印方案

編寫打印代碼

於我而言,我個人把打印分成兩種,一種是錯誤打印(一般用於else的后面,或者校驗失敗的地方),另一種就是常規打印,這些打印還可能遇到一些場景,例如我的單片機資源比較少,我就寫程序的時候用一下,或者我想控制我的打印輸出等等。

直接上代碼開講

USER_DEBUG是程序控制的開關,用於單片機資源比較少的時候,我們調試的時候用一下。

Print_Switch是一個接口控制的開關,可用於遠程網絡或者本地串口修改,來開啟或者關閉打印。

當然,我們還可以分很多級別的打印,希望各位舉一反三。

測試

4.總結

這個宏定義最好放在.h頭文件中,方便其他.c文件,后續我會加在Dbg.c和Dbg.h中,對於邏輯復雜的狀態機,用打印的方法是一個很好的調試手段,當然如果遇到死機,那得用仿真器Debug了。

代碼已全部上傳到gitee,希望各位小伙伴們在下載的同時不忘點擊Star,地址:https://gitee.com/Notmi/stm32-standard-peripheral-libraries


免責聲明!

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



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