Try   HackMD

Chapter 6 Assembly Language Programming for PIC18F: Part 1

tags: microcontroller

Introduction

  • code 會轉成 ASCII 後再被 assembler 轉成 Binary Op-Code 。
  • 如果在 operand 只有寫數字,沒有多餘的表示符號,一律會被視為 16 進位。
  • 如果要被視為 ASCII characters 要表示成 '(string)' or A'(string)' 。
  • ORG 表示開始程式碼的 starting address 。
  • (variable) EQU (value) ,可以使 variable 賦值,之後可以當 literal 使用,也可以拿來當作 address 使用。
  • DB 用來存 8-bit wide 的數, DW 用來存 16-bit wide 的數。

這邊我在 mplab 裡面執行都找不到存進去的數值到底在哪裡,哭阿。
( 應該是從 ORG 開始存? )

  • 要記得 low byte 會先存, high byte 後存。
  • assembler 會把 source file ( .asm ) 轉成 object file ( .obj & .lst )。
  • .obj 是一個 binary file containing the mechine code and data 。
  • .lst 是一個 list file shows how the assembler interpretes the source file 。

PIC18F Instruction Format

  • 分四種:
    1. Byte-oriented operations
      • 多有以下三種 operands :
        1. The file register ( specified by 'f' )
        2. The destination of the result ( specified by 'd' )
        3. The access memory ( specified by 'a' )
    2. Bit-oriented operations
      • 有以下三種 operands :
        1. The file register ( specified by 'f' )
        2. The bit in the file register ( specified by 'b' )
        3. The accessed memory ( specified by 'a' )
    3. Literal operations
    4. Control operations
  • 大部分的 instructions 是 16-bit wide 但只有 4 個 instructions 是 double-word instruction ( 32-bit wide ),而且執行會佔用 two instruction cycles 。

PIC18F Instruction Set

  • PIC18F contains a total of 75 core instructions.
  • all instructions 由以下 10 項延伸而來:
    1. Data movement instructions
    2. Arigthmetic instructions
    3. Logic instructions
    4. Rotate instructions
    5. Bit manipulation insturctions
    6. Jump/Branch instructions
    7. Test, Compare, and Skip instructions
    8. Table Read/Write instructions
    9. Subroutine instructions
    10. System control insturctions
  • 講了一堆指令,去做實驗你就會ㄌ
  • 使用 ADDWF 時,可以使用 'W' 或 'F' 來取代 'd' 的 0 跟 1 。。
  • 當 a = 0 ,會存在 file register 的 0x00 ~ 0x7F 裡面( access bank )。

Data Movement Insturcton

CLRF F, a ( e.g. CLRF 0x20 )

  • 把 F register 清除成 0 。
  • 當 a = 0 時代表 F register 在 access bank 裡;當 a = 1 時代表 F register 在 BSR 裡面。
  • 當清除完成時 STATUS register 的 Z-flag 會被設為 1 。

LFSR F, K ( e.g. LFSR 2, 0x0020 )

  • 會把 K 的 low 12 bits 讀進 FSRx 中,使 FSR register 可以指向某一個 data register 。
  • FSR register 的 high 4 bits 全是 0 。

MOVLB K ( e.g. MOVLB 0x01 )

  • 把 K 放入 BSR register 裡面,而且會把 BSR register 的 high 4 bits 清為 0 。
    ( 用來更改bank位置 ? )

MOVLW data8 ( e.g. MOVLW 0x25 )

  • 把 8-bit literal 放入 WREG 裡面。

MOVWF F, a ( e.g. MOVWF 0x40 )

  • 把 WREG register 裡面的值,放入 F register 裡面。
  • 當 a = 0 代表 F 在 access bank 裡;當 a = 1 代表 F 在 BSR bank 裡面。

MOVFF Fs, Fd ( e.g. MOVFF 0x04, 0x03 )

  • 把資料從 source data register 放入 destination data register 裡面。
  • Fs 和 Fd 可以在範圍 0x000 ~ 0xFFF 之間。( data memory address 有 12-bit wide )

MOVF F, d, a ( e.g. MOVF 0x30, W or MOVF 0x30, F )

  • 當 d = W 時,會把 F register 裡面的值搬到 WREG register 裡面;當 d = F 時,會把 F register 裡面的東西,搬回自己裡面( function same as NOP operation )。

SETF F, a ( e.g. SETF 0x20 )

  • 把 F register 裡面的值設為 0xFF 。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

可以用來 configure an I/O port ,像是如果 SETF TRISB ,代表 Port B 被設為 input port 。

SWAPF F, d, a ( e.g. SWAPF 0x60, W or SWAPF 0x60, F )

  • 把 F register 裡面的 low order 4 bits 和 high order 4 bits 調換。
  • 當 d = W 時,會把結果存在 WREG register 裡面;當 d = F 時,會把結果存在原本的 register 裡面。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

ppt 後面都是例子,自己看。

Arithmetic Instruction

  • PIC18F 提供以下類別的 arithmetic instruction :
    1. 8-bit addition and substraction ( include signed and unsigned )
    2. 8-bit by 8-bit unsigned multiplication
    3. Negate instruction
    4. Decrement and Increment Instructions
    5. BCD Adjust ( BCD Correction )

Add and Substract Instruction

ADDLW data8 ( e.g. ADDLW 0x02 )

  • 把 8-bit content 和 WREG register 裡面的值加在一起,並存入 WREG register 。

ADDWF F, d, a ( e.g. ADDWF 0x50, W or ADDWF 0x50, F )

  • 會把 WREG register 裡面的值和 F register 裡面的值加在一起,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

ADDWF F, d, a ( e.g. ADDWFC 0x60, W or ADDWFC 0x60, F )

  • 會把 WREG register 裡面的值和 F register 裡面的值以及 carry flag 加起來,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。

SUBLW data8 ( e.g. SUBLW 0x07 )

  • 會把 8-bit immediate data 減掉 WREG register 裡面的值,結果會存入 WREG register 中。

去看一下 ppt 上的例子, final carry 的 1's complement 會是是否為 true borrow 。

SUBWF F, d, a ( e.g. SUBWF 0x20, W or SUBWF 0x20, F )

  • 會把 F register 裡面的值減掉 WREG register 裡面的值,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

SUBWFB F, d, a ( e.g. SUBWFB 0x30, W or SUBWFB 0x30, F )

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 →

這邊的
C
( carry bit )要取 toggle 。所以下面的 SUBFWB 應該也是同理。

  • 會把 F register 裡面的值減掉 WREG register 和 carry flag ,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

SUBFWB F, d, a ( e.g. SUBFWB 0x20, W or SUBFWB 0x20, F )

  • 會把 WREG register 裡面的值減掉 F register 和 carry flag ,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

要記得如果是減法,會是寫在後面的減掉寫在前面的。 ( 除了SUBLW )

Multiplication Instruction

  • 不會有任何的 status flag 出現。

MULLW data8 ( e.g. MULLW 0x03 )

  • 會把 WREG register 裡面的值乘上 immediate data 。
  • 會把結果存入 PRODH 和 PRODL 中,在 WREG register 中的直是不改變的。

MULWF F, a ( e.g. MULWF 0x50 )

  • 會把 WREG register 中的值和 F register 中的值乘起來。
  • 會把結果存入 PRODH 和 PRODL 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

Negate Instruction

NEGF F, a ( e.g. NEGF 0x70 )

  • 會把 F register 中的值,轉換換成 2's complement ,並存入 F register 中。

Decrement and Increment Instructions

DECF F, d, a ( e.g. DECF 0x50, W or DECF 0x50, F)

  • 會把 F register 裡面的值減 1 。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

INCF F, d, a ( e.g. INCF 0x50, W or INCF 0x50, F )

  • 會把 F register 裡面的值加 1 。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

BCD adjust ( BCD correction ) Instruction

DAW ( e.g. DAW )

  • 似乎是會把上面那行的運算(加減乘除),轉成 BCD 來進行,並最後的結果也會轉成 BCD 。

後面也是一堆例子啦,自己看~

Logic Instruction

  • PIC18F include logic AND, NOT ( one's complement ), OR and XOR operation.

ANDLW data8 ( e.g. ANDLW 0x8F )

  • 會把 WREG register 中的值和 immediate data 做 AND 。並把結果存入 WREG register 中。

ANDWF F, d, a ( ANDWF 0x60, W or ANDWF 0x60, F )

  • 會把 WREG register 中的值和 F register 中的值做 AND 。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

COMF F, d, a ( e.g. COMF 0x50, W or COMF 0x50, F )

  • 會把 F register 中的值做 one's complement 。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

IORLW data8 ( e.g. IORLW 0x7F )

  • 會把 WREG register 中的值和 immediate data 做 OR 。並把結果存入 WREG register 中。

IORWF F, d, a ( e.g. IORWF 0x50, W or IORWF 0x50, F)

  • 會把 WREG register 中的值和 F register 中的值做 OR
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

XORLW data8 ( e.g. XORLW 0x02 )

  • 會把 WREG register 中的值和 immediate data 做 XOR 。並把結果存入 WREG register 中。

XORWF F, d, a ( e.g. XORWF 0x42, W or XORWF 0x42, F )

  • 會把 WREG register 中的值和 F register 中的值做 XOR 。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

Rotate Instruction

RLCF F, d, a ( e.g. RLCF 0x40, W or RLCF 0x40, F )

  • 會把 F register 中的值像左推,而且會經過 carry flag 。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

RLNCF F, d, a ( e.g. RLNCF 0x70, W or RLNCF 0x70, F )

  • 會把 F register 中的值向左推,不考慮 carry flag 的影響。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

RRCF F, d, a ( e.g. RRCF 0x30, W or RRCF 0x30, F )

  • 會把 F register 中的值像右推,而且會經過 carry flag 。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

RRNCF F, d, a ( e.g. RRNCF 0x60, W or RRNCF 0x60, F )

  • 會把 F register 中的值向右推,不考慮 carry flag 的影響。
  • 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

又是一堆ㄉ例子,去看 ppt 喔~

Bit Manipulation Instructions

  • 不會影響任何 STATUS register 的 flag 。

BCF F, b, a ( e.g. BCF 0x50, 2 )

  • 會把 F register 中的第 b 個 bit 設為 0 。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

BSF F, b, a ( e.g. BSF 0x50, 2 )

  • 會把 F register 中的第 b 個 bit 設為 1 。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

可以直接修改 STATUS register 的值,太爽了吧!!!

BTG F, b, a ( e.g. BTG 0x40, 2 )

  • 會把 F register 中的第 b 個 bit 做 one's complement 。
  • 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。

又是一堆ㄉ example 哭阿。