STM32 RTC之日历显示

发布者:吉州古玩斋最新更新时间:2015-10-30 来源: eefocus关键字:STM32  RTC  日历显示 手机看文章 扫描二维码
随时随地手机看文章
    使用STM32的RTC功能,制作一份私人专属的日历,就SO简单了。不废话,上效果图:

 

   

STM32 <wbr>RTC之日历显示

    鄙人通过串口输出时间到超级终端的(SecureCRT 5.5这货最好),如果配上TFT就制作一个简易的电子日历了。这个里面主要涉及RTC的初始化,时间数据的初始化输入,串口输出,还有就是公历时间和农历时间的转换处理。通过串口初始化RTC数据,RTC通过串口把时间显示出来,上代码:

   工程结构图:

  STM32 <wbr>RTC之日历显示
    1、main.c如下:


#include"stm32f10x.h"
#include"beep.h"
#include"led.h"
#include"usart1.h"
#include"rtc.h"


int main(void)
{
  USART_Config();

  Beep_Init();
  Beep_State(1,BeepOn);

  Led_Init();
  Led_Spark(LedAll,1,LedOn);

  RTC_NVIC_Config();      //RTC嵌套中断向量初始化

  RTC_Display();
}

    2、beep led usart这些在博客其他文章里面出现过,这里就不提也罢。

    3、RTC.c这是本文的重点了。

    C文件如下:


#include"stm32f10x.h"
#include"rtc.h"
#include"usart1.h"
#include"date.h"
#include"calendar.h"
#include


u8 SecondFlag=0;

struct rtc_time systmtime;

u8 const *WEEK_STR[] = {"日", "一", "二", "三", "四", "五", "六"}; //这是一个指针数组的赋值 不是指向一个数组的指针 而是一个数组的每一个元素都是一个指针

//==============================================================================================1-RTC初始化部分

void RTC_NVIC_Config(void)
{
  NVIC_InitTypeDef                 NVIC_InitStructure;

  NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0000);       //起始地址位于FLASH

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);       //优先级分组方式2

 
  NVIC_InitStructure.NVIC_IRQChannel                  =RTC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority       =0; 
  NVIC_InitStructure.NVIC_IRQChannelCmd            =ENABLE;

  NVIC_Init(&NVIC_InitStructure);
}



static void RTC_Config(void)
{
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
  PWR_BackupAccessCmd(ENABLE);
 
  BKP_DeInit();

 
  RCC_LSEConfig(RCC_LSE_ON);
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);    //等待LSE准备就绪
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  RCC_RTCCLKCmd(ENABLE);

 
  RTC_WaitForSynchro();
 
  RTC_ITConfig(RTC_IT_SEC,ENABLE);
 
  RTC_WaitForLastTask();

 
  RTC_SetPrescaler(32767);
  RTC_WaitForLastTask();
}

//==============================================================================================2--设置时间部分

static u8 RTC_USART_Scanf(uint32_t value)
{
  uint32_t index = 0;
  uint32_t tmp[2] = {0, 0};

  while (index < 2)
  {
   
    while (USART_GetFlagStatus(USART, USART_FLAG_RXNE) == RESET)
    {}
    tmp[index++] = (USART_ReceiveData(USART));
    if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39))
    {
        if((index == 2) && (tmp[index - 1] == ' '))   //第一个输入的是数字,第二个是按的回车键的情况
        {
            tmp[1] = tmp[0];
            tmp[0] = 0x30;
        }
        else
        {
          printf(" Please enter valid number between 0 and 9 -->:  ");
          index--;
        }
    }
    else
    {
        printf("%c", tmp[index - 1]);       //输入一个显示一个数字
    }
  }
 
  index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);
 
  if (index > value)
  {
    printf(" Please enter valid number between 0 and %d -->:  ", value);
    return 0xFF;
  }
  return index;
}

[page]

static void RTC_Time_Setting(struct rtc_time *tm)
{
  uint32_t DataIn = 0xFF;

  printf(" ==============请设置时间==================");

  printf("   请输入年份(Please Set Years):  20");
  while (DataIn == 0xFF)
  {
    DataIn = RTC_USART_Scanf(99);
  }
  printf("   年份被设置为:  20%0.2d ", DataIn);
  tm->tm_year = DataIn+2000;

  DataIn = 0xFF;
  printf("   请输入月份(Please Set Months):  ");
  while (DataIn == 0xFF)
  {
    DataIn = RTC_USART_Scanf(12);
  }
  printf("   月份被设置为:  %d ", DataIn);
  tm->tm_mon= DataIn;

  DataIn = 0xFF;
  printf("   请输入日期(Please Set Dates):  ");
  while (DataIn == 0xFF)
  {
    DataIn = RTC_USART_Scanf(31);
  }
  printf("   日期被设置为:  %d ", DataIn);
  tm->tm_mday= DataIn;

  DataIn = 0xFF;
  printf("   请输入时钟(Please Set Hours):  ");
  while (DataIn == 0xFF)
  {
    DataIn = RTC_USART_Scanf(23);
  }
  printf("   时钟被设置为:  %d ", DataIn);
  tm->tm_hour= DataIn;
   
  DataIn = 0xFF;
  printf("   请输入分钟(Please Set Minutes):  ");
  while (DataIn == 0xFF)
  {
    DataIn = RTC_USART_Scanf(59);
  }
  printf("   分钟被设置为:  %d ", DataIn);
  tm->tm_min= DataIn;
 
  DataIn = 0xFF;
  printf("   请输入秒钟(Please Set Seconds):  ");
  while (DataIn == 0xFF)
  {
    DataIn = RTC_USART_Scanf(59);
  }
  printf("   秒钟被设置为:  %d ", DataIn);
  tm->tm_sec= DataIn;
}



static void RTC_Time_Adjust(void)
{
 
  RTC_WaitForLastTask();
 
  RTC_Time_Setting(&systmtime);          //把输入的年月日时分秒导入到结构体systmtime里面
 
  GregorianDay(&systmtime);     //这个会求出tm->tm_wday=day%7  星期
 
  RTC_SetCounter(mktimev(&systmtime));  //根据systmtime里面的内容计算出RTC计数器里面需要装载的数字然后写入计数器里面
 
  RTC_WaitForLastTask();
}



static void RTC_WhetherOrNot_First(void)
{
  if(BKP_ReadBackupRegister(BKP_DR1)!=0xa6a6)
  {
   printf(" 第一次进入RTC ");
 RTC_Config();
 printf(" RTC初始化完成 ");

 printf(" 设置时间 ");
 RTC_Time_Adjust();       //设置时间

 BKP_WriteBackupRegister(BKP_DR1,0xa5a5);
  }
  else
  {
   if(RCC_GetFlagStatus(RCC_FLAG_PINRST)!=RESET)
   printf(" 上次发生了复位引脚复位 ");
 else if(RCC_GetFlagStatus(RCC_FLAG_PORRST)!=RESET)
   printf(" 上次发生了上电复位 ");
 
 printf(" RTC已经设置 ");
  }
}


//==============================================================================================3--时间显示部分

static void RTC_TimeHandle(u32 TimeVar)
{
   static uint32_t FirstDisplay = 1;
   __IO u8 str[15];                                                                                     // 字符串暂存
  
   to_tm(TimeVar, &systmtime);                                                                      //TimeVar:RTC的值    把相应的数据填入结构体systmtime(年月日 时分秒 星期)

  if((!systmtime.tm_hour && !systmtime.tm_min && !systmtime.tm_sec)  || (FirstDisplay))                 //天数变更或者是第一次进入此语句
  {
     
      GetChinaCalendar((u16)systmtime.tm_year, (u8)systmtime.tm_mon, (u8)systmtime.tm_mday, (u8 *)str); //得到的是农历日期

      printf(" 今天农历:%0.2d%0.2d,%0.2d,%0.2d", str[0], str[1], str[2], str[3]);

      GetChinaCalendarStr((u16)systmtime.tm_year,(u8)systmtime.tm_mon,(u8)systmtime.tm_mday,(u8 *)str); //得到的是甲子年
      printf("  %s", str);

     if(GetJieQiStr((u16)systmtime.tm_year, (u8)systmtime.tm_mon, (u8)systmtime.tm_mday, (u8 *)str)) //得到的是节气
          printf("  %s ", str);                                                                      //  计算农历节气

      FirstDisplay = 0;
  }
 
  printf(" 当前时间为: %d年 %d月 %d日 (星期%s)  %0.2d:%0.2d:%0.2d",
                    systmtime.tm_year, systmtime.tm_mon, systmtime.tm_mday,
                    WEEK_STR[systmtime.tm_wday], systmtime.tm_hour,
                    systmtime.tm_min, systmtime.tm_sec);

}



static void RTC_TimeShow(void)
{
  while(1)
  {
    if(SecondFlag==1)
    {
     RTC_TimeHandle(RTC_GetCounter());
   SecondFlag=0;
    }
  }
}



void RTC_Display(void)
{
  RTC_WhetherOrNot_First();
 
  RTC_WaitForSynchro();
 
  RTC_ITConfig(RTC_IT_SEC,ENABLE);
  RTC_WaitForLastTask();

#ifdef RTC_CLK_Output        //RTC时钟信号输出
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
  PWR_BackupAccessCmd(ENABLE);
  BKP_DeInit();

 
  BKP_TemperPinCmd(DISABLE);
 
  BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
#endif

  RCC_ClearFlag();

 
  printf(" -------------时间显示如下------------ ");
  RTC_TimeShow();
}

    H文件如下:


#ifndef _RTC_H
#define _RTC_H

#include"stm32f10x.h"


void RTC_NVIC_Config(void);      //RTC嵌套中断向量初始化

void RTC_Display(void);       //RTC全过程

#endif

   以上,注释很给力了,不说了。

 

   至于这STM32 <wbr>RTC之日历显示两个文件,是通过LINUX移植过来的,网上有现成的代码,读者可以自行下载。由于其代码量相对较大,鄙人这里就不粘贴了。我的QQ380986295 ,免费提供。

   还是给这两个文件一个效果图吧:

STM32 <wbr>RTC之日历显示

STM32 <wbr>RTC之日历显示


    以上RTC结束了。

    使用STM32的RTC功能,制作日历就很简单了,加上一个TFT就很容易做一个电子时钟。作为初学者,还是很有必要做一做提升一下自信心,鼓励自己坚持下去。

关键字:STM32  RTC  日历显示 引用地址:STM32 RTC之日历显示

上一篇:STM32 I2C AT24C02驱动
下一篇:STM32 串口之中断接受

推荐阅读最新更新时间:2024-03-16 14:38

STM32中对SysTick_Init()函数和Delay_us()的理解
STM32中对SysTick_Init()函数(sysTick_Config()、TimingDelay_Decrement()自定义)和Delay_us()的理解: 实验:3个LED灯以500ms的频率闪烁。
[单片机]
STM32库中关于GPIO_PinRemapConfig函数的使用
对于初学习者来说为什么用到PB3和PB4时无法控制输出呢? 下面就这一问题进行分析讲解。 首先,STM32F10x系列的MCU复位后,PA13/14/15 & PB3/4默认配置为JTAG功能。有时我们为了充分利用MCU I/O口的资源,会把这些 端口设置为普通I/O口。具体方法如下: 在GPIO_Configuration(); // 配置使用的 GPIO 口: GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // 改变指定管脚的映射 GPIO_Remap_SWJ_Disable,SWJ 完全禁用(JTAG+SW-DP),而且管脚映射函数,需要在GPIO配置函数GP
[单片机]
STM32 输入捕获功能
01、STM32捕获功能 从STM32的定时器框图中看 ①部分基础定时器模块,已经在《 STM32基础定时器详解 》讲解过了。 ②部分捕获/对比通道模块,已经在《 定时器的PWM功能 》讲解过了。 ③部分是本文的重点,输入捕获模块。 从上图可以看出定时器1共有4个输入捕获通道。 下文以定时器1的捕获通道2为例讲解。 首先确定下对应的GPIO,从STM32F207数据手册的Alternatefunction mapping看出,定时器1通道2对应的GPIO有PA9和PE11,下文将使用PE11。 02、输入捕获过程 输入阶段采样对应的对输入TIx,去产生滤波后的信号TIxF。然后极性选择边沿检测器产生一个信号(TIx
[单片机]
<font color='red'>STM32</font> 输入捕获功能
STM32中重要的C语言知识点总结
说在前面的话一位初学单片机的小伙伴让我推荐C语言书籍,因为C语言基础比较差,想把C语言重新学一遍,再去学单片机,我以前刚学单片机的时候也有这样子的想法。 其实C语言是可以边学单片机边学的,学单片机的一些例程中,遇到不懂的C语言知识,再去查相关的知识点,这样印象才会深刻些。 下面就列出了一些STM32中重要的C语言知识点,初学的小伙伴可以多读几遍,其中大多知识点之前都有写过,这里重新整理一下,更详细地分析解释可以阅读附带的链接。 assert_param断言(assert)就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式。 断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真。
[单片机]
<font color='red'>STM32</font>中重要的C语言知识点总结
STM32笔记---RTC的初始化
RTC这东西晕晕的,因为一个模块涉及到了RTC,BKP,RCC多个模块,之间的关系让人有点模糊 入门的知识请大家看手册,我来总结: 总之,RTC只是个能靠电池维持运行的32位定时器over! 所以,使用时要注意以下问题: 1.上电后要检查备份电池有没有断过电。如何检查? 恩,RTC的示例代码中已经明示: 往备份域寄存器中写一个特殊的字符,备份域寄存器是和RTC一起在断电下能保存数据的。 上电后检查下这个特殊字符是否还存在,如果存在,ok,RTC的数据应该也没丢,不需要重新配置它 如果那个特殊字符丢了,那RTC的定时器数据一定也丢了,那我们要重新来配置RTC了 这个过程包括时钟使能、RTC时钟源切换、设置分频系数等等,这个可以
[单片机]
stm32库函数记录
一、系统初始化函数执行完毕各时钟的状态 二、三类(总线上的)时钟函数 2.1、外设时钟使能函数 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewStat e); void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewStat e); 此3 个时钟使能函数也是 STM32
[单片机]
<font color='red'>stm32</font>库函数记录
在linux环境下如何进行stm32的开发建议
工具链一般用gcc-arm-none-eabi,可以用包管理装,也可以到arm官网下,也可以自己编译,毕竟gnu源有这个配置。 纯用命令行的话,cubemx可以生成makefile工程,改下编译器路径就能make,会生成bin文件。 用IDE的话,可以用eclipse,参考wiced sdk。 可以用vscode,体验要优于sublime。网上搜搜怎么配环境,主要就是设置工具链的目录。 烧录程序,如果烧的是bin的话需要一个烧录程序。用jlink的话可以用segger官网下的jlinkexe工具。用stlink的话可以用github上的stutils什么的。用cmsis-dap或者ft2232的话就只能配openo
[单片机]
基于Cortex-M3的STM32微控制器处理先进电机控制方法
  变频器的问世和先进的 电机控制 方法让 三相无刷电机 (交流感应电机或永磁同步电机)曾经在调速应用领域取得巨大成功。这些高性能的电机驱动器过去主要用于工厂自动化系统和机器人。十年来,电子元器件的大幅降价使得这些电机驱动器能够进入对成本敏感的市场,例如:家电、空调或个人医疗设备。本文将探讨基于ARM的标准微控制器如何在一个被DSP和FPGA长期垄断的市场上打破复杂的控制模式,我们将以意法半导体的基于Cortex-M3内核的STM32系列微控制器为例论述这个过程。   首先,我们回顾一下电机控制的基本原理。在电机控制系统内,为什么处理器非常重要?我们为什么需要非常好的计算性能?毕竟,Nicolas Tesla在一个世纪前发明
[安防电子]
基于Cortex-M3的<font color='red'>STM32</font>微控制器处理先进电机控制方法
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved