---
tags: 單晶片助教
---
# [5] Arduino講義:SPI、I²C<!--、藍芽模組(UART)~-->
## 課程大綱
[ToC]
# Serial communication-UART/I²C/SPI/(GPIO)

# Arduino講義:Serial Communication (UART/SPI/I²C)
## Intoduction of UART
* 全文為 **Universal Asynchronous Receiver/Transmitter** ,即**通用非同步收發傳輸器**,是一種硬體介面。
* 資料傳輸硬體會根據 **是否提供時脈訊號** 區分為
1. 同步傳輸 (Synchronous Receiver/Transmitter)
2. 非同步傳輸 (Asynchronous Receiver/Transmitter)
同時根據 **資料流向** 被區分為
1. 單工 (simplex)
2. 半雙工 (half-duplex)
3. 雙工 (duplex)
* 而UART是一種非同步收發傳輸器,其特性為
* 全雙工
* 串列
* 非同步
* [相關動畫](http://wiki.csie.ncku.edu.tw/embedded/USART_DataTransmission.gif)
---
### 單工、半雙工與雙工
| 單工 | 半雙工 | 全雙工 |
| -------- | -------- | -------- |
|| ||
|只支持信號在一個方向上傳輸(正向或反向),任何時候不能改變訊號的方向。 EX:計算機和印表機之間的通信、B.B.Call。 | 允許信號在兩個方向上傳輸,但同一時間只允許信號在一個信道上單向傳輸。EX:傳統的對講機。 |允許數據同時在兩個方向上傳輸,即有兩個信道,因此允許同時進行雙向傳輸。 EX:電話、手機、RS232。 |
* 原文網址:https://kknews.cc/zh-tw/other/y2av3rj.html
---
### 非同步 (Asynchronous) v.s 同步 (Synchronous)
* 非同步

* 雙方有各自的時脈, 在傳送資料時插入額外資訊,表示資料起始、結束。優點是設定時間短、硬體成本低、機器時脈不同也能傳資料,缺點是單次傳輸的資料量較少。
* EX : RS-232 (實現方式簡單低廉)、 RS-422 (較長距離的傳輸)、RS-485 (較多的裝置連接數目)。
* 同步

* 雙方共用時脈(一次只做一件事),額外提供時脈訊號,使兩端機器在溝通時能夠藉此同步收發資料。比起非同步傳輸,同步傳輸不需要 start/stop bit ,因此能夠一次傳較多的資料。
* EX : I2C 、 SPI 。
---
### 串列 v.s 並列
* 串列

* 一次傳送一個 bit,傳輸速率較慢、成本較低、可遠距離傳輸。
* EX :滑鼠、鍵盤、USB、HDMI、RS-232 介面。
* 並列

* 一次傳送多個 bit,傳輸速率快、成本高、易受雜訊干擾,僅限短距離使用。
* EX :25Pin D-Type印表機、顯卡PCI介面。
<!-- * 注意:並列傳輸的線路較多,但傳輸速度不一定比較快(因為接收端要同時將傳進來的資料整合及排列,虛耗額外的位元及處理時間)-->
[參考資料](https://zh.wikipedia.org/wiki/%E6%B3%A2%E7%89%B9%E7%8E%87)
---
## Introduction of SPI
* SPI 是 Serial Peripheral Interface的縮寫 ,中文叫做序列周邊介面
* 一種主從式架構的同步資料協定,用於短距離通訊
* SPI 裝置之間使用<font color="red">全雙工模式通訊</font>,包含一個<font color="red">主機(master)</font>和一個或多個<font color="red">從機(slave)</font>
* **SPI** : <font color="red"> 全雙工、串列、同步</font>
* 主要用以連接 ADC、DAC、EEPROM、通訊傳輸 IC...等週邊晶片
|模組名|模組外觀|
|:--:|:--:|
|MCP3008 ADC||
|PCM1794 DAC||
|ILI9341觸碰液晶螢幕||
|ENC28J60網路擴展模組||
* [模組來源](https://www.taiwaniot.com.tw/)
### SPI 接腳名稱及意義
* Arduino Uno
| 接腳名稱 | 腳位 | 說明 |
| -------- | :--------:|--------|
| MOSI (Master Output,Slave Input)|11| master 數據輸出,slave 數據輸入(主出從入)|
| MISO (Master Input,Slave Output) |12| master 數據輸入,slave 數據輸出(主入從出)|
| SCLK/SCK (Serial Clock)|13| 時脈信號,由 master 產生並控制(Clock) |
| SS (Slave Selected) |10| LOW(低電位)時表示裝置可以與Master通訊(Enable)|
* 其他

* SPI 匯流排:
* 單一主機對單一從機

* 單一主機對複合從機
主機將欲操作之從機選擇線拉低(SS to LOW),再分別透過 MOSI/MISO 啟動數據發送/接收。

* SPI優點有三,一是非常簡單的硬體介面,二是完整的傳輸位協定靈活性,訊息大小、內容、目的可任意選擇,三是slave裝置直接使用master裝置的clock,不需要精密的振盪器。
* SPI也有缺點,一是隨著連接裝置數的增加,線路也是要增加的,二是通常只支援一個主裝置。
#### 傳輸方式
* 當 Master 對 Slave 做 select 之後 (連接到該 slave 的 SS 拉 low), Master 開始送出 clock, 同時 Master 的資料 (MSB, 最高位元), 也由 shift register 推出,以在 MOSI 上維持住它的值,而 Slave 的資料也是在同一時間送到 MISO,說明了 SPI 是一個全雙工同步的訊號系統。

---
## Data Modes
* CPOL(Clock Polarity)
* 用來決定在空閒時,時脈(SCK)信號線上的電位是HIGH還是LOW
* 寫入1時,時脈(SCLK)閒置時為HIGH;寫入0時,時脈(SCLK)閒置時為LOW。
write 1 
write 0 
| CPOL0 | Leading edge | Trailing edge |
| -------- | --------| --------|
| 0 | Rising | Falling |
| 1 | Falling | Rising |

* CPHA(Clock Phase)
* 用來決定要在時脈(SCK)的前緣或後緣取樣
| CPHA0 | Leading edge | Trailing edge |
| -------- | --------| --------|
| 0 | Sample | Setup |
| 1 | Setup | Sample |
### The Table of SPI Modes
| SPI Mode | Conditions | Leading Edge |Trailing Edge|
| -------- | --------| --------|--------|
|0| CPOL=0, CPHA=0 | <font color="red">Sample (Rising)</font> | Setup (Falling)|
|1| CPOL=0, CPHA=1 | Setup (Rising) | <font color="red">Sample (Falling)</font>|
|2| CPOL=1, CPHA=0 | <font color="red">Sample (Falling)</font> | Setup (Rising)|
|3| CPOL=1, CPHA=1 | Setup (Falling) |<font color="red">Sample (Rising)</font>|
:::success
舉例:CPOL =0 表示 clock 原本在 low,CPHA =0 表示資料在第1個 edge 被讀取. 也就是 rising edge 被讀取。其他以此類推。
:::
{%youtube 4zx0s9ZKYZY %}
<!-- * 平常使用 SPI Library 時,SPI Mode 預設值為0,SCLK 為4Mhz。
``` c++=
SPISettings() {
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
}
```
### SPI Transfer Format with CPHA = 0

### SPI Transfer Format with CPHA = 1
 -->
---
### 相關函數(記得include SPI.h喔~)
| 函數 | 作用 |
| -------- | -------- |
| SPI.begin()| 通過將 SCK,MOSI 和 SS 設定為輸出,將 SCK 和 MOSI 設為LOW,SS 為HIGH來初始化 SPI 匯流排。|
|SPI.end()|結束 SPI Bus|
|SPI.setBitOrder(order)|設定數據在 SPI Bus 上傳送順序為低位元(`LSBFIRST`)優先或高位元(`MSBFIRST`)優先|
|SPI.setClockDivider(divider)|設定 SPI 時脈的除數(Arduino硬體時脈為16Mhz),可用的分頻器為 2,4,8,16,32,64 或 128,預設設定為 SPI_CLOCK_DIV4|
|SPI.transfer(val)|由 SPI 介面發送並接收 1 個 byte 資料|
---
## LAB1-1
* 實驗目的 :利用 SPI 進行 Arduino 間通訊,傳送 **Happy!**
* Arduino UNO 內定 10,11,12,13 為 SPI 通信界面使用
* Pin 10 :SS chip select從設備致能信號,由主設備控制
* Pin 11 : MOSI 主設備數據輸出,從設備數據輸入
* Pin 12 : MISO 主設備數據輸入,從設備數據輸出
* Pin 13 : SCLK ,由主設備產生
* hint:[code參考連結](http://www.tastones.com/zh-tw/tutorial/arduino/arduino_serial_peripheral_interface/)
* schematic

* 參考程式:Master example
<!--https://imgur.com/aOMFjhi.png -->
```c++=
#include <SPI.h>
void setup (void) {
Serial.begin(115200);
digitalWrite(SS, HIGH); // 確保SS初始狀態為HIGH
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV8);//設定時脈為16/8 = 2 Mhz
}
void loop (void) {
char c;
digitalWrite(SS, LOW); //開始與從機通訊 //SS pin為10
// 傳送字串
/*
Do Something
*/
digitalWrite(SS, HIGH); // 關閉與從機的通訊
delay(2000);
}
```
* Slave example
<!--https://imgur.com/r3NicNc.png -->
```c++=
#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;
void setup (void) {
Serial.begin (115200);
pinMode(MISO, OUTPUT); //設定主入從出
SPCR |= _BV(SPE); //開啟從機的SPI通訊
indx = 0; // buffer 裡頭為空
process = false;
SPI.attachInterrupt(); //啟用中斷函式
}
ISR (SPI_STC_vect){ //SPI中斷程序
byte c = SPDR; //從SPI Data Register獲取資料(byte)
/*
Do Something
*/
}
void loop (void) { // 等待中斷函式回傳true
/*
Do Something
*/
}
```
<!-- #include <SPI.h>
char buf [100];
volatile byte pos;
volatile bool process_it;
void setup (void)
{
Serial.begin (115200);
SPCR |= bit (SPE); //開啟從機的SPI通訊
pinMode (MISO, OUTPUT); //設定主入從出
pos = 0; // buffer 裡頭為空
process_it = false;
SPI.attachInterrupt(); //啟用中斷函式
}
ISR (SPI_STC_vect) //SPI中斷程序
{
byte c = SPDR; //從SPI Data Register獲取資料(byte)
Do something
process_it = true;
}
void loop (void) // 等待中斷函式回傳true
{
if (process_it)
{
Do something
}
}
``` -->
* SPCR

* SPCR Register

[1.相關暫存器程式碼參考資料](https://medium.com/%E9%96%B1%E7%9B%8A%E5%A6%82%E7%BE%8E/arduino-avr-18-spi-communication-9c9a6532a5ee)
[2.參考資料](https://www.sparkfun.com/datasheets/Components/SMD/ATMega328.pdf)
* ISR 介紹 [click here](http://programmermagazine.github.io/201407/htm/article1.html)
* 參考結果 :
{%youtube s6FiiVmn2TE %}
<!-- :::info
關於中斷函式:[**點我**](http://coopermaa2nd.blogspot.tw/2011/04/attachinterrupt.html)
::: -->
<!--## LAB1-2
* 實驗目標 :兩個Arduino都分別帶有一個LED和一個按鈕。按下一端的按鈕,使另一端的LED亮起,放開後熄滅,
* 主機Arduino的LED可以通過從機Arduino的按鈕來控制
* 從機Arduino的LED可以通過主機Arduino的按鈕來控制
* 示範影片 :
<iframe width="560" height="315" src="https://www.youtube.com/embed/W1SFkGn0vdQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>~~~~
* Master example:
```c++=
#include<SPI.h>
#define LED 7
#define buttonpin 2
int button;
int x;
void setup (void){
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8); //設定時脈為 16/8 = 2 Mhz
digitalWrite(SS,HIGH); // 確保ss初始狀態為high
Serial.begin(115200);
pinMode(buttonpin,INPUT);
pinMode(LED,OUTPUT);
}
void loop(void){
/*
do something
*/
}
```
* Slave example
```c++=
#include<SPI.h>
#define LED 7
#define buttonpin 2
volatile boolean received;
volatile byte Slavereceived;
int button;
int buttonvalue;
void setup(){
Serial.begin(115200);
SPCR |= bit (SPE); //開啟從機的SPI通訊
pinMode(MISO,OUTPUT); //主入從出
pinMode(buttonpin,INPUT);
pinMode(LED,OUTPUT);
received = false;
SPI.attachInterrupt(); //啟用中斷函式
}
ISR (SPI_STC_vect){ //SPI中斷程序
Slavereceived = SPDR; //從SPI Data Register獲取資料(byte)
received = true;
}
void loop(){
if(received){
/*
do something
*/
}
}
```
<!--master code
#include <SPI.h>
#define button 2
int buttonvalue;
int x;
void setup() {
digitalWrite(SS,HIGH);
pinMode(button,INPUT);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8);
}
void loop() {
byte Mastersend;
buttonvalue=digitalRead(button);
if(buttonvalue == HIGH)
{x=1;}
else
{x=0;}
digitalWrite(SS,LOW);
Mastersend=x;
SPI.transfer(Mastersend);
digitalWrite(SS,HIGH);
delay(10);
// put your main code here, to run repeatedly:
}
slave code
#include <SPI.h>
#define LEDpin 7
volatile boolean received;
volatile byte Slavereceived;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LEDpin,OUTPUT);
SPCR |= _BV(SPE);
pinMode (MISO,OUTPUT);
received = false;
SPI.attachInterrupt();
}
ISR(SPI_STC_vect)
{
Slavereceived = SPDR;
received = true ;
}
void loop() {
if(received)
{
if(Slavereceived==1)
{
digitalWrite(LEDpin,HIGH);
Serial.println("Slave LED ON");
}
else
{
digitalWrite(LEDpin,LOW);
Serial.println("Slave LED OFF");
}
::: -->
---
## Introduction of I²C
* I²為Inter-Interated Circuit的簡稱,中文名稱叫積體匯流排電路
* 一種串列通訊匯流排
* 主要應用在board-to-board,無法使用在長距離通訊上
* 被應用在各種控制架構上,Ex:系統管理匯流排、電源管理匯流排、智慧平台管理介面....等
## I²C Bus

* I²C 使用兩條雙向 open-drain Line
* SDA : Serial Data Line, holds Data or address signal
* SCL : Serial Clock Line, holds Clock signal
* 導通時是低電位,不導通時float,所以利用電阻(pullup resistor)將電位拉高。常用電壓為 +5 V or +3.3 V
* IO 必須是 open drain (or open collector in TTL)
* bus 為 wired-AND configuration
## Timing Diagram

* 當未傳輸時(IDLE 狀態) ,SCL 和 SDA 都會維持在 high 電位
* SCL 為 high 時,表示 SDA 上的資料為有效,此時 SDA 的值不能改變,以確保可以收到到正確的 SDA 狀態
* SCL 為 low 時,SDA 的狀態可以改變
* 當 SCL 為 high 時,如果 SDA 變動,只有兩種情況:
* SDA由 "1" 變 "0" ---> START
* SDA由 "0" 變 "1" ---> STOP

## Arbitration procedure of two masters

* 避免同時間有 2個以上的master (不同資料) 控制 I²C
* 利用 bus wired-AND 的機制,若 Master 1 欲將 SDA logic 拉高,最後卻 SDA logic 為低,代表仲裁輸了,該 master 立即停止動作
* 輸掉的 master 寧可先放棄 (Back Off) 等候,到看見停止狀態的出現才開始傳送
{%youtube u62_Rjd5oMY %}
---
## Lab2-1:
* 接線圖:


* Mirotek 1602 I²C 模組說明:
* 是一個16字元乘2行LCD顯示螢幕,帶有藍色背景和白色背光
* 內置Arduino IIC / I2C接口
* 實驗影片:
{%youtube 3t7jcdBhbDE %}
* 程式範例:
* [下載LCD_I2C模組程式庫](https://github.com/johnrickman/LiquidCrystal_I2C)
* [指令參考](http://maker.tn.edu.tw/modules/tad_book3/page.php?tbsn=16&tbdsn=284)
```c++=
#include <Wire.h> // I2C程式庫
#include <LiquidCrystal_I2C.h> // LCD_I2C模組程式庫
LiquidCrystal_I2C lcd(0x27, 16, 2);// LCD I2C位址,默認為0x27或0x3F,依據背板的晶片不同而有差異,16、2為LCD顯示器大小。
const int sw_up = 2; //按鈕1
const int sw_down = 3; //按鈕2
int count;
void setup() {
lcd.init();
lcd.backlight();
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);//為了下拉電阻設置5v
pinMode(sw_up, INPUT_PULLUP); //內建上拉電阻
pinMode(sw_down,INPUT);
}
void loop() {
bool swstate_up = digitalRead(sw_up);
bool swstate_down = digitalRead(sw_down);
if(swstate_up==LOW){
/*
Do something
*/
}
else if(swstate_down==HIGH){
/*
Do something
*/
}
lcd.setCursor(5,0);//5是空五格,0是第一行
/*
Do something
*/
}
```
## Bonus
* 實驗目標:
* title為組別人數閃爍3下,接著螢幕顯示停留在Use Serial Monitor,進入Serial Monitor,分別輸入組員號碼,lcd將顯示該組員生日
* Hint:
lcd.noBacklight() 為關閉背光的指令
* 範例影片
{%youtube H4_qAhLU6ck %}
* 參考程式:
```c++=
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // 設定 LCD I2C 位址
void setup() {
/*
do something
*/
Serial.begin(9600);
for(int i = 0; i < 3; i++) {
/*
do something // 閃爍二次
*/
}
/*
do something
*/
}
void loop() {
if(Serial.available()){
/*
do something
*/
switch(num){
/*
do something
*/
}
}
}
```
---
<!--## Bluetooth
* 藍芽模組 HC-05、HC-06,使用 UART 介面與 Ardunio 溝通。
* 藍芽模組也可以視為一塊 MCU 並且可以透過 UART 介面進行設定。
* 設定方式:
* 透過 USB to UART 轉換電路 ,從電腦開啟 Serial Port 做寫入動作。
* 利用 Ardunio uno 開發板本身就有的 IC 來做轉換即可寫入 AT 指令。
#### 藍芽開發環境設定:
* 接線:
| Arduino | 藍芽模組 | 備註 |
| -------- | -------- | -------- |
| 5V | VCC |注意電源不可接錯 |
| GND | GND |注意電源不可接錯 |
| RXD(pin10)| TXD | |
| TXD(pin11)| RXD | |


* 程式碼:
```c++=
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // 宣告10腳位為Arduino的RX 、11為Arduino的 TX
char val; //儲存接受到的資料變數
void setup() {
Serial.begin(9600);
BTSerial.begin(38400); //注意,HC-06要設定成9600(bps)
}
void loop() {
// 若收到「序列埠監控視窗」的資料,則送到藍牙模組
if (Serial.available()) {
val=Serial.read();
BTSerial.print(val);
}
// 若收到藍牙模組的資料,則送到「序列埠監控視窗」
if (BTSerial.available()) {
val=BTSerial.read();
Serial.print(val);
}
}
```-->
<!--### 進入AT模式的方法說明:
注意:若要進入AT模式則,要先確保不能有任何裝置與藍芽模組連線。
以下分為HC-05與HC-06說明:
### HC-05:
* **同時按住紅框鈕及接上 5v 即可進入 AT 模式。**
在尚未與裝置連線之前,HC-05板子上的LED快速閃爍,成功進入AT模式後,LED將兩秒閃爍一次。

* **Serial Port設定:**
* 打開 Serial Port。
* Serial Monitor 的鮑率選**9600**,另外一個選項要選 **NL&CR**,即可下 AT 指令。
* 輸入 AT 指令第一次會出現 ERROR:(0),第二次輸入 AT 出現 OK ,即可進入 AT 模式。
* 詳細AT指令請參考以下AT指令表。

### HC-06:
* HC-06與任何裝置連線之前,只要有通電,都是在AT模式的狀態。因此要進入AT模式,只須**確保HC-06沒有與其他裝置相連即可。**
* **Serial Port設定:**
* 打開 Serial Port。
* Serial Monitor 的鮑率選**9600**,另外一個選項要選 **沒有結尾行**,即可下 AT 指令。
* 輸入 AT 出現 OK ,即可進入 AT 模式。
* 詳細AT指令請參考以下AT指令表。
-->
<!--### AT指令表:
* **AT指令版本HC-05:**
| 指令 | 序列埠回應 | 功能 |
| -------- | -------- | -------- |
| AT | OK | 確認藍芽與序列埠溝通正常 |
|AT+UART? | +UART:XXXXX,0,0| 得知目前Baud rate設定 |
|AT+ADDR? | +ADDR:98d3:b1:fd6ece| 查詢address |
| AT+VERSION| 版本資訊 | 查看韌體版本 |
| AT + NAME=XXXX | OK | 設定藍芽名稱 |
| AT + PSWD=XXXX | OK | 設定密碼 |
| AT + UART=38400,0,0 (鮑率 , 停止位元 , 同位位元) | OK |設定鮑率為38400 |
| AT+ROLE=1 | OK | 設定主動模式 |
| AT+BIND=XXXXXXXX | OK | 綁定藍芽位置 |
| AT+CMODE=0 | OK | 指定藍芽位置連接模式 |
| AT+RESET | OK | 重啟藍牙 |
* **AT指令版本HC-06** :
| 指令 | 序列埠回應 | 功能 |
| -------- | -------- | -------- |
| AT | OK | 確認藍芽與序列埠溝通正常 |
| AT+VERSION| 版本資訊 | 查看韌體版本 |
| AT+NAMEXXX | OKsetname | 設定藍芽名稱 |
|AT+PINXXXX | OKsetPIN | 設定密碼 |-->
<!--### 將兩個藍芽模組連接:
* **slave 端設定:**
* 設定鮑率
* 連接模式
* 設定模組的角色
* 位置查詢
* **master 端設定:**
* 設定鮑率
* 連接模式
* 設定模組的角色
* 指定要連哪個位置
* 請先確認不是在AT模式,在AT模式將無法配對。
* 通訊時,baud rate 也要設為一樣。
### 若顯示出現亂碼:
* 進入AT模式設定更改鮑率設定。
* 確認Serial port 介面是否正確設定。
* 確認程式藍芽連線速率是否正確設定。
---
# Lab2-1:
### 藍芽實作
* 實驗目的:學習使用手機搭配藍芽模組
* 實驗目標:透過藍芽來控制led明滅燈。
* 輸入1:LED ON。
* 輸入0:LED OFF。
* 輸入其他:LED 閃爍2次。
* 結果:
{%youtube TzQHrURN2dI %}-->
<!--### Lab2-2:
### 藍芽實作
* 實驗目的:學習使用手機搭配藍芽模組來控制LED跑馬燈。
* 實驗目標:使用五顆LED燈與藍芽模組,
輸入0:停止目前動作。(除非輸入0,否則以下動作必須不斷重複執行)
輸入1:LED跑馬燈。
輸入2:LED跑馬燈每次間隔一顆暗的。
輸入3:LED由右至左依次點亮,由左至右依次熄滅。
輸入4:LED全亮。
輸入其他:LED 全部閃爍。
* 結果:
{%youtube oRaqOo-qGeU %}
## Bonus:
### Bonus 1:藍芽控制碼錶
* 實驗目的:使用手機搭配藍芽模組以及四位七段顯示器,實現藍芽控制碼錶。
* 實驗目標:設計一個四位數的碼錶,第四位為小數,按下1則計時開始/暫停,按下0則計時歸0。
* 結果:
{%youtube 9kJ4dHWSlLI %}
### Bonus 2:藍芽密碼鎖
* 實驗目的:使用手機搭配藍芽及密碼鎖函式庫,完善密碼鎖功能。
* 實驗目標:擁有以下功能,
1.自訂一個密碼(如1234),使用手機來輸入值,輸入完成按送出,之後再輸入A按送出代表輸入密碼(也可以數字與A一起輸入再一起送出),若輸入值與密碼相同則印出 Unlock!,錯誤則印出Wrong passwords!
2.按A為送出輸入的值,按B為重設密碼。
3.顯示剩餘可錯誤次數,若連續錯誤3次後印出需等待10秒才能再次輸入。
* 參考結果:
{%youtube IeFvISNWMVI %}
::: -->
## 課後問題 (2個)
:::info
* **Q1.** 請簡述 SPI通訊涉及到哪些信號線?它們分別是什麼作用?<!--SPI通訊包括四條信號線:SCK(時鐘線)、MOSI(主端數據輸出、從端數據輸入)、MISO(主端數據輸入、從端數據輸出)和SS/CS(從端選擇/片選)。-->
* **Q2.** 請簡述 全雙工、半雙工名詞解釋<!--全雙工:(Full Duplex)是指在發送數據的同時也能夠接收數據,兩者同步進行
半雙工:(Half Duplex),所謂半雙工是指一段時間內,只有一種動作發生,發或者收。-->
* **Q3.** 在I2C裡,什麼是ACK(Acknowledge)和NACK(Not Acknowledge)位?
<!--* **Q3.** 請說明 **HC-05** 作為 **master** 以及 **slave** 的功用是什麼?-->
:::
:::success
## 作業繳交格式
**W5結報_第XX組.zip**
壓縮檔裡包含:
1.W(週數)結報.pdf
2.資料夾:W(週數)
Lab1.ino
Lab2.ino
...
:::