---
# System prepended metadata

title: '8051'
tags: [大三上]

---

# 注意資料要不要初始化
## ㄏ


## ?
* register, stack
* CY AC N/A RS1 RS0 OV N/A P
* MOV, ADD, SETB, CLR, PUSH, POP, EQU, END...
    :::spoiler 2ㄏ2
    * ADDC, SUBB: with CY
    * L for bits caculation
    * MUL, DIV operand 只能是AB
    * DA A change into BDC
    ![image.png](https://hackmd.io/_uploads/HJV_UaJQT.png)
    :::
* PUSH 6 ____ ; push register6 data into stack
* 可以透過更改SP地址去改變stack地點，不被限制在08~1F中
    * SP 是pointer所以要用MOV SP, #xx 去改變指到的地方，#xx為地址(為immediate)
* 
* JZ (look up A)
* DJNZ, **JNZ(A)**, JNC, JNB bit offset, JBC bit offset, CPL, CJNE
    * JBC bit(Jump and clear)，也只有SET(=1)的時候才能clear
    * CJNE Reg, #xx
    * CJNE A, data
:::spoiler 2ㄏ3
![image.png](https://hackmd.io/_uploads/rJoYwak76.png)
:::
* DJNZ: 先decrease才判斷，LOOP跳回前面，所以說在判斷之前一定會先執行一次
    * 這是一個do while loop 且i--擺在loop最下面，在SJMP(LCALL、ACALL)到上面(不判斷)
    * for, while 是用CJNE + J
* 1
* 去看High, low ADD, SUB
* 
* 



## CH2 ASSEMBLY PROGRAM LANGUAGE
* PUSH 6 ____ ; push register6 data into stack
* 可以透過更改SP地址去改變stack地點，不被限制在08~1F中
    * SP 是pointer所以要用MOV SP, #xx 去改變指到的地方，#xx為地址(為immediate)
* 
* Mem-to-Mem never allow in 8051 assembly
* Program counter (PC):
    * 16 bits wide
    * address for <font color='red'> **next** </font> instruction to be execute
    * as CPU fetch the OPcode PC increment to next instruciton
    * address <font color='red'> **0000** </font> when power up (org 0)
        * 所以說第一行要加org 0
        * ROM is 8 bit so we need two address of ROM to construction one PC
        * PC = PC + <font color='red'>(instruction size)</font>
* 8051 only have one data type
* EQU (equal) define a constant without occupy memory(done by assembler sililer in C *#define COUNT 10, COUNT EQU 10*)<font color='red'> EQU 沒冒號 </font>
    * 要用immediate 去呼叫
* PSW (Program Stste Word) Register <font color='red'> **背** </font>
    * CY: carry out from D7
        * 當兩數
    * AC(auxiliary): carry out from D3 to D4 (use for BCD)
    * RS1: set register bank high bit
    * RS2: set register bank low bit
    * OV: overflow flag for sign calculation
    * P: parity flag the number in A have odd(P = 1) or even(P = 0) 1，可以理解為把A和P的1總數永遠都是偶數  
    :::spoiler 圖片資料
    ![](https://hackmd.io/_uploads/By1CtHFzp.png)
    :::
* Register Bank and Stack
    :::spoiler 概覽 
    ![](https://hackmd.io/_uploads/S1PxW8tG6.png)
    :::
    * 4 register bank contol by RS1(PS4), RS0(PS3)
    * <font color='red'> **Stack** </font>: 
        * initilize be Bank 1
        * PUSH: SP 先+1後才再放資料進去，所以初始化<font color='red'> **SP = 07** </font>
            * PSDH 4: push R4 into stack
        * POP: 從SP把值拿出來，之後才再把SP-1
            * POP 4: pop data to R4
            * 因為20~2F 為bit location，所以stack會被<font color='red'> **限制08~1F** </font>，當要用更大的stack, 就要把SP移到30~7F的位置。
            * 8F以上為special function register

## CH3 JUMP, LOOP, AND CALL intstruction
:::spoiler JUMP instruction
CJZE: compare jump not equal
![](https://hackmd.io/_uploads/BkivtUYza.png)
:::
* DJNZ<font color='red'> **先decrease才check** </font>之後才會JUMP
* One DJNZ max jump 256 因為R2只有8bits
    * 要用Nast Loop 解決256以上的loop
* JZ Jump if A = 0
* <font color='red'> Example 3.6 算PC </font>
    * 下一行加多少到target in 2's cmplement
    * 因為會先fetch 所以PC要先+，所以用下一行為標準
* 在算跳到哪都是用**下一行(當前PC指的地方)**，去用OPcode做加法(2's complement form), 把**PC = PC + OFFSET**

:::spoiler CALL instruction
:::
* 直接存要跳到的地址
* LCALL: 
    * 3 byte instruction
    * call anywhere in 64KB address space in 8051
    * 用Stack儲存要RET的地址，又因為地址是4 bytes 所以要拆成兩個Low bytes 先放進去，再放High bytes，和有被使用的register中的原始資料
* ACALL(absolute call)
    * 2 byte instruction
    * target address <font color='red'> must be in 2KB </font>, due only <font color='red'> 11 bits save offset (-512~511)</font>

:::spoiler
:::
* <font color='red'> Example 3.13 算Mechine cycle </font>
* <font color='red'> Example 3.21 算delay time </font>
* Ex: 8051: 1 mechine cycle lasts 12 oscillator, for 11.5092MHz
    * so a mechine take $1/f*12 = 1/11.5092M*12=1.085us$

## CH4 I/O Port Programming
* lacth: port; input pin另外一邊
* PX.X 不能直接MOV, 要透過flag 或regiter
* latch: DATA 進CPU 再write back to pin 就會從latch讀資料, 會同步出現再pin上
* Pin: 只有讀data，就是看pin data, Port 的直不會改變
* <font color='red'> port 變 pin 變，pin 變 port不變</font>
* 8051 有4個port 其中port 0, port 2可以傳送
    * when RESET are configure as input port, 還沒輸入當然不能當輸出，也就是說REST會把全部register設成1
    * 若要輸入之前要把會用到的的bit<font color='red'>先設成1，才可以作為輸入</font>
        * 會因為Port=0會把下拉電路MOS打開，Pin接地，就算輸入為1也會讀成0
        :::spoiler 若設成0，此時輸入為1會出現錯誤，如下圖
        ![](https://hackmd.io/_uploads/rJMdrEcMa.png)
        :::
    * 也就是說若有一個0被擺進port, port就只能是輸出，直到下一個1出現去trigger port 
    :::spoiler port 0
        
    :::
    * 需要接上拉電路，當資料要從Port出來(C = 0,Port = 1)需要上拉電路，讓pin=1
    * 當control = 1 從Add/Data(memory走)，Pin change latch 不會
    * 當control = 0 從latch抓資料
    * dual rule: allow to be used for both address and data <font color='red'>from memory</font>
    :::spoiler port 1
        
    :::
    * 只有GPIO的功能
    * 不需要外接上拉電路(有internal)
    * 一樣要輸入的時候要先把port=1
    :::spoiler port 2
        
    :::
    * 當control=1只會傳輸地址，不會傳輸資料(都接到的是CPU)
    * 不需要外接上拉電路(有internal)
    * 一樣要輸入的時候要先把port=1
    * 一般使用到P2當地址時會搭配P0組合成16bits address
    :::spoiler port 3
        
    :::
    * 不需要外接上拉電路(有internal)
    * 有較多的功能
    * 複習一下影片
* bit manipulation 
    * SETB P1.3
    * CPL P1.4
    * CLR P1.2
    * JB P1.2, HERE
    * JNB P1.2, HERE
    * JBC P1.2, HERE (clear P1.2)
    * MOV c, P2.4 (MOV to CY flag)
    * CJNE A. P2, HERE (compare jump not equal)
:::spoiler read latch
![image.png](https://hackmd.io/_uploads/Bkgzw0yQa.png)
:::


## CH5 Addressing Mode
1. immediate (#)
2. register (R0~R7)
3. direct (address)
4. register indirect (pointer, DPTR, PC, SP, @R0, @R1)
5. index (A + Register indirect)

* immediate
    * 凡是前面加#的都是
    * MOV DPTR #1234H, 和MOV DPH #12H MOV DPL #34H 一樣
    * 可以用EQU處理，因為常數是immediate
        * EQU沒有冒號
* Register 
    * symbol: R0~R7
* Direct address mode
    * 128 byte (00h~70h) RAM
        * 00~1F for bank and stack
        * 20~2F for bit-addressable
        * 30~7F byte size data
        * <font color='red' >MOV A, 4 == MOV A, R4</font> 不是放#4到A
    * SFR (special function register)
        * 80H~FFH
        :::spoiler SFR structure
            
        :::
* register indirector mode
    * register save the target address
    * only R0, R1, DPTR can use for this propose 
* index addressing 
    * MOVC A, @A+DPTR
    * DJNZ 30H, LOOP ;30H is direct, means load the number in 30H
:::spoiler bit address instruction

:::
* the direct means the bit in 20H~2FH
    * 128 bit 00H~7FH
    * 81H --> P0.1
    
## CH6 Arithmetic, Logic Instructions, AND Programming
* ADD A, source ___ ; A = A + source
    * destination always be A
    * can change all flag(CF, AF, P)
* ADDC A, source ___ ; A = A + Source + CY
    * 做16bit 加法，High byte use ADDC
* BCD(Binary coded decimal)
    * unpacked lower 4 bits BCD, upper are all 0s
    * packed: two BCD number in a byte
    * after adding two BCD number use <font color='red'>**DA A**</font> to correct the BCD addtion problem
    * <font color='red'>DA A</font>(Decimal adjust for addition)
        * only use A be operand
    * if use INC DA A will <font color='red'>not work</font>
* SUBB A, source ______ A = A - source **- CY**
    * Use 2's complement form ADD A + source(2's)
    1. change source to 2's complemet form 
    2. ADD A + T(source) + T(-CY)
    * 當再做2 byte減法，High byte就和ADDC 一樣要用SUBB把CY考慮進去
    * 可以理解為向高位界一個bit
    * 因為當Low byte is Over 會溢位到CY
* MUL AB
    * operand always be A and B
    * A = low byte, B = High byte
* DIV AB A/B = A...B
    * IF B = 0, OV = 1 means ERROR
    * <font color='red'>Ex: 6.8(P21)</font>
* Sign
    * MSB = 1 neg, MSB = 0 postive
    * 2's complement -128~127
        * -128 = 1000,0000
* Overflow
    * sign number is too large for register
    1. 正數+正數 MSB=1(負數), OV=1
        * carry from D6 to D7 but not carry out of D7
    2. 負數-負數 MSB=0(正數), OV=1
        * carry out of D7 but not carry from D6 to D7
    * set 1 if there is [carry from D6 to D7] XOR [D7 carry out]
* Login instruction every bit(bit wise)
    * ANL dest, source _____ ;dest = dest AND source
    * ORL dest, source _____ ;dest = dest OR source
    * XRL dest, source _____ ;dest = dest XOR source
        * <font color='red'>可以抓兩個數是不是一樣
        * EX6.21</font>
    * CPL A 
* compare instruction
    * CJNE des, source, label (compare jump not equal)
        <font color='red'>
        * destination >= source,  CY = 0
        * destination < source,  CY = 1 </font>
* Rotate (operand only be A)
    * RR A (ratate right)
    * RL A (ratate left)
    * RRC A (ratate right to CY)
    * RLC A (rotate left to CY)
    1. serializing a byte of data, move a bit to CY copy CY
* SWAP A
    * RL 4次
    
<font color='red'>Ex 6.34, 6.35 ASCII</font>
* Checksum byte
    * add all data drop carry find 2's complement number
    * add data + checksum = 0(correct)
    * 若不等於0代表有ERROR