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
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
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
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
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)
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)
NVIC Setting tick vào bật Ngắt cho Timer 2
Đặt tên, Chọn Toolchain và Gen code
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ó
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()
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.
Trước While(1), chúng ta viết các hàm khởi chạy IC và OC
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
Nhấn Run(F5) sẽ thấy u16_CaptureVal có giá trị là 100
Để 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
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.
Vì vậy giá trị Capture được sẽ có giá trị là 100.