# Chapter 11 PIC18F CCP AND SERIAL I/O Part 1網址 ###### tags: `microcontroller` ## PIC18F CCP Mode - 可用 Timer1 ~ Timer3,會根據你現在用的是啥 mode 來決定哪個可以用 , Timer0 不可用。 :::info ![](https://i.imgur.com/mDmsd8k.png) ::: - 在 CCP1 module 中,除了正常的 CCP 功能,還有在 PWM 下對於 DC motor control 的增強,所以又被稱為 **ECCP** 。 - CCP1 和 CCP2 是獨立的,所以可以同時運行不同的模式,但不可以同一個 CCP module 同時做不同的模式,即便使用的 Timer 不一樣,但 logic function 是一樣的。 - CCP module 可以做的事: 1. Capture mode ( CCPx pin 作為 input ) - 使用 16-bit Timer ( Timer1 or Timer3 )。 - 當偵測到 input pin 有 rising/falling edge 時(透過 program 設定),就會把 Timer register 加 1 。 - 可用來測量兩次事件( rising/falling edge )間經過的時間長度。 2. Compare mode ( CCPx pin 作為 output ) - 使用 16-bit Timer ( Timer1 or Timer3 )。 - 很像倒數計時器,當 specified timer value ( Timer1/Timer3 )和 16-bit register value ( CCPRxH:CPPRxL ) 相等時,就可以 output signal 。 3. PWM mode ( CCPx pin 作為 output ) - 使用 Timer2 。 - 可以在 CCPx pin 上產生 square wave ,而這個方波的 frequency 和 duty cycle 都可以由使用者自行設定。 - duty cycle 越大會導致能量越大 ex : 用來控制燈泡亮暗。 :::info duty cycle - 代表在一個 square wave 中的 peroid 當中, HIGH 的比例是多少。 ::: - polled I/O 和 interrupt I/O 都可以實做 CCP module 。 - 每一個 CCP module 都會有一個 8-bit control register ( CCPxCON ),還有一個 16-bit data register ( CCPRxH:CCPRxL ),但當是 PWM mode 時, CCPRxL 會被當作除存 duty cycle 使用。 :::info ![](https://i.imgur.com/4dgGFOr.png) ::: ### PIC18F4321 Capture mode - 在 capture mode 中,當發生 event ( rising/falling edge on CCPx pin )時, **CCPRxH:CCPRxL** 會擷取當下 TMR1/TMR3 (看你設定)中的值,而且 **CCPxIF** 會被設為 1 。 - 所以代表 capture mode 是可以使用 interrupt 的。( **CCPxIE** bit in *PIE* register ) - 當第二次 event 發生時, register 中的值會被覆蓋掉,所以要記得存起來。 - 在使用 Capture mode 前要確定: 1. CCPx pin 要是設定成 input 。 2. Timer1 or Timer3 要打開,至於要是哪一個要去設定 *T3CON* register。 :::info ![](https://i.imgur.com/Lwnn8bc.png) ::: - 實做步驟: 1. 設定 *CCP1CON* register 。 2. 設定 CCP1 pin ( RC2 ) as input pin 。 3. 設定 *T3CON* register 來決定要用 Timer1 or Timer3 。 4. 清空 CCP1 flag : **CCP1IF** bit in *PIR1* 。 5. 清空 CCP1 data register *CCPR1H:CCPR1L* 。 6. 跑迴圈去檢查 **CCP1IF** ,當第一次變成 1 時,開啟 Timer ,並將 *CCPR1H:CCPR1L* 中的值存起來,最後把 **CCP1IF** 清 0 。 7. 繼續跑迴圈等第二次 **CCP1IF** 變成 1 ,然後把 Timer 停掉,清空 *CCP1CON* 來停掉 capture 。 8. 把 *CCPR1H:CCPR1L* 扣掉原本存的數值,即可求得一次的 peroid 。 - 應用: 1. 用來測未知訊號的脈衝寬度。 2. 用來測量信號週期。 3. 用來測量訊號的 duty cycle 。 ### PIC18F4321 Compare mode - 在 compare mode 中, 16-bit CCPRx register 會跟 TMRx 做比較,當相同的時候, CCPx pin 可以輸出: 1. driven high 2. driven low 3. toggled ( high-to-low or low-to high ) 4. remain unchanged - 至於要做什麼在 *CCPxCON* register 可以調整。 - 而當相同時, **CCPxIF** 也會變成 1 ,可以寫 interrupt 。 - 不過當然,在跑 compare mode 的時候, Timer1/Timer3 必須要為 Timer mode 。 - 應用: 1. 可以產生特定 duty cycle 的脈衝列。 2. 可以控制一段時間開啟某 external device 。 - 實做步驟: 1. 設定 **CCPxCON** 開啟 compare mode ,然後把 CCPx pin 設置為 output 。 2. 設定 **CCPRxH:CCPRxL** 指定的數字。 3. 選擇 Timer1 or Timer3 當 clock source ( *T3CON* )。 4. 初始化 **TMRxH:TMRxL** 。 5. 清除 **CCPxIF** 。 6. 把 Timerx 打開( *TxCON* ) ( ex : TMR1ON bit )。 7. 當觸發 compare 時,關閉 Timer ,輸出要的東西在 CCPx pin 。 ### PIC18F4321 PWM mode - 能輕易的輸出 特定頻率的週期波 和 10-bit duty cycle ( 8-bit integer and 2-bit fractional part )。 - duty cycle 是寫在 *CCPxL* register ( high 8-bit )和 *CCPxCON* 的 bit 4 and 5 ( low 8-bit )。 - 而 PWM peroid 是寫在 *PR2* register 中(因為使用 Timer2 )。 :::info ![](https://i.imgur.com/8uymxEx.png) ::: :::info ![](https://i.imgur.com/GAhc9J8.png) ::: - duty cycle 的儲存方式是以 percentage of a clock period 的方式儲存。 - 舉例:如果 duty cycle 是 25% 且 PR2 裡面是 30 ,那就是 30×0.25=7.5 ,那 10-bit duty cycle 就會是 0b0000011110 。 - 當 output waveform 時,會先把 *CCPR1L* 複製到 *CCPR1H* 裡面,然後內部會 latch **CCP1CON<5:4>** 的值,達成 10-bit duty cycle 。 - 而 TMR2 也會 internal latch 2-bit 來達成 10-bit 。 - 在 TMR2 開始的時候, CCP1 pin 會從 HIGH 開始, **CCP1H** 會和 TMR2 做比較(當然是包含 latch 的 10-bit ),當兩者相等的時候,CCP1 pin 會變 LOW 。 - 這時 TMR2 持續往上加,當 TMR2 = PR2 時, CCP1 pin 又回到 HIGH ,然後 TMR2 被歸 0 。 :::info ![](https://i.imgur.com/ahmfDX5.png) ::: - 實做步驟: 1. *PR2* register 要設定為 PWM period 。 2. 設定 duty cycle ( *CCPR1L* register and *CCP1CON<5:4>* bits )。 3. 先關閉 PWM mode ( *CCP1CON* )。 4. 把 CCP1 pin 設為 output ( *TRISC* )然後把輸出清 0 ( *PORTC* )。 5. 設定 Timer2 prescale value ( *T2CON* )。 6. 這時再開啟 PWM mode ( *CCP1CON* )。 7. 初始化 *TMR2* register 。 8. 把 Timer2 打開 ( *T2CON* )。 9. 清除 **TMR2IF** ( *PIR1* )。 :::success 最好把開啟 mode 跟 timer 之類的操作放到最後應該會比較安全?! ::: ## DC Motor Control - 用 PWM 來控制馬達可以有效的減少能源的浪費。 - 如果想要換馬達旋轉的方向,可以外接一個 H-Bridge 來達成(我也不知道那是啥)。 - 因為 PIC18F4321 不能輸出大電壓和電流,所以通常都會需要放大器來完成。 :::info ![](https://i.imgur.com/KPRhvev.png) ::: :::danger 老實說這邊我直接放掉,例題看不懂QQ ::: ## Serial Interface - 很常需要把數據從一個微算機傳到另一個,但不可能要傳 8-bit wide 的訊息就要用 8 條線來傳,所以就有了不同的方式。 - 在 serial transmition 中只會用到一條線,所以會用到 clock signal ,有分兩種,同步和非同步。 ### Synchronous Serial Data Transissoin - Data 傳輸是依靠 clock signal 的頻率來發出的,而那個 rate 稱為 **baud rate** ( bits per second )。 - 通常,在傳輸的數據當中,會包含錯誤位,讓接收者去看他收到的資料有沒有錯誤,而在一開始的時候,發送者會先發出一或兩個 SYNC characters ,而接收者如果匹配到要接收的 SYNC characters 就會開始接收。 - 在 synchronous transmition 中,發送者必須要連續發送資料,但如果尚未準備好的話會用 SYNC characters 來填充,直到有可用的數據為止。 - 接收者也必須要知道使用的 SYNC characters 和要傳輸的資料單位數,所以再接收到匹配的 SYNC characters 後,接收者會收到指定數量的數據,然後就會在回到 hunt 模式尋找匹配的 SYNC characters 。 ### Asynchronous Serial Data Transmission - 在這種模式中,發送者不必一直發送資料,但是每一次發送的資料都必須被格式化,也就是包含 start and end 的 bits 來代表這次發送的開始與結束。 :::danger 我看不懂 ![](https://i.imgur.com/x4Yrzhj.png) :::