阅读资料了解 STM32F103的RTC(实时时钟)原理,使用带SPI或IIC接口的OLED屏显模块实现以下功能:1) 读取STM32F103C8T6 内部的时钟(年月日时分秒),日历(星期x),

一.了解时钟RTC
RTC (Real Time Clock):实时时钟

RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。

在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。

RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。

两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时( 12 或 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。

上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写访问。

无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。

RCT特征:
● 可编程的预分频系数:分频系数高为220。
● 32位的可编程计数器,可用于较长时间段的测量。
● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟 频率的四分之一以上)。
● 可以选择以下三种RTC的时钟源:
● HSE时钟除以128;
● LSE振荡器时钟;
● LSI振荡器时钟

● 2个独立的复位类型:
● APB1接口由系统复位;
● RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位

● 3个专门的可屏蔽中断:
● 1.闹钟中断,用来产生一个软件可编程的闹钟中断。

● 2.秒中断,用来产生一个可编程的周期性中断信号(长可达1秒)。

● 3.溢出中断,指示内部可编程计数器溢出并回转为0的状态。

RTC时钟源:
三种不同的时钟源可被用来驱动系统时钟(SYSCLK):

● HSI振荡器时钟
● HSE振荡器时钟
● PLL时钟

这些设备有以下2种二级时钟源:

● 40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。 RTC用于从停机/待机模式下自动唤醒系统。
● 32.768kHz低速外部晶体也可用来通过程序选择驱动RTC(RTCCLK)。

RTC原理框图

RTC时钟的框图还是比较简单的,这里我们把他分成 两个部分:

APB1 接口:用来和 APB1 总线相连。 此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总 线时钟驱动,用来与 APB1 总线连接。

通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。

RTC 核心接口:由一组可编程计数器组成,分成 两个主要模块 。
g)
第一个模块是 RTC 的 预分频模块,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个 TR_CLK 周期中 RTC 产生一个中断(秒中断)。

第二个模块是一个 32 位的可编程计数器 (RTC_CNT),可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记 录 4294967296 秒,约合 136 年左右,作为一般应用,这已经是足够了的。

RTC具体流程:
RTCCLK经过RTC_DIV预分频,RTC_PRL设置预分频系数,然后得到TR_CLK时钟信号,我们一般设置其周期为1s,RTC_CNT计数器计数,假如1970设置为时间起点为0s,通过当前时间的秒数计算得到当前的时间。RTC_ALR是设置闹钟时间,RTC_CNT计数到RTC_ALR就会产生计数中断,

### STM32F103C8T6 定时器配置及与 DS1302 实现 RTC 功能 #### 配置定时器用于基本延时操作 为了实现精确的时间管理,在STM32F103C8T6上可以利用其内置的高级控制定时器(TIM)完成毫秒级更长时间间隔的任务调度。通常会选择TIM2至TIM5这些通用型定时器之一来进行基础延时函数的设计。 ```c void TIM_Config(void){ // 初始化结构体定义 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // 设置自动重装载预分频值 TIM_TimeBaseStructure.TIM_Period = 999; TIM_TimeBaseStructure.TIM_Prescaler = 7199; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); NVIC_InitTypeDef nvicstructure; nvicstructure.NVIC_IRQChannel = TIM4_IRQn; nvicstructure.NVIC_IRQChannelPreemptionPriority = 0x00; nvicstructure.NVIC_IRQChannelSubPriority = 0x00; nvicstructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvicstructure); TIM_Cmd(TIM4, ENABLE); } ``` 上述代码片段展示了如何初始化并启动一个周期性的中断源,这里选择了TIM4作为例子[^2]。 #### 使用外部RTC模块DS1302扩展日历时钟功能 由于STM32F103内部并不具备完整的日期处理能力,因此可以通过连接专用的实时时钟芯片如DS1302来增强设备的时间记录精度服务范围。通过SPI接口通信协议读取当前时间设定闹钟功能变得十分便捷。 以下是关于如何编写程序访问DS1302的一些指导: - **硬件连线**: 将MCU的SCLK、I/ORST引脚分别对应接到DS1302相同名称的数据线。 - **软件驱动层开发**: ```c #include "stm32f1xx_hal.h" #define DS1302_CE_PIN GPIO_PIN_4 #define DS1302_IO_PIN GPIO_PIN_5 #define DS1302_SCLK_PIN GPIO_PIN_6 // 写入命令到DS1302寄存器 uint8_t WriteByteToDs1302(uint8_t regAddr,uint8_t data){ uint8_t i=8; HAL_GPIO_WritePin(GPIOA, DS1302_CE_PIN ,GPIO_PIN_SET); while(i--){ if(regAddr&0x80) HAL_GPIO_WritePin(GPIOA, DS1302_IO_PIN ,GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOA, DS1302_IO_PIN ,GPIO_PIN_RESET); HAL_Delay(1); HAL_GPIO_TogglePin(GPIOA, DS1302_SCLK_PIN ); HAL_Delay(1); regAddr<<=1; } HAL_GPIO_WritePin(GPIOA, DS1302_CE_PIN ,GPIO_PIN_RESET); } // 从DS1302读取数据 uint8_t ReadByteFromDs1302(){ uint8_t value=0,i=8; HAL_GPIO_WritePin(GPIOA, DS1302_CE_PIN ,GPIO_PIN_SET); while(i--){ HAL_GPIO_TogglePin(GPIOA, DS1302_SCLK_PIN ); HAL_Delay(1); if(HAL_GPIO_ReadPin(GPIOA, DS1302_IO_PIN )) value|=(1<<(7-i)); HAL_Delay(1); } HAL_GPIO_WritePin(GPIOA, DS1302_CE_PIN ,GPIO_PIN_RESET); return value; } ``` 这段代码实现了向DS1302发送指令以及接收返回值的基础逻辑[^3].
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值