Try   HackMD

Chapter 8 PIC18F Programmed I/O Using Assembly & C

tags: microcontroller

PIC18F Pins and Signals

  • 有兩個 VDD ( Vcc )和 VSS ( Ground ), VDD 的電壓範圍在 +4.2 V ~ +5.5V 之間。
  • 為了要降低 noise problems at high frequencies 所以才會有兩個 VDD 和 VSS 。
  • 剩下的 pins 分為 Port A/B/C/D/E ,而且同一個 pin 腳會有多種功能。

Clock

  • 可以使用內部或外部的 clock ,內部使用 on-chip oscillator ,外部可以使用 OSC1 和 OSC2 來傳進 clock pulse 。

  • 如果使用內部的振盪器,可能會因為周圍的溫度,造成時間算的不準確、精準。

  • PIC18F 使用 Phase-Locked Loop ( PLL ) 來使頻率加乘。

  • 內部的 clock 也可以透過 INTIO1 mode 和 INTIO2 mode 傳出去。

  • PIC18F 有三種 clock sources,

    1. Primary oscillators

      • 需要外部的電路連接 OSC1 和 OSC2 來傳入 clock 。
      • 簡單來說就是 generate the clock externally 。
    2. Secondary oscillators

      • 就是 external sources 連接到 T1OSI ( Timer1 Oscillator Input ) 和 T1OSO ( Timer1 Oscillator Output )。
      • 也是外部傳進來的,也可以被內部的程式運用,只是傳進來的方式不一樣。
    3. Internal oscillators

      • 就內部自己的振盪器。
  • 調整要用哪個可以透過 OSCCON 的 SCS bits ( Oscillator Control )來控制。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  • PIC18F power-managed mode 代表晶片消耗比較少的能源,而且能承受低電源供應而能正常運作,應用像是 smoke detectors, hospital ID tags, and automobile ignition systems 。

  • IDLEN bit 控制當 PIC18F 執行 SLEEP instruction 時會進入 Sleep mode 或 one of the Idle modes 。

  • IOFS 和 OSTS 是 read-only bits ,是用來確認 external oscillator 是否穩定。

  • SCS 調整現在用的是 external source 還是 internal oscillators。

  • 在 default mode ( after reset ) , OSCCON = 0x40 ( Fosc = 1 Mhz )。

  • 而 clock 的頻率範圍在 31 kHz ~ 8 MHZ 之間。

  • PIC18F4321 可以透過修改 CONFIG1H 裡面的 FOSC3:FOSC0 的值去改 OSC1 和 OSC2 的用途,好像啦:

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

    1. 其實我看不太懂這邊 ppt 裡面在講啥,但是就是說使用 crystal oscillator 的時候,要和 resonant crystal 並聯,然後一個接 OSC1 一個接 OSC2 ,不然 resonant crystal 不會動。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

    2. 另一種是說,拿 RC circuit 接到 OSC1 來當作 input clock source ,然後 OSC2 來當作 clock output ,可以接到其他外接的 device (其實我一直很好奇 Fosc/4 的 /4 到底是什麼意思?)

  • ⚠補影片了:他說這兩個圖看看就好,寫的時候跟著下面那個 summary 原則就好。

  • ppt 裡面的小總結(快速複習就不要看上面了,有夠雜)。

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

Reset

  • 當觸發 reset 的時候, PIC18F 會把 0 讀入 program counter ,這樣執行第一個 instruction 的時候就會抓到 address 是 0 的 program memory。
  • 當 reset 觸發的時候,大多數的 register 都不會變,只有:
    1. WREG 會變 0
    2. STKPTR 會變 0
    3. TRISx 全部的 bit 都會變 1 (代表全部的 I/O ports 都是 inputs)
  • reset 的方式有很多種:
    1. Power-On Reset ( POR )
      • 當 VDD 有足夠電力的時候,就會有一個 power-on reset pulse 發出來 reset 。
      • 而 power-on reset 有沒有發生可以看 RCON 的 POR bit ,如果是 0 代表有發生,但如果是 1 的話代表沒有發生。
        Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More →
    2. Manual Reset
      • 有一個 MCLR pin 通常是 1 ,但當觸發按鈕的時候(至少要 2 微秒),會變成 0 ,然後就觸發 Manual Reset 。
    3. Brown-out Reset ( BOR )
      • 當 PIC18F 的 power supply 低於一個值得時候會觸發。
      • 有這種 reset 的想法是,處理器會暫停現在的工作,而不是想辦法不穩定且不安全的進行下去。
      • 所以當電源供應足夠時,程式又可以繼續跑下去。
    4. Watchdog Timer reset ( TO )
      • 當 WDTCON ( Watchdog Timer Control register )被設定開啟的時候, internal colock 也會自動被開啟。
      • 然後當時間到達設定時間的 timeout 的時候會自動觸發 reset 。
  • 總結來說如果要 track reset 的狀態的話,去看 RCON ( Reset Control ) 的 lower 5 bits 。

"pragma config" and 'config' directives

  • 用來告訴 assembler 你要的設定,範例:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

PIC18F4321 Programmed I/O

  • microcontroller 可以透過 I/O ports 跟外部裝置交換訊息,而每一個 port 是 input 或 output 會透過 Data Direction Register ( DDR ) 來設定。

  • 在 PIC18F 中,如果是 input ,在 DDR 中就是 1 ,而如果是 output 則為 0 。

  • 範例(往上指是 input):

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  • I/O ports are addressed using Standard I/O or Memory-mapped I/O

    1. Standard I/O
      • CPU 會發出信號給
        M/IO
        來跟 memory 說現在是在做 memory operation ( HIGH )或是 I/O operation ( LOW )。
      • 舉例來說,如果再做 IN or OUT instruction 的話,
        M/IO
        就會是 LOW ;當再做 memory0oriented instructions 時就會是 HIGH 。
    2. Memory-mapped I/O
      • CPU 使用一部分的 memory address 來代表 I/O ports 。
      • PIC18F 就是用這種。
  • PIC18F4321 有五個 ports ,分 A B C D E ,只有 E 是 4-bit ,其他都 8-bit 。

  • 每個 port 有 3 個 latches 跟他有關:

    1. TRIS ( Tristate ) latch
      • 當為 1 的時候代表 input , 0 為 output
    2. Input latch
    3. Output latch
  • 接下來都是廢話,反正就在 TRISx 中 1 是 input 0 ,是 output。

來囉

  • PORT A, B, E 和 C, D 不一樣,因為前面 3 個有部份 bits multiplexed with analog inputs (就是之前要把某個東西關掉的機掰設定)。
  • 所以在使用這 3 個 ports 之前要先設定 ADCON1 ( A/D Control Register 1 ),設定是那一種 input 。
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • 感謝 MPLAB C18 compiler 他可以單單拜訪一個 register 中的其中一個 bit,寫法為:
TRISCbits.TRISC5 = 0; //let RC5 to be an output bit
  • 要注意 register 名字後面要加 bits 。
  • 而 MPLAB C18 compiler 可以用 define 來定義其中一個 bit :
#define portbit PORTCbits.RC2
  • 這樣之後可以用 portbit 來代表 PORTC 中的 RC2 這個 bit 。

Interfacing LED's and Seven-segment displays

  • LED 能正著接也能反著接:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • 關於 Seven-segment 有兩種:
    1. common cathode : HIGH 時亮, LOW 時暗。
    2. common anode : LOW 時亮, HIGH 時暗。
  • 阿 Seven-segment 也能反著接,兩種的接法大概會長這樣:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

基本上為了程式正常運行,在 config 那邊都會這樣寫:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

經過我的電腦實驗, PIC18F4520 好像沒有 BOR ,如果設定的話會報錯。

ㄟ乾,我發現他們不管是 input 還是 output 都是用 PORTx ㄟ
我們好像還會用到 LATx ,這樣這個原本的用途到底是啥呢??
經實驗證明,只使用 PORTx 是可行的,而且反接也是可以實現的。哭阿

  • 七段顯示器(這個是 common anode 的吧):
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

小技巧,如果要用到七段顯示器可以先把表存到 memory 裡面,要用的時候直接拿:

ORG 0x70 MOVLW 0x40 MOVWF 0x100 MOVLW 0x79 MOVWF 0x101 MOVLW 0x24 MOVWF 0x102 MOVLW 0x30 MOVWF 0x103 MOVLW 0x19 MOVWF 0x104 MOVLW 0x12 MOVWF 0x105 MOVLW 0x03 MOVWF 0x106 MOVLW 0x78 MOVWF 0x107 MOVLW 0x00 MOVWF 0x108 MOVLW 0x18 MOVWF 0x109

然後設定 FRSx 指到 0x100
使用 MOVFF PLUSWx, (你要 output 的 port )

  • PLUSWx 是代表讀取 FSRx + WREG 中地址的值。

Programmed I/O examples using C

  • 三種 preprocesser directive:
    1. #include : 用來把外部的檔案包進 program 裡面,像下面這種檔案,裡面會寫哪 一個 register 會對到哪一個記憶體地址。
    ​​​​#include <p18f4520.h>
    1. #define : 這個是 texual replacement 。
    ​​​​#define y 4
    1. #pragma config : 告訴 preprocesser 你在 compile 之前要設定什麼。
    ​​​​#pragma config OSC = INTIO67 ​​​​#pragma config WDT = OFF ​​​​#pragma config BOREN = ON
  • 剛剛上面講的七段顯示器,在 C 裡可以這樣寫他的 table :
unsigned char code[10] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x03, 0x78, 0x00, 0x18};
  • 在 C 中寫 Delay 的方法:
    1. 用 PIC18F on-chip timers : 他說他第10章會教。
    2. 用 loop :
    ​​​​void delay(usigned int itime){ ​​​​ unsigned int i, j; ​​​​ for(i=0;i<itime;i++) ​​​​ for(j=0;j<255;j++); ​​​​}
    • 如果要算 C 中的 loop 是要多就的話,要拆成 assemble 去看。像上面的會變成:
    ​​​​DELAY: ​​​​ MOVWF 0x20 ​​​​LOOP1: ​​​​ MOVLW D'255' //LOOP2 provides 2 ms delay with a count of 255 ​​​​ MOVWF 0x21 ​​​​LOOP2: ​​​​ DECFSZ 0x21 ​​​​ GOTO LOOP2 ​​​​ DECFSZ 0x20 ​​​​ GOTO LOOP1 ​​​​ RETURN
    1. 用內建的 Delay function 10KTCYx() :
      • 這個 function 包含在 <delays.h> 裡面。
      • 然後他會 delay 10K * (括號內的值) 個 instruction cycle 。
      • 注意括號內的值一定要是 0 ~ 255 。
    ​​​​ #include <p18f4520.h> ​​​​ #include <delays.h> ​​​​ unsigned char count; ​​​​ void main(){ ​​​​ OSCCON = 0x60; ​​​​ for(count = 0;count <4;count++) ​​​​ Delay10KTCYx(250); ​​​​ }
  • 後面有三個範例,做實驗就會了。