Lập trình Nuvoton Timer 0 và Timer 1

Lập trình Nuvoton Timer 0 va 1

Timer là một ngoại vi không thể thiếu của bất kỳ một vi điều khiển nào. Timer đơn giản chỉ là một bộ đếm (counter) nhưng xung clock mà nó đếm lại có tần số ổn định được tạo ra bởi thạch anh hoặc bộ dao động RC. Do đó timer là một bộ đo thời gian (bộ đếm thời gian).

N76E885 được trang bị 6 timer, gồm có: timer 0, timer 1, timer 2, timer 3, self wake up timer, watchdog timer. Các bộ timer này chỉ có thể đếm lên.

Ở nội dung bài này, chúng sẽ khảo sát hai bộ timer/counter 0 và 1 trên N76E885.

Vì timer 0 và timer 1 là giống nhau, nên mình chỉ đề cập đến timer 0. Nếu muốn sử dụng timer 1, các bạn cấu hình thanh ghi và bit tương ứng của timer 1.

Cấu tạo của timer 0 và 1

Cấu tạo phần clock và prescaler cho cả timer/counter 0 được mô tả như hình sau:

word image 8534 1

Clock cho timer/counter 0 có thể đến từ 3 nguồn, được cấu hình bởi 2 bit T0LXTM và C/T:

word image 8534 2

(Một số ứng dụng liên quan đến đếm sản phẩm, đếm xung,… nhận vào pin T0, các xung này thường không có tần số cụ thể. Do đó, timer 0 còn được gọi là counter 0 trong trường hợp này).

Timer/counter 0 cũng có một bộ prescaler nhưng chỉ kết nối với clock từ Fsys. Prescaler này cho phép chia xung ở hai mức:

word image 8534 3

Ta có thể run/stop timer 0 thông qua phần mềm hoặc phần cứng:

word image 8534 4

Timer 0 cũng cho phép xuất tín hiệu báo tràn ra ngoài. Khi bit T0OE (P1M1.2) được set, pin T0 sẽ đảo trạng thái tại mỗi lần timer 0 tràn.

word image 8534 5

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

Timer 0 có 4 mode hoạt động, được cấu hình bởi TMOD [1:0]:

word image 8534 6

Mode 0 thường được sử dụng như một prescaler = 1/(213), kết hợp với thạch anh 32.768 kHz. Khi đó, tần số tràn timer là 4 Hz có thể áp dụng trong các ứng dụng đồng hồ thời gian thực.

Mode 3 sẽ không sử dụng timer 1 (TH1 & TL1), thay vào đó, timer 0 sẽ tách ra làm 2 phần:

  • TL0 nối với clock của timer 0.
  • TH0 nối với clock của timer 1.

Trong bài viết này, mình chỉ đề cập đến 2 mode phổ biến là mode 1 và mode 2. Các bạn có thể đọc thêm datasheet để tìm hiểu thêm về mode 0 và mode 3.

Chúng ta tạo một project như các bài trước nhé:

word image 8534 7

Lập trình Nuvoton Timer 0 Mode 1

word image 8534 8

Sau khi cấu hình prescaler và cho phép clock vào timer 0, nó sẽ bắt đầu đếm lên. Ngay khi vừa đếm đến 65536 (tương ứng với 0 của số 16-bit) thì cờ báo tràn TF0 set lên 1, timer tiếp tục đếm lên như bình thường.

Dựa vào tần số clock cấp cho timer, ta có thể tính được chu kỳ tràn của timer (thời gian từ lúc bắt đầu khởi tạo giá trị và run cho đến lúc timer tràn):

timer 0 1

Với Ftimer0 là tần số của clock cấp trực tiếp cho timer 0 (đã qua prescaler nếu có).

Ví dụ 1 – Tạo delay chu kỳ lớn bằng timer 0

Yêu cầu:

Viết hàm delay1sec(n) cho phép delay n giây. Dùng timer 0 mode 1, nhận clock từ thạch anh ngoài 32.768 kHz. Đảo trạng thái LED1 sau mỗi 2 giây.

Phân tích:

Các cấu hình về mode, clock, prescaler có thể dựa vào các bảng giá trị ở phần 2 và 3.

Khi đó, tần số clock cấp cho timer 0 là:

timer 0 2

Giả sử timer 0 tràn sau mỗi giây thì:

timer 0 3

Từ công thức tính chu kỳ tràn của timer 0, ta tính được giá trị khởi tạo của [TH0:TL0]:

timer 0 4

(Tầm giá trị của [TH0:TL0] là từ 0 đến (216-1) = 65535).

Có một lưu ý nhỏ khi sử dụng các clock ngoài. Mặc định sau khi N76E885 reset, các nguồn clock ngoài đều ở trạng thái disable và ta không thể sử dụng ngay. Để enable các nguồn clock ngoài, ta cần can thiệp vào giá trị trên thanh ghi CKEN bằng một số thao tác đặc biệt. Trong bài viết này, mình sẽ cung cấp sẵn một đoạn code để enable clock từ thạch anh ngoài 32.768 kHz. Chúng ta sẽ nói về cách truy cập đến một số thanh ghi đặc biệt như CKEN trong bài viết Timed Access Protection.

Trong vòng lặp while (1) mình sẽ đảo trạng thái LED1 sau mỗi 2 giây.

Chương trình hoàn chỉnh 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 delay1sec(uint16_t duration) {
    TMOD &= CLR_BIT3 & CLR_BIT2 & CLR_BIT1 & CLR_BIT0;  // xoá 4 bit thấp của TMOD
    TMOD |= SET_BIT0;   // timer 0: GATE = 0, C/T = 0, mode 1
    AUXR1 |= SET_BIT4;  // clock thạch anh 32.768 kHz
    for (; duration > 0; duration--) {
        TH0 = HIBYTE(32768);
        TL0 = LOBYTE(32768);
        TR0 = 1;        // run
        while (!TF0);   // chờ đến khi tràn
        TR0 = 0;        // stop
        TF0 = 0;        // xoá cờ báo tràn
    }
}



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;

    //
    // enable thạch anh 32.768 kHz
    //
    // __bit bit_tmp = EA;
    // EA = 0;
    uint8_t tmp = CKEN;
    tmp &= CLR_BIT7;
    tmp |= SET_BIT6;
    TA = 0xaa;
    TA = 0x55;
    CKEN = tmp;
    // EA = bit_tmp;



    while (1) {
        LED1 = !LED1;
        delay1sec(2);
    }
}

Biên dịch và nạp code, ta được kết quả:

Lập trình Nuvoton Time Mode 2

word image 8534 13

Khi timer 0 ở mode 2, hai thanh ghi TL0 và TH0 được tách rời. TL0 dùng làm bộ đếm, trong khi đó TH0 sẽ chứa giá trị nạp lại. Ở mỗi lần TL0 đếm đến giá trị tràn 256 (ứng với 0 của số 8-bit) thì cờ báo tràn TF0 được set lên 1, đồng thời giá trị trong TH0 sẽ nạp (copy) vào TL0. Sau đó, TL0 tiếp tục đếm lên đến khi tràn, quá trình lặp lại.

Dựa vào tần số clock cấp cho timer, ta có thể tính được chu kỳ tràn của timer (thời gian từ lúc bắt đầu nạp lại giá trị và run cho đến lúc timer tràn):

timer 0 5

Với Ftimer0 là tần số của clock cấp trực tiếp cho timer 0 (đã qua prescaler nếu có).

Ví dụ 2 – Phát xung tần số cao bằng timer 0

Yêu cầu:

Phát xung 100 kHz ra pin T0 (cũng là P2.0). Sử dụng timer 0 mode 2.

Phân tích:

Ta tận dụng pin T0 của timer 0 để phát xung. Các bạn nhớ cấu hình pin P2.0 (tức T0) ở mode quasi-bidirectional và set P2.0 lên 1 thì timer 0 mới có thể toggle pin P2.0.

(Nếu đặt P2.0 ở mức 0 thì NMOS mở, nên timer 0 không thể thay đổi mức logic trên P2.0. Mức logic 1 ở mode quasi-bidirectional về bản chất là một điện trở pull-up nên timer 0 có thể thay đổi logic trên pin P2.0. Các bạn xem lại bài GPIO phần Quasi-bidirectional mode để hiểu rõ).

Pin T0 đảo trạng thái tại mỗi lần timer 0 tràn. Do đó, chu kỳ tràn của timer 0 bằng một nửa chu kỳ tín hiệu pin T0:

timer 0 6

Yêu cầu tần số khá cao nên ta dùng clock Fsys với prescaler = 1/1, suy ra:

timer 0 7

Giá trị nạp lại TH0:

.timer 0 8

Chương trình 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 main(void) {

    // Insert code

    //
    // P2.0 (T0) quasi-bidirectional mode
    //
    P2M1 &= CLR_BIT0;
    P2M2 &= CLR_BIT0;

    //
    // nhường mức logic cho timer 0
    //
    P20 = 1;

    //
    // cho phép toggle pin P2.0 (T0) khi tràn timer 0
    //
    P1M1 |= SET_BIT2;

    //
    // cấu hình timer 0
    //
    TMOD &= CLR_BIT3 & CLR_BIT2 & CLR_BIT1 & CLR_BIT0;  // xoá 4 bit thấp của TMOD
    TMOD |= SET_BIT1;   // timer 0: GATE = 0, C/T = 0, mode 2
    CKCON |= SET_BIT3;  // clock Fsys, prescaler = 1/1
    TH0 = 145;          // giá trị nạp lại
    TR0 = 1;            // run



    while (1) {
        // do nothing
    }
}

Sau khi biên dịch và nạp code, các bạn sử dụng oscilloscope hoặc máy đo logic để kiểm tra tín hiệu trên pin P2.0 (tức T0).

word image 8534 18

Hoặc có thể thấy như sau:

Kết luận

Như vậy chúng ta đã cùng nhau khảo sát hai bộ timer/counter 0 và 1.

Các timer còn lại sẽ được chúng ta khảo sát ở các bài kết tiếp.

Rate this post
0 0 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest

0 Góp ý
Phản hồi nội tuyến
Xem tất cả bình luận
tohgarashi hideyu areahentai.com danmachi aiz hentai juhi chawla ki bf momandboyporn.net picnic porn طيزك xunleimi.org سكس وزن تقيل punjabi local sexy video fuxee.mobi desi babes.com ikki hentai hentaibaru.com aneotouto
broken marriage vow april 18 2022 full episode pinoyteleseryechannel.com probinsyano november 11 2021 izanami hentai hentaichaos.com cervix penetration hentai manga gujarati sexy video analpornvids.info hariyana sex video blue film blue altoporn.mobi masalapornmovies.com سكس بنات مساج freetvtube.info اكبر قضيب في العالم
indian girl masterbating porntubemania.info nadiya sex video uncensored incest hentai manga bluhentai.com onii chan to issho tamil schoolsex indianpornsource.com bangali xxx indianfreeporn coxhamster.mobi indiansexporn indiandot.com xvideosporn.mobi pure punjabi sexy video