Lập trình Nuvoton Timer 2 và 3

Lập trình Nuvoton Timer 2 và 3

Trong bài trước chúng ta đã khảo sát hai bộ timer/counter 0 và 1. Ở bài này, chúng ta sẽ khảo sát timer 3 và timer 2.

Lập trình Nuvoton Timer 3

Cấu tạo

Timer 3 có cấu tạo tương đối đơn giản, bao gồm một một prescaler 3-bit nhận clock từ Fsys, một bộ counter 16-bit và một cặp thanh ghi chứa giá trị nạp lại 16-bit (gồm hai thanh ghi 8-bit RH3 & RL3 gộp lại), kèm theo cờ điều khiển TR3 và cờ báo tràn TF3:

word image 8581 1

Prescaler được cấu hình tại T3CON[2:0], các giá trị độ chia được mô tả cụ thể trong datasheet:

word image 8581 2

Timer 3 cũng có bit dùng để run/stop là TR3 (T3CON.3) và một cờ báo tràn là TF3 (T3CON.4).

Timer 3 chỉ có duy nhất mode tự nạp lại. Giá trị nạp lại được lưu trong cặp thanh ghi RH3 & RL3. Mỗi khi timer 3 tràn, cờ TF3 được set, đồng thời giá trị trong RH3 & RL3 cũng được nạp vào counter 16-bit để bắt đầu chu kỳ mới.

Chu kỳ tràn của timer 3:

timer 3 1

Lưu ý: các bit điều khiển TR3, T3PS và cờ báo tràn TF3 không thể định địa chỉ bit, bắt buộc truy cập thông qua thanh ghi T3CON:

word image 8581 4

(Ở dòng 8051 nói chung, chỉ những thanh ghi có low nibble (4-bit thấp) của địa chỉ bằng 0h hoặc 8h thì mới có thể truy cập trực tiếp đến bit).

Lập trình Nuvoton Timer 3 tạo delay

Yêu cầu:

Viết hàm delay100ms(n) cho phép delay (n * 100) mili giây, sử dụng timer 3. Blink LED1 tần số 1Hz với hàm delay100ms vừa tạo.

Phân tích:

Khi dùng timer để đếm một khoảng thời gian lớn, ta nên cài đặt prescaler mở mức chia lớn.

Chọn prescaler = 1/128, chu kỳ tràn timer 3 là 100ms, ta tính được giá trị nạp lại:

timer 3 2

Như vậy ta cần ghi 49256 vào cặp RH3 & RL3.

Chương trình được viết như sau:

#include <stdint.h>
#include <mcs51/N76E885.h>
#include <mcs51/Define.h>



#define     LED1        P04
// #define     LED2        P03
#define     ON_LED      0
#define     OFF_LED     1



void delay100ms(uint16_t duration) {
    T3CON |= SET_BIT2 | SET_BIT1 | SET_BIT0;    // prescaler = 1/128
    RH3 = HIBYTE(65536 - 17280);
    RL3 = LOBYTE(65536 - 17280);
    T3CON |= SET_BIT3;  // run
    for (; duration > 0; duration--) {
        while (!(T3CON & SET_BIT4));    // while (TF3 == 0);
        T3CON &= CLR_BIT4;  // xoá cờ tràn TF3
    }
    T3CON &= CLR_BIT3;  // stop
}



void main(void) {

    // Insert code

    //
    // P0.4 (LED1) quasi-bidiretional mode
    //
    P0M1 &= CLR_BIT4;
    P0M2 &= CLR_BIT4;

    //
    // khởi tạo giá trị mặc định
    //
    LED1 = OFF_LED;



    while (1) {
        LED1 = !LED1;
        delay100ms(5);
    }
}

 

Sau khi biên dịch và nạp code:

 

Lập trình Nuvoton Timer 2

Cấu tạo

word image 8581 6

Timer 2 dùng clock Fsys, bộ prescaler có 8 mức chia và được cấu hình bởi T2MOD[6:4]:

word image 8581 7

Tương tự như những timer khác, timer 2 cũng có bit run/stop là TR2 và cờ báo tràn TF2. Ngoài chức năng báo tràn, TF2 còn là cờ báo “so sánh bằng”.

Các mode hoạt động của Timer 2

Timer 2 có bit CM_RL2 nằm trên thanh ghi T2CON dùng để cấu hình mode.

word image 8581 8

Cấu trúc timer 2 khi bit CM_RL2 = 0.

word image 8581 9

Cấu trúc timer 2 khi bit CM_RL2 = 1.

Timer 2 là một bộ đếm 16-bit gồm TH2 & TL2.

Ngoài ra, timer 2 còn có một cặp thanh ghi đa năng RCMP2H & RCMP2L. Tuỳ theo cấu hình mode, mà giá trị bên trong cặp thanh ghi này có thể dùng để nạp lại cho TH2 & TL2 hoặc so sánh với TH2 & TL2.

Phần cứng của timer 2 tương đối phức tạp nên diễn tả bằng lời văn khá là dài dòng. Mình sẽ cô động cách cấu hình cho timer 2 trong bảng giá trị bên dưới:

word image 8581 10

Mặc dù trong datasheet mô tả timer 2 có hai mode là Auto-reload và Compare, nhưng mode Auto-reload cho phép chúng ta chủ động enable/disable việc nạp lại. Do đó, có thể xem timer 2 có 3 mode. Ngoài ra, timer 2 cũng hỗ trợ một số tuỳ chọn tự động xoá theo như bảng trên.

Trong bảng trên có đề cập đến một số sự kiện (event) liên quan đến timer 2:

  • Sự kiện “timer tràn”.

Tương tự như những timer 16-bit khác, sự kiện này xảy ra khi timer 2 ([TH2:TL2]) vượt quá 0xFFFF. Khi đó, cờ TF2 được set lên 1, timer 2 có thể cuộn về 0 hoặc được reload tuỳ theo cấu hình đã cài đặt. Do đó, chu kỳ tràn của timer 2 không có một công thức chung.

Trường hợp cấu hình mode nạp lại và không tự động xoá, mình tạm gọi khoảng thời gian từ lúc reload đến lúc timer tràn là “chu kỳ reload”:

timer 2 1

  • Sự kiện “compare match” (không có ví dụ cho chế độ này)

Sự kiện “compare match” xảy ra ở mode so sánh, khi mà [TH2:TL2] = [RCMP2H:RCMP2L].

Trường hợp cấu hình mode so sánh và tự động xoá khi “compare match”, mình tạm gọi khoảng thời gian từ lúc timer 2 bằng 0 đến khi xảy ra “compare match” là “chu kỳ match”:

timer 2 2

  • Sự kiện “capture” (không có ví dụ cho chế độ này)

Sự kiện “capture” xảy ra khi module input capture đã được enable và xuất hiện 1 cạnh xung (lên hoặc xuống) trên một GPIO có kết nối với module input capture. Mình sẽ dành một bài viết riêng dành cho module input capture để nói về cấu tạo và cách cấu hình sử dụng.

Khi sự kiện capture xảy , cờ báo capture của module này được set và đồng thời giá trị [TH2:TL2] cũng được lưu vào module input capture.

Lập trình Nuvoton Timer 2 tạo delay

Yêu cầu:

Viết hàm delay1ms(n) cho phép delay n mili giây, sử dụng timer 2. Blink LED1 tần số 1 Hz.

Phân tích:

Với thời gian delay ngắn, mình ưu tiên sử dụng prescaler có độ chia nhỏ, chọn prescaler = 1/1.

Các bạn có thể sử dụng bất kỳ mode nào để tạo delay:

  • Mode “không nạp lại”: cách triển khai giống mode 1 (16-bit) của timer 0.
  • Mode “nạp lại”: cách triển khai giống timer 3.
  • Mode “so sánh”: mình sẽ dùng mode này cho ví dụ.

Mình sẽ cấu hình cho timer 2 ở mode so sánh, cho phép tự động xoá mỗi khi “compare match” và tính toán sao cho “chu kỳ match” là 1ms.

Từ công thức tính “chu kỳ match”, ta tính được giá trị compare [RCMP2H:RCMP2L]:

timer 2 3

Chương trình được viết như sau:

#include <stdint.h>
#include <mcs51/N76E885.h>
#include <mcs51/Define.h>



#define     LED1        P04
// #define     LED2        P03
#define     ON_LED      0
#define     OFF_LED     1



void delay1ms(uint16_t duration) {
    CM_RL2 = 1;         // mode so sánh
    T2MOD &= CLR_BIT6 & CLR_BIT5 & CLR_BIT4;    // prescaler = 1/32
    T2MOD |= SET_BIT2;  // tự đông xoá khi "compare match"
    RCMP2H = HIBYTE(22118);
    RCMP2L = LOBYTE(22118);
    TR2 = 1;
    for (; duration > 0; duration--) {
        while (!TF2);   // chờ đến khi "compare match"
        TF2 = 0;
    }
    TR2 = 0;
}



void main(void) {

    // Insert code

    //
    // P0.4 (LED1) quasi-bidiretional mode
    //
    P0M1 &= CLR_BIT4;
    P0M2 &= CLR_BIT4;

    //
    // khởi tạo giá trị mặc định
    //
    LED1 = OFF_LED;



    while (1) {
        LED1 = !LED1;
        delay1ms(500);
    }
}

 

Sau khi biên dịch và nạp code:

Kết luận

Như vậy chúng ta đã khảo sát xong timer 3 và timer 2. Ở bài kết tiếp, chúng ta cùng nhau khảo sát module input capture của timer 2 và một số ứng dụng của nó.

 

Rate this post

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *