突破渴望

红外调光灯设计-源码加注释

0
阅读(3083)
#include "MSP430X14X.h"

#define uchar unsigned char
#define uint  unsigned int
#define PWM   BIT2
#define IR    BIT3

///////////////////////////////////////////////////////////////
//变量定义
uchar dir_flag=0;                    //方向中断标志位
int dir_value=0;                     //方向值
uchar ir_code[2];
uchar ir_flag=0;
uchar light=0;

//时钟初始化程序
void init_clk()                      
{
  unsigned char i;
  BCSCTL1 &= ~XT2OFF;                //打开XT2
  do
  {
    IFG1 &= ~OFIFG;                  //清除错误标志
    for(i = 0; i < 100; i++)
    _NOP();			     //延时等待
  }while((IFG1 & OFIFG) != 0);       //错误标志是否还在
  BCSCTL2 |= SELM1;                  //选择MCLK为高速晶体振荡器
//BCSCTL2 |= DIVM_1 + DIVM_0;        //MCLK 8分频
  BCSCTL2 |= SELS;                   //SMCLK 选择为高速晶体振荡器
  BCSCTL2 |= DIVS_0 + DIVS_1;        //SMCLK 8分频          
}

//定时器初始化函数
void init_timer()
{
  TACTL |= SSEL1;                    //定时器时钟选择为MCLK
  TACTL |= MC1 + MC0;                //选择为增减计数模式
  TACTL |= TAIE;                     //允许定时器中断
}
void init_PWM()
{
  P1SEL |= PWM;                      //设置P1.2为比较输出功能
  P1DIR |= PWM;                      //设置P1.2方向为输出
  
  TACCR0 = 1000;
  TACCR1 = 500;
  TACCTL1= OUTMOD0 + OUTMOD1 + OUTMOD2;
                                     //模式为PWM复位、置位
  TACTL |= TASSEL1 + MC0;            //时钟选择为SMCLK,增计数模式
}
void delay(uint i)
{
  while(i--);
}

void delay_740us()                   //延时780us
{
  unsigned int i;
  i=1480;
  while(--i);
}

void delay_840us()                   //延时840us
{
  unsigned int i;
  i=1660;
  while(--i);
}

void delay_1300us()                  // 延时1200us
{
  unsigned int i;
  i=2580;
  while(--i);
}
void delay_3000us()                  // 延时4720us
{
  unsigned int i;
  i=5953;
  while(--i);
}

void init()
{
  P1IES |= BIT0 + BIT1;               // P1.0~P1.1选择上升沿中断
  P1IFG  = 0;
  P1IE  |= BIT0 + BIT1 + IR;          // 打开中断使能
  P5DIR  = 0xFF;                      // P5口显示键值
  ADC12CTL0 =  SHT0_15  + ADC12ON;
  ADC12CTL1 = SHP;
  ADC12IE = 0X01;                     
  ADC12MCTL0 |= INCH_1 ;              //端口改为A1;
  ADC12CTL0 |= ENC;  
}

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;           //关闭看门狗
  init_clk();                         //初始化时钟
  init_PWM();                         //初始化PWM波生成参数
  init();
  _EINT();                            //使能中断
  while(1)
  {
    if(light)                         //判断是什么状态:
      ADC12CTL0 |= ADC12SC;           //       1:自动判光,光线过强过后自动关闭台灯
    else
      ADC12CTL0 &=~ADC12SC;           //       2:人工设定亮度
    P5OUT = ir_code[0];
    if(ir_flag)                       //如果红外有键按下
    {
      ir_flag=0;
      switch(ir_code[0])
      {
        case 0x02:                    //按下为减弱亮度
                    if(TACCR1==1000)
                      TACCR1 =1000;
                    else
                      TACCR1 += 100;
                    break;
        case 0x01:                    //按下为增加亮度         
                    if(TACCR1==0)
                      TACCR1 =0;
                    else
                      TACCR1 -= 100;
                    break;
        case 0x07:                    //按键为进入自动判光状态
                    light=1;
                    break;
        case 0x06:                    //退出自动判光
                    light=0;
                    break;
      }
    }
    if(dir_value==2)                  //编码旋钮开关方向为顺时针
    {
      dir_value=0;
      if(TACCR1==1000)
        TACCR1 =1000;
      else
        TACCR1 += 50;
    }
    if(dir_value==1)                  //编码旋钮开关方向为逆时针
    {
      dir_value=0;
      if(TACCR1==0)
        TACCR1 =0;
      else
        TACCR1 -= 50;
    }
    delay(60000);
  }
}


//中断判断函数

#pragma vector=PORT1_VECTOR
__interrupt void  PORT1_ISR(void)
{
  unsigned char i;
  if(P1IFG&IR)
  {
    _DINT();
    for(i=0;i<8;i++)
    {
      delay_840us(); 
      if(P1IN&IR)
      {
        P1IFG=0;
        _EINT();
        return; 
      }
    }
    delay_1300us(); 
    delay_1300us(); 
    delay_1300us(); 
    while(P1IN&IR); 
    for(i=0;i<8;i++)
    {
      while(~(P1IN|(~IR))); 
      delay_740us();
      ir_code[1]=(ir_code[1]>>1);
      if(P1IN&IR)
      {
        ir_code[1]=(ir_code[1]|0x80);
        while(P1IN&IR); 
      }
    }
    delay_3000us();
    while(P1IN&IR); 
    for(i=0;i<8;i++)
    {
      while(~(P1IN|(~IR))); 
      delay_740us();
      ir_code[0]=(ir_code[0]>>1);
      if(P1IN&IR)
      {
        ir_code[0]=(ir_code[0]|0x80);
        while(P1IN&IR); 
      }
    }
    ir_flag++;
    _EINT();
    P1IFG=0;
    return;
  }
  else
  if(P1IFG&0x02)
  {
    if(dir_flag==0)
    {
      dir_flag=2;
      P1IFG=0;
      _EINT();
      return;
    }
    else
    if(dir_flag==1)
    {
      dir_value=1;
      dir_flag=0;
      P1IFG=0;
      _EINT();
      return;
    }
    else
    if(dir_flag==2)
    {
      dir_value=2;
      dir_flag=0;
      P1IFG=0;
      _EINT();
      return;
    }
  }
  else 
  if(P1IFG&0x01)
  {
    if(dir_flag==0)
    {
      dir_flag=1;
      P1IFG=0;
      _EINT();
      return;
    }
    else
    if(dir_flag==2)
    {
      dir_value=2;
      dir_flag=0;
      _EINT();
      P1IFG=0;
      return;
    }
    else
    if(dir_flag==1)
    {
      dir_value=1;
      dir_flag=0;
      P1IFG=0;
      _EINT();
      return;
    }
  }
}

//AD中断函数

#pragma vector = ADC_VECTOR
__interrupt void ADC12_ISR(void)
{
  if(ADC12MEM0<0X7ff)
    TACCR1=300;
  else
    TACCR1=1000;
}