红外调光灯设计-源码加注释
0赞
发表于 11/22/2011 10:54:06 PM
阅读(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;
}
