数字温度计

数字温度计

一、时钟RTC简单介绍

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

   在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。

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

 上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写访问。无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。

2.2、RTC特征:
可编程的预分频系数:分频系数高为220。

32位的可编程计数器,可用于较长时间段的测量。

2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟 频率的四分之一以上)。

可以选择以下三种RTC的时钟源:

HSE时钟除以128;
LSE振荡器时钟;
SI振荡器时钟
2个独立的复位类型:

APB1接口由系统复位;
RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位
3个专门的可屏蔽中断:

1.闹钟中断,用来产生一个软件可编程的闹钟中断
2.秒中断,用来产生一个可编程的周期性中断信号(长可达1秒)。
3.溢出中断,指示内部可编程计数器溢出并回转为0的状态。
RTC时钟源:
三种不同的时钟源可被用来驱动系统时钟(SYSCLK):

HSI振荡器时钟
HSE振荡器时钟
PLL时钟
这些设备有以下2种二级时钟源:

40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。 RTC用于从停机/待机模式下自动唤醒系统。
32.768kHz低速外部晶体也可用来通过程序选择驱动RTC(RTCCLK)。
2.3、RTC原理框图:
在这里插入图片描述

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

(1)APB1 接口: 用来和 APB1 总线相连。 此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总 线时钟驱动,用来与 APB1 总线连接。通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。

(2)RTC 核心接口:由一组可编程计数器组成,分成 两个主要模块 :

——第一个模块是 RTC 的 预分频模块 ,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个 TR_CLK 周期中 RTC 产生一个中断(秒中断)。

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

2.4、RTC结构:
RTC时钟主要由两个内部低速时钟和一个外部高速时钟构成。基本结构如下:
在这里插入图片描述

硬件电路原理图如下 :
在这里插入图片描述

   RTC(Real Time Clock)实时时钟是一种高精度、低功耗的定时器,它可以在各种环境下提供精确的时间和日期信息。即使在系统处于低功耗模式时,RTC也可以继续运行,确保时间的连续性。此外,它还支持时钟校准功能,可以校正时钟的偏差,保证时间的准确性。 除了基本的时间提供功能,RTC还具有报警功能,用户可以设置报警功能,当达到指定时间时触发中断,这在实际应用中非常有用。例如,可以在系统到达预定维护时间时触发警报,提醒用户进行维护操作。

   另外,RTC还支持外部电池备份,用户可以使用外部电池进行时间备份,即使在断电的情况下也能保持时间的准确。这一特性使得RTC在某些应用场景下特别适用,例如在应急照明系统、安全监控系统等需要持续、准确计时的情况下。

  RTC还具有自动唤醒功能,用户可以根据需要设置自动唤醒条件,当满足预设条件时自动唤醒系统。这一功能在许多嵌入式系统和物联网设备中非常有用,可以大大降低系统的功耗。

2.5、RTC具体流程:
RTCCLK经过RTC_DIV预分频,RTC_PRL设置预分频系数,然后得到TR_CLK时钟信号,我们一般设置其周期为1s,RTC_CNT计数器计数,假如1970设置为时间起点为0s,通过当前时间的秒数计算得到当前的时间。RTC_ALR是设置闹钟时间,RTC_CNT计数到RTC_ALR就会产生计数中断。RTC_Second为秒中断,用于刷新时间;RTC_Overflow是溢出中断;RTC Alarm 控制开关机。

2.6、RTC时钟选择:
使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作.所以RTC一般都时钟低速外部时钟LSE,频率为实时时钟模块中常用的32.768KHz,因为32768 = 2^15,分频容易实现,所以被广泛应用到RTC模块.(在主电源VDD有效的情况下待机,RTC还可以配置闹钟事件使STM32退出待机模式)。

2.7、RTC复位过程:
除了RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器仅能通过备份域复位信号复位。系统复位后,禁止访问后备寄存器和RCT,防止对后卫区域(BKP)的意外写操作。

2.8、RTC中断:
(1)秒中断:
这里时钟自带一个秒中断,每当计数加一的时候就会触发一次秒中断,。注意,这里所说的秒中断并非一定是一秒的时间,它是由RTC时钟源和分频值决定的“秒”的时间,当然也是可以做到1秒钟中断一次。我们通过往秒中断里写更新时间的函数来达到时间同步的效果

(2)闹钟中断:
闹钟中断就是设置一个预设定的值,计数每自加多少次触发一次闹钟中断

二、创建工程

打开STAM32CubeMX,创建新项目,选择STM32F103C8T6芯片

配置SYS
在这里插入图片描述

配置RCC(设置高速外部时钟,使能外部晶振LSE)
在这里插入图片描述

配置RTC(激活时钟源(Activate Clock Source)和日历(Activate Calendar))
在这里插入图片描述

设置时间,可自定
在这里插入图片描述

日期和年份可自行设定
在这里插入图片描述
设置USART1
在这里插入图片描述

配置时钟树
在这里插入图片描述

配置项目
在这里插入图片描述
在这里插入图片描述

三、启动keil

首先我们打开main函数,然后在main函数里面添加头文件#include “stdio.h”,再添加以下代码:
``int fputc(int ch,FILE *f){ uint8_t temp[1]={ch}; HAL_UART_Transmit(&huart1,temp,1,2); return ch; }`

RTC_DateTypeDef GetData; //获取日期结构体

RTC_TimeTypeDef GetTime; //获取时间结构体

在主函数内将while循环修改:

   while (1)
  {
/* Get the RTC current Time */
	    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
      /* Get the RTC current Date */
      HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
  /* Display date Format : yy/mm/dd */
  printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
  /* Display time Format : hh:mm:ss */
	/* Display date Format : weekday */
	if(GetData.WeekDay==1){
		printf("星期一\r\n");
	}else if(GetData.WeekDay==2){
		printf("星期二\r\n");
	}else if(GetData.WeekDay==3){
		printf("星期三\r\n");
	}else if(GetData.WeekDay==4){
		printf("星期四\r\n");
	}else if(GetData.WeekDay==5){
		printf("星期五\r\n");
	}else if(GetData.WeekDay==6){
		printf("星期六\r\n");
	}else if(GetData.WeekDay==7){
		printf("星期日\r\n");
	}

  printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
  printf("\r\n");

  HAL_Delay(1000);
  
  }

在这里插入图片描述
点击魔法棒,进行配置
在这里插入图片描述

然后在进行烧录程序,得到结果:
请添加图片描述

四、实时温、湿度

这里我们采用标准库的方式进行实验

将AH的两个文件添加至工程下,方法前面的的博客已写详细的过程

修改主函数内容:

#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"
#include "OLED.h"
#include "MyRTC.h"
#include "Timer.h"

int main(void)
{	
	delay_init();  
	uart_init(9600);
	OLED_Init();
	MyRTC_Init();
	IIC_Init();
	Timer_Init();
MyRTC_SetTime();
while(1)
{
	//delay_ms(1000);
}
}
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		read_AHT20_once();
	MyRTC_ReadTime();
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}

烧录程序得到结果:

请添加图片描述

五、总结

本次实验让我收获很大,之前基本使用HAL库直接创建工程,这次第二个任务只能用标准库,这让我回忆了标准库的使用,并且比以前更加熟悉。本次实验也深切体会到了测试温度的过程。因为有上次使用AHT20的经验,这次也轻松不少。
Time();
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}

烧录程序得到结果:
在这里插入图片描述

五、总结

本次实验让我收获很大,之前基本使用HAL库直接创建工程,这次第二个任务只能用标准库,这让我回忆了标准库的使用,并且比以前更加熟悉。本次实验也深切体会到了测试温度的过程。因为有上次使用AHT20的经验,这次也轻松不少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值