---
# System prepended metadata

title: I2C_PIC16F18854
tags: [I2C, PIC16F18854]

---

# I2C_PIC16F18854
[I~2~C連結](https://hackmd.io/AoNinmg_Q6i2Hs2IVk4KfA)
###### tags:`PIC16F18854` `I2C`
<style> .red {color:red;} </style> 
## <span class =" red">接線方式:</span>
![](https://i.imgur.com/DdTflAz.png)
R=2K Ω

## <span class =" red">介紹:</span>
bus總線:所有SDA或SCL Wire-AND 在一起的線\
\
因為這顆IC有兩個MSSP，所以之後介紹的站存器中的x代表1or2

| 狀態      | 介紹     | 
| -------- | --------|
| 仲裁     | 確保一次僅一個master控制bus的過程，仲裁獲勝可確保消息不被破壞 |
| 空閒(idel) | 沒有master控制bus，且SDA和SCL均為high |
| 活動(active) | 任何時候一個或多個master控制bus |
| 從站尋址(Addressed Slave) | 從設備已接收到匹配的地址，並且正在被master主動計時 |
| 匹配地址(Matching Address) | clock輸入到與SSPxADD中的值匹配的slave中的地址字節 |
| 寫請求(write request) | slave接收到一個匹配的地址，並且$R/\bar{W}$位清零，並準備好輸入數據 |
| 閱讀要求(read request) | master發送一個$R/\bar{W}$位置1的地址字節，表明它希望將數據從slave中移出。 該數據是下一個以及隨後的所有字節，直到重新啟動或停止為止 |
|clock伸展(clock stretching) | 當bus上的設備將SCL保持為low以停止通信時 |
| bus事故(bus collision) | 每當SDA在其輸出處於預期high時被模塊採樣為low時 |
\
ACK的結果放置在ACKSTAT(SSPxCON2)中，當AHEN和DHEN(SSPxCON3)為1時(SCL和SDA保持智能)，允許用戶設置發送回發送器的ACK值。將ACKDT(SSPxCON2)設為1(在SDA和SCL引腳上啟動應答序列)/清0以確定響應，則AHEN和DHEN(SSPxCON3)清零，slave將產生ACK響應。\
\
當接收到一個字節時，如果BF(SSPxSTAT)(接收完成，SSPxBUF滿了)或SSPOV(SSPxCON1)(SSPxBUF溢出)為1，slave不會發送ACK。\
\
當被尋址時，在bus上SCL的第八個下降沿之後，ACKTIM(SSPxCON3)為1(將要回答ACK)\
==僅當智能了AHEN位或DHEN位時，ACKTIM狀態位才有效。==
\
SSPxADD 將啟動或重新啟動條件之後收到的第一個字節與該暫存器中儲存的值進行比較。 如果字節匹配，則將該值加載到SSPxBUF暫存器中並產生中斷。\
如果該值不匹配，則模塊將進入空閒狀態，並且不會向軟件提供任何指示。\
\
==每個傳送的byte後都會產生一個MSSP中斷(SSPxIF=1)==\
\
當SEN(SSPxCON2)為1時，SCL將保持low（時鐘延長）\
\
==SCL上的 High/Low 訊號主要是由Master的CLK產生==


# PIE3_p119
![](https://i.imgur.com/QiG3rB5.png)
## <span class ="red">BCLxIE：</span>MSSPx bus衝突中斷智能bit
##### ==可讀可寫==
1 =允許MSSPx bus衝突中斷\
0 =禁止MSSPx bus衝突中斷

## <span class ="red">SSPxIE：</span>:同步串列阜（MSSPx）中斷智能bit
##### ==可讀可寫==
1 =允許MSSPx 中斷\
0 =禁止MSSPx 中斷



# PIR3_p128
![](https://i.imgur.com/lDpHFyw.png)
## <span class =" red">BCLxIF:</span>：MSSPx bus衝突中斷標誌位bit
##### ==可讀可寫==
1 =檢測到bus衝突（必須在軟體中清除）\
0 =未檢測到bus衝突

## <span class =" red">SSPxIF:</span>：同步串列端口（MSSPx）中斷標誌bit
##### ==可讀可寫==
1 =傳輸/接收/bus 狀態已完成（必須在軟體中清除）\
0 =等待傳輸/接收/bus 狀態進度


# SSPSTAT_p463
![](https://i.imgur.com/NNNe3Tq.png)
## <span class="red">SMP:</span>SPI Data Input Sample bit
##### ==可讀可寫==
1 =在標準速度模式（100 kHz和1 MHz）下禁用slew rate control\
0 =在高速模式（400 kHz）下啟用slew rate control

## <span class="red">CKE:</span> SPI時鐘邊沿選擇位
##### ==可讀可寫==
1 =智能輸入邏輯，以使閾值符合SMBus規範\
0 =禁用SMBus特定的輸入

## <span class ="red">$D/\bar{A}$ :</span>Data/Address bit
##### ==唯讀==
1 =指示接收或發送的最後一個字節是Date\
0 =指示接收或發送的最後一個字節是Address

## <span class ="red">P :</span> Stop bit（當MSSP模塊被禁用時，該位被清除，SSPEN被清除。）
##### ==唯讀==
1 =指示最後檢測到一個stop bit（復位時該位為0）\
0 =上次未檢測到stop bit\

## <span class ="red">S :</span> Start bit（當MSSP模塊被禁用時，該位被清除，SSPEN被清除。）
##### ==唯讀==
1 =指示最後一次檢測到start bit（復位時該位為0）\
0 =最後未檢測到start bit

## <span class ="red">$R/\bar{W}$ :</span> 讀/寫位信息
##### ==唯讀==
該位保存最後一次地址匹配後的$R/\bar{W}$信息。\
該位僅在地址匹配到下一個start bit，stop bit或ACK bit之間有效。\
\
在I~2~C slave 模式下：\
1 =讀\
0 =寫\
\
在I~2~C master 模式下：\
1 =發送正在進行\
0 =發送不在進行中將該位與SEN，RSEN，PEN，RCEN或ACKEN進行或運算，將指示是否 MSSP處於空閒模式。

## <span class ="red">BF：</span> Buffer Full Status bit
##### ==唯讀==
接收：\
1 =接收完成，SSPxBUF已滿\
0 =接收未完成，SSPxBUF為空\
發送：\
1 =正在進行數據發送（不包括 （ACK和stop bit），SSPxBUF已滿\
0 =數據發送完成（不包括ACK和stop bit），SSPxBUF為空



# 主從選擇_SSPxCON1_p464
![](https://i.imgur.com/AbO0XxD.png)
## <span class =" red"> WCOL：</span>寫衝突檢測bit （僅發送模式）
##### ==唯讀==
1 =在仍發送前一個字的同時寫入SSPxBUF寄存器（必須在軟件中清除）\
0 =無衝突

## <span class ="red">SSPOV：</span>接收溢出指示符bit
##### ==唯讀==
1 =當SSPxBUF寄存器仍保留前一個字節時，接收到一個字節。在發送模式下，SSPOV=don't care（必須在軟件中清除）\
0 =無溢出

## <span class ="red">SSPEN：</span>同步串列阜啟用bit
##### ==可讀可寫==
在兩種模式下，啟用後，必須將以下引腳正確配置為輸入或輸出\
\
1 = 啟用串列阜，並將SDA和SCL引腳配置為串列阜引腳的源\
0 = 禁用串列阜並將這些引腳配置為I/O端口引腳

## <span class ="red">CKP：</span>clock極性選擇bit
##### ==可讀可寫==
在I~2~C slave模式下：\
SCL釋放控制\
1 =制能clock\
0 =使clock保持低電平（clock伸展，用於確保數據建立時間。）\
\
在I~2~C master模式下：\
在此模式下不使用

## <span class ="red">SSPM ＜3：0＞：</span>同步串列阜模式選擇bit
##### ==可讀可寫== ==選主從模式==
1111 = I~2~C slave模式，智能了start bit和stop  bit中斷的10位地址\
1110 = I~2~C slave模式，智能了start bit和stop bit中斷的7位地址\
1101 = 保留\
1100 = 保留\
1011 = I~2~C固件控制的master模式（slave空閒）\
1010 = SPI master模式，clock= FOSC/（4 *（SSPxADD + 1））\
1001 = 保留\
1000 = I~2~C master模式，clock= FOSC/（4 *（SSPxADD + 1））\
0111 = I~2~C slave 模式，10位地址\
0110 = I~2~C slave 模式，7位地址\
0101 = SPI slave 模式，clock= SCK引腳，禁止SS引腳控制，SS可以用作I/O引腳\
0100 = SPI slave 模式，clock= SCK引腳，啟用SS引腳控制\
0011 = SPI master模式，clock= T2_match/2\
0010 = SPI master模式，clock= FOSC/64\
0001 = SPI master模式，clock = FOSC/16\
0000 = SPI master模式，clock= FOSC/4



# SSPxCON2_p465
![](https://i.imgur.com/cPIXj4S.png)
## <span class="red">GCEN:</span>通用呼叫智能bit（==僅在I~2~C slave模式下==）
##### ==可讀可寫==
1 =當在SSPxSR中接收到通用呼叫地址（0x00或00h）時使能中斷\
0 =禁用通用呼叫地址

## <span class ="red">ACKSTAT：</span>acknowledge(確認) 狀態 bit
##### ==唯獨==
1 =未收到確認\
0 =已收到確認

## <span class ="red">ACKDT：</span>acknowledge(確認)data bit
##### ==可讀可寫==
在接收模式下：\
當用戶在接收結束時啟動確認序列時發送的值\
1 =沒有確認\
0 =確認

## <span class ="red">ACKEN：</span>應答序列智能bit（==僅在I~2~C master模式下==）
##### ==可設定==
在 master 接收模式下：\
1 =在SDA和SCL引腳上啟動應答序列，並發送ACKDT data bit。由硬件自動清除。\
0 =確認序列空閒

## <span class ="red">RCEN：</span>接收智能bit（==僅在I~2~C master模式下==）
##### ==可設定==
1 =智能I~2~C的接收模式\
0 =先不接收

## <span class ="red">PEN：</span>停止條件智能bit（==僅在I~2~C master模式下==）
##### ==可設定==
SCKMSSP釋放控制：\
1 =在SDA和SCL引腳上啟動停止條件。由硬體自動清除。\
0 =先不停止 

## <span class ="red">RSEN：</span>重複啟動條件智能bit（==僅在I~2~C master 模式下==）
##### ==可設定==
1 =在SDA和SCL引腳上啟動重複啟動條件。由硬件自動清除。\
0 =先不重複啟動條件

## <span class ="red">SEN：</span>啟動條件智能bit/拉伸智能bit
##### ==可設定==
在master模式下：\
1 =在SDA和SCL引腳上啟動啟動條件。由硬體自動清除。\
0 =先不起始\
在slave模式下：\
1 =為slave發送和slave接收使能時鐘延長（允許拉伸）\
0 =禁止了clock延長 



# SSPxCON3_p466
![](https://i.imgur.com/nZPvi8H.png)
## <span class =" red">ACKTIM:</span> 確認時間狀態bit
##### ==唯讀==
1 =表示I~2~C bus 將要回答ack，在SCL的第8個負緣時設置\
0 =沒有要回答ack，在SCL時鐘的第9個上升沿被清除

## <span class =" red">PCIE:</span> 停止條件中斷智能bit（==僅I~2~C slave模式==）
##### ==可讀可寫==
1 =在檢測到停止條件時啟用中斷\
0 =禁用停止檢測中斷

## <span class =" red">SCIE:</span> 啟動條件中斷智能bit（==僅I~2~C slave模式==）
##### ==可讀可寫==
1 =在檢測到啟動或重啟條件時啟用中斷\
0 =禁用啟動檢測中斷

## <span class =" red">BOEN:</span> 緩衝區覆寫智能位
##### ==可讀可寫==
在I~2~C™ master模式下：\
該位被忽略。\
\
在I~2~C™ slave模式下：
1 =更新SSPxBUF並為接收到的地址/數據字節生成ACK，僅當BF(SSP1STAT)=0時才忽略SSPOV（SSPxCON1）的狀態\
0 =僅在清除SSPOV（SSPxCON1）時更新SSPxBUF

## <span class =" red">SDAHT:</span> SDA保持時間選擇 bit
##### ==可讀可寫== ==為了不要漏接資料==
1 = SCL負緣後，SDA上的保持時間最少為300 ns \
0 = SCL負緣後，SDA上的保持時間最少為100 ns

## <span class =" red">SBCDE:</span> slave模式bus衝突檢測智能bit（==僅I~2~C slave模式==）
##### ==可讀可寫==
如果在SCL的正緣上，當模塊輸出high時SDA被採樣為low，則BCL1IF(PIR3)=1，bus空閒\
1 =智能從bus衝突中斷\
0 =禁止從bus衝突中斷

## <span class =" red">AHEN:</span> 地址保持智能bit（==僅I~2~C slave模式==）
##### ==可讀可寫==
1 =在SCL的第八個負緣後，找到匹配的接收地址字節，CKP(SSPxCON1)=0，並且SCL將保持low\
0 =禁用地址保持

## <span class =" red">DHEN:</span> 數據保持智能位（==僅I~2~C slave模式==）
##### ==可讀可寫==
1 =在接收數據字節的SCL的第八個負緣後；從硬件將CKP(SSPxCON1)=0，並且SCL保持low\
0 =禁用數據保持



# SSPxMSK_p467
![](https://i.imgur.com/KmXHhYP.png)
## <span class =" red">SSPxMSK＜7:0＞:</span> mask bit
##### ==可讀可寫==
SSPxMSK<7:1>:\
1 =接收到的地址與SSPxADD比較以檢測I~2~C地址是否匹配\
0 =接收到的地址不用於檢測I~2~C地址匹配\
\
SSPxMSK<0>：don’t care



# SSP1ADD_p467
![](https://i.imgur.com/FdrH1uj.png)
## <span class =" red">SSPxADD<7:0>:</span> Baud Rate Clock Divider bits
##### ==可讀可寫==
在I~2~C master模式下：\
SCL period = ((ADD<7:0> + 1) *4)/FOSC\
\
在I~2~C slave模式下：\
SSPxADD<7：1>：7位地址位\
SSPxADD<0>：don’t care