//程序烧进板子后先进入led灯交替闪烁的待机模式;按下按键后,进入应用模式,绿灯开始呼吸;此时温度上升后绿灯呼吸加快,温度下降后呼吸又会变慢。当温度过高时红灯亮
#include "msp430g2553.h"
#define LED1 BIT0
#define LED2 BIT6
#define LED_DIR P1DIR
#define LED_OUT P1OUT
#define BUTTON BIT3 //P1.3为板上按键S2
#define BUTTON_OUT P1OUT //端口输出寄存器
#define BUTTON_DIR P1DIR //端口方向控制寄存器
#define BUTTON_IN P1IN //端口输入寄存器
#define BUTTON_IE P1IE //端口中断允许寄存器
#define BUTTON_IES P1IES //端口中断触发沿控制寄存器
#define BUTTON_IFG P1IFG //端口中断标志寄存器
#define BUTTON_REN P1REN //端口上下拉电阻使能控制寄存器
#define APP_STANDBY_MODE 0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态
#define APP_APPLICATION_MODE 1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度
#define TIMER_PWM_MODE 0
long TIMER_PWM_PERIOD = 5000;
#define TIMER_PWM_OFFSET 20
#define TEMP_SAME 0
#define TEMP_HOT 1
#define TEMP_COLD 2
#define TEMP_THRESHOLD 0
// Conditions for 9600/4=2400 Baud SW UART, SMCLK = 1MHz
#define Bitime_5 0x05*4 // ~ 0.5 bit length + small adjustment
#define Bitime 13*4//0x0D
unsigned char BitCnt;
unsigned char applicationMode = APP_STANDBY_MODE; //功能模式标志,初始值为待机模式
unsigned char timerMode = TIMER_PWM_MODE;
unsigned char tempMode;
unsigned char calibrateUpdate = 0;
unsigned char tempPolarity = TEMP_SAME;
unsigned int TXByte;
long tempMeasured[8]; //定义数组以计算8次10位ADC温度采样的平均值
unsigned char tempMeasuredPosition=0; //温度测量值数组索引
long tempAverage; //8次10位ADC温度采样的平均值
long tempCalibrated, tempDifference;
void InitializeLeds(void); //IO端口初始化,设置两颗LED对应的端口并两设置为熄灭初始状态
void InitializeButton(void); //IO端口初始化,配置按键
void PreApplicationMode(void); //进入待机模式,红绿灯交替闪,等待按键 Blinks LED, waits for button press
void ConfigureAdcTempSensor(void); //配置温度传感器模数转换
void ConfigureTimerPwm(void); //配置定位器为PWM模式
void InitializeClocks(void); //初始化时钟系统
void main(void)
{
unsigned char i;
WDTCTL = WDTPW + WDTHOLD; // 停止看门狗 Stop WDT
InitializeClocks(); //初始化时钟系统
InitializeButton(); //配置按键
InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态
PreApplicationMode();
applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式
ConfigureAdcTempSensor(); //配置温度传感器模数转换
ConfigureTimerPwm(); //配置定位器PWM模式
__enable_interrupt(); //使能全局中断 Enable interrupts.
LED_OUT &=~LED1;
while(1)
{
ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次 Sampling and conversion start
__bis_SR_register(CPUOFF + GIE);
P1SEL |=BIT6;
P1OUT |=BIT6;
ConfigureTimerPwm();
unsigned int j;
for(j=0;j { 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[i]; 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[i] = 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
上一篇:MSP430 LaunchPad IO外部中断
下一篇:MSP430学习笔记1---点亮第一个LED
推荐阅读
史海拾趣





M55342K04B172ACBS






京公网安备 11010802033920号