找回密码
 立即注册

QQ登录

只需一步,快速开始

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

秒表程序

[复制链接]
跳转到指定楼层
楼主
ID:325084 发表于 2018-5-8 15:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*
****************************************************************************
* 程序说明 ;使数码管依次显示0-8
****************************************************************************
*/
#include "io430.h"
#define uint unsigned int
#define uchar unsigned char
#define KeyPort         P1IN    //独立键盘接在P60~P63
#define CPU_F ((double)1000000)
#define DelayUs(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define DelayMs(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define KEY1  1
#define KEY2  2
#define KEY3  3
#define KEY4  4
#define KEY5  5
uchar KeyScan(void);
#define SMG_DATA    P4OUT           //573位选信号的输入管脚
#define SMG_WEI  P5OUT
//#define CLK_H       P6OUT|=BIT6     //595时钟信号的输入置高
//#define CLK_L       P6OUT&=~BIT6    //595时钟信号的输入置低
//#define ST_H        P6OUT|=BIT5     //595锁存信号置高
//#define ST_L        P6OUT&=~BIT5    //595锁存信号置低
//#define DATA_H      P6OUT|=BIT4    //595数据信号输入置高
//#define DATA_L      P6OUT&=~BIT4    //595数据信号置低
//#define LED_E0      P5OUT&=~BIT7     //数码管 573使能置低
//#define LED_E1      P5OUT|=BIT6     //点阵 573使能置高
uchar uc7leds[17]={0x3f,0x06,0x5b,0x4f,   //0,1,2,3,
                   0x66,0x6d,0x7d,0x07,          //4,5,6,7,
                   0x7f,0x6f,0x77,0x7c,          //8,9,A,b,
                   0x39,0x5e,0x79,0x71,0x00};  //C,d,E,F
uchar jishu=0;
uchar mode=1;
uchar downtime=1;
void PortInit();
uchar number[4] = {0,0,0,0};
void ClockInit();
void display();
void TimerAInit();
void fentime(int num);
void fenshu(int num);
void main()
{
  uint b;
  WDTCTL=WDTPW+WDTHOLD;
  ClockInit();    //时钟初始化
  TimerAInit();
  PortInit();
  uchar jishi=0;
  uchar keyvalue=0;
  uchar zhu=1;  
  uchar wait=1;
  uchar mode2start=0;
  
  while(1)
  {
    if(b==0)  
      keyvalue=KeyScan();
    //*
    if(zhu==1)
    {
      if(keyvalue==5)
        zhu=0;        
      if(keyvalue==4)
        mode++;
      if(mode==4)
        mode=1;
        number[0]=mode+9;
        number[1]=16;
        number[2]=16;
        number[3]=16;      
    }

    else if(mode==1)
    {
      if(wait)
      {
        fentime(0);
        wait=0;
      }
      if(keyvalue==1)
      {
        jishi=!jishi;
        if(jishi)
          TACTL=TASSEL_1+MC_1+ID_3+TAIE;
        else
          TACTL=TASSEL_1+MC_0+ID_3+TAIE;        
      }
   }
   else if(mode==2)
   {
     if(!mode2start)
     {
       if(wait)
       {
         fentime(60);
         wait=0;
       }
       else
       {  
         if(keyvalue==4)
         {
         downtime++;
         fentime(downtime*60);
         }
         if(keyvalue==1)
         {
           mode2start=1;
           TACTL=TASSEL_1+MC_1+ID_3+TAIE;
         }
       }
     }
     else
     {
      
     }      
   }
   if(keyvalue==2)
   {
      jishi=0;
      keyvalue=0;
      zhu=1;  
      wait=1;
      mode2start=0;
      jishu=0;
      mode=1;
      downtime=1;
      TACTL=TASSEL_1+MC_0+ID_3+TAIE+TACLR;
      P2OUT_bit.P0=0;   
     
   }
   


    display();
    if(keyvalue!=0)
    {
      b=0x8fff;
      keyvalue=0;      
    }
    if(b!=0)
      b--;
  }
}

/*
****************************************************************************
*                         PortInit()
* 功能说明 ;IO初始化
*   参数   :无
* 返回值   :无
****************************************************************************
*/
void PortInit()
{
  P4SEL=0X00;//普通
  P4DIR=0XFF;//输出
  P5SEL=0X00;//普通
  P5DIR=0XF0;//输出  
  P5OUT=0XFF;
  P2SEL = 0x00;   //设置IO口为普通I/O模式
  P2DIR = 0x01;   //设置IO口方向为输出
  P2OUT = 0x00;   //初始设置为00,即都为低电平
  P1SEL = 0x00;
  P1DIR = 0x00;
  P4OUT=uc7leds[0];
  //P6SEL=0X00;
  //P6DIR=0XFF;
  //P5SEL=0X00;
  //P5DIR=0XFF;
  //LED_E1;
  //LED_E0;
}


/*
****************************************************************************
*                         TimerAInit()
* 功能说明 ;定时器A初始化
*   参数   :无
* 返回值   :无
****************************************************************************
*/

void TimerAInit()
{
TACTL=TASSEL_1+MC_0+ID_3+TAIE;//选择ACK,增计数模式,8分频,使能定时器中断
CCR0=4095;
  __enable_interrupt();
}

void ClockInit()
{
  uchar i;

  BCSCTL1&=~XT2OFF;   //设置XT2为有效
  BCSCTL2|=SELM1+SELS;
  do{
    IFG1&=~OFIFG;   //清除振荡器失效标志
    for(i=0;i<100;i++)
       __no_operation();
  }while((IFG1&OFIFG)!=0);    //如果振荡失效标志存在则继续循环
  IFG1&=~OFIFG;
}





/*
****************************************************************************
*                         TimerA()
* 功能说明 ;定时器A中断处理程序
*   参数   :无
* 返回值   :无
****************************************************************************
*/
#pragma vector = TIMERA1_VECTOR
__interrupt void TimerA(void)
{
  switch(TAIV)
  {
case 2:break;
case 4:break;
case 10:
        jishu++;
        if(mode==1)
        {
          fentime(jishu);
        }
        else if(mode==2)
        {
          fentime(downtime*60-jishu);
          if(!(downtime*60-jishu))
          {
            P2OUT_bit.P0=1;
            TACTL=TASSEL_1+MC_0+ID_3+TAIE;            
          }
        }
        break;
  }
}
/*
****************************************************************************
*                       uchar KeyScan(void)
* 功能说明 ;按键检测
*   参数   :无
* 返回值   :KeyNum:按下的按键值
****************************************************************************
*/
uchar KeyScan(void)
{
  uchar keycode;
    static uchar sta=0;       //不支持连续按
    //uchar sta=0;                //支持连按
    uchar tmp=0;
   
    P1DIR  |= 0X1f;
    P1OUT = 0X1f;
    P1DIR  &=  0xe0;    //设置P10 P11 P12为输入
    if(sta==0)                  //sta=0 时检测按键是否按下
    {
         if((P1IN&0X1f)!=0X1f)     // 扫描按键
         {
            DelayMs(10);
            if((P1IN&0X1f)!=0X1f)  //确认按键按下
            {
              
              keycode=(P1IN&0X1f);
              switch(keycode)           //确认按键
              {               
              case 0x1e:tmp=1;;break;
              case 0x1d:tmp=2;;break;
              case 0x1b:tmp=3;;break;
              case 0x17:tmp=4;;break;
              case 0x0f:tmp=5;;break;
              default : ;break;
            }
            sta=1;
            }
            
         }
    }
   
   else if((P1IN&0X1f)!=0X1f)   // 确定按键是否松开
    {
      DelayMs(10);
      if((P1IN&0X1f)!=0X1f)     //若是按键松开,sta = 0;
        sta=0;
    }
   
   return tmp;          //返回按下的按键数

}

void fenshu(int num)
{
  number[0]=num%10;
  number[1]=(num%100)/10;
  number[2]=(num%1000)/10;
  number[3]=num/1000;  
}
void fentime(int num)
{
  number[0]=(num%60)%10;
  number[1]=(num%60)/10;
  number[2]=(num/60)%10;
  number[3]=(num/60)/10;   
}

void display()           //数码管显示
{
        static uchar i=0;
        i++;
        if(i >= 4)
                i = 0;        
        P4OUT =0x00;                //消隐
        switch(i)               //位选
        {
                case 3: SMG_WEI=0x10; break;
                case 2: SMG_WEI=0x20; break;
                case 1: SMG_WEI=0x40; break;
                case 0: SMG_WEI=0x80; break;
        }        
        P4OUT = uc7leds[number];
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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