12: STM32 --- reloj en tiempo real RTC

Tabla de contenido

1: relacionado con el tiempo

1: marca de tiempo Unix

2: UTC/GMT

3: conversión de marca de tiempo

2:BKP

1: reanudar

2: estructura básica

Tres: RTC

1: reanudar

2: diagrama de bloques

3: estructura básica RTC

4: Notas sobre el funcionamiento del RTC

Cuatro: Caso

R: Leer y escribir registro de respaldo

1: diagrama de conexión

2: Pasos

 3: código 

B: reloj en tiempo real

1: diagrama de conexión

2: Introducción a la función 

3: Código


1: relacionado con el tiempo

1: marca de tiempo Unix

        La marca de tiempo de Unix se define como el número de segundos que han transcurrido desde las 0:00:00 del 1 de enero de 1970 UTC/GMT, independientemente de los segundos intercalares.

        La marca de tiempo se almacena en un contador de segundos, que es una variable entera de 32/64 bits.

        El contador de segundos es el mismo para todas las zonas horarias del mundo. Las diferentes zonas horarias añaden compensaciones para obtener la hora local.

2: UTC/GMT

         GMT (Greenwich Mean Time) La hora media de Greenwich es un sistema de medición del tiempo basado en la rotación de la Tierra. Divide el intervalo de tiempo de una rotación de la Tierra en 24 horas para determinar el estándar de tiempo.

         UTC (Tiempo Universal Coordinado) es un sistema de medición del tiempo basado en relojes atómicos. Estipula que la duración de 9.192.631.770 ciclos de radiación de transición entre los dos niveles de energía hiperfina del estado fundamental de un átomo de cesio 133 en un campo magnético cero es de 1 segundo. Cuando la diferencia entre la hora diurna del reloj atómico y la hora de rotación de la Tierra supera los 0,9 segundos, UTC realizará un segundo intercalar para garantizar que su sincronización sea coherente con la rotación de la Tierra.

3: conversión de marca de tiempo

        El módulo time.h del lenguaje C proporciona funciones relacionadas para la adquisición de tiempo y la conversión de marcas de tiempo, que pueden convertir fácilmente entre contador de segundos, fecha y hora y cadena.

2:BKP

1: reanudar

        Registros de respaldo BKP (Backup Registers)

        BKP se puede utilizar para almacenar datos de aplicaciones de usuario. Cuando se corta la fuente de alimentación del VDD (2,0~3,6V), todavía reciben alimentación de VBAT (1,8~3,6V). Tampoco se restablecen cuando el sistema sale del modo de espera o cuando se reinicia el sistema o se reinicia la energía.

        Un evento de intrusión generado por el pin TAMPER borra todo el contenido del registro de respaldo.

        El pin RTC genera un reloj de calibración RTC, un pulso de alarma RTC o un segundo pulso.

        Almacenar la capacidad de almacenamiento de datos del usuario del registro de calibración del reloj RTC:     

                20 bytes (capacidad media y pequeña capacidad) / 84 bytes (gran capacidad y tipo de interconexión)

2: estructura básica

        BKP está en el área de respaldo y la función del área de respaldo: cuando la fuente de alimentación principal de VDD está apagada, el área de respaldo aún puede recibir energía de la batería de respaldo VBAT; cuando la fuente de alimentación principal de VDD está encendida, el área de respaldo La fuente de alimentación del área se cambiará de VBAT a VDD, es decir, la fuente de alimentación principal. Cuando se enciende la fuente de alimentación, VBAT no se utilizará, lo que ahorrará energía de la batería.

        El BKP incluye principalmente: registro de datos, registro de control, registro de estado y registro de calibración del reloj RTC. El registro de datos es la parte principal y se utiliza para almacenar datos. Cada registro impar de datos tiene 16 bits. Un registro impar de datos puede almacenar 2 bytes. Para los pequeños, hay DR1, DR2, hasta y DR10, un total de 10 registros de datos; para los de gran capacidad e interconectados, hay registros de datos DR11~DR42.

        Se puede introducir un anunciador de detección desde el pin TAMPERS en la PC 13. Cuando TAMPER genera un flanco ascendente o descendente, todo el contenido del BKP se borrará para garantizar la seguridad ----- correspondiente al tercer elemento del currículum

        Salida de reloj, el reloj relacionado con RTC se puede emitir desde el pin RTC en PC13 para uso externo. Cuando se emite el reloj de calibración, el error del RTC se puede calibrar con este registro de calibración.

Tres: RTC

1: reanudar

        Reloj en tiempo real RTC (Reloj en tiempo real)

        RTC es un temporizador independiente que puede proporcionar funciones de reloj y calendario para el sistema. El RTC y el sistema de configuración del reloj están en el área de respaldo. Los datos no se borran cuando se reinicia el sistema. Después de apagar el VDD (2.0~3.6V) , la fuente de alimentación VBAT (1,8 ~ 3,6 V) continúa funcionando

        Contador programable de 32 bits, segundo contador que puede corresponder a la marca de tiempo Unix

        El preescalador programable de 20 bits puede adaptarse a relojes de entrada de diferentes frecuencias

        Se pueden seleccionar tres fuentes de reloj RTC:     

                Reloj HSE dividido por 128 (normalmente 8MHz/128)     

                Reloj oscilador LSE (normalmente 32,768 KHz)     

                Reloj oscilador LSI (40 KHz)

2: diagrama de bloques

3: estructura básica RTC

        Hay 3 relojes, elija uno como RTCCLK y luego RTCCLK pasa primero por el preescalador para dividir el reloj.

        Registro de resto (DIV): es un contador autodecreciente que almacena el valor de conteo actual.

        Registro de recarga: Es el objetivo de conteo y determina el valor de división de frecuencia, luego de la división se obtiene una segunda señal de conteo de 1Hz, lo que conduce a un contador de 32 bits que se incrementa una vez por segundo.

        Tres señales pueden activar interrupciones, a saber, la segunda señal, la señal de desbordamiento del contador y la señal de alarma. Las tres señales son controladas primero por la salida de interrupción. Las tres señales son controladas primero por la salida de interrupción. Solo la interrupción habilitada puede dirigirse a el NVIC.

4: Notas sobre el funcionamiento del RTC

        Hacer lo siguiente permitirá el acceso a BKP y RTC:   

                 Configure PWREN y BKPEN de RCC_APB1ENR y habilite los relojes PWR y BKP     

                Configure el DBP de PWR_CR para permitir el acceso a BKP y RTC

        Si la interfaz APB1 de RTC se ha desactivado al leer el registro RTC, el software primero debe esperar a que el hardware establezca el bit RSF (indicador de sincronización de registro) en el registro RTC_CRL en 1.

        El bit CNF en el registro RTC_CRL debe configurarse para que el RTC pueda ingresar al modo de configuración antes de escribir en los registros RTC_PRL, RTC_CNT y RTC_ALR. De hecho, esta operación está en la función de biblioteca. Cada función que escribe registros impares, Agrega automáticamente esta operación por nosotros, por lo que no necesitamos llamar al código por separado para ingresar al modo de configuración.

        Se debe realizar una operación de escritura en cualquier registro RTC después de completar la operación de escritura anterior. Puede determinar si el registro RTC se está actualizando consultando el bit de estado RTOFF en el registro RTC_CR. Escribir en el registro RTC solo es posible cuando el bit de estado RTOFF es 1

Cuatro: Caso

R: Leer y escribir registro de respaldo

1: diagrama de conexión

2: Pasos

  1: Configure PWREN y BKPEN de RCC_APB1ENR y habilite los relojes PWR y BKP     

  2: Configure el DBP de PWR_CR para permitir el acceso a BKP y RTC

 3: código 

Implementación simple de funciones BKP 

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"

void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
		Delay_ms(20);
		KeyNum = 1;
	}
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
		Delay_ms(20);
		KeyNum = 2;
	}
	
	return KeyNum;
}


/*
 执行以下操作将使能对BKP和RTC的访问:     

        1: 设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和BKP时钟     

        2: 设置PWR_CR的DBP,使能对BKP和RTC的访问

*/
uint16_t ArrayWrite[]={0x1234,0x5678};
uint16_t ArrayRead[2];
uint16_t KeyNum;
int main(void)
{	
	Key_Init();
	OLED_Init();
	//1: 设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和BKP时钟     
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	//2: 设置PWR_CR的DBP,使能对BKP和RTC的访问
	PWR_BackupAccessCmd(ENABLE);
	
	OLED_ShowString(1,1,"W:");
	OLED_ShowString(3,1,"R:");
	
	while (1)
	{
		KeyNum=Key_GetNum();
		if (KeyNum==1)
		{
			ArrayWrite[0]++;
			ArrayWrite[1]++;
			BKP_WriteBackupRegister(BKP_DR1,ArrayWrite[0]);
			BKP_WriteBackupRegister(BKP_DR2,ArrayWrite[1]);
			OLED_ShowHexNum(1,3,ArrayWrite[0],4);
			OLED_ShowHexNum(1,8,ArrayWrite[1],4);

		}
		ArrayRead[0]=BKP_ReadBackupRegister(BKP_DR1);
		ArrayRead[1]=BKP_ReadBackupRegister(BKP_DR2);
		OLED_ShowHexNum(3,3,ArrayRead[0],4);
		OLED_ShowHexNum(3,8,ArrayRead[1],4);
	
	}
	
}

 Hacer lo siguiente permitirá el acceso a BKP y RTC:     

        1: Configure PWREN y BKPEN de RCC_APB1ENR y habilite los relojes PWR y BKP     

        2: Configure el DBP de PWR_CR para permitir el acceso a BKP y RTC

B: reloj en tiempo real

1: diagrama de conexión

2: Introducción a la función 

En el archivo stm32f10x_rcc.h ----- funciones relacionadas con el reloj

vacío RCC_LSEConfig(uint8_t RCC_LSE);

void RCC_LSICmd(EstadofuncionalNuevoEstado);

vacío RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
 

void RCC_RTCCLKCmd(EstadofuncionalNuevoEstado)

RCC_LSEConfig : configura el reloj externo de baja velocidad (LSE)

RCC_LSICmd : configurar el reloj interno de baja velocidad (LSI)

RCC_RTCCLKConfig : Esta función se utiliza para seleccionar la fuente de reloj de RTCCLK, en realidad es el selector de datos que configura el PPT.

RCC_RTCCLKCmd : Habilitar: enciende o apaga el reloj RTC

Después de seleccionar el reloj, es necesario obtener el bit de bandera y esperar a que se complete la bandera antes de operar.

	RCC_LSEConfig(RCC_LSE_ON);//选择外部低速时钟
	
	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);//LSE准备ok了

En el archivo stm32f10x_rcc.h ----- obtenga la función de bit de bandera

Estado de bandera RCC_GetFlagStatus(uint8_t RCC_FLAG);

En el archivo stm32f10x_rtc.h ----- Ingrese al modo de configuración RTC

anular RTC_EnterConfigMode (anular)

 La función de esta función es establecer el CNF de CRL en 1 e ingresar al modo de configuración.

        El bit CNF en el registro RTC_CRL debe configurarse para que el RTC pueda ingresar al modo de configuración antes de escribir en los registros RTC_PRL, RTC_CNT y RTC_ALR.

En el archivo stm32f10x_rtc.h -----Salga del modo de configuración RTC

anular RTC_ExitConfigMode (anular)

Función: Es para borrar el bit CNF. 

En el archivo stm32f10x_rtc.h -----Contador CNT relacionado

uint32_t RTC_GetCounter(nulo)
 

vacío RTC_SetCounter (uint32_t CounterValue)

RTC_GetCounter : obtiene el valor del contador RTC

RTC_SetCounter : el valor escrito en CNT

En el archivo stm32f10x_rtc.h-----prescaler

vacío RTC_SetPrescaler (uint32_t PrescalerValue)

 RTC_SetPrescaler : escribe el valor del preescalador. Este valor se escribirá en el registro de recarga PRL del preescalador y se utiliza para configurar el coeficiente de división del preescalador.

En el archivo stm32f10x_rtc.h ----- escribe el valor del despertador

anular RTC_SetAlarm (uint32_t AlarmValue)

En el archivo stm32f10x_rtc.h ----- Lea el registro restante DIV en el preescalador

 uint32_t RTC_GetDivider(nulo);

El registro impar restante es un contador decreciente automáticamente. Obtener el valor del registro impar restante es generalmente para obtener un tiempo más detallado.

En el archivo stm32f10x_rtc.h ----- espere a que se complete la operación

anular RTC_WaitForLastTask (anular);

anular RTC_WaitForSynchro (anular);

RTC_WaitForLastTask : espera a que se complete la última operación 

        Se debe realizar una operación de escritura en cualquier registro RTC después de completar la operación de escritura anterior. Puede determinar si el registro RTC se está actualizando consultando el bit de estado RTOFF en el registro RTC_CR. Escribir en el registro RTC solo es posible cuando el bit de estado RTOFF es 1

 RTC_WaitForSynchro : Espere la sincronización----borre el indicador RSF, luego realice un bucle hasta que RSF sea 1

        Si la interfaz APB1 de RTC se ha desactivado al leer el registro RTC, el software primero debe esperar a que el hardware establezca el bit RSF (indicador de sincronización de registro) en el registro RTC_CRL en 1.

3: Código

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MYRTC.h"

uint16_t MyRTC_Time[] = {2023, 1, 1, 23, 59, 55};
void MYRTC_init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	PWR_BackupAccessCmd(ENABLE);
	
	if(BKP_ReadBackupRegister(BKP_DR1)!=0xA5A5)
	{
		//LSE的频率是32.768KHz,也就是32768Hz
		RCC_LSEConfig(RCC_LSE_ON);//选择外部低速时钟
		
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);//LSE准备ok了
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//配置RTC时钟RTCCLK
		RCC_RTCCLKCmd(ENABLE);//开启RTC时钟
		
		RTC_WaitForLastTask();//等待上次操作完成 
		RTC_WaitForSynchro();//等待同步时钟
		
		//写预分频器
		RTC_SetPrescaler(32768-1);
		RTC_WaitForLastTask();
		
		RTC_SetCounter(1672588795); //写入CNT
		RTC_WaitForLastTask();
		
		BKP_WriteBackupRegister(BKP_DR1,0xA5A5);
	
	}
	else
	{
			
		RTC_WaitForLastTask();//等待上次操作完成 
		RTC_WaitForSynchro();//等待同步时钟
		
	}

	
}

void MYRTC_Settime(void)
{
	//内部的定义typedef unsigned int time_t; /* date/time in unix secs past 1-Jan-70 */	
	time_t time_cnt;
	struct tm time_date;
	time_date.tm_year = MyRTC_Time[0] - 1900;
	time_date.tm_mon = MyRTC_Time[1] - 1;
	time_date.tm_mday = MyRTC_Time[2];
	time_date.tm_hour = MyRTC_Time[3];
	time_date.tm_min = MyRTC_Time[4];
	time_date.tm_sec = MyRTC_Time[5];
	//默认是伦敦时间,  转化为北京的东八区的时间
	time_cnt=mktime(&time_date)-8*60*60; //mktimer日期类型的时间数据类型--转化为--秒计数器数据类型
	RTC_SetCounter(time_cnt);//写入CNT计数器
	RTC_WaitForLastTask();

}
	
void MyRTC_ReadTime(void)
{
	time_t time_cnt;
	struct tm time_date;
	
	time_cnt = RTC_GetCounter() + 8 * 60 * 60;
	
	time_date = *localtime(&time_cnt);  //秒计数器数据类型--转化为---日期类型的时间数据类型
	
	MyRTC_Time[0] = time_date.tm_year + 1900;
	MyRTC_Time[1] = time_date.tm_mon + 1;
	MyRTC_Time[2] = time_date.tm_mday;
	MyRTC_Time[3] = time_date.tm_hour;
	MyRTC_Time[4] = time_date.tm_min;
	MyRTC_Time[5] = time_date.tm_sec;
}




int main(void)
{
	OLED_Init();
	MYRTC_init();
	
	OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
	OLED_ShowString(2, 1, "Time:XX:XX:XX");
	OLED_ShowString(3, 1, "CNT :");
	OLED_ShowString(4, 1, "DIV :");
	
	while (1)
	{
		MyRTC_ReadTime();
		
		OLED_ShowNum(1, 6, MyRTC_Time[0], 4);
		OLED_ShowNum(1, 11, MyRTC_Time[1], 2);
		OLED_ShowNum(1, 14, MyRTC_Time[2], 2);
		OLED_ShowNum(2, 6, MyRTC_Time[3], 2);
		OLED_ShowNum(2, 9, MyRTC_Time[4], 2);
		OLED_ShowNum(2, 12, MyRTC_Time[5], 2);
		
		OLED_ShowNum(3, 6, RTC_GetCounter(), 10);
		OLED_ShowNum(4, 6, RTC_GetDivider(), 10);
	}
}

Supongo que te gusta

Origin blog.csdn.net/m0_74739916/article/details/133084178
Recomendado
Clasificación