Bài 5: Lập trình Timer STM32 chớp tắt Led dùng ngắt

Timer STM32

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

Bài 5 trong Serie Lập trình STM32 từ A tới Z

Timer là gì?

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 đó:

  • Timer 1: Là bộ Advanced – control Timer hay là bộ Timer điều khiển nâng cao, có nhiều chức năng nhất
  • 3 bộ Timer chung là Timer 2,3,4 Có chức năng tương tự nhau và độc lập với nhau

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

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

H1 2

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

H2 3

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:

  1. Khởi tạo bộ Timer 1 với xung Clock thích hợp(Tất cả các ngoại vi đều phải có bước này)
  2. Ghi giá trị cho bộ chia tần Prescaler
  3. Ghi giá trị cho thanh ghi Auto-reload
  4. Bật Timer cho hoạt động
  5. Xử lý các sự kiện sảy ra như tràn ….

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

Cấu hình Timer STM32 chế độ Time Base

Đề 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

H3 2

Chi tiết về cách cấu hình Clock các bạn xem Bảng 1 Mục 3.1

H4 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

H5 2

Chọn PC13 là LED output

H6 2

Trong NVIC tick vào Tim2 global Interupts để bật ngắt cho Timer 2

H7 3

Sau đó dặt tên Project – chọn tool MDK-ARM V5 và ấn Gen Code

H8 2

Lập trình Timer STM32 chớp tắt led

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);

H9 2

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

H10 2

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:

H11 2

Trước while (1) ta khởi chạy Timer với ngắt bằng câu lệnh sau

H12 1

Sau đó Build và Nạp chương trình và xem kết quả

Kết

Timer là một ngoại vi không thể thiếu trong việc lập trình nhúng. Timer STM32 ngoài được sử dụng trong việc hẹn giờ, chúng còn được sử dụng đo đếm thời gian của các xung, tạo ra các xung có tần số khác nhau mà bài sau chúng ta sẽ đề cập.

5/5 - (3 bình chọn)
5 1 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest

7 Góp ý
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất
Phản hồi nội tuyến
Xem tất cả bình luận
Anh Tuấn
Anh Tuấn
2 năm trước

Sao em làm đến bước go to define HAL_TIM_IRQHandler(&htim2); nó lại báo lỗi cái này chưa đc define vậy à 🙁 em ktra các bước trên làm đúng hết r mà 🙁

Anh Tuấn
Anh Tuấn
2 năm trước
Trả lời  Anh Tuấn

À thôi anh ơi :V em biết sao bị vậy e 😛

Nguyễn Hùng Thịnh
Nguyễn Hùng Thịnh
2 năm trước

anh ơi, như vậy là bị sao, em cx bị

Lê Văn Hiếu
Lê Văn Hiếu
2 năm trước

Hay, cảm ơn ad.

nguyễn Hoàng Qúy
nguyễn Hoàng Qúy
2 năm trước

A ơi sao e làm chạy được đèn led PC13 sáng nhưng nó lại không nhấp nháy ạ