基于MSP430的简易时钟程序

2019-07-25 14:42发布

#include<msp430x14x.h>
#include "Config.h"

uchar key_num=0;
uchar flag=0;
uchar sec=0,mit=0,hor=0,key;
void Port_init()         //I/O口初始化
{
  P4SEL=0x00;
  P4DIR=0xff;
  P5SEL=0x00;
  P5DIR|=BIT5+BIT6+BIT7;
}
void LCD_COM(uchar a)      //写命令
{
  RS_CLR;
  RW_CLR;
  EN_SET;
  delay_us(50);
  DataPort=a;
  delay_us(50);
  EN_CLR;
  delay_us(50);
}
void LCD_Write(uchar b)    //写数据
{
  RS_SET;
  RW_CLR;
  EN_SET;
  delay_us(50);
  DataPort=b;
  delay_us(50);
  EN_CLR;
  delay_us(50);
}
void LCD_init()        //LCD1602初始化
{
  RW_CLR;
  EN_CLR;
  LCD_COM(0x01);  //清指令
  LCD_COM(0x38);  //模式设置
  LCD_COM(0x0c);  //开显示,不显示光标,光标不闪烁
  LCD_COM(0x06);  //光标加一,整屏不移动
}
  
void LCD_string(uchar x,uchar y,uchar *s)    //字符串输入函数   x:列 y:行
{
  if(y==0)
    LCD_COM(0x80+x);
  else
    LCD_COM(0xc0+x);
  while(*s)
  {
    LCD_Write(*s);
    s++;
  }
}
void time_go(uchar x,uchar y)        //时间改变子函数
{
  uchar a,b;
  a=y/10;
  b=y%10;
  LCD_COM(0xc0+x);
  LCD_Write(0x30+a);
  LCD_Write(0x30+b);
}

uchar keyscan(void)                     //按键扫描子函数
{
//  uchar key_check;
  uchar key_checkin;
  key_checkin=KeyPort;           //读取IO口状态,判断是否有键按下
  key_checkin&= 0x0F;            //读取IO口状态,判断是否有键按下
  if(key_checkin!=0x0F)             //IO口值发生变化则表示有键按下
    {
      delay_us(50);                  
      key_checkin=KeyPort;
      if(key_checkin!=0x1F)
        {  
//          key_check=KeyPort&0x0f;
          while((KeyPort&0x0f)!=0x0f);     //等待按键松开
         
            switch (key_checkin & 0x0F)
            {
              case 0x0E:key=1;break;
              case 0x0D:key=2;break;
              case 0x0B:key=3;break;
              case 0x07:key=4;break;
            }
         
         
        }
      
   }
  else
   {
     key=0xFF;        
   }
  return key;
}
void time_cor()       //按键调整时间子函数
{
  if(key==1)
  {
    _DINT();          //关中断
    key_num++;
    if(key_num==1)
    {
      LCD_COM(0xc0+11);
      LCD_COM(0x0F);
    }
    if(key_num==2)
    {
      LCD_COM(0xc0+8);
    }
    if(key_num==3)
    {
      LCD_COM(0xc0+5);
    }
    if(key_num==4)
    {
      key_num=0;
      LCD_COM(0x0C);
      _EINT();        //开中断
    }
  }
  if(key_num!=0)
  {
    if(key==2)
    {
      if(key_num==1)
      {
        sec++;
        if(sec==60)
          sec=0;
        time_go(10,sec);
        LCD_COM(0xc0+11);
      }
      if(key_num==2)
      {
        mit++;
        if(mit==60)
          mit=0;
        time_go(7,mit);
        LCD_COM(0xc0+8);
      }
      if(key_num==3)
      {
        hor++;
        if(hor==24)
          hor=0;
        time_go(4,hor);
        LCD_COM(0xc0+5);
      }
    }
  }
      
}
void timerA_init()                //定时器A初始化
{
  TACTL |= TASSEL0+ TACLR +  MC0 + TAIE;
  CCR0=32768;  
}
#pragma vector=TIMERA1_VECTOR     //定时器A中断函数
__interrupt void Timer_A(void)
{
  switch(TAIV)
  {
  case 2:
    break;
  case 4:
    break;
  case 10:
    flag=1;
    break;
  }  
  if(flag==1)//计时
  {
    flag=0;
    sec++;
    if(sec==60)
    {
      sec=0;
      time_go(10,sec);
      mit++;
      if(mit==60)
      {
        mit=0;
        time_go(7,mit);
        hor++;
        if(hor==24)
        {
          hor=0;
          time_go(4,hor);
        }
        else
          time_go(4,hor);
      }
      else
        time_go(7,mit);
    }
    else
      time_go(10,sec);
  }
}
  
void main()
{
  WDT_Init();//关开门狗程序
  Clock_Init_Ex32768();//系统时钟初始化,MCLK为32.768kHz
  Port_init();//I/O端口初始化
  delay_us(100);
/**********LCD1602初始化*************/  
  LCD_init();
  LCD_string(0,0,"Time of CST:");
  LCD_string(4,1,"00:00:00");
/************************************/      
  timerA_init();
  _EINT();
  while(1)
  {
    keyscan();
    delay_us(100);
    time_cor();
  }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
xyz549040622
1楼-- · 2019-07-25 14:46
:lol给灰哥顶起,现在越来越不喜欢用这类直接操作寄存器的芯片了,太麻烦。
依然幸福
2楼-- · 2019-07-25 18:47
果然是简易的程序。
baimiaocun2015
3楼-- · 2019-07-25 20:55
这个简易始终程序的,关键点在于定时器的定时准确性的。
lwsn
4楼-- · 2019-07-26 01:24
版主把简易原理图也弄上来吧
王大熊
5楼-- · 2019-07-26 01:44
 精彩回答 2  元偷偷看……

一周热门 更多>