如何用msp430f449设计实时时钟,只要代码就行

2019-03-24 15:05发布

谢谢各位大虾的帮忙啊,小弟不胜感激 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2条回答
hansonhe
2019-03-25 02:05
< :TI_MSP430_内容页_SA7 -->

//             |  MSP430F449   |
//     VOUT <--|P3             |
//   为1位选<--|P4.0           |
//   为1段选<--|P4.1           |
//功能选择键-->|P1.1           |
//     加1键-->|P1.2           |
//     减1键-->|P1.3           |
//
//工作环境:IAR for MSP430 4.21

//显示方式:数码管动态扫描,共阴极数码管接有两个寄存器,故加P4.0、P4.1后可实现显示功能
//实现功能:通过六位数码管显示时间,正常情况下显示日时分;按功能键1次,显示年月日
//          按下2次后时钟停止计数,开始调整年,按下3次调整月,按下4次调整日
//          按下5次调整时,按下6次调整分,按下7次退出至正常状态,依次循环
//          被调整位闪烁显示,其它正常显示;
//          调整状态时,可按加1键和减1减对时间进行调整;
//          MCU自动判断平闰年,校准当月最大天数;
//计时方法:TA中断,TACCR0=32767,1s一次中断秒加1,RTC进行时间处理
//按    键:采用查询方式,外接上拉电阻(以后可以尝试中断方式)
#include "msp430x44x.h"
//******定义子程序******
void Init_Sys(void);            //初始化子程序
void LEAP(void);               //判断闰年子程序
void MAX(void);                //天数判断子程序
void DISPLY(void);             //显示子程序
void RTC(void);                //实时时钟程序
void DIS_BIT(void);            //送显缓子程序
void DLY_5ms(void);            //延时子程序
unsigned char KEY_SET(void);   //返回按键标志0,1,2,3
void DISPLY_Normal(void);
void DISPLY_SETmin(void);
void DISPLY_SEThour(void);
void DISPLY_SETday(void);
void DISPLY_SETmonth(void);
void DISPLY_SETyear(void);
//*****定义变量********
unsigned char max;         //当月最大的天数
unsigned char sec=0;
unsigned char min=35;
unsigned char hour=13;
unsigned char day=10;
unsigned char month=2;
unsigned int year=2011;
unsigned char leap;      //闰年标志,1为闰年,0为平年
unsigned char fct=0;      //功能标志,0显示时钟,1显示年月,2~6分别调整分、时、日、月、年
unsigned char led_bit[6];     //led显示缓存
unsigned char key_flag;               //按键是否按下标志,0为按下,1没有按下
unsigned int dis_num;                //显示循环次数
// LED显示代码LED
const unsigned char LED_TAB[]=
{  
    0xd7,0x14,0xcd,0x5d,0x1e,           //0,1,2,3,4,
    0x5b,0xdb,0x15,0xdf,0x5f,0X00       //5,6,7,8,9,灭标志符
};
//******主程序**********
void main( void )
{
  Init_Sys();
  _EINT();
  while(1)
  {
    RTC();             //时钟处理程序
    KEY_SET();        //返回key_flag,0没有按下,1功能键,2加1键,3减1键
    if(key_flag==1)
    {
     fct++;
     if (fct>=7)fct=0;
    }
     DIS_BIT();                       //将需要显示的字符送入显示缓存dis_bit[]
    switch(fct)             
    {
    case 0:DISPLY_Normal();break;     //正常显示日时分
    case 1:DISPLY_Normal();break;     //正常显示年月
    case 2:DISPLY_SETyear();break;     //
    case 3:DISPLY_SETmonth();break;    //
    case 4:DISPLY_SETday();break;      //
    case 5:DISPLY_SEThour();break;     //
    case 6:DISPLY_SETmin();break;     //闪烁显示分,若key_flag=2,分加1,若=3,分减1
    default:
      {
        fct=0;
        TACTL|=TAIE;                //退出时间调整状态,开启TA中断
        break;
      }
    }
   
  }
}
//======================
//****定时器中断****
//**********************
#pragma vector=TIMERA1_VECTOR
__interrupt void TimerA1(void)
{
  TACTL&=~TAIFG;
  sec++;
  P1OUT^=BIT0;
}
//=====================
//***实时时钟子程序****
//*********************
void RTC(void)                                        
{
  if(sec>=60)
  {
    min++;
    sec-=60;
    if(min>=60)
    {
      hour++;
      min=0;
    if(hour>=24)
    {
      day++;
      hour=0;
      MAX();
      if(day>=max+1)
      {
        month++;
        day=1;
        if(month>=13)
        {
          year++;
          month=1;
        }
      } 
     }
    }
  }
}
//=====================
//***闰年判断子程序****
//***闰年leap=1,平年leap=0
//*********************
void LEAP(void)
{
  if(year%4==0)
  {
    if(year%100==0)
    {
      if(year%400==0)
        leap=1;
      else
        leap=0;
    }
    else
      leap=1;
  }
  else
    leap=0;   
}
//========================
//*****天数判断子程序*****
//**功能:判断当月天数max**
//************************
void MAX(void)
{
  LEAP();
  if((month==4)||(month==6)||(month==9)||(month==11))
     max=30;
  else if((month==2))
  {
    if(leap==1)
      max=29;
    else
      max=28;
  }
  else
    max=31;
}
//=====================
//****送显示位子程序***
//*********************
void DIS_BIT(void)
{
  if ((fct==0)||(fct==4)||(fct==5)||(fct==6))
  {
    led_bit[0]=min%10;
    led_bit[1]=min/10;
    led_bit[2]=hour%10;
    led_bit[3]=hour/10;
    led_bit[4]=day%10;
    led_bit[5]=day/10;
  }
  else
  {
    led_bit[0]=month%10;
    led_bit[1]=month/10;
    led_bit[2]=year%10;
    led_bit[3]=(year%100)/10;
    led_bit[4]=(year%1000)/100;
    led_bit[5]=year/1000;    
  }
}
//=====================
/******显示子程序*******/
/*********************/
void DISPLY(void)
{
  unsigned char idis=0;
  unsigned int wei=0x20;          //0010 0000
  while(idis<=5)
  {
    P3OUT=LED_TAB[led_bit[idis]];  
    P4OUT|=BIT1;                  //开启寄存器送显示字符码
    P4OUT&=~BIT1;                 //禁止段选寄存器输入
    P3OUT =~wei;                 //1101 1111 共阴极数码管
    P4OUT|=BIT0;                //开启寄存器送位选
    P4OUT&=~BIT0;                //禁止位选寄存器输入
    wei>>=1;                      //位选左移1位
    DLY_5ms();
    /////消鬼影//////
    P3OUT =0xff;
    P4OUT|=BIT0;                //开启寄存器送位选
    P4OUT&=~BIT0;                //禁止位选寄存器输入
    idis++; 
  }
}
//////1310*4/(32*32768)*1000约为5ms////////
//for语句,判断为3个机周,减1为2个机周///
void DLY_5ms(void)
{
  unsigned int idly1;
  for(idly1=1000;idly1>=1;idly1--);
}
//////////////////
unsigned char KEY_SET(void)
////按下功能键,key_flag=1退出,按下加1键,key_flag=2退出,
//按下减1键,key_flag=3退出,没有按下,则key_flag=0
////////////
{
  if((P1IN&BIT1)==0)       //扫描P1.1功能键是否按下,按下为0
  {
    //DLY_5ms();          //延时消斗
    if((P1IN&BIT1)==0)
      key_flag=1;
  }
  else if((P1IN&BIT2)==0)  //扫描P1.2加1键是否按下,按下为0
  {
   // DLY_5ms();          //延时消斗
    if((P1IN&BIT2)==0)
       key_flag=2;
  } 
   else if((P1IN&BIT3)==0)  //扫描P1.3减1键是否按下,按下为0
  {
    //DLY_5ms();          //延时消斗
    if((P1IN&BIT3)==0)
       key_flag=3;
  }
  else key_flag=0;
  return key_flag;
}
//////////初始化/////////////
void Init_Sys(void)
{
  WDTCTL = WDTPW + WDTHOLD;             //关闭看门狗
  FLL_CTL0|=XCAP14PF;
  TACTL=MC_1+TASSEL_1+TAIE+TACLR;      //Up模式,计数器中断使能,ACLK=32k
  TACCR0=32767;                        //定时1s
  P3OUT=LED_TAB[10];
  P3DIR=0Xff;                          //IO口初始化
  P4DIR|=BIT0+BIT1;
  P1DIR&=(~BIT1)+(~BIT2)+(~BIT3);       //P1.1功能键,P1.2加1键,P1.3减1键
  P1DIR|=BIT0;
  LEAP();
  MAX();
}
////////////各种状态下的显示子程序////////////////////
void DISPLY_Normal(void)
{
  TACTL|=TAIE;
  P5DIR|=BIT1;
  dis_num=0;
  while(dis_num<=50)
  {
    DISPLY();
    dis_num++;
  }
  ////////////////
  P5OUT^=BIT1;   //测试频率
  /////////////////////
}
///////分设置子程序/////////
//////闪烁间隔时间:5*6*16约为500ms/////////
//此处用30*20=600ms,及1.2s扫描一次按键////
void DISPLY_SETmin(void)
{
  KEY_SET();           
  if(key_flag==2)
  {
    min++;
    if(min==60)min=0;
  }
  else if(key_flag==3)
  {
    if(min==0)min=59;
    else min--;
  }
  led_bit[0]=min%10;
  led_bit[1]=min/10;
  for(dis_num=0;dis_num<=20;dis_num++)
  {
    DISPLY();
   }
  led_bit[0]=10;
  led_bit[1]=10;
  for(dis_num=0;dis_num<=20;dis_num++)
    {
     DISPLY();
    }
}
/////////////////////////////
void DISPLY_SEThour(void)
{
  KEY_SET();           
  if(key_flag==2)
  {
    hour++;
    if(hour>=24)hour=0;
  }
  else if(key_flag==3)
  {
    if(hour==0)hour=23;
    else hour--;
  }
  led_bit[2]=hour%10;
  led_bit[3]=hour/10;
  for(dis_num=0;dis_num<=20;dis_num++)
  {
    DISPLY();
   }
  led_bit[2]=10;
  led_bit[3]=10;
  for(dis_num=0;dis_num<=20;dis_num++)
    {
     DISPLY();
    }
}
//////////////////////////////
void DISPLY_SETday(void)
{
  MAX();
  KEY_SET();           
  if(key_flag==2)
  {
    day++;
    if(day>max)day=1;
  }
  else if(key_flag==3)
  {
    if(day==1)day=max;
    else day--;
  }
  led_bit[4]=day%10;
  led_bit[5]=day/10;
  for(dis_num=0;dis_num<=20;dis_num++)
  {
    DISPLY();
   }
  led_bit[4]=10;
  led_bit[5]=10;
  for(dis_num=0;dis_num<=20;dis_num++)
    {
     DISPLY();
    }
}
/////////////////////////////
void DISPLY_SETmonth(void)
{
  KEY_SET();           
  if(key_flag==2)
  {
    month++;
    if(month>12)min=1;
  }
  else if(key_flag==3)
  {
    if(month==1)month=12;
    else month--;
  }
  led_bit[0]=month%10;
  led_bit[1]=month/10;
  for(dis_num=0;dis_num<=20;dis_num++)
  {
    DISPLY();
   }
  led_bit[0]=10;
  led_bit[1]=10;
  for(dis_num=0;dis_num<=20;dis_num++)
    {
     DISPLY();
    }
}
////////////////////////////
void DISPLY_SETyear(void)
{
  TACTL&=(~TAIE);       //进入时间调整状态,关闭TA中断
  KEY_SET();           
  if(key_flag==2)
  {
    year++;
  }
  else if(key_flag==3)
  {
    year--;
  }
   led_bit[2]=year%10;
   led_bit[3]=(year%100)/10;
   led_bit[4]=(year%1000)/100;
   led_bit[5]=year/1000;
  for(dis_num=0;dis_num<=20;dis_num++)
  {
    DISPLY();
   }
  led_bit[2]=10;
  led_bit[3]=10;
  led_bit[4]=10;
  led_bit[5]=10;
  for(dis_num=0;dis_num<=20;dis_num++)
    {
     DISPLY();
    }
}
          
          

一周热门 更多>

相关问题

    相关文章