记录学习的RTC实时时钟之两种代码形式,在OLED和串口或OLED中显示现象

BKP (Backup Registers)备份寄存器:
  1、BKP可用于存储用户应用程序数据。当VDD (2.0~3.6V)电源被切断,他们仍然由VBAT (1.8~3.6V)维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位TAMPER引脚产生的侵入事件将所有备份寄存器内容清除RTC引脚输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲存储RTC时钟校准寄存器。
  2、用户数据存储容量:20字节(中容量和小容量)/84字节(大容量和互联型)


RTC (Real Time Clock)实时时钟
  1、RTC是一个独立的定时器,可为系统提供时钟和日历的功能
  2、RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD(2.0~3.6V)断电后可借助VBAT (1.8~3.6V)供电继续走时
  3、 32位的可编程计数器,可对应Unix时间戳的秒计数器
  4、 20位的可编程预分频器,可适配不同频率的输入时钟可选择三种RTC时钟源:
HSE时钟除以128(通常为8MHz/128)LSE振荡器时钟(通常为32.768KHz)LSI振荡器时钟(40KHz)(通常为32.768KHz时,才能提供VBAT (1.8~3.6V)供电)

第一种写法代码如下:

在OLED中显示)

1、MyRTC.c

#include "stm32f10x.h"                  // Device header
#include "MyRTC.h"
#include <time.h>

uint16_t MyRTC_Time[ ] = {2023,7,25,20,58,59};



void MyRTC_Init(void)
{
   // 使能PWR时钟,用于控制备份寄存器
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
   
   // 使能BKP时钟,用于控制备份寄存器
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
    
   // 允许访问备份寄存器
   PWR_BackupAccessCmd(ENABLE);
    
   // 如果备份寄存器中的值不等于0xA7A7,表示RTC还未初始化
   if (BKP_ReadBackupRegister(BKP_DR1) != 0xA7A7)
   {
        // 使能外部低速晶振(LSE)
        RCC_LSEConfig(RCC_LSE_ON);
        
        // 等待外部低速晶振就绪
        while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);
        
        // 将RTC时钟源配置为外部低速晶振
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        
        // 使能RTC时钟
        RCC_RTCCLKCmd(ENABLE);
        
        // 等待RTC寄存器同步
        RTC_WaitForSynchro();
        
        // 等待RTC最后的任务完成
        RTC_WaitForLastTask();
        
        // 设置RTC预分频器,使RTC时钟频率为1Hz
        RTC_SetPrescaler(32768-1);
        
        // 等待RTC最后的任务完成
        RTC_WaitForLastTask();

        // 设置RTC时间,可能是一个自定义的函数
        MyRTC_SetTime();
        
        // 将特定值(0xA7A7)写入备份寄存器,表示RTC已经初始化过
        BKP_WriteBackupRegister(BKP_DR1, 0xA7A7);
    }
    else
    {
        // 如果备份寄存器中的值等于0xA7A7,表示RTC已经初始化过
        // 等待RTC寄存器同步
        RTC_WaitForSynchro();
        
        // 等待RTC最后的任务完成
        RTC_WaitForLastTask();
    }
}


// RTC设置时间函数
void MyRTC_SetTime(void)
{
    // 定义time_t类型的变量time_cnt,用于保存RTC的时间值
    time_t time_cnt;
    
    // 定义tm结构体类型的变量time_data,用于保存时间的年月日时分秒信息
    struct tm time_data;
    
    // 将MyRTC_Time数组中的年份减去1900,存入time_data的年份字段
    time_data.tm_year = MyRTC_Time[0] - 1900;
    
    // 将MyRTC_Time数组中的月份减1,存入time_data的月份字段
    time_data.tm_mon = MyRTC_Time[1] - 1;
    
    // 将MyRTC_Time数组中的日期存入time_data的日期字段
    time_data.tm_mday = MyRTC_Time[2];
    
    // 将MyRTC_Time数组中的小时存入time_data的小时字段
    time_data.tm_hour = MyRTC_Time[3];
    
    // 将MyRTC_Time数组中的分钟存入time_data的分钟字段
    time_data.tm_min = MyRTC_Time[4];
    
    // 将MyRTC_Time数组中的秒钟存入time_data的秒钟字段
    time_data.tm_sec = MyRTC_Time[5];
    
    // 使用mktime函数将time_data结构体转换成time_t类型的时间值,并减去8小时的偏移量(假设时区为UTC+8)
    time_cnt = mktime(&time_data) - 8 * 60 * 60;
    
    // 将计算得到的时间值设置为RTC的计数器值
    RTC_SetCounter(time_cnt);
    
    // 等待RTC最后的任务完成
    RTC_WaitForLastTask(); 
}


// RTC读取时间函数
void MyRTC_ReadTime(void)
{
    // 定义time_t类型的变量time_cnt,用于保存RTC的时间值
    time_t time_cnt;
    
    // 定义tm结构体类型的变量time_data,用于保存时间的年月日时分秒信息
    struct tm time_data;
    
    // 从RTC获取计数器的值,并加上8小时的偏移量(假设时区为UTC+8),存入time_cnt
    time_cnt = RTC_GetCounter() + 8 * 60 * 60;
    
    // 使用localtime函数将time_t类型的时间值转换成tm结构体类型的时间信息,并存入time_data
    time_data = *localtime(&time_cnt); 
    
    // 将time_data结构体中的年份加上1900,存入MyRTC_Time数组的年份字段
    MyRTC_Time[0] = time_data.tm_year + 1900;
    
    // 将time_data结构体中的月份加1,存入MyRTC_Time数组的月份字段
    MyRTC_Time[1] = time_data.tm_mon + 1;
    
    // 将time_data结构体中的日期存入MyRTC_Time数组的日期字段
    MyRTC_Time[2] = time_data.tm_mday;
    
    // 将time_data结构体中的小时存入MyRTC_Time数组的小时字段
    MyRTC_Time[3] = time_data.tm_hour;
    
    // 将time_data结构体中的分钟存入MyRTC_Time数组的分钟字段
    MyRTC_Time[4] = time_data.tm_min;
    
    // 将time_data结构体中的秒钟存入MyRTC_Time数组的秒钟字段
    MyRTC_Time[5] = time_data.tm_sec;
}

2、MyRTC.h

#ifndef __MYRTC_H
#define __MYRTC_H

extern uint16_t MyRTC_Time[];

void MyRTC_Init(void);
void MyRTC_SetTime(void);
void MyRTC_ReadTime(void);

#endif

 3、main.c

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


int main(void)
{
	OLED_Init();
    MyRTC_Init();
    OLED_ShowString(1,1,"Data: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,(32767-RTC_GetDivider())/32767.0*999,10);//0~999毫秒
    }
}

(注:第一种写法在VBAT引脚接了一个3.3V,因为我这块板子没有纽扣电池之类的给VBAT引脚供电,一定要接3.3V嗷)

第二种写法代码如下:

(串口和OLED显示)

1、rtc.c

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "sys.h"
#include "rtc.h" 
#include "OLED.h"
#include "usart.h"
#include "stdio.h"	

__IO uint32_t TimeDisplay = 0;

uint8_t const table_week[12] = {0,3,3,6,1,4,6,2,5,0,3,5};//月修正数据表
const uint8_t mon_table[12] = {31,28,31,30,31,30,31,31,30,31,30,31};//平年的月份日期表
struct RTC_TIME{
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t week;
    uint8_t hour;
    uint8_t min;
    uint8_t sec;
}rtc_timer = {2023,07,19,3,13,54,10};



void rtc_init(void)
{
   //NVIC的配置
   NVIC_Configuration();
   if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A4)
   {
       //通过判断 BKP_DR1是否是0xA5A5来识别是否是第一次系统上电
       
       printf("RTC no yet configured...\r\n");
       //配置RTC 设置初始时间
       RTC_Configuration();
       
       printf("RTC Configured....\r\n");
       //设置初始时间:年 月 日 时 分 秒
       RTC_Set(rtc_timer.year,rtc_timer.month,rtc_timer.day,rtc_timer.hour,rtc_timer.min,rtc_timer.sec);
       
       BKP_WriteBackupRegister(BKP_DR1, 0xA5A4); 
   }
   else
   {
        //看系统是否掉电
       if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
       {
           printf("Power On Reset occurred...\r\n");
       }
       //看是否是复位引脚引起的复位
       else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
       {
           printf("External Reset occurred...\r\n");
       }
       printf("No need to configure RTC...");
       
       RTC_WaitForSynchro();
       
       //使能秒中断
       RTC_ITConfig(RTC_IT_SEC,ENABLE);
       
       RTC_WaitForLastTask();
           
   }
   //清除标志位
   RCC_ClearFlag();

}


void RTC_Configuration(void)
{
    uint32_t t;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP,ENABLE);
    
    //允许访问BKP区
    PWR_BackupAccessCmd(ENABLE);
    
    
    //复位
    BKP_DeInit();
     
    //外部低速时钟 使能 LES
    RCC_LSEConfig(RCC_LSE_ON);
    
    //等待LSE时钟稳定
    while((RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) && t<5000)
    {
        t++;
    }
     // 选择LSE作为时钟源  
     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
    
    //使能 RTC 时钟
    RCC_RTCCLKCmd(ENABLE);
    
    //等待RTC寄存器的时钟同步
    RTC_WaitForSynchro();
    
    
    //等待RTC寄存器上一次操作完成RTOFF标志位
    RTC_WaitForLastTask();
    
    //使能RTC秒中断
    RTC_ITConfig(RTC_IT_SEC,ENABLE);
    
    //等待RTC寄存器上一次操作完成RTOFF标志位
    RTC_WaitForLastTask();
    
    //设置RTC预分频器时间是1秒
    RTC_SetPrescaler(32767);
    
    
    //等待RTC寄存器上一次操作完成
    RTC_WaitForLastTask();
}


//读出当前时间值  //返回值:0,成功;其他:代码错误;
uint8_t RTC_Get(void)
{
	static uint16_t daycnt=0;
	uint32_t timecount=0;
	uint32_t temp=0;
	uint16_t temp1=0;
	timecount=RTC_GetCounter();		
	temp=timecount/86400;   //得到天数(秒钟数对应的)24*3600S
	if(daycnt!=temp)
        {//超过一天了
		daycnt=temp;
		temp1=1970;  //从1970年开始
		while(temp>=365)
            {
                    if(Is_Leap_Year(temp1))
                        {//是闰年
                            if(temp>=366)temp-=366;//闰年的秒钟数
                            else {temp1++;break;} 
                         }
                    else temp-=365;       //平年
                    temp1++; 
                 }  
            rtc_timer.year=temp1;//得到年份
            temp1=0;
            while(temp>=28){//超过了一个月
                if(Is_Leap_Year(rtc_timer.year)&&temp1==1){//当年是不是闰年/2月份
                    if(temp>=29)temp-=29;//闰年的秒钟数
                    else break;
                }else{
                    if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年
                    else break;
                }
                temp1++; 
            }
            rtc_timer.month=temp1+1;//得到月份
            rtc_timer.day=temp+1;  //得到日期
	}
	temp=timecount%86400;     //得到秒钟数      
	rtc_timer.hour=temp/3600;     //小时
	rtc_timer.min=(temp%3600)/60; //分钟     
	rtc_timer.sec=(temp%3600)%60; //秒钟
	rtc_timer.week=RTC_Get_Week(rtc_timer.year,rtc_timer.month,rtc_timer.day);//获取星期  
	return 0;
} 
//判断是否是闰年函数
//月份   1  2  3  4  5  6  7  8  9  10 11 12
//闰年   31 29 31 30 31 30 31 31 30 31 30 31
//非闰年 31 28 31 30 31 30 31 31 30 31 30 31
//输入:年份
//输出:该年份是不是闰年.1,是.0,不是



uint8_t Is_Leap_Year(uint16_t year)
{                    
	if(year%4==0)
        { //必须能被4整除
		if(year%100==0)
            {		
			if(year%400==0)
                return 1;//如果以00结尾,还要能被400整除          
			else 
                return 0;  
		    }
            else 
              return 1;  
	    }
        else 
          return 0;
} 
//按年月日计算星期(只允许1901-2099年)
//由RTC_Get调用 
uint8_t RTC_Get_Week(uint16_t year,uint8_t month,uint8_t day)
{    
	uint16_t temp2;
	uint8_t yearH,yearL;
	yearH=year/100;     
	yearL=year%100;
	// 如果为21世纪,年份数加100 
	if (yearH>19)yearL+=100;
	// 所过闰年数只算1900年之后的 
	temp2=yearL+yearL/4;
	temp2=temp2%7;
	temp2=temp2+day+table_week[month-1];
	if (yearL%4==0&&month<3)temp2--;
	return(temp2%7); //返回星期值
}	







//写入时间与日期
//月份数据表                                                                       

uint8_t RTC_Set(uint16_t syear,uint8_t smon,uint8_t sday,uint8_t hour,uint8_t min,uint8_t sec){ //写入当前时间(1970~2099年有效),
	uint16_t t;
	uint32_t seccount=0;
	if(syear<2000||syear>2099)return 1;//syear范围1970-2099,此处设置范围为2000-2099       
	for(t=1970;t<syear;t++){ //把所有年份的秒钟相加
		if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数
		else seccount+=31536000;                    //平年的秒钟数
	}
	smon-=1;
	for(t=0;t<smon;t++){         //把前面月份的秒钟数相加
		seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加
		if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//闰年2月份增加一天的秒钟数        
	}
	seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加
	seccount+=(u32)hour*3600;//小时秒钟数
	seccount+=(u32)min*60;      //分钟秒钟数
	seccount+=sec;//最后的秒钟加上去
	RTC_SetCounter(seccount);//把换算好的计数器值写入
	RTC_WaitForLastTask(); //等待写入完成
	return 0; //返回值:0,成功;其他:错误代码.    
}


void Time_Display(void)
{
    OLED_Init();
    
    RTC_Get();
    
    printf("DATA: %0.2d-%0.2d-%0.2d\r\n",rtc_timer.year, rtc_timer.month,rtc_timer.day);
    printf("Time: %0.2d:%0.2d:%0.2d\r\n",rtc_timer.hour,rtc_timer.min,rtc_timer.sec);
    
    OLED_ShowString(1,1,"DATA:");
    OLED_ShowNum(1,6,rtc_timer.year,4);//2023
    OLED_ShowChar(1,10,'-');
    OLED_ShowNum(1,11,rtc_timer.month,2);//07
    OLED_ShowChar(1,13,'-');
    OLED_ShowNum(1, 14,rtc_timer.day, 2);//18
    
    OLED_ShowString(3,1,"Time:");
    OLED_ShowNum(3,6,rtc_timer.hour,2);
    OLED_ShowChar(3,8,':');
    OLED_ShowNum(3,9,rtc_timer.min,2);
    OLED_ShowChar(3,11,':');
    OLED_ShowNum(3,12,rtc_timer.sec,2);
    
}


void NVIC_Configuration(void)
{
    	NVIC_InitTypeDef NVIC_InitStructure;
    
        //使能RTC中断
    	NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;		//RTC全局中断
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	//先占优先级1位,从优先级3位
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;	//先占优先级0位,从优先级4位
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		//使能该通道中断
    	NVIC_Init(&NVIC_InitStructure);		//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}

void RTC_IRQHandler(void)
{
    if(RTC_GetITStatus(RTC_IT_SEC) != RESET)
    {
        //清除秒中断标志位
        RTC_ClearITPendingBit(RTC_IT_SEC);
        
        PCout(13) ^= 1;
        
        TimeDisplay = 1;
        
        RTC_WaitForLastTask();
    }
    
}

2、rtc.h

#ifndef _RTC_H
#define _RTC_H	 

extern __IO uint32_t TimeDisplay;
void rtc_init(void);
void RTC_Configuration(void);
void Time_Display(void);
uint8_t RTC_Set(uint16_t syear,uint8_t smon,uint8_t sday,uint8_t hour,uint8_t min,uint8_t sec);
uint8_t RTC_Get_Week(uint16_t year,uint8_t month,uint8_t day);
uint8_t RTC_Get(void);
void RTC_Configuration(void);
uint8_t Is_Leap_Year(uint16_t year);
uint8_t RTC_Get(void);



void NVIC_Configuration(void);
#endif

3、main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "rtc.h"
#include "LED.h"

//uint8_t RxData; 
int ok = 0;

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//	LED_Init();
	Serial_Init();
	rtc_init();

	while (1)
	{
        //秒标志位 1
        if(TimeDisplay == 1)
        {
            Time_Display();
            TimeDisplay = 0;           
        }
	}
}

 第二种写法串口打印结果

 这是第一种写法的视频嗷

OLED显示实时时间

 

第二种的也来咯

第二种写法效果图

 

欢迎在座的大佬们过来指正批评 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是基于STM32F103系列驱动RTC实时时钟并使用OLED显示的示例代码: ```c #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_rtc.h" #include "stm32f10x_i2c.h" #include "oled.h" void RTC_Configuration(void); void I2C_Configuration(void); void OLED_Configuration(void); void OLED_UpdateTime(RTC_TimeTypeDef RTC_TimeStruct, RTC_DateTypeDef RTC_DateStruct); int main(void) { RTC_Configuration(); //初始化RTC I2C_Configuration(); //初始化I2C OLED_Configuration(); //初始化OLED while(1) { RTC_TimeTypeDef RTC_TimeStruct; RTC_DateTypeDef RTC_DateStruct; RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct); //获取当前时间 RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct); //获取当前日期 OLED_UpdateTime(RTC_TimeStruct, RTC_DateStruct); //更新OLED显示时间 } } void RTC_Configuration(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问 RCC_LSEConfig(RCC_LSE_ON); //打开LSE外部晶振 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //等待LSE晶振稳定 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //将RTC时钟源改为LSE外部晶振 RCC_RTCCLKCmd(ENABLE); //使能RTC时钟 RTC_WaitForSynchro(); //等待RTC寄存器同步 RTC_InitTypeDef RTC_InitStructure; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //时间格式为24小时制 RTC_InitStructure.RTC_AsynchPrediv = 0x7F; //RTC异步分频系数为0x7F+1=128 RTC_InitStructure.RTC_SynchPrediv = 0xFF; //RTC同步分频系数为0xFF+1=256 RTC_Init(&RTC_InitStructure); //初始化RTC RTC_TimeTypeDef RTC_TimeStruct; RTC_TimeStruct.RTC_Hours = 0x00; //设置RTC小时数 RTC_TimeStruct.RTC_Minutes = 0x00; //设置RTC分钟数 RTC_TimeStruct.RTC_Seconds = 0x00; //设置RTC秒数 RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct); //设置RTC时间 RTC_DateTypeDef RTC_DateStruct; RTC_DateStruct.RTC_Year = 0x20; //设置RTC年份 RTC_DateStruct.RTC_Month = RTC_Month_January; //设置RTC月份 RTC_DateStruct.RTC_Date = 0x01; //设置RTC日数 RTC_DateStruct.RTC_WeekDay = RTC_Weekday_Thursday; //设置RTC星期几 RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct); //设置RTC日期 } void I2C_Configuration(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //使能I2C1外设时钟 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //PB6和PB7引脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //开漏输出 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C模式 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //占空比为2 I2C_InitStructure.I2C_OwnAddress1 = 0x00; //本地地址为0 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能应答 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //7位地址模式 I2C_InitStructure.I2C_ClockSpeed = 100000; //时钟速度为100kHz I2C_Cmd(I2C1, ENABLE); //使能I2C1 I2C_Init(I2C1, &I2C_InitStructure); //初始化I2C1 } void OLED_Configuration(void) { OLED_Init(); //初始化OLED OLED_Clear(); //清屏 } void OLED_UpdateTime(RTC_TimeTypeDef RTC_TimeStruct, RTC_DateTypeDef RTC_DateStruct) { char time_str[20]; sprintf(time_str, "%02d:%02d:%02d", RTC_TimeStruct.RTC_Hours, RTC_TimeStruct.RTC_Minutes, RTC_TimeStruct.RTC_Seconds); char date_str[20]; sprintf(date_str, "%04d-%02d-%02d", RTC_DateStruct.RTC_Year, RTC_DateStruct.RTC_Month, RTC_DateStruct.RTC_Date); OLED_ShowString(0, 0, "Time:"); OLED_ShowString(48, 0, time_str); OLED_ShowString(0, 2, "Date:"); OLED_ShowString(48, 2, date_str); } ``` 这段代码,我们在`main()`函数调用`RTC_Configuration()`函数、`I2C_Configuration()`函数和`OLED_Configuration()`函数,分别初始化RTC、I2C和OLED。然后我们在一个无限循环不断获取当前的时间和日期,并调用`OLED_UpdateTime()`函数来更新OLED上的时间和日期显示。`OLED_UpdateTime()`函数,我们首先使用`sprintf()`函数将当前时间和日期转换为字符串。然后我们调用`OLED_ShowString()`函数来在OLED显示时间和日期。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值