---
# System prepended metadata

title: GPIO&PWM
tags: [嵌入式]

---

# GPIO&PWM

#### 組員: A1105129 吳祥毅 M1115114 楊皓翔
#### 指導老師:林宏益
---
### 一、實驗目的 
使用Raspberry Pi 的 GPIO，從中了解數位與類比的輸入/輸出、PWM、Debounce和中斷觸發
### 二、實驗原理
* 透過Debounce解決按鍵放開到回彈之間的訊號抖動問題
* 按鍵在輪詢與中斷，CPU上資源占用問題
* 上緣觸發的波形變化
* 透過PWM調整一固定周期訊號的高電位輸出時間，改變平均輸出電壓
### 三、實驗材料
1. 樹莓派(Raspberry Pi 1)
2. UART模組
3. 電阻、LED、杜邦線、麵包版
### 四、實驗步驟
>打開樹莓派後，將各實驗存為.py檔案，在command line輸入`python 檔名.py`，以執行pyhton的檔案


**1. 輸出模式**
```python=
# 以下程式可以使 GPIO17 一秒變換一次狀態，起始輸出高電位。
from time import sleep
import RPi.GPIO as GPIO

output_pin = 17
state = 1
GPIO.setmode(GPIO.BCM)
GPIO.setup(output_pin, GPIO.OUT, initial=1)
while 1:
    state = state +1
    a=state%2
    GPIO.output(output_pin, a)
    sleep(1)
```
**2. 輸入模式**
```python=
import RPi.GPIO as GPIO

def callback_func(channel):
    print(f"Channel {channel} generated interrupt")

input_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(input_pin, GPIO.IN, GPIO.PUD_DOWN)
GPIO.add_event_detect(input_pin, GPIO.RISING)
GPIO.add_event_callback(input_pin, callback_func)

# 此無限迴圈是為了防止程式結束，程式結束會清除所有 GPIO 設定。
while True:
    pass

```
**3. PWM模式**
```python=
from time import sleep
import RPi.GPIO as GPIO

output_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(output_pin, GPIO.OUT)
pwm_var = GPIO.PWM(output_pin, 10)
while True:
    
    pwm_var.start(10)
    sleep(1)
    pwm_var.ChangeDutyCycle(70)
    sleep(1)

```
**4. Four PWM Signal Output**
```python=
from time import sleep
import RPi.GPIO as GPIO

OutPut_Pin1 = 17
OutPut_Pin2 = 18
OutPut_Pin3 = 22
OutPut_Pin4 = 27
GPIO.setmode(GPIO.BCM)
GPIO.setup(OutPut_Pin1, GPIO.OUT)
GPIO.setup(OutPut_Pin2, GPIO.OUT)
GPIO.setup(OutPut_Pin3, GPIO.OUT)
GPIO.setup(OutPut_Pin4, GPIO.OUT)
pwm_1 = GPIO.PWM(OutPut_Pin1 , 1000)
pwm_2 = GPIO.PWM(OutPut_Pin2 , 1000)
pwm_3 = GPIO.PWM(OutPut_Pin3 , 1000)
pwm_4 = GPIO.PWM(OutPut_Pin4 , 1000)
while 1:
    pwm_1.start(5)
    pwm_2.start(5)
    pwm_3.start(5)
    pwm_4.start(5)
    sleep(1)
    pwm_1.ChangeDutyCycle(80)
    pwm_2.ChangeDutyCycle(80)
    pwm_3.ChangeDutyCycle(80)
    pwm_4.ChangeDutyCycle(80)
    sleep(1)
    pwm_1.stop()
    pwm_2.stop()
    pwm_3.stop()
    pwm_4.stop()
```
### 五、實驗結果
**1. 輸入模式**
![](https://hackmd.io/_uploads/BJPwPC5ea.png =50%x)![](https://hackmd.io/_uploads/rJmivAcgT.jpg =50%x)
>**結論**
>
>由BCM選擇輸出腳位，一秒更新一次高低電位。


---

**2. 輸入模式**
![](https://hackmd.io/_uploads/SyevJKRqea.jpg =50%x)

>**結論**
>先使用下拉電阻，在按鍵(本實驗以GPIO17導通VCC)觸發中斷函式時產生了短期波動，除了可使用硬體電容、電感除去，也可使用軟體Debounce的方式，加入等待累計時間解決該問題。



---

**3. PWM**
![](https://hackmd.io/_uploads/HyzJo0qxp.jpg =50%x)![](https://hackmd.io/_uploads/B1gvsR9lp.jpg =50%x)



>**結論**
>透過產生不同的佔空比達到不同程度電壓輸出，實驗以佔空比10%和佔空比70%交替循環。


---

**4. Four PWM**

![](https://hackmd.io/_uploads/r1iNkZsep.jpg =50%x)

>**結論**
>分別對4個GPIO腳位產生不同的佔空比，達到不同程度電壓輸出，實驗以佔空比5%和佔空比80%交替循環。

### 六、實驗討論&心得
在實驗中，除了PWM外，我認為在輪詢、中斷與訊號抖動，都是值得討論的地方。這次實驗能夠瞭解到輪詢弊處及中斷優點，且對於Bounce有初步了解，而不論是透過硬體或軟體來解決Bounce的問題，也值得我們深入探討。
### 七、參考文獻
:::danger
參考文獻 : 
 * [助教的HackMD](https://hackmd.io/@neko-yoru/rJrW8nbkp) //  [Debounce](https://edisonyu71.blogspot.com/2017/08/debunce.html)
:::
:::info
* 編輯人員 ：[name=吳祥毅] // [name=楊皓翔]
:::