Learning Objectives
- 說明電容怎麼儲存電荷,讀懂電容上標示的容量、耐壓與極性
- 用時間常數 τ = R × C 估算 RC 電路充電、放電要多久
- 用 ADC 量電容充電的曲線,從資料找出時間常數
- 說明按鈕彈跳的原因,用 RC 電路或程式去彈跳
電容:會慢慢充滿的小水桶
前幾課的電路只有電阻和 LED:開關一按,電流立刻就到,電壓立刻就穩定。 加上電容(capacitor)之後,電路多了「時間」這個因素:電壓要花一段時間才會升上去,也要一段時間才會降下來。
可以把電容想成一個水桶,電阻是接到水桶的水管:
- 水管越細(電阻越大),水流得越慢,水桶越久才裝滿
- 水桶越大(電容越大),要裝的水越多,也越久才裝滿
- 水位越接近滿,水壓差越小,流進去的速度越慢,所以永遠是「越來越慢地接近滿」
這一課要回答:
- 電容上的數字代表什麼?怎麼接才安全?
- 電容要多久才會充滿?可以算出來嗎?
- 按鈕明明只按一次,程式為什麼會數到好幾次?電容怎麼幫忙?
電容的規格
| 標示 | 意思 | 例子 |
|---|---|---|
| 容量 | 能存多少電荷,單位法拉(F);常用的是 μF(百萬分之一法拉)、nF、pF | 10μF、0.1μF(常寫成 104) |
| 耐壓 | 兩端能承受的最高電壓,要比電路的電壓高,留一些餘裕 | 16V、25V |
| 極性 | 電解電容有正負極(外殼上有一條標示負極的色帶、長腳是正極);陶瓷電容沒有極性 |
電解電容接反、或電壓超過耐壓,可能發熱、鼓起甚至破裂。接電之前先確認極性與耐壓。
電容在微控制器電路裡常做的事
- 去耦電容(decoupling capacitor):在晶片的電源腳旁邊放一顆 0.1μF,晶片突然用電時就近供應,讓電壓比較穩。開發板上那些小小的方塊很多就是它。
- 濾波:把快速跳動的訊號變平滑,例如把 PWM 變成接近固定的電壓。
- 計時與去彈跳:利用「充電需要時間」這件事,做延遲或過濾雜訊。
時間常數 τ = R × C
一顆電容 C 經過電阻 R 接到電壓 Vs,從 0V 開始充電,電容的電壓是:
充電:V(t) = Vs ×(1 − e^(−t ÷ τ))
放電:V(t) = V0 × e^(−t ÷ τ)
其中 τ(讀作 tau)= R × C,單位是秒(歐姆 × 法拉 = 秒)
不必背公式,記住這張表就夠用:
| 經過時間 | 充電到 Vs 的 | 放電剩下 V0 的 |
|---|---|---|
| 1τ | 63.2% | 36.8% |
| 2τ | 86.5% | 13.5% |
| 3τ | 95.0% | 5.0% |
| 5τ | 99.3% | 0.7% |
工程上常說「大約 5τ 就充滿(或放完)」。例如 R = 10kΩ、C = 10μF:
τ = 10000Ω × 0.00001F = 0.1 秒 = 100 ms
1τ = 100 ms 時充到 63.2%,5τ = 500 ms 時幾乎充滿
在下面的示波器小工具裡換不同的 R 和 C,看曲線怎麼變。
逐步看:用 ADC 量電容充電
GPIO23 經過 20kΩ 電阻接到一顆 10μF 電容,電容的電壓接到 ADC 腳位 GPIO34。程式先讓電容放電,再輸出 3.3V 開始充電, 每 50 ms 量一次,量到 63% 就停下來:那時經過的時間就是時間常數。 算算看 τ = 20kΩ × 10μF = 200 ms,看量到的結果是否吻合。(模擬器裡電容電壓是依這組 R、C 事先算好的曲線。)
按鈕彈跳
按鈕裡面是兩片金屬,按下時互相碰到。金屬片碰到的瞬間會彈開、再碰到、再彈開, 在幾毫秒之內接觸好幾次才穩定,這叫彈跳(bounce)。人感覺不到,但微控制器一秒可以讀上百萬次,每一次接觸它都看得到。
如果用中斷「腳位一從 1 變成 0 就加 1」,按一次可能數到三、四次。下面的範例裡,按鈕在 1000 ms 時按下, 接觸、彈開又接觸了三次(電路規格裡寫成 1000~1002、1003~1004、1006~1600 ms 三段)。
逐步看:按一次,數到三次
看中斷處理函式 on_press 被呼叫了幾次,以及每次呼叫的時間只差幾毫秒。
兩種去彈跳的方法
硬體去彈跳:在按鈕旁邊加一顆電容,配合電阻組成 RC 電路。彈跳時電壓只會小幅跳動, 要按住夠久,電容的電壓才會降到「低電位」的門檻以下。常見的組合是 10kΩ 與 1μF(τ = 10 ms)。 腳位如果有施密特觸發(Schmitt trigger)輸入,上升與下降用兩個不同的門檻,緩慢變化的電壓也不會來回跳。
軟體去彈跳:不加零件,在程式裡規定「上一次觸發後的一小段時間內(例如 50 ms),再觸發都不算」。
last = -1000 # 上一次觸發的時間
def on_press(pin):
global count, last
now = time.ticks_ms()
if time.ticks_diff(now, last) > 50: # 和上一次相隔超過 50 ms 才算
count += 1
last = now
兩種方法常常一起用:硬體先把大部分雜訊濾掉,程式再把關。下面的電路模擬器裡,按鈕按了三次,每次都有彈跳。
小測驗:時間常數
電阻 10kΩ、電容 100μF,時間常數 τ 是多少?
電容從 0V 開始充電,經過 1τ 時,電壓大約是電源電壓的多少?
下面的程式會印出什麼?
import math
R = 10000
C = 0.000047
tau = R * C
print(round(tau, 2), round(3.3 * (1 - math.exp(-1)), 2))
小測驗:去彈跳
按鈕按一次,程式卻數到好幾次,最主要的原因是什麼?
下面的程式模擬軟體去彈跳(edges 是每次觸發的毫秒數),會印出什麼?
edges = [100, 103, 105, 400, 402, 900]
count = 0
last = -1000
for t in edges:
if t - last > 50:
count += 1
last = t
print(count)
硬體去彈跳用了 100kΩ 與 10μF(τ = 1 秒),最可能出現什麼問題?
重點整理
- 電容儲存電荷,單位法拉(F),常用 μF;電解電容有極性,耐壓要高於電路電壓。
- 經過電阻充放電時,時間常數 τ = R × C;1τ 充到 63.2%,約 5τ 就算充滿或放完。
- 去耦電容放在晶片電源腳旁邊穩定電壓;RC 電路也能濾波與計時。
- 按鈕彈跳讓一次按下變成好幾次觸發:可以用 RC 電路(硬體)或「一段時間內不重複計算」(軟體)去彈跳。
- 去彈跳的時間太短擋不住彈跳,太長會讓按鈕變遲鈍、甚至漏掉。
下一課用電晶體與繼電器,讓 3.3V 的腳位控制需要更大電流的馬達與燈。