Timer là một ngoại vi được ứng dụng rất nhiều trong lập trình nhúng, trong STM32 có khá nhiều Timer đa số là 16bit và chúng có thể làm việc một các độc lập với nhau
Trong bài này ta sẽ tìm hiểu Timer STM32 được sử dụng như thế nào, lập trình Timer STM32 điều khiển chớp tắt led không dùng delay
Timer dịch đơn giản là người ghi giờ, bộ hẹn giờ.
Ví dụ khi bạn cần thức dậy sau 8 tiếng ngủ bạn sử dụng một bộ hẹn giờ, đếm ngược hoặc đếm xuôi đủ 8 tiếng, chuông sẽ kêu và bạn thức dậy.
Hoặc khi chạy 100m người trọng tài chính là Timer để đo thời gian bạn chạy hết 100m đó.
Trong lập trình Timer là một khối độc lập, có tác dụng tạo ra các sự kiện hoặc ngắt để kích hoạt các ngoại vi khác hoạt động, hoặc đo thời gian hoạt động của 1 giá trị đầu vào nào đó.
Trong STM32F103C8 có 4 bộ Timer trong đó:
Trong bài này chúng ta sẽ làm việc với Timer 2, các chức năng đều tương tự với các Timer khác
Các chức năng chính của Timer STM32 bao gồm:
– Thanh ghi 16bit đếm lên, xuống, lên/xuống tự nạp lại
– 16 bit bộ chia tần số để chia tần số từ APB(giá trị dao động từ 1 – 65536)
– 4 Kênh độc lập mỗi Timer cho các chức năng:
+ Input Capture
+ Output Compare
+ One Pulse
– Đồng bộ hóa với các mạch tạo tín hiệu bên ngoài để kết hợp nhiều bộ Timer với nhau
– Ngăt/DMA được sinh ra khi có các sự kiện:
+ Cập nhật: tràn Counter, khởi tạo Counter (bởi phần mềm hoặc kích hoạt inernal/external trigger)
+ Sự kiện kích hoạt (Bắt đầu đêm, dừng đếm, khởi tạo bộ đếm hoặc đếm bởi inernal/external trigger)
+ Input Capture: Bắt xung đầu vào
+ Output Compare: So sánh xung đầu ra
– Hỗ trợ điều khiển Encoder và Hall-sensor
– Đầu vào kích hoạt cho đồng hồ bên ngoài hoặc quản lý theo chu kì
Chi tiết các bạn tham khảo mục 15.2 trong Reference Manual
Trong bài này chúng ta sẽ cấu hình Timer 2 chế độ Time-base unit.
Mô tả chức năng này như sau:
– Chế độ Timer-Base unit là chế độ chính của Timer bao gồm các chế độ đếm: lên, xuống hoặc cả lên lên và xuống
– Xung Clock được chia bởi bộ chia tần Prescaler để lấy thời gian thích hợp đếm 1 lần
– Các thanh ghi quản lý bao gồm:
+ Counter Register (TIMx_CNT):lưu giá trị đếm
+ Prescaler Register (TIMx_PSC): lưu giá trị chia từ tần số cơ sở cấp cho Timer để tạo ra tần số thích hợp
+ Auto-Reload Registor(TIMx_ARR): lưu giá trị đích đếm lên hoặc đếm xuống
– Thanh ghi Auto-Reload sẽ được nạp trước khi Timer hoạt động, và có thể nạp trong khi Timer hoạt động, trước khi một sự kiện cập nhật sảy ra (UEV).
– Chế độ đếm sẽ được hoạt động khi Bit CEN của thanh ghi TIMx_CR1 được bật
Chi tiết các bạn tham khải mục 15.3.1
Nhìn vào mô tả này chúng ta có thể viết ra các bước để Timer hoạt động như sau:
Các bước cơ bản là vậy, sau đây mình sẽ hướng dẫn các bạn cấu hình trên CubeMX
Đề bài của chúng ta như sau: Sử dụng TimerSTM32 cụ thể là Timer 2 nhấp nháy led mỗi 500ms một lần.
Các bạn mở phần mềm, chọn chip STM32F103C8, cấu hình SYS debug: Serial Wire.
Chuyển qua Tab Clock Configuration , chúng ta chọn Thạch Anh nội 8Mhz. Vì xung Clock của Timer 2 sẽ được cấp bởi bộ APB1 thế nên xung Interal Clock có tần số là 8Mhz
Chi tiết về cách cấu hình Clock các bạn xem Bảng 1 Mục 3.1
Trong Tab Timer các bạn chon Timer 2. Clock Source chon Internal Clock.
Trong bảng Parameter Settings:
Chọn Prescale là 8000 sẽ đếm mỗi 1ms vì 8MHz/8000 = 1khz => T = 1ms
Counter Mode : Up down đều được
Counter Period: 499 , đếm từ 0 đến 499 là 500 lần 1ms ta sẽ được 500ms
Auto-preload: Enable
Các thông số còn lại giữ nguyên
Chọn PC13 là LED output
Trong NVIC tick vào Tim2 global Interupts để bật ngắt cho Timer 2
Sau đó dặt tên Project – chọn tool MDK-ARM V5 và ấn Gen Code
Mở Project – Nhấn Build (F7)
Trong phần stm32f1xx_it.c đã có hàm thực thi ngắt Timer2, các bạn nhấn chuột phải chọn Go to Define hàm HAL_TIM_IRQHandler(&htim2);
Tại đây các bạn nhấn CtrF Tìm từ update nhấn Find Next sẽ tìm thấy, phần xử lý ngắt Update Event.
Chọn File HAL_TIM_PeriodElapsedCallback(htim); nhận chuột phải Go to Define để tìm thấy nơi viết hàm đó.
Đây là hàm gọi về khi có sự kiện ngắt Update xảy ra
Coppy hàm đó dán vào khu tiền xử lý trên hàm main() trong main.c nhớ bỏ __weak nhé.
Sau đó trong hàm này chúng ta viết thêm hàm đảo trạng thái led như sau:
Trước while (1) ta khởi chạy Timer với ngắt bằng câu lệnh sau
Sau đó Build và Nạp chương trình và xem kết quả