单芯片解决方案,开启全新体验——W55MH32 高性能以太网单片机
W55MH32是WIZnet重磅推出的高性能以太网单片机,它为用户带来前所未有的集成化体验。这颗芯片将强大的组件集于一身,具体来说,一颗W55MH32内置高性能Arm? Cortex-M3核心,其主频最高可达216MHz;配备1024KB FLASH与96KB SRAM,满足存储与数据处理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP协议栈、内置MAC以及PHY,拥有独立的32KB以太网收发缓存,可供8个独立硬件socket使用。如此配置,真正实现了All-in-One解决方案,为开发者提供极大便利。
在封装规格上,W55MH32 提供了两种选择:QFN68和QFN100。
W55MH32Q采用QFN68封装版本,尺寸为8x8mm,它拥有36个GPIO、3个ADC、12通道DMA、17个定时器、2个I2C、3个串口、2个SPI接口(其中1个带I2S接口复用)、1个CAN以及1个USB2.0。在保持与同系列其他版本一致的核心性能基础上,仅减少了部分GPIO以及SDIO接口,其他参数保持一致,性价比优势显著,尤其适合网关模组等对空间布局要求较高的场景。紧凑的尺寸和精简化外设配置,使其能够在有限空间内实现高效的网络连接与数据交互,成为物联网网关、边缘计算节点等紧凑型设备的理想选择。 同系列还有QFN100封装的W55MH32L版本,该版本拥有更丰富的外设资源,适用于需要多接口扩展的复杂工控场景,软件使用方法一致。更多信息和资料请进入http://www.w5500.com/网站或者私信获取。
此外,本W55MH32支持硬件加密算法单元,WIZnet还推出TOE+SSL应用,涵盖TCP SSL、HTTP SSL以及MQTT SSL等,为网络通信安全再添保障。
为助力开发者快速上手与深入开发,基于W55MH32Q这颗芯片,WIZnet精心打造了配套开发板。开发板集成WIZ-Link芯片,借助一根USB C口数据线,就能轻松实现调试、下载以及串口打印日志等功能。开发板将所有外设全部引出,拓展功能也大幅提升,便于开发者全面评估芯片性能。
若您想获取芯片和开发板的更多详细信息,包括产品特性、技术参数以及价格等,欢迎访问官方网页:http://www.w5500.com/,我们期待与您共同探索W55MH32的无限可能。
第十三章 RTC 实时时钟
本章分为如下几个小节:
1 RTC简介
2 功能描述
3 RTC寄存器描述
4 程序设计
5 下载验证
1 RTC简介
实时时钟是一个独立的定时器。RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC 模块和时钟配置系统(RCC_BDCR 寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC 的设置和时间维持不变。系统复位后,对后备寄存器和 RTC 的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。
执行以下操作将使能对后备寄存器和 RTC 的访问:
?设置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位,使能电源和后备接口时钟
?设置寄存器 PWR_CR 的 DBP 位,使能对后备寄存器和 RTC 的访问。
1.1 主要特性
W55MH32的RTC的主要特性如下:
?可编程的预分频系数:分频系数最高为 220。
?32 位的可编程计数器,可用于较长时间段的测量。
?2 个分离的时钟:用于 APB1 接口的 PCLK1 和 RTC 时钟(RTC 时钟的频率必须小于 PCLK1 时钟频率的四分之一以上)。
?可以选择以下三种 RTC 的时钟源:
······ HSE 时钟除以 128;
······LSE 振荡器时钟;
······LSI 振荡器时钟(详见 6.2.8 节 RTC 时钟)。
?2 个独立的复位类型:
······APB1 接口由系统复位;
······RTC 核心(预分频器、闹钟、计数器和分频器)只能由后备域复位(详见 6.1.3 节)。
?3 个专门的可屏蔽中断:
·······闹钟中断,用来产生一个软件可编程的闹钟中断。
······秒中断,用来产生一个可编程的周期性中断信号(最长可达 1 秒)。
······溢出中断,指示内部可编程计数器溢出并回转为 0 的状态。
2 功能描述
2.1 概述
RTC 由两个主要部分组成(参见下图)。第一部分(APB1 接口)用来和 APB1 总线相连。此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总线时钟驱动,用来与 APB1 总线接口。
另一部分(RTC 核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是 RTC 的预分频模块,它可编程产生最长为 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个TR_CLK 周期中 RTC 产生一个中断(秒中断)。第二个模块是一个 32 位的可编程计数器,可被初始化为当前的系统时间。系统时间按 TR_CLK 周期累加并与存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。
简化的 RTC 框图
2.2 复位过程
除了 RTC_PRL、RTC_ALR、RTC_CNT 和 RTC_DIV 寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。
2.3 读RTC寄存器
RTC 核完全独立于 RTCAPB1 接口。
软件通过 APB1 接口访问 RTC 的预分频值、计数器值和闹钟值。但是,相关的可读寄存器只在与RTCAPB1 时钟进行重新同步的 RTC 时钟的上升沿被更新。RTC 标志也是如此的。这意味着,如果 APB1 接口曾经被关闭,而读操作又是在刚刚重新开启 APB1 之后,则在第一次的内部寄存器更新之前,从 APB1 上读出的 RTC 寄存器数值可能被破坏了(通常读到 0)。下述几种情况下能够发生这种情形:
发生系统复位或电源复位
系统刚从待机模式唤醒(参见第 18.3节:低功耗模式)。
系统刚从停机模式唤醒(参见第 18.3节:低功耗模式)。
所有以上情况中,APB1 接口被禁止时(复位、无时钟或断电)RTC 核仍保持运行状态。
因此,若在读取 RTC 寄存器时,RTC 的 APB1 接口曾经处于禁止状态,则软件首先必须等待RTC_CRL 寄存器中的 RSF 位(寄存器同步标志)被硬件置'1')。
注: RTC 的 APB1 接口不受 WFI 和 WFE 等低功耗模式的影响。
2.4 配置RTC寄存器
必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入 RTC_PRL、RTC_CNT、RTC_ALR 寄存器。
另外,对 RTC 任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询 RTC_CR寄存器中的 RTOFF 状态位,判断 RTC 寄存器是否处于更新中。仅当 RTOFF 状态位是'1'时,才可以写入 RTC 寄存器。
配置过程:
1. 查询 RTOFF 位,直到 RTOFF 的值变为'1'
2. 置 CNF 值为 1,进入配置模式
3. 对一个或多个 RTC 寄存器进行写操作
4. 清除 CNF 标志位,退出配置模式
5. 查询 RTOFF,直至 RTOFF 位变为'1'以确认写操作已经完成。仅当 CNF 标志位被清除时,写操作才能进行,这个过程至少需要 3 个 RTCCLK 周期。
2.5 RTC标志的设置
在每一个 RTC 核心的时钟周期中,更改 RTC 计数器之前设置 RTC 秒标志(SECF)。在计数器到达0x0000 之前的最后一个 RTC 时钟周期中,设置 RTC 溢出标志(OWF)。
在计数器的值到达闹钟寄存器的值加 1(RTC_ALR+1)之前的 RTC 时钟周期中,设置 RTC_Alarm 和RTC 闹钟标志(ALRF)。对 RTC 闹钟的写操作必须使用下述过程之一与 RTC 秒标志同步:
使用 RTC 闹钟中断,并在中断处理程序中修改 RTC 闹钟和/或 RTC 计数器。
等待 RTC 控制寄存器中的 SECF 位被设置,再更改 RTC 闹钟和/或 RTC 计数器。
RTC 秒和闹钟波形图示例,PR=0003,ALARM=00004
RTC 溢出波形图示例,PR=0003
3 RTC寄存器描述
3.1 RTC控制寄存器高位(RTC_CRH)
偏移地址:0x00
复位值:0x0000
这些位用来屏蔽中断请求。注意:系统复位后所有的中断被屏蔽,因此可通过写 RTC 寄存器来确保在初始化后没有挂起的中断请求。当外设正在完成前一次写操作时(标志位 RTOFF=0),不能对RTC_CRH 寄存器进行写操作。RTC 功能由这个控制寄存器控制。
3.2 RTC控制寄存器低位(RTC_CRL)
偏移地址:0x00
复位值:0x0000
注:1.任何标志位都将保持挂起状态,直到适当的 RTC_CR 请求位被软件复位,表示所请求的中断已经被接受。
2.在复位时禁止所有中断,无挂起的中断请求,可以对 RTC 寄存器进行写操作。
3.当 APB1 时钟不运行时,OWF、ALRF、SECF 和 RSF 位不被更新。
4.OWF、ALRF、SECF 和 RSF 位只能由硬件置位,由软件来清零。
5.若 ALRF=1 且 ALRIE=1,则允许产生 RTC 全局中断。如果在 EXTI 控制器中允许产生 EXTI 线 17 中断,则允许产生 RTC 全局中断和 RTC 闹钟中断。
6.若 ALRF=1,如果在 EXTI 控制器中设置了 EXTI 线 17 的中断模式,则允许产生 RTC 闹钟中断;如果在 EXTI 控制器中设置了 EXTI 线 17 的事件模式,则这条线上会产生一个脉冲(不会产生 RTC闹钟中断)。
3.3 RTC预分频装载寄存器(RTC_PRLH/RTC_PRLL)
预分频装载寄存器用来保存 RTC 预分频器的周期计数值。它们受 RTC_CR 寄存器的 RTOFF 位保护,仅当 RTOFF 值为'1'时允许进行写操作。
RTC 预分频装载寄存器高位(RTC_PRLH)
偏移地址:0x08
复位值:0x0000
RTC 预分频装载寄存器低位(RTC_PRLL)
偏移地址:0x0C
复位值:0x8000
注: 如果输入时钟频率(fRTCCLK)为 32.768 千赫,则在此寄存器中写入 7FFFh 以获得 1 秒的信号周期
3.4 RTC预分频器余数寄存器(RTC_DIVH/RTC_DIVL)
在 TR_CLK 的每个周期里,RTC 预分频器中计数器的值都会被重新设置为 RTC_PRL 寄存器的值。用户可通过读取 RTC_DIV 寄存器,以获得预分频计数器的当前值,而不停止分频计数器的工作,从而获得精确的时间测量。此寄存器是只读寄存器,其值在 RTC_PRL 或 RTC_CNT 寄存器中的值发生改变后,由硬件重新装载。
RTC 预分频器余数寄存器高位(RTC_DIVH)
偏移地址:0x10
复位值:0x0000
RTC 预分频器余数寄存器低位(RTC_DIVL)
偏移地址:0x14
复位值:0x8000
3.5 RTC计数器寄存器(RTC_CNTH/RTC_CNTL)
RTC 核有一个 32 位可编程的计数器,可通过两个 16 位的寄存器访问。计数器以预分频器产生的TR_CLK时间基准为参考进行计数。RTC_CNT寄存器用来存放计数器的计数值。他们受 RTC_CR的位RTOFF写保护,仅当RTOFF值为'1'时,允许写操作。在高或低寄存器(RTC_CNTH或RTC_CNTL)上的写操作,能够直接装载到相应的可编程计数器,并且重新装载 RTC 预分频器。当进行读操作时,直接返回计数器内的计数值(系统时间)。
RTC 计数器寄存器高位(RTC_CNTH)
偏移地址:0x18
复位值:0x0000
RTC 计数器寄存器低位(RTC_CNTL)
偏移地址:0x1C
复位值:0x0000
3.6 RTC闹钟寄存器(RTC_ALRH/RTC_ALRL)
当可编程计数器的值与 RTC_ALR 中的 32 位值相等时,即触发一个闹钟事件,并且产生 RTC 闹钟中断。此寄存器受 RTC_CR 寄存器里的 RTOFF 位写保护,仅当 RTOFF 值为'1'时,允许写操作。
RTC 闹钟寄存器高位(RTC_ALRH)
偏移地址:0x20
复位值:0xFFFF
RTC 闹钟寄存器低位(RTC_ALRL)
偏移地址:0x24
复位值:0xFFFF
3.7 RTC寄存器映像
RTC-寄存器映像和复位值
4 程序设计
4.1 RTC_Calendar例程
1.初始化部分:延时初始化:调用delay_init()函数,虽未展示其具体实现,但为程序提供时间相关基础功能。
?时钟配置:RCC_ClkConfiguration()函数对系统时钟进行配置。先复位 RCC,开启 HSE 并等待其就绪,配置 PLL 为 HSE 经 1 分频后输入,9 倍频输出,使能 PLL 并等待其就绪,选择 PLLCLK 作为系统时钟源,同时设置 HCLK、PCLK1 和 PCLK2 的分频因子,还开启 LSI 和 HSI。
?串口初始化:UART_Configuration()函数配置 USART1 串口。使能 USART1 和 GPIOA 时钟,将 PA9 配置为复用推挽输出(TX),PA10 配置为浮空输入(RX),设置波特率为 115200,数据位 8 位,停止位 1 位,无校验,无硬件流控制,工作模式为收发模式,最后使能串口。
?NVIC 配置:NVIC_Configuration()函数设置 NVIC 优先级分组为 1,使能 RTC 中断,设置其抢占优先级为 1,子优先级为 0。
?RTC 配置:RTC_Configuration()函数配置 RTC。使能 PWR 和 BKP 时钟,允许访问备份区域,对 BKP 进行初始化,开启 LSI 并等待其就绪,选择 LSI 作为 RTC 时钟源,使能 RTC 时钟并等待同步,设置 RTC 秒中断,设置预分频器为 32767,使 RTC 周期为 1 秒。
2.主循环部分:在main()函数中,先进行延时、时钟配置,接着配置串口,输出 “RTC Calendar Test.” 及系统时钟频率信息。检查 BKP 寄存器值判断 RTC 是否已配置,若未配置则进行 RTC 配置并设置时间,若已配置则判断复位类型并根据情况处理。最后调用Time_Show()函数进入一个循环,当TimeDisplay为 1 时显示当前时间。
3.时间调整与显示部分:时间调整:Time_Adjust()函数调用Time_Regulate()函数获取用户通过串口输入的时分秒,然后设置 RTC 计数器。
// 时间调整函数(通过串口输入设置时间) void Time_Adjust(void) { RTC_WaitForLastTask(); RTC_SetCounter(Time_Regulate()); // 调用输入函数获取时间并设置RTC计数器 RTC_WaitForLastTask(); } // 时间输入函数(串口交互获取时分秒) uint32_t Time_Regulate(void) { uint32_t Tmp_HH, Tmp_MM, Tmp_SS; // 输入小时(0-23) printf("rn Please Set Hours"); while ((Tmp_HH = USART_Scanf(23)) == 0xFF); // 输入分钟(0-59) printf("rn Please Set Minutes"); while ((Tmp_MM = USART_Scanf(59)) == 0xFF); // 输入秒(0-59) printf("rn Please Set Seconds"); while ((Tmp_SS = USART_Scanf(59)) == 0xFF); return (Tmp_HH * 3600 + Tmp_MM * 60 + Tmp_SS); // 返回总秒数 } // 时间显示函数(实时打印时间) void Time_Show(void) { printf("nr"); while (1) { if (TimeDisplay == 1) // TimeDisplay由RTC中断触发置1 { Time_Display(RTC_GetCounter()); // 转换并显示时间 TimeDisplay = 0; } } } // 时间格式化显示 void Time_Display(uint32_t TimeVar) { uint32_t THH = TimeVar / 3600; uint32_t TMM = (TimeVar % 3600) / 60; uint32_t TSS = TimeVar % 60; // 计数器溢出处理(约24小时归零) if (RTC_GetCounter() == 0x0001517F) { RTC_SetCounter(0); RTC_WaitForLastTask(); } printf("Time: %02d:%02d:%02dn", THH, TMM, TSS); }
时间显示:Time_Show()函数进入一个循环,当TimeDisplay为 1 时,调用Time_Display()函数获取 RTC 计数器的值并转换为时、分、秒格式进行显示。同时,Time_Display()函数还会在 RTC 计数器达到特定值(0x0001517F)时将其重置为 0。
4.串口输入处理部分:USART_Scanf()函数用于从串口接收用户输入的数字,检查输入是否为有效数字,若无效则提示用户重新输入,直到输入有效数字。
4.2 RTC_LSICalib例程
1.初始化部分:延时初始化:调用delay_init()函数,虽未给出其具体实现,但为程序提供时间相关的基础功能。
// 1. 延时初始化(依赖delay.h实现) delay_init(); // 1.a 串口初始化 void UART_Configuration(uint32_t bound) { // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置TX/RX引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA9-TX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA10-RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置串口参数 USART_InitStructure.USART_BaudRate = bound; // 115200bps USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } // 1.b RTC配置 void RTC_Configuration(void) { // 使能电源和备份域时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); PWR_BackupAccessCmd(ENABLE); BKP_DeInit(); // 复位备份域 // 配置RTC时钟源(LSI) RCC_LSICmd(ENABLE); RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro(); // 等待RTC寄存器同步 RTC_ITConfig(RTC_IT_SEC, ENABLE); // 使能秒中断 RTC_SetPrescaler(40000); // 预设预分频值(假设LSI=40kHz) // 配置RTC输出 BKP_TamperPinCmd(DISABLE); BKP_RTCOutputConfig(BKP_RTCOutputSource_Second); } // 1.c 定时器配置(TIM5用于测量LSI频率) void TIM_Configuration(void) { // 使能时钟和引脚重映射 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE); // 配置TIM5时基 TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); // 配置TIM5通道4为输入捕获模式 TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM5, &TIM_ICInitStructure); // 使能TIM5和捕获中断 TIM_Cmd(TIM5, ENABLE); TIM5->SR = 0; // 清除中断标志 TIM_ITConfig(TIM5, TIM_IT_CC4, ENABLE); } // 1.d NVIC中断配置 void NVIC_Configuration(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 优先级分组1 // 配置RTC中断(最高优先级) NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // 配置TIM5中断(次高优先级) NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
串口初始化:UART_Configuration()函数配置 USART1 串口。使能 USART1 和 GPIOA 时钟,将 PA9 配置为复用推挽输出(用于 TX 发送),PA10 配置为浮空输入(用于 RX 接收)。设置串口波特率为 115200,数据位 8 位,停止位 1 位,无校验位,无硬件流控制,工作模式为同时接收和发送,并最终使能串口。
RTC 配置:RTC_Configuration()函数对 RTC 进行配置。使能 PWR 和 BKP 时钟,允许访问备份区域,对 BKP 进行初始化。开启 LSI,选择 LSI 作为 RTC 时钟源,使能 RTC 时钟并等待同步,设置 RTC 秒中断,设置预分频器为 40000,禁用 BKP 篡改引脚,配置 RTC 输出为秒信号。
定时器配置:TIM_Configuration()函数对 TIM5 进行配置。使能 AFIO 和 TIM5 时钟,重映射 TIM5 通道 4 到 LSI。设置 TIM5 的预分频器为 0,计数模式为向上计数,周期为 0xFFFF,时钟分频为 1。配置 TIM5 通道 4 为输入捕获模式,上升沿触发,直接映射到 TI,不分频,无滤波。使能 TIM5,清除状态寄存器,使能 TIM5 通道 4 捕获中断。
NVIC 配置:NVIC_Configuration()函数设置 NVIC 优先级分组为 1。使能 RTC 中断,设置其抢占优先级为 0,子优先级为 0;使能 TIM5 中断,设置子优先级为 2。
2.主循环部分:在main()函数中,先进行延时初始化,接着配置串口,输出 “RTC LSI Calib Test.” 及系统时钟频率信息。然后进行 RTC、TIM5 配置和 NVIC 配置。等待OperationComplete变为 2,这意味着 TIM5 测量操作完成。当OperationComplete为 2 时,计算 LSI 的实际频率,并根据该频率设置 RTC 的预分频器,最后进入无限循环while(1)。
int main(void) { // 系统初始化 delay_init(); UART_Configuration(115200); printf("RTC LSI Calib Test.n"); RCC_GetClocksFreq(&clocks); printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn", (float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000, (float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000); // 外设初始化 RTC_Configuration(); TIM_Configuration(); NVIC_Configuration(); // 2. 等待TIM5测量完成(OperationComplete=2) while (OperationComplete != 2); // 计算LSI实际频率并校准RTC if (PeriodValue != 0) { // LSI频率 = (2*PCLK1)/PeriodValue LsiFreq = (uint32_t)((uint32_t)(clocks.PCLK1_Frequency * 2) / (uint32_t)PeriodValue); } printf("LsiFreq: %d Hzn", LsiFreq); // 根据测量结果校准RTC预分频器 RTC_SetPrescaler(LsiFreq - 1); RTC_WaitForLastTask(); // 无限循环 while (1); }
3.辅助函数部分:IncrementVar_OperationComplete()函数使OperationComplete变量自增,并返回自增前的值。
// 3.a 递增OperationComplete并返回旧值 uint32_t IncrementVar_OperationComplete(void) { OperationComplete++; return (uint32_t)(OperationComplete - 1); } // 3.b 获取OperationComplete值 uint32_t GetVar_OperationComplete(void) { return (uint32_t)OperationComplete; } // 3.c 设置PeriodValue值 void SetVar_PeriodValue(uint32_t Value) { PeriodValue = (uint32_t)(Value); }
GetVar_OperationComplete()函数返回OperationComplete变量的值。
SetVar_PeriodValue()函数设置PeriodValue变量的值。
5 下载验证
5.1 RTC_Calendar例程
5.2 RTC_LSICalib例程
WIZnet 是一家无晶圆厂半导体公司,成立于 1998 年。产品包括互联网处理器 iMCU?,它采用 TOE(TCP/IP 卸载引擎)技术,基于独特的专利全硬连线 TCP/IP。iMCU? 面向各种应用中的嵌入式互联网设备。
WIZnet 在全球拥有 70 多家分销商,在香港、韩国、美国设有办事处,提供技术支持和产品营销。
香港办事处管理的区域包括:澳大利亚、印度、土耳其、亚洲(韩国和日本除外)。
审核编辑 黄宇
-
实时时钟
+关注
关注
4文章
315浏览量
67140 -
RTC
+关注
关注
2文章
623浏览量
69081
发布评论请先 登录
明德扬点拨FPGA课程---第十三章 ?计数器的使用
布尔值转换(逐点)vi怎么用啊?还有8.2第十三章中火车轮的检测中怎样画出的柱状图 ?
RTC是什么?RTC实时时钟实验
浅谈RTC实时时钟特征与原理
STM32CubeMX系列|RTC实时时钟

评论