一.串口的中斷觸發
? ? ? ? 一般我們都是使用TXE或者RXNE來觸發中斷,其實還有完整傳輸結束的TC標志位和接收完成的IDLE標志位
? ? ? ? 這兩個標志位有些不同,RXNE標志位只需要讀取寄存器就會自行清除,但是這兩個需要讀取兩個,拿IDLE舉例子
這里需要這么寫,才能清理標志位
二.關于DMA提前人為中斷
????????如果手動disable了DMA,那么TCIF標志位會立馬掛起
但是如果不清除該標志位,DMA就無法啟動
所以我們再配置好DMA后,啟動前,要清理標志位,1,2兩種清理方式,任意一種都行
三.3種關于定義print導向串口輸出的方法
1.覆寫庫函數
基礎概念
關于怎么覆寫標準庫里面的原函數_c語言編譯,怎么覆蓋庫文件的函數-CSDN博客
我們首先需要點開keil中的MicroLIB庫
什么是MicroLIB庫,為什么需要點開?
這是keil的精簡C語言庫,代碼量少很多,他使用是了標準庫的頭文件接口,接口在編譯階段會被鏈接到選擇的庫(比如 MicroLIB)的 實現部分。
同時他的底層實現函數和標準庫的不同
這里我們需要重新定義他的底層fputc()函數,一下定義即可
2.使用sprintf打印到字符數組,再用串口發送字符數組,此方法打印到字符數組
3.將sprintf函數封裝起來,實現專用的printf,此方法就是把方法2封裝起來
方法三涉及到可變參函數,這里介紹說明如何使用和原理
四.可變參函數
1.我們首先需要添加<stdarg.h>頭文件,包括一下宏
首先類似void Serial_Printf(char *format, ...),這種帶有....的函數就是,可變參函數,他允許你
👆這些操作都是合理的
2.實現原理
?
首先每個函數的調用就會構建一個屬于自己的棧空間,存放自己的變量
va_list args;可以理解為生成了一個棧指針
va_start(arg, format);可以理解為將棧指針指向format后
所以使用va_arg(arg, int);取出數據的時候,會直接取走format后面的int類型數據,類似👇操作
?va_end(arg);就是清理掉之前的指針
這樣上面的代碼就很簡單可以看懂了 ,下面的這個代碼也能輕松看懂使用了