{
CCR1=j;
_delay_cycles(1000);
}
for(j=TIMER_PWM_PERIOD ;j>0;j-=1)
{
CCR1=j;
_delay_cycles(1000);
}
for (j=TIMER_PWM_PERIOD;j>0;j-=1)
{
_delay_cycles(100);
}
tempMeasured[tempMeasuredPosition++] = ADC10MEM; //将温度采样值存入温度值数组下一位
if (tempMeasuredPosition == 8)
tempMeasuredPosition = 0; //复位温度采样值数组索引
tempAverage = 0;
for (i = 0; i < 8; i++)
tempAverage += tempMeasured;
tempAverage >>= 3; //除以8得到平均值 Divide by 8 to get average
tempDifference = tempAverage - tempCalibrated; //计算相对于参考温度的差值
if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD
{
tempDifference = -tempDifference; //差值取正
tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD
}
else
if (tempDifference > TEMP_THRESHOLD) //如果采样温度值高于参考温度值差值TEMP_THRESHOLD
{
tempPolarity = TEMP_HOT; //极性变量设为值TEMP_HOT
}
else //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD
{
tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME
TACCTL0 &= ~CCIE; //关TACCTL0中断使能
TACCTL1 &= ~CCIE; //关TACCTL1中断使能
}
if (tempPolarity != TEMP_SAME) //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD
{
tempDifference <<= 9; //温度偏差值乘以8
//tempDifference += TIMER_PWM_OFFSET; //加上一个偏置值
TACCR1 = ( (tempDifference) < (TIMER_PWM_PERIOD-1) ? (tempDifference) : (TIMER_PWM_PERIOD-1) ); //置TACCR1,最大为TIMER_PWM_PERIOD-1。
//TACCR1值控制亮的时间,定时器计数到TACCR1在中断中将关闭灯,在TACCR0中断中亮灯
TACCTL0 |= CCIE; //开TACCTL0中断使能
TACCTL1 |= CCIE; //开TACCTL1中断使能
}
} //返回主循环
}
//进入待机模式,红绿灯交替闪,等待按键
void PreApplicationMode(void)
{
LED_DIR |= LED1 + LED2; //p1.0和P1.6口为输出
LED_OUT |= LED1;
LED_OUT &= ~LED2; //绿灯灭
BCSCTL1 |= DIVA_1;
BCSCTL3 |= LFXT1S_2;
TACCR0 = 1200;
TACTL = TASSEL_1 | MC_1;
TACCTL1 = CCIE + OUTMOD_3;
TACCR1 = 600;
__bis_SR_register(LPM3_bits + GIE);
}
//配置温度传感器模数转换
void ConfigureAdcTempSensor(void)
{
unsigned char i;
/* Configure ADC Temp Sensor Channel */
ADC10CTL1 = INCH_10 + ADC10DIV_3; //选择ADC通道为温度传感器,时钟4分频 // Temp Sensor ADC10CLK/4
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; // VR+ = VREF+ and VR- = VSS,采样保持时间=64×ADC10CLK周期,打开内部参考电压,打开ADC模块,ADC中断允许
__delay_cycles(1000); //延时等待ADC参考电压建立 // Wait for ADC Ref to settle
ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次 // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); //进入省电模式LPM0,等待AD转换完成中断 // LPM0 with interrupts enabled
tempCalibrated = ADC10MEM;
for (i=0; i < 8; i++)
tempMeasured = tempCalibrated;
tempAverage = tempCalibrated; //第一次转换,平均温度取样值和校准值相等
}
//配置定位器为PWM模式
void ConfigureTimerPwm(void)
{
timerMode = TIMER_PWM_MODE;
TACCR0 = TIMER_PWM_PERIOD; //
TACTL = TASSEL_2 | MC_1; //定时器时钟源选择辅助时钟SMCLK,增计数模式 // TACLK = SMCLK, Up mode.
TACCTL1 = OUTMOD_7;//CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 ??OUTMOD_3有什么用? // TACCTL1 Capture Compare
}
//TACCR0中断专用, Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
if (tempPolarity == TEMP_HOT)
{
//LED_OUT |= LED1; //如果相对于参考温度偏差为正,LED1绿灯置为亮
TIMER_PWM_PERIOD -= tempDifference;
if (TIMER_PWM_PERIOD < 0)
{
LED_DIR |= LED1;
LED_OUT |= LED1;
//TIMER_PWM_PERIOD = 1;
}
tempCalibrated = tempAverage;
}
if (tempPolarity == TEMP_COLD)
{
//LED_OUT |= LED2; //如果相对于参考温度偏差为负,LED2红灯置为亮
TIMER_PWM_PERIOD += tempDifference;
tempCalibrated = tempAverage;
if (TIMER_PWM_PERIOD>0)
{
LED_OUT &= ~LED1;
}
}
TACCTL0 &= ~CCIFG; //清中断标志位??有必要么?不是自动清除?
TACCTL0 &= ~CCIE;
}
//TACCR1和定时器共用中断向量
#pragma vector=TIMER0_A1_VECTOR
__interrupt void ta1_isr(void)
{
TACCTL1 &= ~CCIFG; //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除
if (applicationMode == APP_APPLICATION_MODE)
{
//LED_OUT &= ~(LED1 + LED2); //如果程序运行至是应用模式,置两灯皆灭
TACCTL1 &= ~CCIE;
}
else
LED_OUT ^= (LED1 + LED2); //如果是待机模式,异或,原来两个灯本来就是一亮一灭的,所以反复中断的效果是交替闪烁。PreApplicationMode(void)中
}
void InitializeClocks(void)
{
BCSCTL1 = CALBC1_1MHZ; //用FLASH中信息存贮器A段的校准数据设置基本时钟系统控制寄存器 1 // Set range
DCOCTL = CALDCO_1MHZ; //用FLASH中信息存贮器A段的校准数据设置 DCO 控制寄存器,设置DCO校准为1MHz,详细原理请查看G2系列芯片的Users Guide
BCSCTL2 &= ~(DIVS_3); //SMCLK为0分频DCO // SMCLK = DCO = 1MHz
}
void InitializeButton(void) // Configure Push Button
{
BUTTON_DIR &= ~BUTTON; //按键对应的端口方向为输入
BUTTON_OUT |= BUTTON; //设置输出寄存器对应的按键位为1
BUTTON_REN |= BUTTON; //使能上拉电阻,因为对应的输出寄存器位为1。反之如果对应的输出寄存器位为0则自动选择下拉电阻。
BUTTON_IES |= BUTTON; //选择下降沿中断
BUTTON_IFG &= ~BUTTON; //中断标志清零
BUTTON_IE |= BUTTON; //按键中断允许
}
//设置两颗LED对应的端口并两设置为熄灭初始状态
void InitializeLeds(void)
{
LED_DIR |= LED1 + LED2; //P1DIR=BIT1+BIT6 p1.0和P1.6口为输出
LED_OUT &= ~(LED1 + LED2); //两个LED低电平熄灭
}
/* *************************************************************
* Port Interrupt for Button Press
* 1. During standby mode: to exit and enter application mode
* 2. During application mode: to recalibrate temp sensor
* *********************************************************** */
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
BUTTON_IFG = 0; //清P1口所有中断标志
BUTTON_IE &= ~BUTTON; //禁止按键中断使能,防抖动,经过看门狗定时器延时在看门狗定时器中断中再打开 /* Debounce */
WDTCTL = WDT_ADLY_250; //=(WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0)看门狗设置为定时器模式,计数清零,时钟源为辅助时钟ACLK,定时周期为Taclk×32768
IFG1 &= ~WDTIFG; //清看门狗定时器中断标志 /* clear interrupt flag */
IE1 |= WDTIE; //使能看门狗定时器中断
if (applicationMode == APP_APPLICATION_MODE) //如果是应用模式
{
//tempCalibrated = tempAverage; //???如果中断发生在for (i = 0; i < 8; i++) tempAverage += tempMeasured;不是错了么?
calibrateUpdate = 1; //参考温度校准标志变量
}
else
{
applicationMode = APP_APPLICATION_MODE; //由待机模式切换到应用模式 // Switch from STANDBY to APPLICATION MODE
__bic_SR_register_on_exit(LPM3_bits); //退出低功耗模式LPM3
}
}
// WDT Interrupt Service Routine used to de-bounce button press
#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void)
{
IE1 &= ~WDTIE; //禁止看门狗定时器中断 /* disable interrupt */
IFG1 &= ~WDTIFG; //清看门狗定时器中断标志 /* clear interrupt flag */
WDTCTL = WDTPW + WDTHOLD; //使看门狗关闭状态 /* put WDT back in hold state */
BUTTON_IE |= BUTTON; //使能按键中断 /* Debouncing complete */
}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); //退出省电模式 // Return to active mode
}