STM32
直播中

李桂英

7年用户 1342经验值
私信 关注
[问答]

如何去实现一种基于STM32F103的可调时钟万年历呢

如何用STM32F103内部RTC实现可调时钟万年历?
如何去实现一种基于STM32F103的可调时钟万年历呢?

回帖(2)

史岩超

2021-11-22 14:31:51
  一、如何用STM32F103内部RTC实现可调时钟万年历?
  通常我们都是利用单片机驱动外设来实现可调时钟万年历的,但是如果手里没有相应的外设又想做一个可调时钟万年历怎么办,先不要着急,找一个STM32单片机我们利用其内部RTC就可以实现,是不是方便了好多呀。
  二、话不多说代码垒起
  1.主函数
  int main(void)
  {
  u8 t=0;
  u8 keynum;
  delay_init(); //延时函数初始化
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  uart_init(115200); //串口初始化为115200
  LED_Init(); //LED端口初始化
  LCD_Init();
  BEEP_Init(); //初始化蜂鸣器IO
  EXTIX_Init();
  // usmart_dev.init(SystemCoreClock/1000000); //初始化USMART
  // alarmclock.hour =17;
  // alarmclock.min =43 ;
  // alarmclock.sec =00;
  RTC_Init(); //RTC初始化
  POINT_COLOR=RED;//设置字体为红色
  //LCD_ShowString(60,50,200,16,16,“Elite STM32”);
  //LCD_ShowString(60,70,200,16,16,“RTC TEST”);
  //LCD_ShowString(60,90,200,16,16,“ATOM@ALIENTEK”);
  //LCD_ShowString(60,110,200,16,16,“2021/2/14”);
  //显示时间
  POINT_COLOR=BLUE;//设置字体为蓝色
  LCD_ShowString(60,130,200,16,16,“ - - ”);
  LCD_ShowString(60,162,200,16,16,“ : : ”);
  while(1)
  {
  POINT_COLOR=BLUE;
  if(t!=calendar.sec)
  {
  t=calendar.sec;
  LCD_ShowNum(60,130,calendar.w_year,4,16);
  LCD_ShowNum(100,130,calendar.w_month,2,16);
  LCD_ShowNum(124,130,calendar.w_date,2,16);
  switch(calendar.week)
  {
  case 0:
  LCD_ShowString(60,148,200,16,16,“Sunday ”);
  break;
  case 1:
  LCD_ShowString(60,148,200,16,16,“Monday ”);
  break;
  case 2:
  LCD_ShowString(60,148,200,16,16,“Tuesday ”);
  break;
  case 3:
  LCD_ShowString(60,148,200,16,16,“Wednesday”);
  break;
  case 4:
  LCD_ShowString(60,148,200,16,16,“Thursday ”);
  break;
  case 5:
  LCD_ShowString(60,148,200,16,16,“Friday ”);
  break;
  case 6:
  LCD_ShowString(60,148,200,16,16,“Saturday ”);
  break;
  }
  LCD_ShowNum(60,162,calendar.hour,2,16);
  LCD_ShowNum(84,162,calendar.min,2,16);
  LCD_ShowNum(108,162,calendar.sec,2,16);
  LED0=!LED0;
  keynum = KEY_Scan(0);
  if(keynum==1)//设置
  {
  BEEP=0;
  main_Set();//时钟万年历调时函数
  }
  else if(keynum==3)//设置
  {
  BEEP=0;
  alarm_Set();//调闹钟
  }
  else if(keynum==2) //关声音
  {
  BEEP=0;
  }
  }
  delay_ms(10);
  };
  }
  2.时钟调时程序代码
  void main_Set()//时钟万年历调时函数
  {
  u8 keynum ,state=1;
  LCD_ShowString(16,112,200,16,16,“Calendar Set:”);//显示字符Calendar Set:可进行相应的时钟设置
  LCD_ShowNum(108,162,calendar.sec,2,16);//定格到当前所在秒
  while(1)
  {
  keynum = KEY_Scan(0);
  if(keynum==1)
  {
  if(state》=6)
  state=0;
  else
  state++;
  switch(state)
  {
  case 0:
  case 1: POINT_COLOR=RED;
  LCD_ShowNum(108,162,calendar.sec,2,16);
  break;//秒
  case 2: POINT_COLOR=RED;
  LCD_ShowNum(84,162,calendar.min,2,16);
  break;//分
  case 3: POINT_COLOR=RED;
  LCD_ShowNum(60,162,calendar.hour,2,16);
  break;//时
  case 4: POINT_COLOR=RED;
  LCD_ShowNum(124,130,calendar.w_date,2,16);
  break;//日
  case 5: POINT_COLOR=RED;
  LCD_ShowNum(100,130,calendar.w_month,2,16);
  break;//月
  case 6: POINT_COLOR=RED;
  LCD_ShowNum(60,130,calendar.w_year,4,16);
  break;//年
  default:break;
  }
  }
  else if(keynum》1)
  {
  if(keynum==4)
  {
  }
  if(state==1)//设置秒,我这里秒不作为可设置开放所以注释掉了
  {
  // if(keynum==3)
  // calendar.sec++;
  // else if(keynum==2)
  // calendar.sec--;
  // if(calendar.sec》=60)
  // calendar.sec=0;
  // else if(calendar.sec《0)
  // calendar.sec=59;
  // POINT_COLOR=BLUE;
  // LCD_ShowNum(108,216,calendar.sec,2,16);
  }
  else if(state==2)//设置分
  {
  if(keynum==3)
  calendar.min++;
  else if(keynum==2)
  calendar.min--;
  if(calendar.min》=60)
  calendar.min=0;
  else if(calendar.min《=0)
  calendar.min=59;
  POINT_COLOR=BLUE;
  LCD_ShowNum(84,162,calendar.min,2,16);
  RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
  RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
  RTC_ExitConfigMode(); //退出配置模式
  }
  else if(state==3)//设置时
  {
  if(keynum==3)
  calendar.hour++;
  else if(keynum==2)
  calendar.hour--;
  if(calendar.hour》=24)
  calendar.hour=0;
  else if(calendar.hour《=0)
  calendar.hour=23;
  POINT_COLOR=BLUE;
  LCD_ShowNum(60,162,calendar.hour,2,16);
  RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
  RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
  RTC_ExitConfigMode(); //退出配置模式
  }
  // else if(state==4)//设置周,我这里周不作为可设置开放所以注释掉了
  // {
  // if(keynum==3)
  // calendar.week++;
  // else if(keynum==2)
  // calendar.week--;
  // if(calendar.week》=7)
  // calendar.week=1;
  // else if(calendar.week《=1)
  // calendar.week=7;
  // POINT_COLOR=BLUE;
  // LCD_ShowNum(84,216,calendar.week,2,16);
  // RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
  // RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
  // RTC_ExitConfigMode(); //退出配置模式
  // }
  else if(state==4)//设置日
  {
  if(keynum==3)
  calendar.w_date++;
  else if(keynum==2)
  calendar.w_date--;
  if(calendar.w_date》=32)
  calendar.w_date=1;
  else if(calendar.w_date《=1)
  calendar.w_date=31;
  POINT_COLOR=BLUE;
  LCD_ShowNum(124,130,calendar.w_date,2,16);
  RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
  RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
  RTC_ExitConfigMode(); //退出配置模式
  }
  else if(state==5)//设置月
  {
  if(keynum==3)
  calendar.w_month++;
  else if(keynum==2)
  calendar.w_month--;
  if(calendar.w_month》12)
  calendar.w_month=1;
  else if(calendar.w_month《1)
  calendar.w_month=12;
  POINT_COLOR=BLUE;
  LCD_ShowNum(100,130,calendar.w_month,2,16);
  RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
  RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
  RTC_ExitConfigMode(); //退出配置模式
  }
  else if(state==6)//设置年,这里年只开放2000-2025年的设置
  {
  if(keynum==3)
  calendar.w_year++;
  else if(keynum==2)
  calendar.w_year--;
  if(calendar.w_year》2025)
  calendar.w_year=2000;
  else if(calendar.w_year《=2000)
  calendar.w_year=2025;
  POINT_COLOR=BLUE;
  LCD_ShowNum(60,130,calendar.w_year,4,16);
  RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
  RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
  RTC_ExitConfigMode(); //退出配置模式
  }
  else
  {
  break;//退出循环
  }
  }
  if(state==0)
  {
  LCD_Clear(WHITE);//清屏
  POINT_COLOR=BLUE;//字体变蓝
  LCD_ShowString(60,130,200,16,16,“ - - ”);
  LCD_ShowString(60,162,200,16,16,“ : : ”);
  break;
  }
  }
  }
  
举报

李泽睿

2021-11-22 14:32:35
3.闹钟设置程序代码
  void alarm_Set()//调闹铃函数
  {
  int Keynum,State=1;
  LCD_ShowString(16,180,200,16,16,“AlarmClock:”);
  LCD_ShowString(60,198,200,16,16,“ - - ”);
  LCD_ShowString(60,216,200,16,16,“ : : ”);
  LCD_ShowNum(60,216,alarmclock.hour,2,16);
  LCD_ShowNum(84,216,alarmclock.min,2,16);
  LCD_ShowNum(108,216,alarmclock.sec,2,16);
  LCD_ShowNum(60,198,alarmclock.w_year ,4,16);
  LCD_ShowNum(100,198,alarmclock.w_month,2,16);
  LCD_ShowNum(124,198,alarmclock.w_date,2,16);
  POINT_COLOR=RED;
  LCD_ShowNum(108,216,alarmclock.sec,2,16);
  while(1)
  {
  Keynum = KEY_Scan(0);
  if(Keynum==1)//设置
  {
  if(State》=6)
  State=0;
  else
  State++;
  switch(State)
  {
  case 0:
  case 1: POINT_COLOR=RED;LCD_ShowNum(108,216,alarmclock.sec,2,16);break;//秒
  case 2: POINT_COLOR=RED;LCD_ShowNum(84,216,alarmclock.min,2,16); break;//分
  case 3: POINT_COLOR=RED;LCD_ShowNum(60,216,alarmclock.hour,2,16); break;//时
  //case 4:
  case 4: POINT_COLOR=RED;LCD_ShowNum(124,198,alarmclock.w_date,2,16); break;//日
  case 5: POINT_COLOR=RED;LCD_ShowNum(100,198,alarmclock.w_month,2,16);break;//月
  case 6: POINT_COLOR=RED;LCD_ShowNum(60,198,alarmclock.w_year,4,16); break;//年
  default:break;
  }
  }
  else if(Keynum》1)
  {
  if(Keynum==4)
  {
  }
  if(State==1)//设置秒
  {
  if(Keynum==3)
  alarmclock.sec++;
  else if(Keynum==2)
  alarmclock.sec--;
  if(alarmclock.sec》=60)
  alarmclock.sec=0;
  else if(alarmclock.sec《0)
  alarmclock.sec=59;
  POINT_COLOR=BLUE;
  LCD_ShowNum(108,216,alarmclock.sec,2,16);
  RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
  }
  else if(State==2)//设置分
  {
  if(Keynum==3)
  alarmclock.min++;
  else if(Keynum==2)
  alarmclock.min--;
  if(alarmclock.min》=60)
  alarmclock.min=0;
  else if(alarmclock.min《=0)
  alarmclock.min=59;
  POINT_COLOR=BLUE;
  LCD_ShowNum(84,216,alarmclock.min,2,16);
  RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec ); //设置时间
  }
  else if(State==3)//设置时
  {
  if(Keynum==3)
  alarmclock.hour++;
  else if(Keynum==2)
  alarmclock.hour--;
  if(alarmclock.hour》=24)
  alarmclock.hour=0;
  else if(alarmclock.hour《=0)
  alarmclock.hour=23;
  POINT_COLOR=BLUE;
  LCD_ShowNum(60,216,alarmclock.hour,2,16);
  RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
  }
  // else if(state==4)//设置周
  // {
  // if(keynum==3)
  // calendar.week++;
  // else if(keynum==2)
  // calendar.week--;
  // if(calendar.week》=8)
  // calendar.week=1;
  // else if(calendar.week《=1)
  // calendar.hour=7;
  // POINT_COLOR=BLUE;
  // LCD_ShowNum(84,216,calendar.week,2,16);
  // RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
  // RTC_Set(calendar.w_year,calendar.w_month ,calendar.w_date ,calendar.hour ,calendar.min ,calendar.sec ); //设置时间
  // RTC_ExitConfigMode(); //退出配置模式
  // }
  else if(State==4)//设置日
  {
  if(Keynum==3)
  alarmclock.w_date++;
  else if(Keynum==2)
  alarmclock.w_date--;
  if(alarmclock.w_date》=32)
  alarmclock.w_date=1;
  else if(alarmclock.w_date《=1)
  alarmclock.w_date=31;
  POINT_COLOR=BLUE;
  LCD_ShowNum(124,198,alarmclock.w_date,2,16);
  RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
  }
  else if(State==5)//设置月
  {
  if(Keynum==3)
  alarmclock.w_month++;
  else if(Keynum==2)
  alarmclock.w_month--;
  if(calendar.w_month》=13)
  alarmclock.w_month=1;
  else if(calendar.w_month《1)
  alarmclock.w_month=12;
  POINT_COLOR=BLUE;
  LCD_ShowNum(100,198,alarmclock.w_month,2,16);
  RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
  }
  else if(State==6)//设置年
  {
  if(Keynum==3)
  alarmclock.w_year++;
  else if(Keynum==2)
  alarmclock.w_year--;
  if(alarmclock.w_year》2025)
  alarmclock.w_year=2000;
  else if(alarmclock.w_year《=2000)
  alarmclock.w_year=2025;
  POINT_COLOR=BLUE;
  LCD_ShowNum(60,198,alarmclock.w_year,4,16);
  RTC_Alarm_Set(alarmclock.w_year,alarmclock.w_month ,alarmclock.w_date ,alarmclock.hour ,alarmclock.min ,alarmclock.sec );
  }
  else
  {
  break;//退出循环
  }
  }
  if(State==0)
  {
  LCD_Clear(WHITE);//清屏
  POINT_COLOR=BLUE;//字体变蓝
  LCD_ShowString(60,130,200,16,16,“ - - ”);
  LCD_ShowString(60,162,200,16,16,“ : : ”);
  break;
  }
  }
  }
  总结
  以上就是今天分享的内容,本文仅仅简单介绍了STM32如何实现可调万年历的方法及主要程序的思想,由于时间的原因,日后再行完善哈哈哈。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分