dwaveme 发表于 2015-6-19 15:07:02

用arduino 做了一个万年历,没有借助时钟模块,纯代码实现,并且能修改时间。

本帖最后由 dwaveme 于 2015-6-19 15:09 编辑

由于培训原因,老师让我们做一个万年历,在网上找了很多,也没有找到相同的案例,就算有,也是没有办法使用按键进行修改的,因此,进行了参考,改进,由于是第一次做这样的大型项目,这两天学习到了很多。比我以前接触arduino 学习到的都要对,头炸了n次,写到写不出来真的哭的心都有了,功夫不负有心人,希望以后有人遇到类似问题的人能有个参考。目前存在问题,星期天是从 0-6,可以用 switch 就行选择输出,自己没改,大家有兴趣再去改吧。








#include<Arduino.h>
#include <LiquidCrystal.h>
#include <FlexiTimer2.h>

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

/*定义日期变量*/
int second0,second1;
int minute0,minute1;
int hour0,hour1;   
int day0,day1;
int month0,month1;
int year0,year1,year2,year3;
int date;
int small_mon,leap_year;
int counter,cycle;

int i;

/*定义按键*/
int Button1 = 6;
int Button2 = 5;
int Button3 = 4;
int Button4 = 3;

int ButtonState_1 = digitalRead(Button1);
int ButtonState_2 = digitalRead(Button2);
int ButtonState_3 = digitalRead(Button3);
int ButtonState_4 = digitalRead(Button4);


/*定义光标位置*/

int x, y;

void print();
void BT1();
void BT2();
void BT3();
void BT4();

void clock(); //时钟函数
void Dater(); //日期函数
void state(); //检查日期状态函数(即判断是否闰年,是否小月的函数)


void setup()
{


lcd.begin(16, 2);

/*设置上拉电平*/
pinMode(Button1, INPUT_PULLUP);
pinMode(Button2, INPUT_PULLUP);
pinMode(Button3, INPUT_PULLUP);
pinMode(Button4, INPUT_PULLUP);

lcd.blink();

FlexiTimer2::set(1000, 1.0 / 1000, clock); // 产生秒频率
FlexiTimer2::start();

/*时间初始化*/
Time_init();
Date_init();

}

void loop()
{
print();
BT1();
lcd.setCursor(x, y);
}



/*显示输出*/
void print()
{

lcd.setCursor(0, 0);
lcd.print(year3);
lcd.print(year2);
lcd.print(year1);
lcd.print(year0);
lcd.print(":");
lcd.print(month1);
lcd.print(month0);
lcd.print(":");
lcd.print(day1);
lcd.print(day0);
lcd.print(" ");
lcd.print(date);

lcd.setCursor(0, 1);
lcd.print(hour1);
lcd.print(hour0);
lcd.print(":");
lcd.print(minute1);
lcd.print(minute0);
lcd.print(":");
lcd.print(second1);
lcd.print(second0);

lcd.setCursor(x, y);

}

void clock() //时钟函数
{
second0++;
if (second0 > 9)
{
    second0 = 0;
    second1++;
    if (second1 > 5)
    {
      second1 = 0;
      minute0++;
      if (minute0 > 9)
      {
      minute0 = 0;
      minute1++;
      if (minute1 > 5)
      {
          minute1 = 0;
          hour0++;
          if (hour0 == 4 && hour1 == 2)
          {
            hour0 = hour1 = 0;
            Dater();
          }
          else if (hour0 > 9)
          {
            hour0 = 0;
            hour1++;
          }
      }
      }
    }
}
}


void Dater() //日期函数
{
state();      
day0++;
date=(date+1)%7;

switch(day0)
{
case 10:
    {
      if(day1 == 2 && month0 == 2 && month1 == 0) //闰年时,把2月30号转变为3月1号
      {
      day0 = 1;
      day1 = 0;
      month0++;
      }
      else//日期各位满10进1
      {
      day0 = 0;
      day1++;
      }
    }
    break;
case 1:
    {
      if(day1 == 3 && small_mon) //小月31号时把日期置为1号,月份+1
      {
      day0 = 1;
      day1 = 0;
      month0++;
      }
    }
    break;
case 2:
    {
      if(day1 == 3)
      {
      day0 = 1;
      day1 = 0;
      month0++;
      }
    }
    break;
case 9:
    {
      if(day1 == 2 && !leap_year && month0 == 2 && month1 == 0)//平年时,把2月29号变为3月1号
      {
      day0 = 1;
      day1 = 0;
      month0++;
      }
    }
    break;
default:
    break;
}
switch(month0)
{
case 10:
    {
      month0 = 0;
      month1++;
    }
    break;
case 3:
    {
      if(month1 == 1)
      {
      month0 = 1;
      month1 = 0;
      year0++;
      }
    }
    break;
}
if(year0 > 9)
{
    year0 = 0;
    year1++;
    if(year1 > 9)
    {
      year1 = 0;
      year2++;
      if(year2 > 9)
      {
      year2 = 0;
      year3++;
      if(year3 > 9)
          year3 = 0;
      }
    }
}
}




void state() //检查日期状态函数(即判断是否闰年,是否小月的函数)
{
switch(month0)
{
case 1:
    if(month1 == 1) //若是11月,则是小月
      small_mon = 1;
    else //若是1月,则不是小月
    small_mon = 0;
    break;
case 4:
case 6:
case 9:
    small_mon = 1;
    break;
default:
    small_mon = 0;
    break;
}
if((year3 * 1000 + year2 * 100 + year1 * 10 + year0) % 100 == 0)
{
    if((year3 * 1000 + year2 * 100 + year1 * 10 + year0) % 400 == 0)
      leap_year = 1;
}
else if((year3 * 1000 + year2 * 100 + year1 * 10 + year0) % 4 == 0)
    leap_year = 1;
else
    leap_year = 0;
}



void Date_init() //日期初始化
{
date = 3;
day0 = 7;
day1 = 1;
month0 = 6;
month1 = 0;
year0 = 5;
year1 = 1;
year2 = 0;
year3 = 2;
}

void Time_init() //时间初始化
{
second0 = 0;
second1 = 3;
minute0 = 0;
minute1 = 3;
hour0 = 2;
hour1 = 1;
counter = 0;
}


/*按键功能设置函数*/
/*设置按键1功能*/
/*光标移动*/
void BT1()
{
delay(50);
int ButtonState_1 = digitalRead(Button1);
if(ButtonState_1==0)
{
    delay(50);
    if(ButtonState_1==0)               //延时消抖处理
    {
      lcd.blink();
      BT2();
      BT3();
      BT4();
    }
}
else
{
    lcd.noBlink();       // 否则说明按键没有按,熄灭LED
}
}

/*设置按键2功能*/
void BT2()
{
delay(100);
int ButtonState2 = digitalRead(Button2);
if(ButtonState2==0)
{
    delay(50);
    if(ButtonState2==0)               //延时消抖处理
    {
      x++;
      if (x>11)
      {
      x=0;
      y++;
      if(y>1)
      {
          y=0;
      }
      }
    }
}
else
{
    lcd.clear();       // 否则说明按键没有按
}
}



/*设置按键3功能*/
void BT3()
{
int ButtonState3 = digitalRead(Button3);
if (ButtonState3 == 0)
{
    delay(10);
    if (ButtonState3 == 0)            //延时消抖处理
    {
      switch (y)
      {
      case 0://对第一行进行修改
      switch(x)
      {
      case 11:
          date = (date + 1) % 7;
          break;

      case 9:
          day0++;
          if (day0 == 2 && day1 == 3)
          {
            day0 = 1;
            day1 = 0;
          }
          if (day0 == 10)
          {
            day0 = 0;
            day1++;
          }
          break;
      case 6:
          month0++;
          if (month0 == 3 && month1 == 1)
          {
            month0 = 1;
            month1 = 0;
          }
          if (month0 == 10)
          {
            month0 = 0;
            month1 = 1;
          }
          break;

      case 3:
          year0++;
          if (year0 > 9)
          {
            year0 = 0;
            year1++;
            if (year1 > 9)
            {
            year1 = 0;
            year2++;
            if (year2 > 9)
            {
                year2 = 0;
                year3++;
                if (year3 > 9)
                  year3 = 0;
            }
            }
          }
          break;
      case 2:
          year1++;
          if (year1 > 9)
          {
            year1 = 0;
            year2++;
            if (year2 > 9)
            {
            year2 = 0;
            year3++;
            if (year3 > 9)
                year3 = 0;
            }
          }
          break;
      case 1:
          year2++;
          if (year2 > 9)
          {
            year2 = 0;
            year3++;
            if (year3 > 9)
            year3 = 0;
          }
          break ;
      case 0:
          year3++;
          if (year3 > 9)
            year3 = 0;
          break ;
      }

      case 1:
      switch (x)//对第二行更改
      {
      case 7:
          second0++;
          if (second0 > 9)
          {
            second0 = 0;
            second1++;
            if (second1 == 6)
            second1 = 0;
            break;

          case 4:
            minute0++;
            if (minute0 > 9)
            {
            minute0 = 0;
            minute1++;
            if (minute1 == 6)
                minute1 = 0;
            }
            break;

          case 1:
            hour0++;
            if (hour1 == 2 && hour0 > 3)
            {
            hour0 = 0;
            hour1 = 0;
            }
            else if (hour0 > 9)
            {
            hour0 = 0;
            hour1++;
            }
          }
          break;
      }
      }
    }
}
}


/*设置按键4功能*/
void BT4()
{
int ButtonState4 = digitalRead(Button4);
if (ButtonState4 == LOW)
{
    delay(100);
    if (ButtonState4 == LOW)            //延时消抖处理
    {
      switch (y)
      {
      case 0://对第一行进行修改
      switch(x)
      {
      case 11:
          date = (date + 1) % 7;
          break;

      case 9:
          if (day0 == 1 && day1 == 0)
            day1 = 3;
          if (day0 == 0)
          {
            day0 = 9;
            day1--;
          }
          else
            day0--;
          break;
          break;
      case 6:
          if (month0 == 1 && month1 == 0)
          {
            month0 = 2;
            month1 = 1;
          }
          else if (month0 == 0)
          {
            month0 = 9;
            month1--;
          }
          else
            month0--;
          break;

      case 3:
          if (year0 == 0)
          {
            year0 = 9;
            if (year1 == 0)
            {
            year1 = 9;
            if (year2 == 0)
            {
                year2 = 9;
                if (year3 == 0)
                  year3 = 9;
                else
                  year3--;
            }
            else
                year2--;
            }
            else
            year1--;
          }
          else
            year0--;
          break;

      case 2:
          if (year1 == 0)
          {
            year1 = 9;
            if (year2 == 0)
            {
            year2 = 9;
            if (year3 == 0)
                year3 = 9;
            else
                year3--;
            }
            else
            year2--;
          }
          else
            year1--;
          break;

      case 1:
          if (year2 == 0)
          {
            year2 = 9;
            if (year3 == 0)
            year3 = 9;
            else
            year3--;
          }
          else
            year2--;
          break ;

      case 0:
          if (year3 == 0)
            year3 = 9;
          else
            year3--;
          break ;
      }

      case 1:
      switch (x)//对第二行更改
      {
      case 7:
          if (second0 == 0)
          {
            second0 = 9;
            if (second1 == 0)
            second1 = 5;
            else
            second1--;
          }
          else
            second0--;

          break;

      case 4:
          if (minute0 == 0)
          {
            minute0 = 9;
            if (minute1 == 0)
            minute1 = 5;
            else
            minute1--;
          }
          else
            minute0--;
          break;

      case 1:
          if (hour0 == 0)
          {
            if (hour1 == 0)
            {
            hour0 = 3;
            hour1 = 2;
            }
            else
            {
            hour0 = 9;
            hour1--;
            }
          }
          else
            hour0--;
          break;
      }
      }
    }
}
}

yuqingshan 发表于 2015-6-20 08:03:10

很好学习材料!能加入时间模块如DS3231,DS1302这类和GPS模块校时,这样就完美了!什么时候LZ上个完美万年历时钟。

dwaveme 发表于 2015-6-20 11:14:02

yuqingshan 发表于 2015-6-20 08:03 static/image/common/back.gif
很好学习材料!能加入时间模块如DS3231,DS1302这类和GPS模块校时,这样就完美了!什么时候LZ上个完美万年历 ...

暂时还用不到,开始折腾举证键盘了,然后就开始 pid,日程比较紧了:lol

asdfcgdc 发表于 2015-7-19 10:43:09

没有线路图么

dwaveme 发表于 2015-7-20 09:18:35

asdfcgdc 发表于 2015-7-19 10:43 static/image/common/back.gif
没有线路图么

嗯,不会画,见谅:P, 从程序里能知道电路怎么连的

asdfcgdc 发表于 2015-7-20 16:42:05

去学学怎么用fritzing吧,会了就方便多了

dwaveme 发表于 2015-7-20 16:48:03

asdfcgdc 发表于 2015-7-20 16:42 static/image/common/back.gif
去学学怎么用fritzing吧,会了就方便多了

恩恩,去看看,多谢指教:handshake

asdfcgdc 发表于 2015-7-20 16:49:41

没事{:soso_e113:}
页: [1]
查看完整版本: 用arduino 做了一个万年历,没有借助时钟模块,纯代码实现,并且能修改时间。