找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2803|回复: 2
打印 上一主题 下一主题
收起左侧

通过矩阵键盘修改STM32F103的RTC时间

[复制链接]
跳转到指定楼层
楼主
ID:711830 发表于 2020-4-16 20:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
思路:我想通过矩阵键盘修改RTC时间,通过矩阵键盘输入一串字符串到数组里面,然后通过数组的值对RTC进行修改,但是数组里面有数据RTC却无法修改时间为什么?

  1. void set_time() //设置时间
  2. {
  3.         unsigned char n=0;
  4.         int m;
  5.         for(;;)
  6.         {
  7.                 OLED_Clear(0);
  8.                 OLED_Display_Flont(0+16*2,0,flont_shijian[0]);
  9.                 OLED_Display_Flont(0+16*3,0,flont_shijian[1]);
  10.                 OLED_Display_Flont(0+16*4,0,flont_shijian[2]);
  11.                 OLED_Display_Flont(0+16*5,0,flont_shijian[3]);
  12.                 OLED_Display_Flont(0+16*1,2,flont_shijian[4]);
  13.                 OLED_Display_Flont(0+16*2,2,flont_shijian[5]);
  14.                 OLED_Display_Flont(0+16*3,2,flont_shijian[6]);
  15.                 OLED_Display_Flont(0+16*4,2,flont_shijian[7]);
  16.                 OLED_Display_Flont(0+16*5,2,flont_shijian[8]);
  17.                 OLED_Display_Flont(0+16*6,2,flont_shijian[9]);
  18.                 for(;;)
  19.                 {
  20.                         key=Key_Scan();//检测按键
  21.                         if(key>=0&&key<=9)
  22.                         {
  23.                                                 sjxg_time[n]=key;
  24.                                                 printf("%d\n",sjxg_time[n]);
  25.                                                 OLED_DisplayString(0+8*n,48,16,&sjxg_time[n]);
  26.                                                 OLED_Refresh_GRAM();
  27.                                                 OLED_Clear_GRAM();
  28.                                                 n++;

  29.                         }
  30.                         if(key=='*')
  31.                         {
  32.                                  yuanshi();
  33.                                  break;
  34.                         }
  35.                         if(key=='#')
  36.                         {
  37.                                 rtc_time.year=(sjxg_time[0]-'0')*1000 +(sjxg_time[1]-'0')*100+(sjxg_time[2]-'0')*10+(sjxg_time[3]-'0');
  38.                                 rtc_time.mon=(sjxg_time[4]-'0')*10+(sjxg_time[5]-'0');
  39.                                 rtc_time.day=(sjxg_time[6]-'0')*10+(sjxg_time[6]-'0');
  40.                                 rtc_time.hour=(sjxg_time[8]-'0')*10+(sjxg_time[9]-'0');
  41.                                 rtc_time.min=(sjxg_time[10]-'0')*10+(sjxg_time[11]-'0');
  42.                                 rtc_time.sec=(sjxg_time[12]-'0')*10+(sjxg_time[13]-'0');
  43.                                 SET_RTC_TIME(rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
  44.                                 memset(sjxg_time,0,sizeof(sjxg_time));
  45.                                 break;
  46.                         }
  47.                 }
  48.                 break;
  49.         }
  50. }



  51. void RTC_IRQHandler(void)
  52. {
  53.         u32 time;
  54.         if(RTC->CRL & 1<<0)//秒中断标志
  55.         {
  56.                 time=RTC->CNTL;       //获取低位
  57.                 time|=RTC->CNTH<<16;  //获取高位
  58.                 GET_RTC_TIME(time);
  59. //                printf("%d-%d-%d %d:%d:%d\r\n",rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
  60.                 yuanshi();
  61.         }
  62.         if(RTC->CRL & 1<<1)//闹钟中断标志
  63.         {
  64.                 printf("闹钟到达\r\n");
  65.         }
  66.         RTC->CRL&=~(0X3<<0);//清除中断标志位
  67.         RTC_WaitForLastTask();                              
  68. }

  69. void yuanshi(void)
  70. {
  71.         char str[50];
  72.         sprintf(str,"%d-%d-%d %d:%d:%d",rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
  73.         OLED_DisplayString(0,48,16,(u8*)str);
  74.         OLED_Refresh_GRAM();
  75.                
  76.         OLED_Clear_GRAM();
  77.         OLED_Display_Flont(0+16*0,0,flont_chu1[0]); //您好
  78.         OLED_Display_Flont(0+16*1,0,flont_chu1[1]);
  79.                
  80.         OLED_Display_Flont(0+16*3,2,flont_chu2[0]); //请打卡!
  81.         OLED_Display_Flont(0+16*4,2,flont_chu2[1]);
  82.         OLED_Display_Flont(0+16*5,2,flont_chu2[2]);
  83.         OLED_Display_Flont(0+16*6,2,flont_chu2[3]);
  84. }
  85. //返回值  0代表平年  1代表闰年
  86. u8 GET_TIME_STATE(u32 year)
  87. {
  88.         if((year % 4 ==0 && year % 100!=0) || year %400 ==0 )return 1;
  89.         else return 0;
  90. }

  91. u8 mon_r[12]={31,29,31,30,31,30,31,31,30,31,30,31};
  92. u8 mon_p[12]={31,28,31,30,31,30,31,31,30,31,30,31};

  93. //年月日转秒
  94. void SET_RTC_TIME(u32 year ,u32 mon,u32 day,u32 hour,u32 min,u32 sec)
  95. {
  96.         u32 i;
  97.         u32 rtc_sec=0;
  98.         for(i=2020;i<year;i++)
  99.         {
  100.                 if(GET_TIME_STATE(i))
  101.                 {
  102.                         rtc_sec+=366*24*60*60;
  103.                 }
  104.                 else
  105.                 {
  106.                         rtc_sec+=365*24*60*60;
  107.                 }
  108.         }
  109.         for(i=0;i<mon-1;i++)
  110.         {
  111.                 if(GET_TIME_STATE(year))
  112.                 {
  113.                         rtc_sec+=mon_r[i]*24*60*60;
  114.                 }
  115.                 else
  116.                 {
  117.                         rtc_sec+=mon_p[i]*24*60*60;
  118.                 }
  119.         }
  120.         rtc_sec+=(day-1)*24*60*60;
  121.         rtc_sec+=hour*60*60;
  122.         rtc_sec+=min*60;
  123.         rtc_sec+=sec;
  124.         
  125.         RCC->APB1ENR|=1<<28;//电源接口时钟使能
  126.         RCC->APB1ENR|=1<<27;//备份域接口时钟使能
  127.         PWR->CR|=1<<8;//允许对备份域和RTC的写入
  128.         while(!(RTC->CRL& 1<<5)){}//等待RTC操作完成
  129.         RTC->CRL|=1<<4;//进入配置模式        
  130.         RTC->CNTH=rtc_sec>>16;
  131.         RTC->CNTL=rtc_sec&0xFFFF;//计数值清0
  132.         RTC->CRL&=~(1<<4);//退出配置模式        
  133.         while(!(RTC->CRL& 1<<5)){}//等待RTC操作完成
  134. }
  135. //秒转年月日
  136. void GET_RTC_TIME(u32 sec)
  137. {
  138.         u32 i=0;
  139.         rtc_time.year=2020;
  140.         rtc_time.mon=1;
  141.         rtc_time.day=1;
  142.         rtc_time.hour=0;
  143.         rtc_time.min=0;
  144.         rtc_time.sec=0;
  145.         
  146.         while(1)
  147.         {
  148.                 if(GET_TIME_STATE(rtc_time.year))
  149.                 {
  150.                         if(sec>=366*24*60*60)
  151.                         {
  152.                                 sec-=366*24*60*60;
  153.                                 rtc_time.year++;
  154.                         }
  155.                         else break;
  156.                 }
  157.                 else
  158.                 {
  159.                         if(sec>=365*24*60*60)
  160.                         {
  161.                                 sec-=365*24*60*60;
  162.                                 rtc_time.year++;
  163.                         }
  164.                         else break;
  165.                 }
  166.         }
  167.         for(i=0;i<12;i++)
  168.         {
  169.                 if(GET_TIME_STATE(rtc_time.year))
  170.                 {
  171.                         if(sec>=mon_r[i]*24*60*60)
  172.                         {
  173.                                 sec-=mon_r[i]*24*60*60;
  174.                                 rtc_time.mon++;
  175.                         }
  176.                         else break;
  177.                 }
  178.                 else
  179.                 {
  180.                         if(sec>=mon_p[i]*24*60*60)
  181.                         {
  182.                                 sec-=mon_p[i]*24*60*60;
  183.                                 rtc_time.mon++;
  184.                         }
  185.                         else break;
  186.                 }
  187.         }
  188.         while(1)
  189.         {
  190.                 if(sec>=24*60*60)
  191.                 {
  192.                         sec-=24*60*60;
  193.                         rtc_time.day++;
  194.                 }
  195.                 else break;
  196.         }
  197.         while(1)
  198.         {
  199.                 if(sec>=60*60)
  200.                 {
  201.                         sec-=60*60;
  202.                         rtc_time.hour++;
  203.                 }
  204.                 else break;
  205.         }
  206.         while(1)
  207.         {
  208.                 if(sec>=60)
  209.                 {
  210.                         sec-=60;
  211.                         rtc_time.min++;
  212.                 }
  213.                 else break;
  214.         }
  215.         rtc_time.sec=sec;
  216. }
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:729982 发表于 2020-4-16 23:12 | 只看该作者
你的代码没什么注释就看的很吃力,我觉得有可能是你中断处理的问题,进入中断服务函数后先关中断,然后才执行操作,不然有可能让中断重复触发导致具体操作没能达到预期(当然也可能不是这个问题),我只是给楼主一个可能的方向
回复

使用道具 举报

板凳
ID:711830 发表于 2020-4-17 10:13 | 只看该作者
我未曾来过 发表于 2020-4-16 23:12
你的代码没什么注释就看的很吃力,我觉得有可能是你中断处理的问题,进入中断服务函数后先关中断,然后才执 ...

我也在思考这个问题,因为我是通过OLED屏幕进行时间显示的,在RTC中断中一直刷新时间在屏幕上进行显示,但是我一按按键就出现一下时间修改界面(时间差不多5s左右),然后就又跳到时间中断里面一直刷新时间了,按键修改就没用,一直想不明白为什么
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表