8052 Timer 2

Posted by: 邱小新 at 下午3:06 in
  1. Timer 2 有三種模式,透過 T2CON 來設定。

    RCLK/TCLKCP/RL2TR2mode
    0011. 16 位元自動載入
    0112. 16 位元補捉
    1x13. 鮑率產生
    xx0停止動作
  2. 當 timer2 發生溢位或 T2EX 偵測到負緣信號時,都會產生中斷訊號。所以在中斷副程式中需要手動判斷並清除 TF2 及 EXF2。
  3. 當 timer2 設定成鮑率產生模式時,oscillator 經過一個 2 除法器,而非一般的 12 除法器,計算時要注意。
  4. 標準的 8052 並沒有 T2MOD 這個 register,一般都是廠商的特殊功能才會設置 T2MOD register。
  5. 當進入中斷函式時,一定要先清除 TF2,否則中斷不會再發生。這一點在 datasheet 裏沒提到,在 timer0/1 因為會自動清除 TFx,所以沒有這個問題。
圖一16-Bit Auto-reload Mode 16 位元自動載入模式
CP/RL2=0 and RCLK=0 and TCLK=0
圖二16-Bit Capture Mode 16 位元補捉模式
CP/RL2=1 and RCLK=0 and TCLK=0
圖三Baudrate Generator Mode 鮑率產生模式
RCLK=1 or TCLK=1

8052 Timer 2 Control Register (T2CON)

Posted by: 邱小新 at 下午1:08 in
  1. TF2: Timer 2 Overflow Flag
    1. 當 timer2 發生溢位時,此位元由硬體自動設成 1。
    2. 當 RCLK=TCLK=1 時,此位元無作用。
    3. 此位元需由軟體手動清除成 0。
  2. EXF2: Timer 2 External Flag
    1. 當 EXEN2=0 無作用。
    2. 當 T2EX 偵測到負緣信號時,此位元由硬體自動設成 1。
    3. 此位元需由軟體手動清除成 0。
  3. RCLK: receive clock bit
    1. 當 uart 工作於 mode 1/3,此位元決定接收時脈來源。
    2. RCLK=0,以 timer1 的溢位脈波為時脈來源。
    3. RCLK=1,以 timer2 的溢位脈波為時脈來源。
  4. TCLK: transmit clock bit
    1. 當 uart 工作於 mode 1/3,此位元決定傳送時脈來源。
    2. RCLK=0,以 timer1 的溢位脈波為時脈來源。
    3. RCLK=1,以 timer2 的溢位脈波為時脈來源。
  5. EXEN2: Timer 2 External Enable bit
    1. EXEN2=0,T2EX 訊號會被忽略。
    2. EXEN2=1,T2EX 偵測到負緣信號時會引發補捉或重載功能並設置 EXF2=1。
  6. TR2: Timer 2 Run Control bit
    1. TR2=0,關閉 timer2。
    2. TR2=1,開啟 timer2。
  7. C/T2: Timer/Counter 2 Select bit
    1. C/T2=0,計時模式,由內部裝置 (內部振盪) 來計數。
    2. C/T2=1,計數模式,由外部裝置 (T2 pin) 來計數。
  8. CP/RL2: Timer 2 Capture/Reload Select bit
    1. RCLK=1 or TCLK=1 無作用。
    2. CP/RL2=0,16 位元自動載入模式,當 timer2 產生溢位或是 T2EX 偵測到負緣信號時,會把 RCAP2H 載入到 TH2,RCAP2L 載入到 TL2。
    3. CP/RL2=1,16 位元補捉模式,當 T2EX 偵測到負緣信號時,會把 TH2 載入到 RCAP2H,TL2 載入到 RCAP2L。

8051 pin define

Posted by: 邱小新 at 上午11:42 in

ALE/PROG 地址使能信号端

  1. 8051外接RAM/ROM时,ALE接地址器(8282)的STB脚,(74373)的EN脚,当CPU对外部存储器进行存取时,用以锁住地址的低位地址。
  2. 8051未外接RAM/ROM时,ALE脚会有1/6晶体振荡频率,可作为外部时钟。
  3. 在烧写EPROM时,ALE作为烧写时钟的输入端。

PSEN 程序储存使能端

  1. 内部程序存储器读取,不动作。
  2. 外部程序存储器读取(ROM),在每个机器周期会动作两次。
  3. 外部数据存储器读取(RAM),两个/PSEN脉冲被跳过不会输出。
  4. 外接ROM时,与ROM的/OE脚连接。

EA/VPP

  1. 接高电平时:CPU 读取内部程序存储器(ROM)。扩充外部 ROM,当读取内部程序存储器超过0FFFH(8051)、1FFFH(8052)时,自动读取外部ROM。
  2. 接低电平时:CPU 读取外部程序存储器(ROM)。
  3. 8751 烧写内部 EPROM 时,利用此脚 21V 的烧写电压。

RESET 复位引脚

  1. 为高电平时(约2个机器周期),可将CPU复位。

P0

  1. 外部扩充存储器时,作数据总线(D0~D7)。
  2. 外部扩充存储器时,作地址总线(A0~A7)。
  3. 不扩充时,作一般 I/O 使用,内部无上拉电阻,作为输出/输入使用时应加上拉电阻。

P1

  1. 只作 I/O 口使用,有内部上拉电阻。

P2

  1. 扩充外部存储器时,作地址总线(A8~A15)使用。
  2. 不扩充时,作一般 I/O 口使用,有内部上拉电阻。

P3

  1. 作一般 I/O 口使用,有内部上拉电阻。
  2. 有一些特殊功能。

8051 UART

Posted by: 邱小新 at 下午3:04 in
點圖看原始圖

baudrate 推導過程,以 timer1 為 baudrate 產生器

  1. baudrate 的單位為 bps 即每秒傳送多少 bits,反過來說傳送一個 bit 要花掉 1/baudrate 時間。
  2. 根據上圖來看,每次 timer 溢位一次,總共要經下列關卡才會接收一個 bit。
    1. 假如 SMOD=0 要經過一個二的除法器。
    2. 再進入 clock 前要先經過一個 16 的除法器。
    3. 當 SMOD=0 需 16 * 2 的計時器溢位才會接收一個 bit。
    4. 當 SMOD=1 需 16 的計時器溢位才會接收一個 bit。
    5. 推導出,需 16 * 2 / 2^SMOD 的計時器溢位才會接收一個 bit。
  3. 以 8-bit auto reload mode 來說,每一次溢位時間為 (256-TH1) * 12 / Fosc。
  4. 每接受一個 bit 要花掉時間為 (16 * 2 / 2^SMOD) * ((256-TH1) * 12 / Fosc)。
  5. 1/baudrate = (16 * 2 / 2^SMOD) * ((256-TH1) * 12 / Fosc)。
  6. 1/baudrate = (32 / 2^SMOD) * ((256-TH1) * 12 / Fosc)。
  7. baudrate = (2^SMOD * Fosc) / (384 * (256-TH1))
  8. 以 40MHz 為例,baudrate 最大值為 208333.33,最小值為 406.90。
  9. Th1 = 256 - (2^SMOD * Fosc / baudrate / 384)
  10. 以 11.0592MHz 為例,baudrate=19200 及 SMOD=1 時,TH1 = 256 - (2*11059200/19200/384) = 256-3 = 253。
  11. 以 11.0592MHz 為例,baudrate=9600 及 SMOD=0 時,TH1 = 256 - (11059200/9600/384) = 256-3 = 253。

8051 Serial Port Control Register (SCON)

Posted by: 邱小新 at 下午2:01 in
  1. SMO, SM1: serial port mode。

    SM0SM1modelength同步baudrate
    0008同步Fosc/12
    01110異步time1
    10211異步Fosc/32 or Fosc/64
    11311異步time1

  2. SM2: multiple processors communication。

    modeSM2action
    00x
    11收到有效的停止位元才會設定 RI。
    2,31當 RB8=1 才會將值送入 SBUF,並設定 RI。

  3. REN (Receive enable): REN=1 才會開啟 uart 接收功能。
  4. TB8: 在模式 2,3 時,在 bit 9 要傳送的數值,軟體要手動設定。
  5. RB8: 在模式 2,3 時,在 bit 9 所接收的數值。
  6. TI: Transmit interrupt flag。 uart 送完資料就會設定這個旗標,須由軟體手動清除此旗標。
  7. RI: Receive interrupt flag。 uart 收到資料就會設定這個旗標,須由軟體手動清除此旗標。

W78E65 on-chip 1KB AUX-RAM

Posted by: 邱小新 at 下午4:47 in
  1. 空間位址在 0x0000 ~ 0x03ff。
  2. 只能使用 MOVX 指令來讀寫,也就是設成 xdata 的變數。
  3. CHPCON 中 ENAUXRAM (bit 4) 可以設定是否使用 on-chip AUX-RAM。
    ENAUXRAM=0,0x0000~0xffff 都指向外部記憶體。
    ENAUXRAM=0,0x0000~0x03ff 指向內部記憶體。

/* enable on-chip 1KB MOVX SRAM */ CHPENR = 0x87; CHPENR = 0x59; CHPCON |= ENAUXRAM; CHPENR = 0x00;

W78E65 security register

Posted by: 邱小新 at 下午4:20 in
  1. 出廠 default 值為 0xFF,存放位址在 LDFlash 的 0xFFFF。
  2. 當某一個 bit 變成 0 後,就不可以再改成 1,要變成 1 的唯一方法就是使用 earse LDFlash 功能。
  3. Bit 0 - Lock bit (LOCK BIT)
    設成 0 時 (Active),flash 及 security 都無法讀取。
  4. Bit 1 - MOVC Inhibit (MOVC BIT)
    設成 0 時 (Enable),當 MOVC 指令在外部記憶体空間時,只能存取外部記憶体。當 MOVC 指令在內部記憶体空間時,則可以存取內部及外部記憶體。
  5. Bit 2 - Encryption
    設成 0 時 (Enable),port 0 的資料輸出會被加密。
  6. Bit 3~6 -- reserved 沒用到
  7. Bit 7 -- Select clock freqency (Osillator Control)
    設成 0 時 (1/2 gain),MCU 頻率小於 24 MHz。
    設成 1 時 (full gain),MCU 頻率大於 24 MHz。

W79L632A ISP Operation Modes register

Posted by: 邱小新 at 下午1:33 in
  1. BANK: BANK=0 選擇 Flash 0,BANK=1 選擇 Flash 1,由於 LD 只有一個 bank,所以當 WFWIN=0 時,BANK 不可寫入 1。
  2. WFWIN: WFWIN=0 選擇 LDFlash,WFWIN=1 選擇 APFlash。
  3. NOE: NOE=0 唯讀模式,NOE=1 寫入模式。
  4. NCE: NCE=0 flash 燒錄模式,NCE=1 flash 工作模式。
  5. CTRL[3:0]: 燒錄模式選擇。

ISP MODEBANKWFWINNOENCECTRLSFRCNtime
抹除 LDFlash011000100x6215ms
抹除 APFlash0001000100x2215ms
抹除 APFlash1101000100xA215ms
寫入 LDFlash011000010x6150us
寫入 APFlash0001000010x2150us
寫入 APFlash1101000010xA150us
讀取 LDFlash010000000x401.5us
讀取 APFlash0000000000x001.5us
讀取 APFlash1100000000x801.5us

  1. 抹除功能一次可抹除整個 flash,抹除完成後全部的值都變成 0xff。
  2. 讀寫功能一次只能讀寫一個 byte。
  3. 操作時間要視 XTAL 的速度來計算,上述的值是以 XTAL=24MHz 來計算。
  4. SFRAH/SFRAL 儲放欲讀寫的位址,SFRFD 則儲放讀寫的值。

W79E632A ISP control register

Posted by: 邱小新 at 上午11:37 in
  1. SWRST: software reset,令 W79E632A 回到初始狀態,並自動清除這個 bit。
  2. HWB: hardware boot,HWB=1 表示 ISP hardware reboot mode。
  3. LDAP: reand only,LDAP=1 表示在 LDFlash 運行,LDAP=0 表示在 APFlash 運行。
  4. LDSEL: LDSEL=1 表示從 LDFlash 讀取 code 執行。
  5. ENP: ENP=1 表示進入 the ISP mode。

從 APFlash 進入 LDFlash

TA = 0xAA; TA = 0x55; CHPCON = CHP_LSEL | CHP_ENP; SFRCN = 0; /* 不執行也可以, 原廠 sample code 有做 */ PCON |= IDL;

從 LDFlash 進入 APFlash

TA = 0xAA; TA = 0x55; CHPCON = SWRST | CHP_LSEL | CHP_ENP; SFRCN = 0; /* 不執行也可以, 原廠 sample code 有做 */ PCON |= IDL;

在 LDFlash 執行 ISP 指令前,需先指定 CHPCON 參數,只需指定一次即可。

TA = 0xAA; TA = 0x55; CHPCON = CHP_LSEL | CHP_ENP; SFRCN = 0; /* 不執行也可以, 原廠 sample code 有做 */ PCON |= IDL; /* 不執行也可以, 原廠 sample code 有做 */

在 APFlash 執行 ISP 指令前,需先指定 CHPCON 參數,只需指定一次即可。

TA = 0xAA; TA = 0x55; CHPCON = CHP_ENP; SFRCN = 0; /* 不執行也可以, 原廠 sample code 有做 */ PCON |= IDL; /* 不執行也可以, 原廠 sample code 有做 */

注意事項

  1. CHPCON 在寫入時需要 timed access protection
  2. CHPCON 在進入 idle mode 才會執行上述指令,所以記得要讓 W79L632A 離開 idle mode,原廠 sample code 使用 XTAL=24MHz 在 idle mode 花費 8us。
  3. 其實可以不要理會 datasheet 上在寫什麼,記住切換 flash 要如上述的下指令即可,不要想要更動指令,會產生錯誤的結果,因為我已經試過都無效了。

8051 Timer

Posted by: 邱小新 at 上午9:45 in
TMOD register 0x89 (timer/counter mode control register)

  1. GATE = 1 需要 INTx 接腳為高電位才計時,GATE = 0 則不需要。

    也就是當 TRx=1 and GATE=0 開始計時,或者當 TRx=1 and GATE=1 and INTx=1 開始計時,其它條件都不計時。

  2. C/T = 0 使用內部時脈,C/T = 1 使用外部時脈。

    Timer 的計時時脈來源有兩種,一種是 8051 單晶片的內部時脈也就是從 XTAL1 與 XTAL2 接腳所輸入的內部時脈,一種是從 T0 與 T1 接腳所輸入的外部時脈。所以一般來說設定成內部時脈時,稱為計時器,因為振盪器頻率固定可以當計時器用;而設定成外部時脈時,稱為計數器,因為不知使用者會接什麼裝置,但是都有計算次數功能。如果外部時脈也是接振盪器時,也可以算是計時器,只是沒人會如此做,因為直接使用內部時脈即可,可以省成本又可以多些腳位使用。

  3. M1, M0: Mode Select bits:

    M1M0MODE
    0013 位元計時器
    0116 位元計時器
    108 位元自動重新載入
    11兩個8位元計時器

  4. 在 8051 單晶片使用內部時脈計時,會在每個機械週期值由〝1〞變為〝0〞時,將 Timer 的值累加1。也就是每一個 count 的時間為一個機械週期的時間,時間算法請見 8051 clock

  5. 當計時器溢位時(0xff->0x00),會設置 TFx 為 1;如果 ETx 被設置成 1,則接著會進入中斷常式,並且把 TFx 設置為 0。

8 位元自動重新載入時間算法,以 40MHz 為例:


  1. 當 TLx 從 0xff 變成 0x00 時,會產一個中斷,並且把 THx 載入 TLx 再繼續計數。所以產生中斷的次數為 256-THx。

  2. 1 count = 12/40000000(s) = 12/40000(ms) = 12/40(us),所以產生中斷的時間為 (256-THx) * 12/40。

  3. 最大值為 (256-0)*12/40 = 76.8(us),最小值為 (256-255)*12/40 = 0.3(us)。

  4. 如果設定中斷時間為 60us 則 (256-THx) * 12/40 = 60,THx = 256 - 60*40/12 = 56。

watchdog interrupt function

Posted by: 邱小新 at 下午5:13 in

watchdog time-out 後會呼叫 watchdog interrupt function,再經過 512 clock 後會做 reset 8051 動作。如果在這 512 clock 之間重置 watchdog 就不會 reset 8051。經過測試結果,在很久很久的時間過後,仍有機會引起 reset 動作,也就是 reset watchdog 沒有來得急做,即使把 watchdog interrupt priority 提高也是一樣。最好不要用喔。

void watchdog_isr(void) interrupt 12 { // clear interrupt flag TA = 0xAA; TA = 0x55; WDIF = 0; // reset watchdog TA = 0xAA; TA = 0x55; RWT= 1; }

W79E632A 啟動時的旗標

Posted by: 邱小新 at 下午4:46 in
flagPower-on resetWatchdog resetExternal reset
POR1xx
WTRF010
EWT0xx
WDCON01000000b0x0x01x0b0x0x0xx0b

由上表得知一些判斷開機的因素,整理如下:

  1. 判斷是因為電源開關所引起的開機。
    只要判斷 POR 為 1 即可,開完機後需要立即把 POR 清為 0,以利後續判斷。
  2. 判斷是因為 watchdog 所引起的開機。
    只要判斷 WTRF 為 1 即可,開完機後需要立即把 WTRF 清為 0,以利後續判斷。
  3. 判斷是因為外部中斷所引起的開機。
    只要不是上述二個條件就是外部中斷引起的。
if (POR) { POR = 0; // power-on reset } else if(WTRF) { WTRF = 0; // watchdog reset } else { // external reset } PS: 一開機後請立即清除 EWT,以免 watchdog reset 再次發生。

W79E632 watchdog function

Posted by: 邱小新 at 下午3:27 in

啟動 watchdog 程序

  1. 先關閉 watchdog 功能,防止一些干擾的問題。
  2. 選擇 watchdog time-out 時間。
  3. 設定 watchdog 中斷開關。
  4. 開啟 watchdog 重置工作。
  5. 開啟 watchdog 功能。
void watchdog_start(void) { // clear watchdog flag TA = 0xAA; TA = 0x55; WDCON = 0; // select 2^26 time-out interval CKCON |= 0xC0; // disable watchdog interrupt EWDI = 0; // start watchdog reset task poller_start(POLLER_WATCHDOG, TIMER_WATCHDOG); // enable watchdog TA = 0xAA; TA = 0x55; WDCON = 3; }

關閉 watchdog 程序

void watchdog_stop(void) { TA = 0xAA; TA = 0x55; EWT= 0; }

重置 watchdog 程序

void watchdog_reset(void) { TA = 0xAA; TA = 0x55; RWT= 1; } PS: 一開機後請立即清除 EWT,以免 watchdog reset 再次發生。

8051 interrupt

Posted by: 邱小新 at 下午1:42 in ,
  1. 8051 的中斷服務功能,可使程式強制中斷去執行需要即時處理的副程式,進而提升執行效率。
  2. 在 8051 中總共提供五個中斷來源。INT0,INT1,Timer0,Timer1,UART。
  3. 中斷源在 8051 中都有相對應的旗標,當中斷條件產生時,中斷源就會使其相對應的旗標值設定為 1。8051 會在每一個機械週期檢查這些旗標的狀態,若系統允許相對的中斷源產生中斷,且該中斷相對應的旗標值亦為 1 時,則 8051 會在執行完目前正在執行的指令後,將程式在記憶體中的位址存入堆疊中,並產生中斷服務副程式的呼叫,跳到該中斷所對應之中斷向量位址去執行,8051 執行該中斷服務副程式,直到 RETI 指令後才結束中斷副程式,再從堆疊中取出先前存入的位址值繼續執行被中斷的程式。
  4. 當一個中斷要求發生時,若中斷是被致能的,則 8051 會執行該中斷服務副程式。然而在執行中斷副程式中若有較高優先權的中斷源要求中斷,則 8051 會先暫停目前正在執行的中斷服務副程式,而立即執行這個較高優先權的中斷服務副程式。如果相同優先權或優先權較低的中斷源要求中斷,則 8051 將不予理會。另外,若兩中斷同時發生,則高優先權中斷源優先執行;但若優先權相同時,則依 INT0、Timer0、INT1、Timer1、UART 之順序先後執行。

中斷產生的要件

  1. 沒有任何事情可以停止高優先權的中斷運行,即使是另一個擁有高優先權的中斷。
  2. 一個擁有高優先權的中斷發生,可以強制停止另一個低優先權的中斷運行,讓自己先行。
  3. 一個擁有低優先權的中斷發生,只能在沒有任何中斷運行的條件下,才可以執行。
  4. 如果二個中斷同時發生,高優先權的中斷會先執行;如果是同樣優先權的中斷,則依 INT0、Timer0、INT1、Timer1、UART 之順序先後執行。

中斷發生時所做的事

  1. Program Counter push 進堆疊裏,low-byte 最先。
  2. 同一優先權及低優先權的中斷被阻塞。
  3. 在時間及外部中斷發生時,相對應的中斷旗標會被自動清除。
  4. Program Counter 轉換成相對應的中斷向量位置。
  5. 執行中斷程式。

中斷結束時所做的事

  1. Program Counter 堆疊裏 pop 出來。
  2. 中斷旗標被恢復成中斷前的值。
  3. 所以在時間及外部中斷發生時,中斷程式中就不需要為了防止再次中斷發生,而自己去操作中斷旗標
  4. 繼續執行中斷前的程式。

中斷必須保護的暫存器

  1. ACC
  2. B
  3. DPTR (DPH/DPL)
  4. PSW
  5. R0~R7

中斷時 register bank 的使用

  1. R0~R7 有 4 個 register bank 可以使用。
  2. SDCC 發現你在中斷使用 bank0 時,都會對 R0~R7 做 push/pop 動作。
  3. SDCC 發現你在中斷使用 bank1~3 時,不會對 R0~R7 做 push/pop 動作。
  4. SDCC 的中斷函數跟 main 函數沒有放在一起編譯時,則不會有任何最佳化作用,也就是中斷必須保護的暫存器通通都會做 push/pop,表示 register bank 的使用無效。
  5. 因為相同優先權不會互相中斷執行,所以相同優先權的 interrupt 可以使用同一個 bank。
  6. 因為高優先權會中斷低優先權的執行,所以不同優先權的 interrupt 不可使用同一個 bank(bank0 除外)。
  7. 最好按照下列方式使用:
    1. bank0: main routine
    2. bank1: low-priority interrupt
    3. bank2: high-priority interrupt
  8. 如果要節省記憶體的使用,就全部用 bank0 吧。

W79x632A timed access protection

Posted by: 邱小新 at 下午1:08 in
  1. W79L632A 有幾個 register 需要接受寫入保護,免得招到中斷破壞,導致問題出現。
  2. 這些需要寫入保護的 register,一定要使用寫入保護方式才可以做寫入動作,其餘無效。
  3. 做法為寫入 TA=0xAA; 再寫入 TA=0x55; 後,有三個 machine cycles 時間受到寫入保護,不被干擾。

受到寫入保護的 register
  1. WDCON
  2. POR
  3. EWT
  4. WDIF
  5. RWT
  6. CHPCON

TA REG C7H MOV TA, #AAH MOV TA, #55H MOV WDCON, #00H

watchdog 中斷觸發時間

Posted by: 邱小新 at 上午11:38 in

watchdog 中斷觸發時間計算方式:(以 40MHz 為例)
1/40000000 * 2^17 = 131072/40000000 = 0.0032768(s) = 3.2768(ms)

WD1WD0intervalclocks@40MHz
002^171310723.2768 ms
012^20104857626.2144 ms
102^238388608209.7152 ms
112^26671088641677.7216 ms

8051 clock

Posted by: 邱小新 at 上午11:00 in
  1. 一個機械週期 (Machine Cycle) 是由 6 個狀態週期 (State) S1-S6 組成。而每一個狀態週期包含 2 個振盪週期分別稱為 Pl 與 P2 。
  2. ALE (位址栓鎖致能)則是每 6 個振盪週期出現一次。
  3. 當震盪器頻率 (crystal frequency) 為 12Mhz 時,表示一秒鐘能震盪 12000000 次,所以每震盪一次時間 (1 clock time) 為 1/12000000,而一個 machine cycyle 的時間需要 12 個振盪週期則為 12*1/12000000=1/1000000。
  4. 當震盪器頻率 (crystal frequency) 為 40Mhz 時,表示一秒鐘能震盪 40000000 次,所以每震盪一次時間 (1 clock time) 為 1/40000000,而一個 machine cycyle 的時間需要 12 個振盪週期則為 12*1/40000000=3/10000000。
  5. 一般每個指令需要二到三個 machine cycle 不等,每個 machine cycle 費時 12 個 clock,因此如果接上 12Mhz 的震盪器,則有 1 MIPS 的運算量。1T 或 4T,代表可在 1 個 clock 或 4 個 clock 完成一個 machine cycle。
  6. 另一種說法,8051 的計數器是一個機器週期為一個 count,而一個機器週期費時 12 個 clock,所以說 counting at the rate of 1/12 of the clock speed,表示每秒只能計數 12000000/12 次;如果是 4T's 8051 則為 1/4 of the clock speed,表示每秒可以計數 12000000/4 次,比一般的 8051 快了三倍速度。
  7. MIPS 即 Million Instructions Per Second 的簡稱,衡量計算機性能的指標之一。它表示單字長定點指令的平均執行速度。

Idle mode 省電功能

Posted by: 邱小新 at 上午10:24 in
  1. 進入 idle mode 後,CPU clock 會停止,進而逹到省電效果。
  2. 只要中斷產生,就可以回復程式執行,會從進入 idel mode 的命令之後開始執行。
  3. 在 main loop 不可有即時性工作,以免進入 idel mode 後無法執行而造成錯誤。
  4. 切記,當使用到 PWM 指令時,不可進入 idle mode,會失效的。

/* entry the idle mode */ PCON |= 1;

W79L632A on-chip 1KB MOVX SRAM

Posted by: 邱小新 at 上午10:03 in
  1. 空間位址在 0x0000 ~ 0x03ff。
  2. 只能使用 MOVX 指令來讀寫,也就是設成 xdata 的變數。
  3. PMR 中 DME0 (bit 0) 可以設定是否使用 on-chip。
    DME0=0,0x0000~0xffff 都指向外部記憶體。
    DME1=0,0x0000~0x03ff 指向內部記憶體。

/* enable on-chip 1KB MOVX SRAM */ PMR |= 0x01;

W79L632A register define

Posted by: 邱小新 at 上午9:56 in
#include <8052.h> /* ------------------------------------------------ */ /* The SFRs reside in the register locations 80-FFh */ /* and are accessed by direct addressing only. */ /* ------------------------------------------------ */ __sfr __at (0x8E) CKCON; __sfr __at (0x92) P4CONA; __sfr __at (0x93) P4CONB; __sfr __at (0x9F) CHPCON; __sfr __at (0xA5) P4; __sfr __at (0xA9) SADDR; __sfr __at (0xAB) ROMCON; __sfr __at (0xAC) SFRAL; __sfr __at (0xAD) SFRAH; __sfr __at (0xAE) SFRFD; __sfr __at (0xAF) SFRCN; __sfr __at (0xC3) PWM5; __sfr __at (0xC4) PMR; __sfr __at (0xC7) TA; __sfr __at (0xCE) PWMCON2; __sfr __at (0xCF) PWM4; __sfr __at (0xD8) WDCON; __sfr __at (0xD9) PWMP; __sfr __at (0xDA) PWM0; __sfr __at (0xDB) PWM1; __sfr __at (0xDC) PWMCON1; __sfr __at (0xDD) PWM2; __sfr __at (0xDE) PWM3; __sfr __at (0xE8) EIE; __sfr __at (0xF8) EIP; /* ------------------------------------------------ */ /* The SFRs that are bit addressable are those */ /* whose addresses end in 0 or 8. */ /* ------------------------------------------------ */ __sbit __at (0xD8) RWT ; /* protected bit */ /* Mnemonic:WDCON, bit 0 */ __sbit __at (0xD9) EWT ; /* protected bit */ __sbit __at (0xDA) WTRF; __sbit __at (0xDB) WDIF; /* protected bit */ __sbit __at (0xDC) WD_4; /* not used */ __sbit __at (0xDD) WD_5; /* not used */ __sbit __at (0xDE) POR ; /* protected bit */ /* Mnemonic:WDCON, bit 6 */ __sbit __at (0xDF) WD_7; /* not used */ //---------------------------------------------------------------------- // EIE register 0xE8 (Extended Interrupt Enable register) // 7 6 5 4 3 2 1 0 // X X X EWDI X X X X //---------------------------------------------------------------------- __sbit __at (0xEC) EWDI; //---------------------------------------------------------------------- // EIP register 0xF8 (Extended Interrupt Priority register) // 7 6 5 4 3 2 1 0 // X X X PWDI X X X X //---------------------------------------------------------------------- __sbit __at (0xFC) PWDI;//---------------------------------------------------------------------- // PWMCON1 register 0xDC (PWM control 1 register) // 7 6 5 4 3 2 1 0 // PWM3OE PWM2OE ENPWM3 ENPWM2 PWM1OE PWM0OE ENPWM1 ENPWM0 //---------------------------------------------------------------------- #define PWM3OE 0x80 // Output enable for PWM3 #define PWM2OE 0x40 // Output enable for PWM2 #define ENPWM3 0x20 // Enable PWM3 #define ENPWM2 0x10 // Enable PWM2 #define PWM1OE 0x08 // Output enable for PWM1 #define PWM0OE 0x04 // Output enable for PWM0 #define ENPWM1 0x02 // Enable PWM1 #define ENPWM0 0x01 // Enable PWM0 //---------------------------------------------------------------------- // PWMCON2 register 0xCE (PWM control 2 register) // 7 6 5 4 3 2 1 0 // X X X X PWM5OE PWM4OE ENPWM5 ENPWM4 //---------------------------------------------------------------------- #define PWM5OE 0x08 // Output enable for PWM5 #define PWM4OE 0x04 // Output enable for PWM4 #define ENPWM5 0x02 // Enable PWM5 #define ENPWM4 0x01 // Enable PWM4 //---------------------------------------------------------------------- // PCON register 0x87 (power control register) // 7 6 5 4 3 2 1 0 // SMOD X X X GF1 GF0 PD IDL //---------------------------------------------------------------------- #define PCON_SMOD 0x80 // double baud rate, when serial mode 1,2,3 #define PCON_GF1 0x08 // general purpose #define PCON_GF0 0x04 // general purpose #define PCON_PD 0x02 // entry power down mode #define PCON_IDLE 0x01 // entry idle mode //---------------------------------------------------------------------- // CHPCON register 0x9F (ISP control register) protected byte // 7 6 5 4 3 2 1 0 // SWRST X LDAP X X X LSEL ENP //---------------------------------------------------------------------- #define CHP_SWRST 0x80 // Set this bit to launch a whole device reset // that is same as asserting high th RST pin. #define CHP_LDAP 0x20 // read only. High: the device is excuting the program in LDFlash // Low: the device is excuting the program in APFlashs #define CHP_LSEL 0x02 // Set to high to route the device fetching code from LDFlash #define CHP_ENP 0x01 // Set this be to launch the ISP mode

SDCC 與 Keil-C 相異之處

Posted by: 邱小新 at 上午11:00 in
  1. sfr and sbit setting,使用 Keil-C 的寫法在 SDCC 編譯一樣會過,沒有錯誤顯示,但是結果完全不同,一定要用 SDCC 寫法才正確。


  2. Keil-C sfr PMR = 0xC4;
    sbit P3_0= 0xB0;
    SDCC __sfr __at (0xC4) PMR;
    __sbit __at (0xB0) P3_0;


  3. Interrupt Service Routines,使用 Keil-C 的寫法在 SDCC 一樣 OK 沒問題。另外 timer0_isr 需要在 maic() 的 source 裏宣告原型,這樣才會被放進 interrupter vector 裏,切記。


  4. Keil-C void timer0_isr(void) interrupt 3 using 3
    SDCC void timer0_isr(void) __interrupt (3) __using (3);

eclipse 雜記

Posted by: 邱小新 at 上午10:47 in
  1. File -> Switch Workspace -> Others 就可以變更路徑了。
  2. 當把一個檔案移到另一個目錄時,在編譯時總是會出錯;這時候只要把 Debug 及 Release 目錄移除再做一次編譯即可。原因就是要移除 makefile,因為 makefile 路徑不對,造成一些誤判。
  3. 要切換 Debug/Release,需進入 project setting → C/C++ Build → Settings → Configuration 右邊的 Manage Configurations...,再做 Set Active 動作即可。千萬不要去改變 Configuration 選項,一點作用都沒有。

Creating an new project on eclipseSDCC

Posted by: 邱小新 at 上午10:31 in
  1. File -> New -> C Project
  2. In the Project name field, type your name as the name of your new project. Do not use spaces or special characters in the project name (for example, "test1").
  3. Click Finish when you are done.
  4. Project -> Properties
  5. Tool Settings -> SDCC Compiler -> Directories -> Include paths(-I) add C:\Program Files\SDCC\include\mcs51 add C:\Program Files\SDCC\include
  6. File -> New -> Source File -> main.c /* * main.c * * Created on: 2008/9/22 * Author: enos_chiou */ #include <8051.h> #include <stdio.h> char tmp[50]; void main(void) { sprintf(tmp, "hello world.\n"); }
  7. Project -> Build Project
  8. burn the ihx file with ALL-11
  9. 如果要全部重新編譯,則使用 Project -> Clean... 就可以了。

SDCC for eclipse install

Posted by: 邱小新 at 上午10:26 in
  1. download Eclipse IDE for C/C++ Developers (CDT integrated) v3.4.0 http://eclipse.cdpa.nsysu.edu.tw/technology/epp/downloads/release
    /ganymede/R/eclipse-cpp-ganymede-win32.zip

  2. download the SDCC plug-in for eclipse -- eclipseSDCC-1.0.0 (support MCS-51 only) http://nchc.dl.sourceforge.net/sourceforge/eclipse-sdcc/net.sourceforge.eclipsesdcc-1.0.0-win32.x86.zip

  3. download Java Runtime Environment (JRE) http://javadl.sun.com/webapps/download/AutoDL?BundleId=23111

  4. download SDCC - Small Device C Compiler http://nchc.dl.sourceforge.net/sourceforge/sdcc/sdcc-2.8.0-setup.exe

  5. Install Java runtime first

  6. Unpack Eclipse to harddrive i.e. C:\Eclipse and made Shortcut on desktop

  7. Unpack EclipseSDCC on Eclipse folder (both feature and plugin)

  8. Finally, Setup SDCC Package with installer (for automatic PATH setting)

W79E632A security bits 說明

Posted by: 邱小新 at 上午10:20 in
  1. 出廠 default 值為 0xFF,存放位址在 LDFlash 的 0xFFFF(根據 W78E65 datasheet 猜測值)。
  2. 當某一個 bit 變成 0 後,就不可以再改成 1,要變成 1 的唯一方法就是使用 earse LDFlash 功能。
  3. Bit 0 - Lock bit (LOCK BIT)
    設成 0 時 (Active),flash 及 security 都無法讀取。
  4. Bit 1 - MOVC Inhibit (MOVC BIT)
    設成 0 時 (Enable),當 MOVC 指令在外部記憶体空間時,只能存取外部記憶体。當 MOVC 指令在內部記憶体空間時,則可以存取內部及外部記憶體。
  5. Bit 2,3 -- reserved 沒用到
  6. Bit 4 - H/W Reboot with P2.6 and 2.7 (Set P2 reboot)
    設成 0 時 (Enable),在開機時(RST = HIGH),P2.6 = LOW and P2.7 = LOW 時,MCU 會進入 LDFlash。
  7. Bit 5 - H/W Reboot with P4.3 (Set P4 reboot)
    設成 0 時 (Enable),在開機時(RST = HIGH),P4.3 = LOW 時,MCU 會進入 LDFlash。
  8. Bit 6 -- reserved 沒用到
  9. Bit 7 -- Select clock freqency (Osillator Control)
    設成 0 時 (FULL),MCU 頻率小於 24 MHz。
    設成 1 時 (1/2),MCU 頻率大於 24 MHz。