🕐 hal::rtc
Real-Time Clock - Tarih/Saat Yönetimi
379 satır
~12 fonksiyon
Low-Power
📖 Genel Bakış
RTC (Real-Time Clock) modülü, düşük güç tüketimli tarih ve saat tutma işlevi sağlar. Batarya destekli çalışma, alarm ve takvim özellikleri sunar.
🔑 Temel Özellikler
- Date/time keeping
- Calendar with leap year
- 2 programmable alarms
- Wakeup timer
- Backup registers (80 bytes)
- Battery-backed operation
- Timestamp event
- Sub-second precision
🚀 Hızlı Başlangıç
içe_aktar hal::rtc
// Initialize RTC
değişken rtc_handle = rtc.init(yap
hour_format: rtc.FORMAT_24H,
async_prediv: 127,
sync_prediv: 255
son)
// Set time
rtc.set_time(rtc_handle, yap
hours: 14,
minutes: 30,
seconds: 0
son)
// Set date
rtc.set_date(rtc_handle, yap
year: 2024,
month: 12,
day: 25,
weekday: rtc.WEDNESDAY
son)
// Read time
değişken time = rtc.get_time(rtc_handle)
io.println("{:02}:{:02}:{:02}".formatla(time.hours, time.minutes, time.seconds))
💡 Örnek: Digital Clock Display
içe_aktar hal::rtc, hal::core
yapı DateTime yap
year: sayı,
month: sayı,
day: sayı,
hours: sayı,
minutes: sayı,
seconds: sayı,
weekday: sayı
son
fonksiyon weekday_name(day: sayı) -> yazı yap
dön eşle day yap
1 => "Pazartesi",
2 => "Salı",
3 => "Çarşamba",
4 => "Perşembe",
5 => "Cuma",
6 => "Cumartesi",
7 => "Pazar",
_ => "Bilinmeyen"
son
son
fonksiyon ana() yap
core.system_init()
// Initialize RTC
değişken rtc_handle = rtc.init(yap
hour_format: rtc.FORMAT_24H
son)
// Set initial time (2024-12-25 14:30:00 Wednesday)
rtc.set_date(rtc_handle, yap
year: 2024,
month: 12,
day: 25,
weekday: rtc.WEDNESDAY
son)
rtc.set_time(rtc_handle, yap
hours: 14,
minutes: 30,
seconds: 0
son)
döngü yap
// Read current time
değişken time = rtc.get_time(rtc_handle)
değişken date = rtc.get_date(rtc_handle)
// Display
io.print("\r") // Carriage return
io.print("{:02}/{:02}/{} {} {:02}:{:02}:{:02}".formatla(
date.day,
date.month,
date.year,
weekday_name(date.weekday),
time.hours,
time.minutes,
time.seconds
))
core.delay_ms(1000)
son
son
💡 Örnek: Alarm Clock
içe_aktar hal::rtc
değişken alarm_triggered = yanlış
fonksiyon alarm_callback() yap
alarm_triggered = doğru
io.println("\n🔔 ALARM! Wake up!")
son
fonksiyon set_alarm(rtc_handle: rtc.Handle, hours: sayı, minutes: sayı) yap
rtc.set_alarm(rtc_handle, rtc.ALARM_A, yap
hours: hours,
minutes: minutes,
seconds: 0,
alarm_mask: rtc.MASK_SECONDS, // Ignore seconds
callback: alarm_callback
son)
io.println("Alarm set for {:02}:{:02}".formatla(hours, minutes))
son
fonksiyon ana() yap
değişken rtc_handle = rtc.init(yap
hour_format: rtc.FORMAT_24H
son)
// Set current time: 07:58:00
rtc.set_time(rtc_handle, yap
hours: 7,
minutes: 58,
seconds: 0
son)
// Set alarm for 08:00
set_alarm(rtc_handle, 8, 0)
döngü yap
değişken time = rtc.get_time(rtc_handle)
io.print("\r{:02}:{:02}:{:02}".formatla(
time.hours, time.minutes, time.seconds
))
eğer alarm_triggered ise yap
alarm_triggered = yanlış
// Snooze for 5 minutes
set_alarm(rtc_handle, time.hours, time.minutes + 5)
son
core.delay_ms(1000)
son
son
💡 Örnek: Wakeup Timer (Auto-Wakeup from Standby)
içe_aktar hal::rtc, hal::core
fonksiyon periodic_wakeup() yap
değişken rtc_handle = rtc.init(yap
hour_format: rtc.FORMAT_24H
son)
// Configure wakeup every 10 seconds
rtc.set_wakeup(rtc_handle, yap
prescaler: rtc.WAKEUP_DIV_16, // 16Hz clock
counter: 160 // 160 / 16Hz = 10 seconds
son)
io.println("Entering standby, wakeup in 10s...")
core.delay_ms(100) // Flush UART
// Enter standby mode (lowest power)
core.standby()
// After wakeup, system resets
io.println("Woke up from standby!")
// Check wakeup flag
eğer rtc.was_wakeup_flag_set() ise yap
io.println("Wakeup timer triggered")
rtc.clear_wakeup_flag()
son
son
fonksiyon ana() yap
// Count wakeups using backup register
değişken wakeup_count = rtc.read_backup(rtc_handle, 0)
wakeup_count += 1
rtc.write_backup(rtc_handle, 0, wakeup_count)
io.println("Wakeup count: {}", wakeup_count)
periodic_wakeup()
son
💡 Örnek: Battery-Backed Data Logger
içe_aktar hal::rtc
// Store sensor readings in backup registers (survives power loss)
yapı LogEntry yap
timestamp: sayı, // Unix timestamp
temp: u16, // Temperature x100
humidity: u16 // Humidity x100
son
sabit MAX_ENTRIES = 20 // 80 bytes / 4 = 20 entries
fonksiyon log_data(temp: kesir, humidity: kesir) yap
değişken rtc_handle = rtc.init(yap hour_format: rtc.FORMAT_24H son)
// Get current index
değişken index = rtc.read_backup(rtc_handle, 0)
eğer index >= MAX_ENTRIES ise index = 0
// Get timestamp
değişken time = rtc.get_time(rtc_handle)
değişken date = rtc.get_date(rtc_handle)
değişken timestamp = date_to_unix(date, time)
// Store in backup registers (4 bytes per entry)
değişken base = 1 + (index * 2)
rtc.write_backup(rtc_handle, base, timestamp)
rtc.write_backup(rtc_handle, base + 1,
((temp * 100.0).sayı() << 16) | (humidity * 100.0).sayı()
)
// Update index
rtc.write_backup(rtc_handle, 0, index + 1)
io.println("Logged: {}°C, {}%RH", temp, humidity)
son
fonksiyon print_log() yap
değişken rtc_handle = rtc.init(yap hour_format: rtc.FORMAT_24H son)
değişken count = rtc.read_backup(rtc_handle, 0).min(MAX_ENTRIES)
io.println("\n=== Data Log ({} entries) ===", count)
her i içinde 0..count için yap
değişken base = 1 + (i * 2)
değişken timestamp = rtc.read_backup(rtc_handle, base)
değişken data = rtc.read_backup(rtc_handle, base + 1)
değişken temp = ((data >> 16) & 0xFFFF).kesir() / 100.0
değişken hum = (data & 0xFFFF).kesir() / 100.0
io.println("{}: {:.1f}°C, {:.1f}%",
unix_to_string(timestamp), temp, hum)
son
son
fonksiyon date_to_unix(date: rtc.Date, time: rtc.Time) -> sayı yap
// Simplified unix timestamp calculation
dön (date.year - 1970) * 31536000 +
date.month * 2592000 +
date.day * 86400 +
time.hours * 3600 +
time.minutes * 60 +
time.seconds
son
fonksiyon ana() yap
// Simulate sensor readings
log_data(23.5, 65.2)
core.delay_ms(5000)
log_data(24.1, 63.8)
core.delay_ms(5000)
// Print all logged data
print_log()
son
💡 Örnek: Timestamp Events (Input Capture)
içe_aktar hal::rtc, hal::gpio
değişken event_count = 0
fonksiyon timestamp_callback() yap
değişken rtc_handle = rtc.init(yap hour_format: rtc.FORMAT_24H son)
// Get timestamp
değişken time = rtc.get_timestamp_time(rtc_handle)
değişken date = rtc.get_timestamp_date(rtc_handle)
event_count += 1
io.println("Event #{}: {:02}:{:02}:{:02}.{:03}",
event_count,
time.hours,
time.minutes,
time.seconds,
time.subseconds
)
son
fonksiyon timestamp_input_capture() yap
// Configure PA0 (WKUP pin) as timestamp trigger
gpio.clock_enable(gpio.PORT_A)
gpio.pin_init(gpio.PORT_A, 0, yap
mode: gpio.MODE_INPUT,
pull: gpio.PULL_DOWN
son)
değişken rtc_handle = rtc.init(yap
hour_format: rtc.FORMAT_24H
son)
// Enable timestamp on rising edge
rtc.enable_timestamp(rtc_handle, yap
edge: rtc.TIMESTAMP_RISING_EDGE,
pin: rtc.TIMESTAMP_PIN_0,
callback: timestamp_callback
son)
io.println("Press button on PA0 to timestamp events...")
döngü yap
core.delay_ms(100)
son
son
fonksiyon ana() yap
timestamp_input_capture()
son
💡 Örnek: Multi-Alarm Scheduler
içe_aktar hal::rtc
yapı Task yap
name: yazı,
alarm: rtc.Alarm,
callback: fn()
son
değişken tasks = []
fonksiyon task_morning() yap
io.println("🌅 Good morning! Time to wake up!")
son
fonksiyon task_lunch() yap
io.println("🍽️ Lunch break!")
son
fonksiyon task_evening() yap
io.println("🌙 Evening reminder: Review tasks")
son
fonksiyon schedule_daily_tasks() yap
değişken rtc_handle = rtc.init(yap
hour_format: rtc.FORMAT_24H
son)
// Set current time (for testing: 06:58)
rtc.set_time(rtc_handle, yap
hours: 6,
minutes: 58,
seconds: 0
son)
// Alarm A: Morning wakeup (07:00)
rtc.set_alarm(rtc_handle, rtc.ALARM_A, yap
hours: 7,
minutes: 0,
seconds: 0,
alarm_mask: rtc.MASK_DATEWEEKDAY, // Daily
callback: task_morning
son)
// Alarm B: Lunch (12:00)
rtc.set_alarm(rtc_handle, rtc.ALARM_B, yap
hours: 12,
minutes: 0,
seconds: 0,
alarm_mask: rtc.MASK_DATEWEEKDAY,
callback: task_lunch
son)
io.println("Scheduler started. Waiting for alarms...")
döngü yap
değişken time = rtc.get_time(rtc_handle)
io.print("\r{:02}:{:02}:{:02}",
time.hours, time.minutes, time.seconds)
core.delay_ms(1000)
son
son
fonksiyon ana() yap
schedule_daily_tasks()
son
⚙️ RTC Yapılandırma
// RTC Configuration
yapı RTCConfig yap
hour_format: HourFormat, // 12H or 24H
async_prediv: sayı, // Asynchronous prescaler (7-bit)
sync_prediv: sayı, // Synchronous prescaler (15-bit)
clock_source: ClockSource // LSE, LSI, HSE
son
// Hour Format
enum HourFormat {
FORMAT_12H, // AM/PM
FORMAT_24H // 00:00-23:59
}
// Clock Source
enum ClockSource {
LSE, // 32.768kHz external crystal (most accurate)
LSI, // 32kHz internal RC (less accurate, ±5%)
HSE // High-speed external (rarely used for RTC)
}
// Alarm Configuration
yapı AlarmConfig yap
hours: sayı,
minutes: sayı,
seconds: sayı,
alarm_mask: AlarmMask, // What to match
callback: fn() // Interrupt callback
son
// Alarm Mask (what to ignore)
enum AlarmMask {
MASK_NONE, // Match all (specific time)
MASK_DATEWEEKDAY, // Ignore date (daily alarm)
MASK_HOURS, // Every hour
MASK_MINUTES, // Every minute
MASK_SECONDS // Every second
}
// Wakeup Configuration
yapı WakeupConfig yap
prescaler: WakeupPrescaler,
counter: u16 // 0-65535
son
enum WakeupPrescaler {
WAKEUP_DIV_16, // RTC/16 (~2048Hz for 32kHz LSE)
WAKEUP_DIV_8, // RTC/8
WAKEUP_DIV_4, // RTC/4
WAKEUP_DIV_2 // RTC/2
}
📚 RTC Fonksiyonları
// Initialization
fonksiyon init(config: RTCConfig) -> Handle
fonksiyon deinit(handle: Handle)
// Time/Date
fonksiyon set_time(handle: Handle, time: Time)
fonksiyon get_time(handle: Handle) -> Time
fonksiyon set_date(handle: Handle, date: Date)
fonksiyon get_date(handle: Handle) -> Date
// Alarms
fonksiyon set_alarm(handle: Handle, alarm: Alarm, config: AlarmConfig)
fonksiyon disable_alarm(handle: Handle, alarm: Alarm)
fonksiyon get_alarm_flag(handle: Handle, alarm: Alarm) -> bool
fonksiyon clear_alarm_flag(handle: Handle, alarm: Alarm)
// Wakeup timer
fonksiyon set_wakeup(handle: Handle, config: WakeupConfig)
fonksiyon disable_wakeup(handle: Handle)
fonksiyon was_wakeup_flag_set() -> bool
fonksiyon clear_wakeup_flag()
// Timestamp
fonksiyon enable_timestamp(handle: Handle, config: TimestampConfig)
fonksiyon get_timestamp_time(handle: Handle) -> Time
fonksiyon get_timestamp_date(handle: Handle) -> Date
// Backup registers
fonksiyon write_backup(handle: Handle, register: sayı, value: u32)
fonksiyon read_backup(handle: Handle, register: sayı) -> u32
// Calibration
fonksiyon calibrate(handle: Handle, ppm: kesir) // Fine-tune frequency
⚙️ RTC Backup Registers
// Store data that survives reset/power-down
rtc.write_backup(rtc_handle, 0, 0x12345678)
değişken value = rtc.read_backup(rtc_handle, 0)
// Common use cases:
// - Boot counter
// - Configuration persistence
// - Crash/reset reason
// - Sensor calibration data
// - Short-term data logging (80 bytes total)
// Example: Boot counter
değişken boot_count = rtc.read_backup(rtc_handle, 0)
boot_count += 1
rtc.write_backup(rtc_handle, 0, boot_count)
io.println("Boot count: {}", boot_count)
📊 RTC Kullanım Senaryoları
| Senaryo | Özellik | Güç Tüketimi | Açıklama |
|---|---|---|---|
| Digital Clock | Time/Date | Active | Real-time display |
| Alarm Clock | Alarm A/B | Sleep + Interrupt | Wake on alarm |
| Periodic Wakeup | Wakeup Timer | Standby (~1μA) | Ultra-low-power sensor reading |
| Event Timestamp | Timestamp | Active | Precise event logging |
| Data Logger | Backup Regs | VBAT (~1μA) | Survive power loss |
⚡ Performans İpuçları
- LSE Crystal: Kullanın en yüksek accuracy için (±20ppm)
- VBAT: CR2032 coin cell ile yıllarca RTC çalıştırabilir (~1μA)
- Wakeup Timer: Periodic sensor reading için ideal (standby mode)
- Backup Registers: Configuration data için kullanın (80 bytes)
- Calibration: Temperature compensation için smooth calibration
🖥️ Platform Desteği
- STM32F1: Basic RTC (1 alarm, backup regs)
- STM32F4/L4: Advanced RTC (2 alarms, wakeup, timestamp, 80 backup bytes)
- STM32H7: High-precision RTC with sub-second resolution
- ESP32: RTC with ULP coprocessor support
⚠️ Önemli Notlar
- Clock Source: LSE (32.768kHz crystal, ±20ppm) en accurate, LSI (32kHz RC, ±5%) backup
- VBAT Pin: CR2032 battery (3V) ile power-down'da RTC çalışmaya devam eder
- Write Protection: RTC register'ları write-protected, unlock gerekir
- Alarm Interrupts: EXTI line 17 (Alarm A), 18 (Alarm B) kullanır
- Wakeup from Standby: Wakeup timer ile ultra-low-power periodic operation
- Backup Domain: RTC + backup regs separate power domain (VBAT)
- Calendar: Leap year otomatik hesaplanır, 2000-2099 range
- Sub-second: Synchronous prescaler ile ms resolution mümkün
🔗 İlgili Modüller
hal::int- RTC alarm interrupts (NVIC)hal::core- System wakeup from standbyhal::gpio- Timestamp input pin
📖 Referanslar
- AN3371: Using STM32 RTC
- AN4759: Using STM32 RTC Wakeup Timer
- Reference Manual: Real-time clock (RTC) chapter