专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
G2553里面有没有温度传感器啊??
2019-03-24 09:42
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
TI MCU
8712
19
1580
有的话怎么设置呢? 此帖出自
小平头技术问答
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
19条回答
寒雪剑91
1楼-- · 2019-03-26 04:06
精彩回答 2 元偷偷看……
加载中...
457887107
2楼-- · 2019-03-26 07:24
/*这是2012.1.3在官方网站http://processors.wiki.ti.com/index.php?title=MSP430_LaunchPad_(MSP-EXP430G2)#Complete_Projects 下载的,版本号:slac435b
*中文为本人http://wangfuchong.com添加的注释,切记不一定正确,仅供尽可能地快速了解程序的结构。
×还是有一些疑惑,总觉得有不够严谨的可能,大家帮助分析。
* main.c
*
* MSP-EXP430G2-LaunchPad User Experience Application
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/******************************************************************************
* MSP-EXP430G2-LaunchPad User Experience Application
*
* 1. Device starts up in LPM3 + blinking LED to indicate device is alive
* + Upon first button press, device transitions to application mode
* 2. Application Mode
* + Continuously sample ADC Temp Sensor channel, compare result against
* initial value
* + Set PWM based on measured ADC offset: Red LED for positive offset, Green
* LED for negative offset
* + Transmit temperature value via TimerA UART to PC
* + Button Press --> Calibrate using current temperature
* Send character '? via UART, notifying PC
*
* Changes:
*
* 1.2 + Updated register naming conventions to reflect latest standard by TI
* e.g.: CCR0 --> TACCR0, CCTL0 --> TACCTL0
* + Changed method to capture TAR value into TACCR0 by using capture a
* SW-triggered event. [Changing TACCR input from GND to VCC]
× 1.2是与版本slac435a相比新更改的部分
* 1.1 + LED1 & LED2 labels changed so that Green LED(LED2) indicates sampled
* temperature colder than calibrated temperature and vice versa
* with Red LED (LED1).
* + Turn off peripheral function of TXD after transmitting byte to
* eliminate the extra glitch at the end of UART transmission
* 1.0 Initial Release Version
*
* Texas Instruments, Inc.
******************************************************************************/
#include "msp430g2231.h"
#define LED1 BIT0 //绿灯,BIT0,BIT6之类的是宏定义,请在头文件"msp430g2231.h"中查看
#define LED2 BIT6 //红灯,参见MSP-EXP430G2 LaunchPad Experimenter Board User's Guide
#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 TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2
#define APP_STANDBY_MODE 0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态
#define APP_APPLICATION_MODE 1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度
#define TIMER_PWM_MODE 0
#define TIMER_UART_MODE 1 //串口模式状态
#define TIMER_PWM_PERIOD 2000
#define TIMER_PWM_OFFSET 20
#define TEMP_SAME 0
#define TEMP_HOT 1
#define TEMP_COLD 2
#define TEMP_THRESHOLD 5
// 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
#define UART_UPDATE_INTERVAL 1000 //主循环次数进行一次串口发送温度值
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;
/* Using an 8-value moving average filter on sampled ADC values */
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 ConfigureTimerUart(void); //配置定时器为Uart模式
void Transmit(void); //串口发送子程序
void InitializeClocks(void); //初始化时钟系统
void main(void)
{
unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL; //主循环次数进行一次串口发送温度值
unsigned char i;
WDTCTL = WDTPW + WDTHOLD; // 停止看门狗 Stop WDT
InitializeClocks(); //初始化时钟系统
InitializeButton(); //配置按键
InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态
PreApplicationMode(); //进入待机模式,红绿灯交替闪,等待按键 Blinks LEDs, waits for button press
//执行PreApplicationMode()将进入低功耗模式,程序停止在此,直到有按键按下
/* 进入应用模式 Application Mode begins */
applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式
ConfigureAdcTempSensor(); //配置温度传感器模数转换
ConfigureTimerPwm(); //配置定位器PWM模式
__enable_interrupt(); //使能全局中断 Enable interrupts.
/* Main Application Loop */
while(1)
{
ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次 Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); //进入省电模式LPM0,等待AD转换完成中断 LPM0 with interrupts enabled
/* Moving average filter out of 8 values to somewhat stabilize sampled ADC */
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
if ((--uartUpdateTimer == 0) || calibrateUpdate ) //如果主循环了UART_UPDATE_INTERVAL次或者参考温度按键按过
{
ConfigureTimerUart();
if (calibrateUpdate)
{
TXByte = 248; // A character with high value, outside of temp range
Transmit(); //串口发送值248表示按键按下进行了校准参考
calibrateUpdate = 0; //复位参考温度校准标志变量
}
TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 ); //计算温度华氏值
Transmit(); //串口发送华氏温度值
uartUpdateTimer = UART_UPDATE_INTERVAL; //复位循环计数变量
ConfigureTimerPwm(); //配置定时器回PWM模式
}
tempDifference = tempAverage - tempCalibrated; //计算相对于参考温度的差值
if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD
{
tempDifference = -tempDifference; //差值取正
tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD
LED_OUT &= ~ LED1; //LED1绿灯置灭
}
else
if (tempDifference > TEMP_THRESHOLD) //如果采样温度值高于参考温度值差值TEMP_THRESHOLD
{
tempPolarity = TEMP_HOT; //极性变量设为值TEMP_COLD
LED_OUT &= ~ LED2; //LED2红灯置灭
}
else //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD
{
tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME
TACCTL0 &= ~CCIE; //关TACCTL0中断使能
TACCTL1 &= ~CCIE; //关TACCTL1中断使能
LED_OUT &= ~(LED1 + LED2); //置两灯皆灭
}
if (tempPolarity != TEMP_SAME) //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD
{
tempDifference <<= 3; //温度偏差值乘以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; //绿灯亮 To enable the LED toggling effect
LED_OUT &= ~LED2; //红灯灭
BCSCTL1 |= DIVA_1; //辅助时钟分频设置为2 ,ACLK=6KHz
BCSCTL3 |= LFXT1S_2; //辅助时钟源选择VLOCLK,12KHz //ACLK = VLO
TACCR0 = 1200; //
TACTL = TASSEL_1 | MC_1; //定时器时钟源选择辅助时钟ACLK,增计数模式 // TACLK = SMCLK, Up mode.
TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 // TACCTL1 Capture Compare
TACCR1 = 600;
__bis_SR_register(LPM3_bits + GIE); // LPM0 with interrupts enabled ??低功耗模式LPM3
//此时cpu停止,等待中断,如果是比较1中断,则进入中断程序:ta1_isr(void),因为是CC1。
//如果是按键中断,则进入PORT1_ISR(void)中断服务程序,在PORT1_ISR(void)中将退出此低功耗模式
}
//配置温度传感器模数转换
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.
TACCTL0 = CCIE;
TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 ??OUTMOD_3有什么用? // TACCTL1 Capture Compare
TACCR1 = 1;
}
//配置定时器为Uart模式
void ConfigureTimerUart(void)
{
timerMode = TIMER_UART_MODE; // Configure TimerA0 UART TX
TACCTL0 = OUT; //输出为高电平 // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2 + ID_3; //定时器时钟源选择辅助时钟SMCLK,连续计数模式 ,时钟8分频 // SMCLK/8, continuous mode
P1SEL |= TXD + RXD; //打开P1.1,P1.2引脚特殊功能
P1DIR |= TXD; //P1.1端口方向为输出
}
//串口发送子程序 Function Transmits Character from TXByte
void Transmit()
{
BitCnt = 0xA; //低电平起始位+8位数据+高电平停止位共10位 // Load Bit counter, 8data + ST/SP
/* Simulate a timer capture event to obtain the value of TAR into the TACCR0 register */
//模仿捕捉模式以获得当前的TAR值赋予TACCR0
TACCTL0 = CM_1 + CCIS_2 + SCS + CAP + OUTMOD0; //上升沿捕捉,输入源为GND,输出模式置位模式 //capture on rising edge, initially set to GND as input // clear CCIFG flag
TACCTL0 |= CCIS_3; //改变输入源为VCC,相当于输入源上升沿变化,触发捕捉//change input to Vcc, effectively rising the edge, triggering the capture action
while (!(TACCTL0 & CCIFG)); //查询TACCTL0中断标志位 //allowing for the capturing//updating TACCR0.
TACCR0 += Bitime ; //首位发送延时 // Some time till first bit
TXByte |= 0x100; //增加停止位 // Add mark stop bit to TXByte
TXByte = TXByte << 1; //左移一位右边添加一位0表示起始位 // Add space start bit
TACCTL0 = CCIS0 + OUTMOD0 + CCIE; //比较模式,OUTMOD0=OUTMOD_1输出模式为置位模式,清中断标志,中断允许 // TXD = mark = idle
while ( TACCTL0 & CCIE ); //循环,直到反复中断中完成发送 // Wait for TX completion
}
//TACCR0中断专用, Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
if (timerMode == TIMER_UART_MODE) //定时器为Uart模式
{
TACCR0 += Bitime; //TACCR0加上一位串口数据所需的计数量,准备下一次中断 // Add Offset to TACCR0
if (TACCTL0 & CCIS0) //为什么要? TX on CCI0B?
{
if ( BitCnt == 0) //如果全部发送完成
{
P1SEL &= ~(TXD+RXD); //取消引脚特殊功能
TACCTL0 &= ~ CCIE ; //关闭中断使能 // All bits TXed, disable interrupt
}
else
{
TACCTL0 |= OUTMOD2; //注意是“或”运算 ,设置成复位模式(原来为复位OUTMOD0,现在为OUTMOD_3) // TX Space
if (TXByte & 0x01)
TACCTL0 &= ~ OUTMOD2; //如果发送的是1,输出模式转为置位模式 // TX Mark
TXByte = TXByte >> 1; //右移一位,准备下一位发送
BitCnt --; //发送位计数
}
}
}
else //定位器为PWM模式
{
if (tempPolarity == TEMP_HOT)
LED_OUT |= LED1; //如果相对于参考温度偏差为正,LED1绿灯置为亮
if (tempPolarity == TEMP_COLD)
LED_OUT |= LED2; //如果相对于参考温度偏差为负,LED2红灯置为亮
TACCTL0 &= ~CCIFG; //清中断标志位??有必要么?不是自动清除?
}
}
//TACCR1和定时器共用中断向量
#pragma vector=TIMERA1_VECTOR
__interrupt void ta1_isr(void)
{
TACCTL1 &= ~CCIFG; //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除
if (applicationMode == APP_APPLICATION_MODE)
LED_OUT &= ~(LED1 + LED2); //如果程序运行至是应用模式,置两灯皆灭
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[i];不是错了么?
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
}
复制代码
加载中...
457887107
3楼-- · 2019-03-26 09:05
#include "msp430g2231.h"
#define LED1 BIT0 //绿灯,BIT0,BIT6之类的是宏定义,请在头文件"msp430g2231.h"中查看
#define LED2 BIT6 //红灯,参见MSP-EXP430G2 LaunchPad Experimenter Board User's Guide
#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 TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2
#define APP_STANDBY_MODE 0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态
#define APP_APPLICATION_MODE 1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度
#define TIMER_PWM_MODE 0
#define TIMER_UART_MODE 1 //串口模式状态
#define TIMER_PWM_PERIOD 2000
#define TIMER_PWM_OFFSET 20
#define TEMP_SAME 0
#define TEMP_HOT 1
#define TEMP_COLD 2
#define TEMP_THRESHOLD 5
// 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
#define UART_UPDATE_INTERVAL 1000 //主循环次数进行一次串口发送温度值
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;
/* Using an 8-value moving average filter on sampled ADC values */
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 ConfigureTimerUart(void); //配置定时器为Uart模式
void Transmit(void); //串口发送子程序
void InitializeClocks(void); //初始化时钟系统
void main(void)
{
unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL; //主循环次数进行一次串口发送温度值
unsigned char i;
WDTCTL = WDTPW + WDTHOLD; // 停止看门狗 Stop WDT
InitializeClocks(); //初始化时钟系统
InitializeButton(); //配置按键
InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态
PreApplicationMode(); //进入待机模式,红绿灯交替闪,等待按键 Blinks LEDs, waits for button press
//执行PreApplicationMode()将进入低功耗模式,程序停止在此,直到有按键按下
/* 进入应用模式 Application Mode begins */
applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式
ConfigureAdcTempSensor(); //配置温度传感器模数转换
ConfigureTimerPwm(); //配置定位器PWM模式
__enable_interrupt(); //使能全局中断 Enable interrupts.
/* Main Application Loop */
while(1)
{
ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次 Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); //进入省电模式LPM0,等待AD转换完成中断 LPM0 with interrupts enabled
/* Moving average filter out of 8 values to somewhat stabilize sampled ADC */
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
if ((--uartUpdateTimer == 0) || calibrateUpdate ) //如果主循环了UART_UPDATE_INTERVAL次或者参考温度按键按过
{
ConfigureTimerUart();
if (calibrateUpdate)
{
TXByte = 248; // A character with high value, outside of temp range
Transmit(); //串口发送值248表示按键按下进行了校准参考
calibrateUpdate = 0; //复位参考温度校准标志变量
}
TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 ); //计算温度华氏值
Transmit(); //串口发送华氏温度值
uartUpdateTimer = UART_UPDATE_INTERVAL; //复位循环计数变量
ConfigureTimerPwm(); //配置定时器回PWM模式
}
tempDifference = tempAverage - tempCalibrated; //计算相对于参考温度的差值
if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD
{
tempDifference = -tempDifference; //差值取正
tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD
LED_OUT &= ~ LED1; //LED1绿灯置灭
}
else
if (tempDifference > TEMP_THRESHOLD) //如果采样温度值高于参考温度值差值TEMP_THRESHOLD
{
tempPolarity = TEMP_HOT; //极性变量设为值TEMP_COLD
LED_OUT &= ~ LED2; //LED2红灯置灭
}
else //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD
{
tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME
TACCTL0 &= ~CCIE; //关TACCTL0中断使能
TACCTL1 &= ~CCIE; //关TACCTL1中断使能
LED_OUT &= ~(LED1 + LED2); //置两灯皆灭
}
if (tempPolarity != TEMP_SAME) //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD
{
tempDifference <<= 3; //温度偏差值乘以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; //绿灯亮 To enable the LED toggling effect
LED_OUT &= ~LED2; //红灯灭
BCSCTL1 |= DIVA_1; //辅助时钟分频设置为2 ,ACLK=6KHz
BCSCTL3 |= LFXT1S_2; //辅助时钟源选择VLOCLK,12KHz //ACLK = VLO
TACCR0 = 1200; //
TACTL = TASSEL_1 | MC_1; //定时器时钟源选择辅助时钟ACLK,增计数模式 // TACLK = SMCLK, Up mode.
TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 // TACCTL1 Capture Compare
TACCR1 = 600;
__bis_SR_register(LPM3_bits + GIE); // LPM0 with interrupts enabled ??低功耗模式LPM3
//此时cpu停止,等待中断,如果是比较1中断,则进入中断程序:ta1_isr(void),因为是CC1。
//如果是按键中断,则进入PORT1_ISR(void)中断服务程序,在PORT1_ISR(void)中将退出此低功耗模式
}
//配置温度传感器模数转换
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.
TACCTL0 = CCIE;
TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 ??OUTMOD_3有什么用? // TACCTL1 Capture Compare
TACCR1 = 1;
}
//配置定时器为Uart模式
void ConfigureTimerUart(void)
{
timerMode = TIMER_UART_MODE; // Configure TimerA0 UART TX
TACCTL0 = OUT; //输出为高电平 // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2 + ID_3; //定时器时钟源选择辅助时钟SMCLK,连续计数模式 ,时钟8分频 // SMCLK/8, continuous mode
P1SEL |= TXD + RXD; //打开P1.1,P1.2引脚特殊功能
P1DIR |= TXD; //P1.1端口方向为输出
}
//串口发送子程序 Function Transmits Character from TXByte
void Transmit()
{
BitCnt = 0xA; //低电平起始位+8位数据+高电平停止位共10位 // Load Bit counter, 8data + ST/SP
/* Simulate a timer capture event to obtain the value of TAR into the TACCR0 register */
//模仿捕捉模式以获得当前的TAR值赋予TACCR0
TACCTL0 = CM_1 + CCIS_2 + SCS + CAP + OUTMOD0; //上升沿捕捉,输入源为GND,输出模式置位模式 //capture on rising edge, initially set to GND as input // clear CCIFG flag
TACCTL0 |= CCIS_3; //改变输入源为VCC,相当于输入源上升沿变化,触发捕捉//change input to Vcc, effectively rising the edge, triggering the capture action
while (!(TACCTL0 & CCIFG)); //查询TACCTL0中断标志位 //allowing for the capturing//updating TACCR0.
TACCR0 += Bitime ; //首位发送延时 // Some time till first bit
TXByte |= 0x100; //增加停止位 // Add mark stop bit to TXByte
TXByte = TXByte << 1; //左移一位右边添加一位0表示起始位 // Add space start bit
TACCTL0 = CCIS0 + OUTMOD0 + CCIE; //比较模式,OUTMOD0=OUTMOD_1输出模式为置位模式,清中断标志,中断允许 // TXD = mark = idle
while ( TACCTL0 & CCIE ); //循环,直到反复中断中完成发送 // Wait for TX completion
}
//TACCR0中断专用, Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
if (timerMode == TIMER_UART_MODE) //定时器为Uart模式
{
TACCR0 += Bitime; //TACCR0加上一位串口数据所需的计数量,准备下一次中断 // Add Offset to TACCR0
if (TACCTL0 & CCIS0) //为什么要? TX on CCI0B?
{
if ( BitCnt == 0) //如果全部发送完成
{
P1SEL &= ~(TXD+RXD); //取消引脚特殊功能
TACCTL0 &= ~ CCIE ; //关闭中断使能 // All bits TXed, disable interrupt
}
else
{
TACCTL0 |= OUTMOD2; //注意是“或”运算 ,设置成复位模式(原来为复位OUTMOD0,现在为OUTMOD_3) // TX Space
if (TXByte & 0x01)
TACCTL0 &= ~ OUTMOD2; //如果发送的是1,输出模式转为置位模式 // TX Mark
TXByte = TXByte >> 1; //右移一位,准备下一位发送
BitCnt --; //发送位计数
}
}
}
else //定位器为PWM模式
{
if (tempPolarity == TEMP_HOT)
LED_OUT |= LED1; //如果相对于参考温度偏差为正,LED1绿灯置为亮
if (tempPolarity == TEMP_COLD)
LED_OUT |= LED2; //如果相对于参考温度偏差为负,LED2红灯置为亮
TACCTL0 &= ~CCIFG; //清中断标志位??有必要么?不是自动清除?
}
}
//TACCR1和定时器共用中断向量
#pragma vector=TIMERA1_VECTOR
__interrupt void ta1_isr(void)
{
TACCTL1 &= ~CCIFG; //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除
if (applicationMode == APP_APPLICATION_MODE)
LED_OUT &= ~(LED1 + LED2); //如果程序运行至是应用模式,置两灯皆灭
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[i];不是错了么?
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
}
复制代码
加载中...
lpmrzx
4楼-- · 2019-03-26 12:36
精彩回答 2 元偷偷看……
加载中...
chuzhitian
5楼-- · 2019-03-26 15:04
但是INCH10是在哪儿啊?在单片机内部吗??
加载中...
chunyang
6楼-- · 2019-03-26 19:36
片内温度传感器是为了应对超低功耗下的便携产品中的低精度温度测量,如果参数不能满足或工艺条件不准许,那就应该外扩适当的传感器。
加载中...
上一页
1
2
3
4
下一页
一周热门
更多
>
相关问题
相关文章
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
- /*这是2012.1.3在官方网站http://processors.wiki.ti.com/index.php?title=MSP430_LaunchPad_(MSP-EXP430G2)#Complete_Projects 下载的,版本号:slac435b
- *中文为本人http://wangfuchong.com添加的注释,切记不一定正确,仅供尽可能地快速了解程序的结构。
- ×还是有一些疑惑,总觉得有不够严谨的可能,大家帮助分析。
- * main.c
- *
- * MSP-EXP430G2-LaunchPad User Experience Application
- *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the
- * distribution.
- *
- * Neither the name of Texas Instruments Incorporated nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- /******************************************************************************
- * MSP-EXP430G2-LaunchPad User Experience Application
- *
- * 1. Device starts up in LPM3 + blinking LED to indicate device is alive
- * + Upon first button press, device transitions to application mode
- * 2. Application Mode
- * + Continuously sample ADC Temp Sensor channel, compare result against
- * initial value
- * + Set PWM based on measured ADC offset: Red LED for positive offset, Green
- * LED for negative offset
- * + Transmit temperature value via TimerA UART to PC
- * + Button Press --> Calibrate using current temperature
- * Send character '? via UART, notifying PC
- *
- * Changes:
- *
- * 1.2 + Updated register naming conventions to reflect latest standard by TI
- * e.g.: CCR0 --> TACCR0, CCTL0 --> TACCTL0
- * + Changed method to capture TAR value into TACCR0 by using capture a
- * SW-triggered event. [Changing TACCR input from GND to VCC]
- × 1.2是与版本slac435a相比新更改的部分
- * 1.1 + LED1 & LED2 labels changed so that Green LED(LED2) indicates sampled
- * temperature colder than calibrated temperature and vice versa
- * with Red LED (LED1).
- * + Turn off peripheral function of TXD after transmitting byte to
- * eliminate the extra glitch at the end of UART transmission
- * 1.0 Initial Release Version
- *
- * Texas Instruments, Inc.
- ******************************************************************************/
-
- #include "msp430g2231.h"
- #define LED1 BIT0 //绿灯,BIT0,BIT6之类的是宏定义,请在头文件"msp430g2231.h"中查看
- #define LED2 BIT6 //红灯,参见MSP-EXP430G2 LaunchPad Experimenter Board User's Guide
- #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 TXD BIT1 // TXD on P1.1
- #define RXD BIT2 // RXD on P1.2
- #define APP_STANDBY_MODE 0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态
- #define APP_APPLICATION_MODE 1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度
- #define TIMER_PWM_MODE 0
- #define TIMER_UART_MODE 1 //串口模式状态
- #define TIMER_PWM_PERIOD 2000
- #define TIMER_PWM_OFFSET 20
- #define TEMP_SAME 0
- #define TEMP_HOT 1
- #define TEMP_COLD 2
- #define TEMP_THRESHOLD 5
- // 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
-
- #define UART_UPDATE_INTERVAL 1000 //主循环次数进行一次串口发送温度值
- 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;
-
- /* Using an 8-value moving average filter on sampled ADC values */
- 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 ConfigureTimerUart(void); //配置定时器为Uart模式
- void Transmit(void); //串口发送子程序
- void InitializeClocks(void); //初始化时钟系统
- void main(void)
- {
- unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL; //主循环次数进行一次串口发送温度值
- unsigned char i;
- WDTCTL = WDTPW + WDTHOLD; // 停止看门狗 Stop WDT
- InitializeClocks(); //初始化时钟系统
- InitializeButton(); //配置按键
- InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态
- PreApplicationMode(); //进入待机模式,红绿灯交替闪,等待按键 Blinks LEDs, waits for button press
- //执行PreApplicationMode()将进入低功耗模式,程序停止在此,直到有按键按下
-
- /* 进入应用模式 Application Mode begins */
- applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式
- ConfigureAdcTempSensor(); //配置温度传感器模数转换
- ConfigureTimerPwm(); //配置定位器PWM模式
-
- __enable_interrupt(); //使能全局中断 Enable interrupts.
-
- /* Main Application Loop */
- while(1)
- {
- ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次 Sampling and conversion start
- __bis_SR_register(CPUOFF + GIE); //进入省电模式LPM0,等待AD转换完成中断 LPM0 with interrupts enabled
-
-
- /* Moving average filter out of 8 values to somewhat stabilize sampled ADC */
- 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
-
- if ((--uartUpdateTimer == 0) || calibrateUpdate ) //如果主循环了UART_UPDATE_INTERVAL次或者参考温度按键按过
- {
- ConfigureTimerUart();
- if (calibrateUpdate)
- {
- TXByte = 248; // A character with high value, outside of temp range
- Transmit(); //串口发送值248表示按键按下进行了校准参考
- calibrateUpdate = 0; //复位参考温度校准标志变量
- }
- TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 ); //计算温度华氏值
-
- Transmit(); //串口发送华氏温度值
-
- uartUpdateTimer = UART_UPDATE_INTERVAL; //复位循环计数变量
- ConfigureTimerPwm(); //配置定时器回PWM模式
- }
-
- tempDifference = tempAverage - tempCalibrated; //计算相对于参考温度的差值
- if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD
- {
- tempDifference = -tempDifference; //差值取正
- tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD
- LED_OUT &= ~ LED1; //LED1绿灯置灭
- }
- else
- if (tempDifference > TEMP_THRESHOLD) //如果采样温度值高于参考温度值差值TEMP_THRESHOLD
- {
- tempPolarity = TEMP_HOT; //极性变量设为值TEMP_COLD
- LED_OUT &= ~ LED2; //LED2红灯置灭
- }
- else //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD
- {
- tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME
- TACCTL0 &= ~CCIE; //关TACCTL0中断使能
- TACCTL1 &= ~CCIE; //关TACCTL1中断使能
- LED_OUT &= ~(LED1 + LED2); //置两灯皆灭
- }
-
- if (tempPolarity != TEMP_SAME) //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD
- {
- tempDifference <<= 3; //温度偏差值乘以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; //绿灯亮 To enable the LED toggling effect
- LED_OUT &= ~LED2; //红灯灭
-
- BCSCTL1 |= DIVA_1; //辅助时钟分频设置为2 ,ACLK=6KHz
- BCSCTL3 |= LFXT1S_2; //辅助时钟源选择VLOCLK,12KHz //ACLK = VLO
-
- TACCR0 = 1200; //
- TACTL = TASSEL_1 | MC_1; //定时器时钟源选择辅助时钟ACLK,增计数模式 // TACLK = SMCLK, Up mode.
- TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 // TACCTL1 Capture Compare
- TACCR1 = 600;
- __bis_SR_register(LPM3_bits + GIE); // LPM0 with interrupts enabled ??低功耗模式LPM3
- //此时cpu停止,等待中断,如果是比较1中断,则进入中断程序:ta1_isr(void),因为是CC1。
- //如果是按键中断,则进入PORT1_ISR(void)中断服务程序,在PORT1_ISR(void)中将退出此低功耗模式
- }
- //配置温度传感器模数转换
- 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.
- TACCTL0 = CCIE;
- TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 ??OUTMOD_3有什么用? // TACCTL1 Capture Compare
- TACCR1 = 1;
- }
- //配置定时器为Uart模式
- void ConfigureTimerUart(void)
- {
- timerMode = TIMER_UART_MODE; // Configure TimerA0 UART TX
-
- TACCTL0 = OUT; //输出为高电平 // TXD Idle as Mark
- TACTL = TASSEL_2 + MC_2 + ID_3; //定时器时钟源选择辅助时钟SMCLK,连续计数模式 ,时钟8分频 // SMCLK/8, continuous mode
- P1SEL |= TXD + RXD; //打开P1.1,P1.2引脚特殊功能
- P1DIR |= TXD; //P1.1端口方向为输出
- }
- //串口发送子程序 Function Transmits Character from TXByte
- void Transmit()
- {
- BitCnt = 0xA; //低电平起始位+8位数据+高电平停止位共10位 // Load Bit counter, 8data + ST/SP
- /* Simulate a timer capture event to obtain the value of TAR into the TACCR0 register */
- //模仿捕捉模式以获得当前的TAR值赋予TACCR0
- TACCTL0 = CM_1 + CCIS_2 + SCS + CAP + OUTMOD0; //上升沿捕捉,输入源为GND,输出模式置位模式 //capture on rising edge, initially set to GND as input // clear CCIFG flag
- TACCTL0 |= CCIS_3; //改变输入源为VCC,相当于输入源上升沿变化,触发捕捉//change input to Vcc, effectively rising the edge, triggering the capture action
- while (!(TACCTL0 & CCIFG)); //查询TACCTL0中断标志位 //allowing for the capturing//updating TACCR0.
- TACCR0 += Bitime ; //首位发送延时 // Some time till first bit
- TXByte |= 0x100; //增加停止位 // Add mark stop bit to TXByte
- TXByte = TXByte << 1; //左移一位右边添加一位0表示起始位 // Add space start bit
- TACCTL0 = CCIS0 + OUTMOD0 + CCIE; //比较模式,OUTMOD0=OUTMOD_1输出模式为置位模式,清中断标志,中断允许 // TXD = mark = idle
- while ( TACCTL0 & CCIE ); //循环,直到反复中断中完成发送 // Wait for TX completion
- }
- //TACCR0中断专用, Timer A0 interrupt service routine
- #pragma vector=TIMERA0_VECTOR
- __interrupt void Timer_A (void)
- {
- if (timerMode == TIMER_UART_MODE) //定时器为Uart模式
- {
- TACCR0 += Bitime; //TACCR0加上一位串口数据所需的计数量,准备下一次中断 // Add Offset to TACCR0
- if (TACCTL0 & CCIS0) //为什么要? TX on CCI0B?
- {
- if ( BitCnt == 0) //如果全部发送完成
- {
- P1SEL &= ~(TXD+RXD); //取消引脚特殊功能
- TACCTL0 &= ~ CCIE ; //关闭中断使能 // All bits TXed, disable interrupt
- }
-
- else
- {
- TACCTL0 |= OUTMOD2; //注意是“或”运算 ,设置成复位模式(原来为复位OUTMOD0,现在为OUTMOD_3) // TX Space
- if (TXByte & 0x01)
- TACCTL0 &= ~ OUTMOD2; //如果发送的是1,输出模式转为置位模式 // TX Mark
- TXByte = TXByte >> 1; //右移一位,准备下一位发送
- BitCnt --; //发送位计数
- }
- }
- }
- else //定位器为PWM模式
- {
- if (tempPolarity == TEMP_HOT)
- LED_OUT |= LED1; //如果相对于参考温度偏差为正,LED1绿灯置为亮
- if (tempPolarity == TEMP_COLD)
- LED_OUT |= LED2; //如果相对于参考温度偏差为负,LED2红灯置为亮
- TACCTL0 &= ~CCIFG; //清中断标志位??有必要么?不是自动清除?
- }
- }
- //TACCR1和定时器共用中断向量
- #pragma vector=TIMERA1_VECTOR
- __interrupt void ta1_isr(void)
- {
- TACCTL1 &= ~CCIFG; //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除
- if (applicationMode == APP_APPLICATION_MODE)
- LED_OUT &= ~(LED1 + LED2); //如果程序运行至是应用模式,置两灯皆灭
- 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[i];不是错了么?
- 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
- }
复制代码
-
- #include "msp430g2231.h"
- #define LED1 BIT0 //绿灯,BIT0,BIT6之类的是宏定义,请在头文件"msp430g2231.h"中查看
- #define LED2 BIT6 //红灯,参见MSP-EXP430G2 LaunchPad Experimenter Board User's Guide
- #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 TXD BIT1 // TXD on P1.1
- #define RXD BIT2 // RXD on P1.2
- #define APP_STANDBY_MODE 0 //待机模式标志,也就是接上电源(或USB)后红绿灯交替闪的状态
- #define APP_APPLICATION_MODE 1 //应用模式标志,也就是待机模式时按按键后进入的状态,也就是测量温度
- #define TIMER_PWM_MODE 0
- #define TIMER_UART_MODE 1 //串口模式状态
- #define TIMER_PWM_PERIOD 2000
- #define TIMER_PWM_OFFSET 20
- #define TEMP_SAME 0
- #define TEMP_HOT 1
- #define TEMP_COLD 2
- #define TEMP_THRESHOLD 5
- // 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
-
- #define UART_UPDATE_INTERVAL 1000 //主循环次数进行一次串口发送温度值
- 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;
-
- /* Using an 8-value moving average filter on sampled ADC values */
- 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 ConfigureTimerUart(void); //配置定时器为Uart模式
- void Transmit(void); //串口发送子程序
- void InitializeClocks(void); //初始化时钟系统
- void main(void)
- {
- unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL; //主循环次数进行一次串口发送温度值
- unsigned char i;
- WDTCTL = WDTPW + WDTHOLD; // 停止看门狗 Stop WDT
- InitializeClocks(); //初始化时钟系统
- InitializeButton(); //配置按键
- InitializeLeds(); //设置端口并两设置两颗LED对应为熄灭初始状态
- PreApplicationMode(); //进入待机模式,红绿灯交替闪,等待按键 Blinks LEDs, waits for button press
- //执行PreApplicationMode()将进入低功耗模式,程序停止在此,直到有按键按下
-
- /* 进入应用模式 Application Mode begins */
- applicationMode = APP_APPLICATION_MODE; //功能模式标志变成应用模式
- ConfigureAdcTempSensor(); //配置温度传感器模数转换
- ConfigureTimerPwm(); //配置定位器PWM模式
-
- __enable_interrupt(); //使能全局中断 Enable interrupts.
-
- /* Main Application Loop */
- while(1)
- {
- ADC10CTL0 |= ENC + ADC10SC; //ADC使能,ADC开始转换一次 Sampling and conversion start
- __bis_SR_register(CPUOFF + GIE); //进入省电模式LPM0,等待AD转换完成中断 LPM0 with interrupts enabled
-
-
- /* Moving average filter out of 8 values to somewhat stabilize sampled ADC */
- 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
-
- if ((--uartUpdateTimer == 0) || calibrateUpdate ) //如果主循环了UART_UPDATE_INTERVAL次或者参考温度按键按过
- {
- ConfigureTimerUart();
- if (calibrateUpdate)
- {
- TXByte = 248; // A character with high value, outside of temp range
- Transmit(); //串口发送值248表示按键按下进行了校准参考
- calibrateUpdate = 0; //复位参考温度校准标志变量
- }
- TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 ); //计算温度华氏值
-
- Transmit(); //串口发送华氏温度值
-
- uartUpdateTimer = UART_UPDATE_INTERVAL; //复位循环计数变量
- ConfigureTimerPwm(); //配置定时器回PWM模式
- }
-
- tempDifference = tempAverage - tempCalibrated; //计算相对于参考温度的差值
- if (tempDifference < -TEMP_THRESHOLD) //如果采样温度值低于参考温度值差值TEMP_THRESHOLD
- {
- tempDifference = -tempDifference; //差值取正
- tempPolarity = TEMP_COLD; //极性变量设为值TEMP_COLD
- LED_OUT &= ~ LED1; //LED1绿灯置灭
- }
- else
- if (tempDifference > TEMP_THRESHOLD) //如果采样温度值高于参考温度值差值TEMP_THRESHOLD
- {
- tempPolarity = TEMP_HOT; //极性变量设为值TEMP_COLD
- LED_OUT &= ~ LED2; //LED2红灯置灭
- }
- else //如果相对于参考温度值偏差没有超过阈值TEMP_THRESHOLD
- {
- tempPolarity = TEMP_SAME; //性变量设为值TEMP_SAME
- TACCTL0 &= ~CCIE; //关TACCTL0中断使能
- TACCTL1 &= ~CCIE; //关TACCTL1中断使能
- LED_OUT &= ~(LED1 + LED2); //置两灯皆灭
- }
-
- if (tempPolarity != TEMP_SAME) //如果相对于参考温度值偏差超过阈值TEMP_THRESHOLD
- {
- tempDifference <<= 3; //温度偏差值乘以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; //绿灯亮 To enable the LED toggling effect
- LED_OUT &= ~LED2; //红灯灭
-
- BCSCTL1 |= DIVA_1; //辅助时钟分频设置为2 ,ACLK=6KHz
- BCSCTL3 |= LFXT1S_2; //辅助时钟源选择VLOCLK,12KHz //ACLK = VLO
-
- TACCR0 = 1200; //
- TACTL = TASSEL_1 | MC_1; //定时器时钟源选择辅助时钟ACLK,增计数模式 // TACLK = SMCLK, Up mode.
- TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 // TACCTL1 Capture Compare
- TACCR1 = 600;
- __bis_SR_register(LPM3_bits + GIE); // LPM0 with interrupts enabled ??低功耗模式LPM3
- //此时cpu停止,等待中断,如果是比较1中断,则进入中断程序:ta1_isr(void),因为是CC1。
- //如果是按键中断,则进入PORT1_ISR(void)中断服务程序,在PORT1_ISR(void)中将退出此低功耗模式
- }
- //配置温度传感器模数转换
- 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.
- TACCTL0 = CCIE;
- TACCTL1 = CCIE + OUTMOD_3; //捕获/比较控制寄存器1设置为比较模式,输出模式为“置位/复位” ,中断允许 ??OUTMOD_3有什么用? // TACCTL1 Capture Compare
- TACCR1 = 1;
- }
- //配置定时器为Uart模式
- void ConfigureTimerUart(void)
- {
- timerMode = TIMER_UART_MODE; // Configure TimerA0 UART TX
-
- TACCTL0 = OUT; //输出为高电平 // TXD Idle as Mark
- TACTL = TASSEL_2 + MC_2 + ID_3; //定时器时钟源选择辅助时钟SMCLK,连续计数模式 ,时钟8分频 // SMCLK/8, continuous mode
- P1SEL |= TXD + RXD; //打开P1.1,P1.2引脚特殊功能
- P1DIR |= TXD; //P1.1端口方向为输出
- }
- //串口发送子程序 Function Transmits Character from TXByte
- void Transmit()
- {
- BitCnt = 0xA; //低电平起始位+8位数据+高电平停止位共10位 // Load Bit counter, 8data + ST/SP
- /* Simulate a timer capture event to obtain the value of TAR into the TACCR0 register */
- //模仿捕捉模式以获得当前的TAR值赋予TACCR0
- TACCTL0 = CM_1 + CCIS_2 + SCS + CAP + OUTMOD0; //上升沿捕捉,输入源为GND,输出模式置位模式 //capture on rising edge, initially set to GND as input // clear CCIFG flag
- TACCTL0 |= CCIS_3; //改变输入源为VCC,相当于输入源上升沿变化,触发捕捉//change input to Vcc, effectively rising the edge, triggering the capture action
- while (!(TACCTL0 & CCIFG)); //查询TACCTL0中断标志位 //allowing for the capturing//updating TACCR0.
- TACCR0 += Bitime ; //首位发送延时 // Some time till first bit
- TXByte |= 0x100; //增加停止位 // Add mark stop bit to TXByte
- TXByte = TXByte << 1; //左移一位右边添加一位0表示起始位 // Add space start bit
- TACCTL0 = CCIS0 + OUTMOD0 + CCIE; //比较模式,OUTMOD0=OUTMOD_1输出模式为置位模式,清中断标志,中断允许 // TXD = mark = idle
- while ( TACCTL0 & CCIE ); //循环,直到反复中断中完成发送 // Wait for TX completion
- }
- //TACCR0中断专用, Timer A0 interrupt service routine
- #pragma vector=TIMERA0_VECTOR
- __interrupt void Timer_A (void)
- {
- if (timerMode == TIMER_UART_MODE) //定时器为Uart模式
- {
- TACCR0 += Bitime; //TACCR0加上一位串口数据所需的计数量,准备下一次中断 // Add Offset to TACCR0
- if (TACCTL0 & CCIS0) //为什么要? TX on CCI0B?
- {
- if ( BitCnt == 0) //如果全部发送完成
- {
- P1SEL &= ~(TXD+RXD); //取消引脚特殊功能
- TACCTL0 &= ~ CCIE ; //关闭中断使能 // All bits TXed, disable interrupt
- }
-
- else
- {
- TACCTL0 |= OUTMOD2; //注意是“或”运算 ,设置成复位模式(原来为复位OUTMOD0,现在为OUTMOD_3) // TX Space
- if (TXByte & 0x01)
- TACCTL0 &= ~ OUTMOD2; //如果发送的是1,输出模式转为置位模式 // TX Mark
- TXByte = TXByte >> 1; //右移一位,准备下一位发送
- BitCnt --; //发送位计数
- }
- }
- }
- else //定位器为PWM模式
- {
- if (tempPolarity == TEMP_HOT)
- LED_OUT |= LED1; //如果相对于参考温度偏差为正,LED1绿灯置为亮
- if (tempPolarity == TEMP_COLD)
- LED_OUT |= LED2; //如果相对于参考温度偏差为负,LED2红灯置为亮
- TACCTL0 &= ~CCIFG; //清中断标志位??有必要么?不是自动清除?
- }
- }
- //TACCR1和定时器共用中断向量
- #pragma vector=TIMERA1_VECTOR
- __interrupt void ta1_isr(void)
- {
- TACCTL1 &= ~CCIFG; //捕获比较中断标志CCIFG。比较模式:定时器 TAR 值等于寄存器 CCR1 值时CCIFG置位。需手动清除
- if (applicationMode == APP_APPLICATION_MODE)
- LED_OUT &= ~(LED1 + LED2); //如果程序运行至是应用模式,置两灯皆灭
- 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[i];不是错了么?
- 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
- }
复制代码一周热门 更多>