Bài 6: STM32 Timer chế độ Input Capture và Output Compare

STM32 Timer

STM32 Timer có nhiều chế độ trong đó Input Capture (IC) và Output Compare (OC) là 2 chế độ được sử dụng rất nhiều trong lập trình nhúng. Trong bài này chúng ta sẽ tìm hiểu IC và OC là gì, cách cấu hình trên Cube MX và lập trình trên Keil C

Bài 6 trong Serie Học lập trình STM32 từ A tới Z

STM32 Timer chế độ Input Capture

Input Capture là chế độ bắt xườn đầu vào, thường ứng dụng trong các hoạt động đo tần số hoặc độ rộng xung.

Input Capture có 2 chế độ là bắt xung xườn lên(Rising) hoặc xườn xuống (Falling)

Nguyên lý hoạt động như sau:

+ Sau khi khởi động Timer , mỗi khi có xung xườn lên (hoặc xuống) tại đầu vào Channelx của Timer. Thanh ghi TIMx_CCRx (x là Timer số 1,2,3,4…)sẽ được nạp giá trị của thanh ghi Counter TIMx_CNT

+ Bit CC1IF được đặt lên 1(Cờ ngắt), Bit CC1OF sẽ được set lên 1nếu 2 lân cờ liên tiếp cờ CC1IF được đặt lên 1 mà ko xóa. Nghĩa là mỗi khi có sự kiện xung lên sẽ có ngắt sảy ra, lập trình viên phải đọc giá trị lưu vào CCR1 sau đó xóa cờ CC1IF, nếu ko cờ CC1OF sẽ được bật lên báo tràn và dữ liệu sẽ ko được ghi vào nữa.

+ Một sự kiện ngắt được sinh ra nếu Bit CC1IE  được đặt lên 1

+ Một sự kiện DMA sinh ra nếu Bit CC1DE được đặt lên 1

h1 1

Các bước khởi tạo IC như sau:

B1: Chọn nguồn xung đếm (internal, external, timer)

B2: Ghi dữ liệu vào Thanh ghi ARR và thanh ghi PSC

B4: Chọn bật Ngắt hoặc DMA bằng bit CCxIE hoặc CCxDE trong thanh ghi CR1

B5: Khởi chạy bộ đếm bằng Bit CEN của thanh ghi CR1

B6: Trong hàm ngắt đọc dữ liệu từ thanh ghi CCRx, xóa thanh ghi CNT về 0 khi có ngắt thứ 2 sinh ra, giá trị của thanh ghi CCRx là khoảng thời gian giữa 2 lần ngắt.

Chi tiết các bạn tham khảo mục 15.3.4 trong reference Manual

STM32 Timer chế độ output compare

Chế độ output Compare là chế độ phát xung ra khi thời điểm được cài đặt, bằng thời điểm mà bộ đếm đang đếm lên/xuống.

Nguyên lý hoạt động: Khi bộ đếm, đếm đến giá trị được cài đặt trong thanh ghi CCR Timer sẽ:

+ Tạo ra một hoạt động tùy vào chế độ được chọn của bộ OC

+ Set cờ ngắt CCxIF lên 1

+ Tạo ra một ngắt hoặc DMA nếu bit CCxIE hoặc CCxDE được bật

Các chế độ làm việc của OC

H2 4

Các bước khởi tạo OC như sau:

B1: Chọn xung Clock cho Timer

B2: Ghi dữ liệu vào thanh ghi ARR và thanh ghi CCR

B3: Set bit CCxIE hoặc CCxDE nếu bật ngắt hoặc DMA

B4: Chọn chế độ OC bằng 4 bit OCxM trong thanh ghi CCMR1

B5: Chạy bộ đếm bằng bit CEN của thanh ghi CR1

Chi tiết các bạn tham khảo mục 15.3.8 trong reference Manual

Cấu hình STM32 Timer trong CubeMX

Trong bài này, chúng ta sẽ cấu hình Channel 1 của Timer 2 là Input Capture,

Channel 1  của Timer 3 là Output Compare.

Mở phần mềm lên , chọn Khởi tạo trên MCU STM32F103C8, nhấn Start project

Trong Sys Debug chọn Serial Wire, nếu các bạn chưa biết các bước cơ bản này vui lòng đọc lại Bài 3 nhé

Trong phần Timer chọn Timer 2 :

Clock Source – Internal Clock

Channel 1: Input Capture direct mode

Trong Parameters Settings chọn Prescaler là 8000 => mỗi lần đếm là 1ms (chi tiết trong bài 5)

Counter Period: 999 Chu kì  tràn là 1000 ms. Vì mình sẽ đọc các xung có F > 1Hz

Auto Reload: Enable

Polarity Selection: Rising (Chọn bắt xung lên)

H3 3

Timer 3 Các bạn cấu hình như sau:

Internal Clock

Channel 1: Ouput Compare CH1

Prescaler 8000 => mỗi lần đếm là 1ms

Counter Period: 49 chu kì tràn là 50ms

Auto Reload: Enable

Mode: Toggle on Match: 24 (đổi trạng thái CH1 khi Counter đếm lên 24 => 25ms)

H4 2

NVIC Setting tick vào bật Ngắt cho Timer 2

H5 3

Đặt tên, Chọn Toolchain và Gen code

H6 3

Lập trình STM32 Timer chế độ IC và OC

Open Project Nhấn F7 để Build Code, Trong stm32f1xx_it.c các bạn tìm đến hàm HAL_TIM_IRQHandler(&htim2); và Goto define nó

H7 4

Trong phần Define hàm đó các bạn sẽ tìm thấy hàm Call_back cho ngắt Input Capture, Go to Define hàm đó coppy và paste vào phần tiền xử lý trên hàm main()

H8 3

Trong main.c chúng ta tạo một biến chứa Giá trị đọc được từ Counter, trong hàm xử lý ngắt ta sẽ phân luồng ngắt, đọc giá trị Capture, sau đó xóa giá trị Counter về 0.

H9 3

Trước While(1), chúng ta viết các hàm khởi chạy IC và OC

H10 3

Build và nạp chương trình vào Kit.

Kết nối chân PA0 và chân PA6 vào nhau. (Timer 2 sẽ đọc xung từ Timer 3 truyền tới). Bật Debug, click vào tên của biến u16_CaptureVal chọn Add to Watch 1

H11 3

Nhấn Run(F5) sẽ thấy  u16_CaptureVal có giá trị là 100

H12 2

Để giải thích vì sao có giá trị đó các bạn dùng bộ Logic Analyzer Cắm vào CH1 của Timer 3 để đọc xung của nó.

Nếu chưa biết sử dụng bạn đọc bài viết: Hướng dẫn sử dụng Logic Analyzer

H13 1

Khi bắt đầu chạy Timer, kênh CH1 sẽ đảo trạng thái đó là khoảng 25ms đầu tiên, sau đó Timer 3 đếm đến 50ms rồi quay về 0, đến 25ms tiếp theo lại đảo trạng thái.

Vì vậy mỗi lần có xung lên sẽ cách nhau 2 lần đảo trạng thái. Nghĩa là 100ms.

H14 1

Vì vậy giá trị Capture được sẽ có giá trị là 100.

Kết

Vậy là chúng ta đã học được cách sử dụng STM32 Timer chế độ Input Capture và Outout Compare.

Đừng quên chia sẻ nếu thấy bài viết này có ích nhé

5/5 - (5 bình chọn)

11 những suy nghĩ trên “Bài 6: STM32 Timer chế độ Input Capture và Output Compare

  1. Nguyễn Hoàng Danh nói:

    /* Channel 1, Configuration in OC mode */
    TIM_OCStructInit(&TIM5_OCInitStructure);
    TIM5_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
    TIM5_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
    TIM5_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
    TIM_OC1Init(TIM5, &TIM5_OCInitStructure);
    TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Disable);
    Em đang gặp dính TIM5 xài m mode timing anh có thế giải thích cho em cái state với nstate k anh

  2. Foli nói:

    Anh nên chú thích các thanh nữa nhe.. em đọc vô chả hình dung được hết ^^!.
    ——————-
    – Counter Register (TIMx_CNT): Khi hoạt động, thanh ghi này tăng hoặc giảm giá trị theo mỗi xung clock đầu vào. Tùy vào bộ timer mà counter này có thể là 16bit hoặc 32bit.
    – Prescaler Register (TIMx_PSC): Giá trị của thanh ghi bộ chia tần (16bit) cho phép người dùng cấu hình chia tần số đầu vào (CK_PSC) cho bất kì giá trị nào từ [1- 65536]. Sử dụng kết hợp bộ chia tần của timer và của RCC giúp chúng ta có thể thay đổi được thời gian của mỗi lần CNT thực hiện đếm, giúp tạo ra được những khoảng thời gian, điều chế được độ rộng xung phù hợp với nhu cầu.
    – Auto-Reload Register (TIMx_ARR): Giá trị của ARR được người dùng xác định sẵn khi cài đặt bộ timer, làm cơ sở cho CNT thực hiện nạp lại giá trị đếm mỗi khi tràn (overflow khi đếm lên – CNT vượt giá trị ARR, underflow khi đếm xuống – CNT bé hơn 0).Tùy vào bộ timer mà counter này có thể là 16bit hoặc 32bit.

Để 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 *