这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【Mini-F5375-OB】移植万年历系统

共1条 1/1 1 跳转至

【Mini-F5375-OB】移植万年历系统

助工
2025-02-01 13:44:38     打赏

【前言】

最近看到了一个波特律动大佬的一个万年历教学视频,这次跟着他的视频,把万年历系统移植到Mini-F5375-OB开发板上来。

工程的基础是在前面几期的帖子基础之上添加的:

1、【Mini-F5375-OB】移植按键驱动

2、【Mini-F5375-OB】驱动编码器

3、【Mini-F5375-OB】来个小OLED时钟

4、【Mini-F5375-OB】移植FreeRTOS

5、【Mini-F5375-OB】配置时钟

在这几篇文章的基础之上,我创建了3个任务,分别为key、RTC、编码器,综合起来就搭建了一个可以跑时,可以设置日历的综合DEMO。

【程序设计思路】

创建3个FreeRTOS的任务,

1、Time_task,他实现日期的展示。

2、Encoder_Task,他实现对编码器的管理,通过正、反转,来实现对日历的增加减少,来设置日历。

3、key_task,他对编码器的按键进行管理,来实现进入设置(退出)模式,以及设置项目的切换。

【程序代码】

1、显示日期函数:

void showTime(RTC_CalendarTypeDef * my_Calendar)
{
    uint8_t x_week;
    OLED_Printf(20,0,OLED_8X16,"%d-%02d-%02d", my_Calendar->year, my_Calendar->month, my_Calendar->day);         
    OLED_Printf(12,20,OLED_12X24,"%02d:%02d:%02d", my_Calendar->hour,my_Calendar->minute,my_Calendar->second);
    x_week = (128 - strlen(weeks[my_Calendar->week]) * 8)/2;  //计算显示星期的位置
    OLED_Printf(x_week,48,OLED_8X16,"%s", weeks[my_Calendar->week]);
       
}

传入参数为RTC的日期结构体函数,通过OLED_Printf来实现格式化输出到OLED屏上。

2、光标显示函数:

typedef struct {
    uint8_t x1;
    uint8_t y1;
    uint8_t x2;
    uint8_t y2;
} CursorPosition;

CursorPosition cursorPosition[6] = {
    {20, 17, 50, 17},   //Year
    {60, 17, 76, 17}, //Month
    {84, 17, 100, 17}, //Day
    {14, 45, 36, 45}, //Hour
    {48, 45, 74, 45}, //Minute
    {86, 45, 104, 45}, //Second
    };
void showCursor(void)
{
    static uint8_t showstate = 0;
    showstate = (showstate+1)%2;
    if(showstate == 0)
    {         
        OLED_DrawLine(cursorPosition[settingState].x1, cursorPosition[settingState].y1, cursorPosition[settingState].x2, cursorPosition[settingState].y2);
    }
}

通过按键的切换,在showCursor函数中,可以动态的在相应的year、month等下标中显示光标。

3、按键切换回调函数:

void Btn1_Dowm_CallBack(void *btn)
{
  PRINT_INFO("Button1 单击!");
  if(calendarState == CalendarState_Normal)
  {
    settingState = Year;
    memcpy(&settingTime, &RTC_Calendar, sizeof(RTC_Calendar));
    calendarState = CalendarState_Setting;
  }
  else 
  {
    if(settingState == Second)
    {
      calendarState = CalendarState_Normal;
      RTC_SetDateTime(settingTime.year, settingTime.month,settingTime.day, settingTime.hour, settingTime.minute, settingTime.second);
    }
    else{
      settingState ++;
    }
    
  }
}

在移植好按键驱动后,按键的单击回调函数中,先判断是在什么状态,可以通过普通(CalendarState_Normal)、设置模式(CalendareSate_Settings)之间切换。

4、编码器向前向后的方向,可以实现在设置模式下面的对月日年,时分秒的参数的调定。

void onKnobForward(void)
{
  printf("Forward\r\n");
  if(calendarState == CalendarState_Setting)
  {
    switch (settingState)
    {
    case Year:
        settingTime.year++;
        break;
    
    case Month:
      settingTime.month++;
      if(settingTime.month > 12)
      {
        settingTime.month = 1;
      }
      
     break;
    case Day:
      settingTime.day++;
      if(settingTime.day > 31)
      {
        settingTime.day = 1;
      }
      if (settingTime.month == 2)
        {
          if(settingTime.year % 4 == 0)
          {
            if(settingTime.day > 29)
            {
              settingTime.day = 1;
            }
          }
          else
          {
            if(settingTime.day > 28)
            {
              settingTime.day = 1;
            }
          }
        }
      else if (settingTime.month == 4 || settingTime.month == 6 || settingTime.month == 9 || settingTime.month == 11) {
          if(settingTime.day > 30)
          {
            settingTime.day = 1;
          }
      }
      break;
    case Hour:
      settingTime.hour++;
      if(settingTime.hour > 23)
      {
        settingTime.hour = 0;
      }
      break;
    case Minute:
      settingTime.minute++;
      if(settingTime.minute > 59)
      {
        settingTime.minute = 0;
      }
      break;
    case Second:
      settingTime.second++;
      if(settingTime.second > 59)
      {
        settingTime.second = 0;
      }
      break;
    default:
      break;
    }
  }
}

void onKnobBackward(void)
{
  printf("Backward\r\n");
  if(calendarState == CalendarState_Setting)
  {
    switch (settingState) {
      case Year:
        settingTime.year--;
        if(settingTime.year < 2000)
        {
          settingTime.year = 2000;
        }
        break;
      case Month:
        settingTime.month--;
        if(settingTime.month < 1)
        {
          settingTime.month = 12;
        }
        break;
      case Day:
        settingTime.day--;
        if(settingTime.day < 1)
        {
          settingTime.day = 31;
        }
        if(settingTime.month == 2)
        {
          if(settingTime.year % 4 == 0)
          {
            if(settingTime.day < 1)
            {
              settingTime.day = 29;
            }
          }
          else
          {
            if(settingTime.day < 1)
            {
              settingTime.day = 28;
            }
          }
        }else if (settingTime.month == 4 || settingTime.month == 6 || settingTime.month == 9 || settingTime.month == 11)
        {
          if(settingTime.day < 1)
          {
            settingTime.day = 30;
          }
        }
        break;
      case Hour:
        settingTime.hour --;
        if(settingTime.hour < 0)
        {
          settingTime.hour = 23;
        }
        break;
      case Minute:
      settingTime.minute--;
        if(settingTime.minute < 0)
        {
          settingTime.minute = 59;
        }
        break;
      case Second:
        settingTime.second--;
        if(settingTime.second < 0)
        {
          settingTime.second = 59;
        }
        break;
      default:
        break;
    }

  }
}

【程序源码】

视频介绍

" target="_self" title="视频介绍"视频介绍

链接:https://www.bilibili.com/video/BV1BEcFe9EX8/?vd_source=e1bd226340c8b87027d5dcfc6b0c3344





关键词: Mini-F5375-OB     灵动MM32     RTC         

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]