32延時us暫存器 高精度延時函式

2021-10-14 20:42:49 字數 1394 閱讀 9709

在後續我們對講解多個感測器,這幾個感測器對時序的要求都比較高,比如溫濕度感測器dh11,檢視晶元手冊時序,至少就需要微秒級的延時函式。

延時函式的方式一般有兩種:

使用for迴圈的方式,可能會因為硬體的差異,導致延時函式不准,因此這裡我們使用定時器的方式。

開啟之前的timers.c檔案,修改timer_init函式的配置。

pclk仍然等於50000000,將prescaler value改為4,divider value設定為2,

這樣,每減1, 對應0.2us;每減5, 對應1us;從50000減到0,對應10ms。

修改對應的暫存器:

tcfg0 = 4;  /* prescaler 0 = 4, 用於timer0,1 */tcfg1 &= ~0xf; /* mux0 : 1/2 *//* 設定timer0的初值 */tcntb0 = 50000;  /* 10ms中斷一次 */
我們先寫乙個us延時的函式,然後ms延時就呼叫us即可。

因此,us延時函式裡,盡量少呼叫函式。

假如現在要延時nus,我們先將n*5,得到nus對應的「計數時鐘數」。

然後如果傳入「計數時鐘週期」如果大於0,則一直計算過去了多少個「計數時鐘數」,與傳入的「計數時鐘數」相減,直到為零,退出迴圈,也就實現了延時nus。

怎樣計算過去了多少個「計算週期」呢?

自然是當前的值,減去一開始進入函式的值。

但還有一種情況是定時器裡的計數記到0時,會自動變成5000,計數計數,這時候,計算方式就變成了pre+(5000-cur):

/* 盡量少呼叫函式 */void udelay(int n)}
然後是ms延時函式:

void mdelay(int m)
我們可以寫乙個測試函式,簡單的測試下是否可用,測試函式隔1分鐘進行列印一下。

如果us不准的話,放大至s,會有比較大的偏差,這樣可以進行粗略的檢測,精確檢測可以使用示波器等工具。

void hrtimer_test(void)}
前面延時裡的計算還是比較耗費時間的,因此,我們盡量提高cpu的執行時鐘,並且 將盡可能的啟動icache、dcache和mmu。

此外,如果延時過程中,發生了中斷,如果中斷比較耗時的話,就會導致延時可能出現不準確,所以,我們可以延時之前關中斷, 延時之後開中斷;

課後作業:

「新品首發」stm32mp157開發板火爆預售!首批僅300套

STM32 BSRR暫存器和BRR暫存器

置gpioa bsrr低16位的某位為 1 則對應的i o埠管腳置 1 置gpioa bsrr低16位的某位為 0 則對應的i o埠管腳保持不變。置gpioa bsrr高16位的某位為 1 則對應的i o埠管腳置 0 置gpioa bsrr高16位的某位為 0 則對應的i o埠管腳保持不變。置gpi...

STM32預裝載暫存器與影子暫存器

捕獲 比較模組由乙個預裝載暫存器和乙個影子暫存器組成。讀寫過程僅操作預裝載暫存器。在捕獲模式下,捕獲發生在影子暫存器上,然後再複製到預裝載暫存器中。在比較模式下,預裝載暫存器的內容被複製到影子暫存器中,然後影子暫存器的內容和計數器進行比較。根據 timx cr1 暫存器中 apre 位的設定 apr...

STM32蜂鳴器 暫存器

這次實驗犯了個笑話,竟然在巨集定義後面加分號.就像這樣 define 大家千萬不要學我,結果報錯expected expression,還苦惱半天,想為啥操作不了暫存器了?我真愚蠢!剛開始我也不會寫這些東西,其實摸清套路就好,rcc時鐘使能 gpio初始化 相關暫存器初始化 延時函式 串列埠等初始化...