C語言中關聯計數器的協同管理

2022-08-30 10:45:12 字數 2337 閱讀 8105

1 起因

在嵌入式應用中,對於很多控制器管腳傳過來的訊號要做軟體防抖。如下面的圖1:

在狀態s1時,若c1的訊號過來了,定時器t1開始計時;當t1的值達到v1時,就認為c1的訊號是有效的。同理,s2與s3是一樣的情況。

圖1 關聯定時器

計數器t1、t2和t3是互相關聯的。它們之中最多有乙個不為0。每當乙個計數器在計數前,都要復位其它計數器。

例如:假如t1正在計數,v1的值為500。當t1計數到200時,a1條件不符合,進入了a2條件,就要先復位t1定時器,然後再對t2進行計數。這樣保證了當a1條件符合時,t1可以從0開始計數,達到了設計目的;否則t1就是從200開始計數了。

圖1中只有3個計數器,當計數器很多時,甚至在condition=c1處再加入幾個判斷,不同定時器的操作就會很複雜,而且維護起來很困難。所以有必要把幾個計數器集中起來進行管理。

2 分析

在圖1中,先提出基本的實現:

實現a1:當state轉移之後,首先要復位與此state下不相關的計數器(例子中只有乙個t1;若不止乙個的話,是不一樣的);

實現a2:然後根據condition的情況,相關計數器復位(c1)或是繼續計算(t1++);

當計數器很多時,若每乙個計數器分配一塊記憶體,消耗很大;同時在需求中,最多只有乙個計數器在工作,所以就定義乙個計數器,通過其它名稱來判斷是為個條件計數。

實現a1就可以變成將計數器復位。考慮到這是乙個迴圈執行的函式,就要保證不能每一次迴圈都要復位,這樣就使用下面的演算法完全沒有作用了;

實現a2的計數器復位和實現a1一樣,繼續計算就是自增1;

現在就變成了兩種情況:計數器復位和計數器數值自增1。而它們的前提是要分辨出前後操作的計數器是否一致。

那麼計數器的名稱在哪一步確定呢?

在圖1中,因為條件c1並不是一定不會成立,這樣當前計數器的計數和其它計數器的復位完全沒有關係了,對於程式設計來說,不好操作,所以要更改程式流程,如圖2:

圖2 關聯定時器

進而,實現就變成了如下的樣子

實現b1:在不符合當前計數器計數條件下,將計數器復位,同時將計數器的名稱復位;

實現b2:在符合當前計數器計數的條件下,當前要使用的計數器名稱與上一次的名稱不同,更新計數器名稱;

實現b3:在符合當前計數器計數的條件下,當前計數器名稱和上一次計數器的名稱是相同的,計數器中的數值自增1。

根據實現b1,要為圖2中的每個計數器分配乙個名稱。

通過對比c1~c4四種情況的計數器操作,可以看出根據這一次和上一次操作計數器名稱的不同,每次操作最多修改兩個計數器的值。

表1 不同情況對計數器的處理

lastorder

order

實際操作00

什麼也不做

0>0

計數器等於1

>0

0計數器復位

>0

=lastorder

計數器加1,不能讓計數器溢位

>0

!=lastorder

計數器等於1

現在已經很明確了,可以開始寫**了。

3 編碼

如下:

#define timer_num       4       //

計數器個數

#define reset_all 0 //

復位名稱

#define t1 1

#define t2 2

#define t3 3

#define t4 4ubyte countermanage(ubyte order)

else

}else

else

if (order =lastorder)

else

}lastorder =order;

return0;}}

上面的**對於計數器溢位的處理並沒有做相應的設計。

同時,對於幾種條件的判斷也可以分成下面三種情況

order=0、order=lastorder和order!=lastorder

我不是很喜歡這種寫法,雖然**少了,但是給理解增添了一些難度。我的標準就是一看就能明白什麼意思,越簡單越好。

另,流程很重要。像圖一的流程,對於圖二中多個condition的情況,很難實現上面的方法。

記憶體管理之計數器的基本操作

記憶體管理 管理範圍 任何繼承了nsobject的物件,對其他基本資料型別 int char float double struct enum等 無效。棧 中放區域性變數 堆 物件放在堆上 指標是區域性變數。棧空間的東西是系統自動 作用域結束後,系統自動 棧空間。堆空間的記憶體是動態儲存的,即使沒有...

C語言中的記憶體管理

先說一下c語言中的記憶體管理。1.動態記憶體分配 原因 程式執行過程中,很有可能需要一些額外的記憶體空間。動態記憶體從 來,還給誰?這塊是記憶體是系統專門預留出來的,給程式動態的分配和動態的歸還的。當free函式的引數為空的時候,那麼我們的free什麼事都不做了。clloc和realloc的用法見截...

C語言中的儲存管理

程式編寫完成後。程式首先要裝載到計算機的核心或者半導體記憶體中,之後執行程式。有四個邏輯段 以上4類根據作業系統和編譯器的不同,堆和棧既可以是被所有同時執行的程式共享的作業系統資源,也可以是使用程式獨佔的區域性資源。堆與棧通過記憶體組織方式可以看到,堆用來存放動態記憶體分配空間,而棧用來存放區域性資...