Site icon TAPIT

Real time clock (RTC) trên STM32F103C8T6

Bài viết này sẽ giúp các bạn tìm hiểu về bộ RTC trên vi điều khiển STM32F103C8T6 và thực hành lập trình làm việc với ngoại vi này. TAPIT cũng có bài viết hướng dẫn giao tiếp vi điều khiển với IC RTC DS3231, các bạn có thể tham khảo thêm tại đây

A. Lý thuyết về RTC

Ưu và nhược điểm khi sử dụng bộ RTC trong chip STM32F103C8:

Ưu điểm: Không phải tốn chi phí cho bất kì IC RTC nào vì đã được tích hợp sẵn, tiết kiểm diện tích thiết kế mạch. 

Nhược điểm: Bộ RTC trong chip STM32F103C8 sử dụng từ Clock từ các bộ LSI, LSE, HSE. Nếu sử dụng LSI làm bộ nguồn Clock thì đây là bộ clock nội và sai số tầm khoảng 1%, vì vậy trong quá trình hoạt động thì khi chúng ta đọc thời gian sẽ bị sai lệch (có thể lưu ý khắc phục được)

Việc của chúng ta chỉ cần tìm hiểu và sử dụng chứ không cần bận tâm đến phần cứng nữa. Một số ứng dụng chính mà bộ RTC mang lại là làm đồng hồ, mạch kiểm soát thời gian, báo thức, bộ đếm…Bộ RTC này sử dụng timer độc lập, tách biệt với các bộ timer khác. Việc cài đặt thời gian, đọc thời gian cũng trở nên dễ dàng bằng cách tác động trực tiếp vào thanh ghi.

[HỌC ONLINE: LẬP TRÌNH VI ĐIỀU KHIỂN STM32, VI XỬ LÝ ARM CORTEX – M]

Nguồn clock cấp cho bộ RTC hoạt động có thể được sử dụng 1 trong 3 nguồn sau:

Thạch anh ngoài giúp bộ MCU hoạt động ổn định hơn so với bộ giao động RC nội (sai số 1%). Khi cần Backup data khi mất nguồn trên chân VDD thì cần có 2 điều kiện là sử dụng thạch anh ngoài và có điện áp trên chân VBAT.
Các chức năng cơ bản của bộ RTC:

Giản đồ block khối RTC: 

Hãy cùng phân tích giản đồ này để hiểu quá trình hoạt động của RTC trước khi chúng ta đi qua một số thanh ghi quan trọng trong RTC.

Bộ RTC ở đây sẽ gồm 2 phần chính:

Một số thanh ghi quan trọng trong bài hôm nay:

1. RTC_CR – RTC control register.

Thanh ghi này bao gồm 2 thanh ghi high và low với các bit như sau:

2. RTC_DIV – RTC prescaler divider register.

3. RTC_CNT – RTC counter register.

Thanh ghi này 32bit chứa giá trị bộ đếm của couter. Muốn biết thời gian cần đọc giá trị từ thanh ghi này về.
B/Thực hành RTC trên kit STM32F103C8

Khi sử dụng CubeMX, phần mềm này đã hỗ trợ cho chúng ta cấu hình tất cả các thanh ghi ban đầu, trong bài này chúng ta sẽ thực hiện 2 việc đọc dữ liệu thời gian và cài đặt thời gian ban đầu.

Đầu tiên, tạo project với CubeMX và cấu hình như sau:

– SYS, phần debug chúng ta sẽ chọn Serial wire để nạp dữ liệu

– UART1, chúng ta sẽ sử dụng với mục đích in dữ liệu đọc được ra phần mềm Hercules

– Ở RTC, các bạn chọn Active Clock source

– Tiếp theo, click vào tab Clock Configuration chúng ta có thể thấy hiện tại bộ RTC đang sử dụng Clock LSI RC với tần số là 40Khz

– Tiếp theo, click vào tab configuration chúng ta mở RTC lên. Ở parameter settings, chúng ta sẽ set thời gian ban đầu cho bộ RTC, ở phần Calendat Date gồm ngày tháng năm, ở phần Calendar Time bao gồm giờ phút giây, phần General liên quan đến bộ chia tần để tạo ra khoảng thời gian đếm 1s, Output là tín hiệu đầu ra tại chân TAMPER pin khi có sự kiện. Ngoài ra còn có Alarm A, đây là thiết lập để hẹn giờ báo thức của bộ RTC.

– Sau khi cấu hình xong các bạn lưu cấu hình lại và qua bên project KeilC để lập trình

– Đầu tiên, chúng ta sẽ có 3 struct để chứa dữ liệu ngày tháng năm, giờ phút giây và alarm. Tiếp theo câu lệnh đọc thanh ghi backup xem thử có phải đúng giá trị 0x32f2 hay không, nếu không đúng giá trị đó thì chúng ta sẽ thực hiện việc cấu hình thời gian ban đầu cho bộ RTC.

– Sau khi cấu hình xong chúng ta sẽ ghi giá trị 0x32f2 vào thanh ghi backup để lần sau khi có khởi động lại chip thì chương trình sẽ chạy lại từ đầu và kiểm tra thanh ghi backup để không cần phải khởi tạo lại thời gian nữa vì nó đã được khởi tạo trước đó.

– Tiếp theo mình đã khởi tạo các biến đễ lưu trữ thời gian

– Tiếp theo, để đọc dữ liệu RTC mình sử dụng 2 hàm HAL_RTC_GetTime, và HAL_RTC_GetDate. Thông số thứ nhất là địa chỉ rtc chúng ta đang sử dụng, thông số thứ 2 là địa chỉ biến truct chúng ta nhận dữ liệu và thông số thứ 3 là format dữ liệu mà chúng ta đọc.

– Để in dữ liệu, mình sử dụng UART đã được cấu hình từ sẵn và dùng hàm printf để in dữ liệu lên Hercules. Để sử dụng printf các bạn tham khảo bài viết này. Hoặc các bạn có thể sử dụng tính năng debugs theo hướng dẫn tại bài viết này

Xem thêm: Tổng hợp các bài hướng dẫn Lập trình vi điều khiển STM32 tại đây.

Chúc các bạn thành công!

Nhóm TAPIT ARM R&D