LaunchPad 官方例程(加注释版)
1.
//******************************************************************************
// LaunchPad Lab2 - Software Toggle P1.0,
//
// MSP430G2xx2
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// | P1.0|-->LED
//
//******************************************************************************
#include <msp430g2553.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
//在MSP430的information A Flash段中一般会有一些比如DCO校正信息,温度传感器校正等等的数据存在,这些是出厂设置好的!但是有时候用户会不小心把infoA擦除掉,而擦除后的内容就为0xFF了。下面程序段的作用是,判断CALBC1_1MHZ的地址内容是否被擦除了,如果擦除了,那么while(1)。如果没有,那么将校正信息添入相应的寄存器,可以得到精度相对高的DCO输出频率
if (CALBC1_1MHZ == 0xFF || CALDCO_1MHZ == 0xFF)
{
while(1); // If calibration constants erased, trap CPU!!
}
// Configure Basic Clock
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
BCSCTL3 |= LFXT1S_2; // Set LFXT1为vol时钟即12kHZ
P1DIR = BIT6; // P1.6 output (green LED),其余位为输入,也可以用 P1DIR=0x40;
P1OUT = 0; // LED off
IFG1 &= ~OFIFG; // Clear OSCFault flag
BCSCTL2 |=SELM_1 + DIVM_0; // Set MCLK
for(;;)
{
P1OUT = BIT6; // P1.6 on (green LED)
_delay_cycles(100);
P1OUT = 0; // green LED off
_delay_cycles(5000);
}
}
2.
//******************************************************************************
// LaunchPad Lab3 - Software Port Interrupt Service
//
// MSP430G2xx2
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// /|\ | |
// --o--|P1.3 P1.0|-->LED
// \|/
//
//******************************************************************************
#include <msp430g2553.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= BIT0; // Set P1.0 to output direction
P1IES |= BIT3; // P1.3 Hi/lo edge
P1IFG &= ~BIT3; // P1.3 IFG cleared
P1IE |= BIT3; // P1.3 interrupt enabled
_BIS_SR(LPM4_bits + GIE); // Enter LPM4 w/interrupt
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if (P1IFG & BIT3)
{
P1OUT ^= BIT0; // P1.0 = toggle
P1IFG &= ~BIT3; // P1.3 IFG cleared
}
}
3.
//******************************************************************************
// LaunchPad Lab5 - ADC10, Sample A10 Temp and Convert to oC and oF
//
// MSP430G2452
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// |A10 |
//
//******************************************************************************
#include "msp430g2553.h"
long temp;
long IntDegF;
long IntDegC;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
//Configure ADC10
ADC10CTL1 = INCH_10 + ADC10DIV_3; // Choose ADC Channel as Temp Sensor
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; //Choose ADC Ref source
__enable_interrupt(); // Enable interrupts.
TACCR0 = 30; // Delay to allow Ref to settle
TACCTL0 |= CCIE; // Compare-mode interrupt.
TACTL = TASSEL_2 | MC_1; // TACLK = SMCLK, Up mode.
LPM0; // Wait for delay.
TACCTL0 &= ~CCIE; // Disable timer Interrupt
__disable_interrupt();
while(1)
{
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(LPM0_bits + GIE); // LPM0 with interrupts enabled
// oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468
temp = ADC10MEM;
IntDegF = ((temp - 630) * 761) / 1024;
// oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
temp = ADC10MEM;
IntDegC = ((temp - 673) * 423) / 1024;
__no_operation(); // SET BREAKPOINT HERE
}
}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(LPM0_bits); // Clear CPUOFF bit from 0(SR)
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void ta0_isr(void)
{
TACTL = 0;
__bic_SR_register_on_exit(LPM0_bits); // Clear CPUOFF bit from 0(SR)
}
4.
//******************************************************************************
// MSP430F20xx Demo - Basic Clock, Output Buffered SMCLK, ACLK and MCLK/10
//
// Description: Buffer ACLK on P2.0, default SMCLK(DCO) on P1.4 and MCLK/10 on
// P1.5.
// ACLK = LFXT1 = VLO, MCLK = SMCLK = default DCO
// //* External watch crystal installed on XIN XOUT is required for ACLK *//
//
// MSP430F20xx
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// | P1.4/SMCLK|-->SMCLK = Default DCO
// | P1.5|-->MCLK/10 = DCO/10
// | P1.0/ACLK|-->ACLK = VLO
//
// M. Buccini / L. Westlund
// Texas Instruments Inc.
// October 2005
// Built with IAR Embedded Workbench Version: 3.40A
//******************************************************************************
#include <msp430x20x3.h>
unsigned char s;
void main(void)
{
WDTCTL = WDTPW +WDTHOLD; // Stop Watchdog Timer
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
//DCOCTL = 0;
//BCSCTL1 = CALBC1_16MHZ;
//DCOCTL = CALBC1_16MHZ;
P1DIR |= 0x31; // P1.0,5 and P1.4 outputs
P1SEL |= 0x11; // P1.0,4 ACLK/VLO, SMCLK/DCO output
//SMCLK Sub-System Main Clk, ACLK和SMCLK可以通过复用引脚输出,MCLK不能直接输出体现, MCLK可以配置为VLO或者DCO
while(1)
{
P1OUT |= 0x20; // P1.5 = 1, 通过开关P1.5来体现MCLK,这两条指令的周期大概为SMCLK的1/10
P1OUT &= ~0x20;//20;
}
}
5.
//******************************************************************************
// MSP430xG46x Demo - FLL+, Runs Internal DCO at 8MHz
//
// Description: This program demonstrates setting the internal DCO to run at
// 8MHz with auto-calibration by the FLL+.
// ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO = (121+1) x 2 x ACLK = 7995392Hz
// //* An external watch crystal between XIN & XOUT is required for ACLK *//
//
// MSP430xG461x
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// | P1.1|--> MCLK = 8MHz
// | |
// | P1.5|--> ACLK = 32kHz
// | |
//
// K. Quiring/ M. Mitchell
// Texas Instruments Inc.
// October 2006
// Built with IAR Embedded Workbench Version: 3.41A
//*****************************************************************************
#include <msp430xG46x.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
FLL_CTL0 |= DCOPLUS + XCAP18PF; // DCO+ set, freq = xtal x D x N+1
SCFI0 |= FN_4; // x2 DCO freq, 8MHz nominal DCO
SCFQCTL = 121; // (121+1) x 32768 x 2 = 7.99 MHz
P1DIR = 0x22; // P1.1 & P1.5 to output direction
P1SEL = 0x22; // P1.1 & P1.5 to output MCLK & ACLK
while(1); // Loop in place
}
6.
//****************************************************************************
// MSP430xG46x Demo - Flash In-System Programming, Copy SegA to SegB
//
// Description: This program first erases flash seg A, then it increments all
// values in seg A, then it erases seg B, then copies seg A to seg B.
// Assumed MCLK 550kHz - 900kHz.
// //* Set Breakpoint on NOP in the Mainloop to avoid Stressing Flash *//
//
// MSP430xG461x
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
//
// M. Mitchell
// Texas Instruments Inc.
// Feb 2005
// Built with IAR Embedded Workbench Version: 3.21A
//******************************************************************************
#include <msp430xG46x.h>
char value; // 8-bit value to write to segment A
// Function prototypes
void write_SegA (char value);
void copy_A2B (void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
FCTL2 = FWKEY + FSSEL0 + FN0; // MCLK/2 for Flash Timing Generator
value = 0; // Initialize value
while(1) // Repeat forever
{
write_SegA(value++); // Write segment A, increment value
copy_A2B(); // Copy segment A to B
_NOP(); // SET BREAKPOINT HERE
}
}
void write_SegA (char value)
{
char *Flash_ptr; // Flash pointer
unsigned int i;
Flash_ptr = (char *) 0x1080; // Initialize Flash pointer
FCTL1 = FWKEY + ERASE; // Set Erase bit
FCTL3 = FWKEY; // Clear Lock bit
*Flash_ptr = 0; // Dummy write to erase Flash segment
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
for (i=0; i<128; i++)
{
*Flash_ptr++ = value; // Write value to flash
}
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCK; // Set LOCK bit
}
void copy_A2B (void)
{
char *Flash_ptrA; // Segment A pointer
char *Flash_ptrB; // Segment B pointer
unsigned int i;
Flash_ptrA = (char *) 0x1080; // Initialize Flash segment A pointer
Flash_ptrB = (char *) 0x1000; // Initialize Flash segment B pointer
FCTL1 = FWKEY + ERASE; // Set Erase bit
FCTL3 = FWKEY; // Clear Lock bit
*Flash_ptrB = 0; // Dummy write to erase Flash segment B
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
for (i=0; i<128; i++)
{
*Flash_ptrB++ = *Flash_ptrA++; // Copy value segment A to segment B
}
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCK; // Set LOCK bit
}
7.
//******************************************************************************
// MSP430xG46x Demo - Software Port Interrupt on P1.0 from LPM4
//
// Description: A hi/low transition on P1.0 will trigger P1_ISR which,
// toggles P2.1. Normal mode is LPM4 ~ 0.1uA. LPM4 current can be measured
// with the LED removed, all unused P1.x/P2.x configured as output or inputs
// pulled high or low, and ensure the P2.0 interrupt input does not float.
// ACLK = 32.768kHz, MCLK = SMCLK = default DCO
//
// MSP430xG461x
// -----------------
// /|\| |
// | | |
// --|RST |
// /|\ | |
// --o--|P1.0 P2.1|-->LED
// \|/
//
// K. Quiring/ M. Mitchell
// Texas Instruments Inc.
// October 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include <msp430xG46x.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
FLL_CTL0 |= XCAP14PF; // Configure load caps
P2DIR = BIT1; // Set P2.1 to output direction
P1IES = BIT0; // H-L transition
P1IE = BIT0; // Enable interrupt
_BIS_SR(LPM4_bits + GIE); // LPM4, enable interrupts
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port1_ISR (void)
{
unsigned volatile int i;
for (i=10000; i>0; i--); // Debounce delay
P1IFG &= ~BIT0; // Clear P1IFG
if ((P1IN & 0x01) == 0)
P2OUT ^= 0x02; // Toggle P2.1 using exclusive-OR
}
8.
//******************************************************************************
// MSP430xG46x Demo - Software Port Interrupt on P1.0 from LPM4
//
// Description: A hi/low transition on P1.0 will trigger P1_ISR which,
// toggles P2.1. Normal mode is LPM4 ~ 0.1uA. LPM4 current can be measured
// with the LED removed, all unused P1.x/P2.x configured as output or inputs
// pulled high or low, and ensure the P2.0 interrupt input does not float.
// ACLK = 32.768kHz, MCLK = SMCLK = default DCO
//
// MSP430xG461x
// -----------------
// /|\| |
// | | |
// --|RST |
// /|\ | |
// --o--|P1.0 P2.1|-->LED
// \|/
//
// K. Quiring/ M. Mitchell
// Texas Instruments Inc.
// October 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include <msp430xG46x.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
FLL_CTL0 |= XCAP14PF; // Configure load caps
P2DIR = BIT1; // Set P2.1 to output direction
P1IES = BIT0; // H-L transition
P1IE = BIT0; // Enable interrupt
_BIS_SR(LPM4_bits + GIE); // LPM4, enable interrupts
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port1_ISR (void)
{
unsigned volatile int i;
for (i=10000; i>0; i--); // Debounce delay
P1IFG &= ~BIT0; // Clear P1IFG
if ((P1IN & 0x01) == 0)
P2OUT ^= 0x02; // Toggle P2.1 using exclusive-OR
}
9.
//******************************************************************************
// MSP430xG46x Demo - USCI_A0, 115200 UART Echo ISR, DCO SMCLK
// (modified code example "msp430xG46x_uscia0_uart_01_115k.c")
//
// Description: Echo a received character, RX ISR used. Normal mode is LPM0.
// USCI_A0 RX interrupt triggers TX Echo.
// Baud rate divider with 1048576hz = 1048576/115200 = ~9.1 (009h|01h)
// ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO = 32 x ACLK = 1048576Hz
// //* An external watch crystal between XIN & XOUT is required for ACLK *//
//
// MSP430FG4619
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// | P2.5/UCA0RXD|<------------
// | | 115200 - 8N1
// | P2.4/UCA0TXD|------------>
//
// Texas Instruments Inc.
// October 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include "msp430xG46x.h"
void main(void)
{
volatile unsigned int i;
WDTCTL = WDTPW+WDTHOLD; // Stop WDT
FLL_CTL0 |= XCAP14PF; // Configure load caps
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (i = 0x47FF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG)); // OSCFault flag still set?
P2SEL |= 0x030; // P2.4,5 = USCI_A0 RXD/TXD
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 18;0x09; // 1MHz 115200
UCA0BR1 = 0;0x00; // 1MHz 115200
UCA0MCTL = 0;0x02; // Modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
_BIS_SR(LPM0_bits + GIE); // Enter LPM0, interrupts enabled
}
// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIA0RX_ISR (void)
{
while(!(IFG2&UCA0TXIFG));
UCA0TXBUF = UCA0RXBUF; // TX -> RXed character
}
10.
/******************************************************************************
* 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
******************************************************************************/
#include "msp430g2553.h"
#define LED0 BIT0
#define LED1 BIT6
#define LED_DIR P1DIR
#define LED_OUT P1OUT
#define BUTTON BIT3
#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
#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];
unsigned char tempMeasuredPosition=0;
long tempAverage;
long tempCalibrated, tempDifference;
void InitializeLeds(void);
void InitializeButton(void);
void PreApplicationMode(void); // Blinks LED, waits for button press
void ConfigureAdcTempSensor(void);
void ConfigureTimerPwm(void);
void ConfigureTimerUart(void);
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();
PreApplicationMode(); // Blinks LEDs, waits for button press
/* Application Mode begins */
applicationMode = APP_APPLICATION_MODE;
ConfigureAdcTempSensor();
ConfigureTimerPwm();
__enable_interrupt(); // Enable interrupts.
/* Main Application Loop */
while(1)
{
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // 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; // Divide by 8 to get average
if ((--uartUpdateTimer == 0) || calibrateUpdate )
{
ConfigureTimerUart();
if (calibrateUpdate)
{
TXByte = 248; // A character with high value, outside of temp range
Transmit();
calibrateUpdate = 0;
}
TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 );
Transmit();
uartUpdateTimer = UART_UPDATE_INTERVAL;
ConfigureTimerPwm();
}
tempDifference = tempAverage - tempCalibrated;
if (tempDifference < -TEMP_THRESHOLD)
{
tempDifference = -tempDifference;
tempPolarity = TEMP_COLD;
LED_OUT &= ~ LED1;
}
else
if (tempDifference > TEMP_THRESHOLD)
{
tempPolarity = TEMP_HOT;
LED_OUT &= ~ LED0;
}
else
{
tempPolarity = TEMP_SAME;
TACCTL0 &= ~CCIE;
TACCTL1 &= ~CCIE;
LED_OUT &= ~(LED0 + LED1);
}
if (tempPolarity != TEMP_SAME)
{
tempDifference <<= 3;
tempDifference += TIMER_PWM_OFFSET;
TACCR1 = ( (tempDifference) < (TIMER_PWM_PERIOD-1) ? (tempDifference) : (TIMER_PWM_PERIOD-1) );
TACCTL0 |= CCIE;
TACCTL1 |= CCIE;
}
}
}
void PreApplicationMode(void)
{
LED_DIR |= LED0 + LED1;
LED_OUT |= LED0; // To enable the LED toggling effect
LED_OUT &= ~LED1;
BCSCTL1 |= DIVA_1; // ACLK/2
BCSCTL3 |= LFXT1S_2; // ACLK = VLO
TACCR0 = 1200; //
TACTL = TASSEL_1 | MC_1; // TACLK = SMCLK, Up mode.
TACCTL1 = CCIE + OUTMOD_3; // TACCTL1 Capture Compare
TACCR1 = 600;
__bis_SR_register(LPM3_bits + GIE); // LPM0 with interrupts enabled
}
void ConfigureAdcTempSensor(void)
{
unsigned char i;
/* Configure ADC Temp Sensor Channel */
ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
__delay_cycles(1000); // Wait for ADC Ref to settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
tempCalibrated = ADC10MEM;
for (i=0; i < 8; i++)
tempMeasured[i] = tempCalibrated;
tempAverage = tempCalibrated;
}
void ConfigureTimerPwm(void)
{
timerMode = TIMER_PWM_MODE;
TACCR0 = TIMER_PWM_PERIOD; //
TACTL = TASSEL_2 | MC_1; // TACLK = SMCLK, Up mode.
TACCTL0 = CCIE;
TACCTL1 = CCIE + OUTMOD_3; // TACCTL1 Capture Compare
TACCR1 = 1;
}
void ConfigureTimerUart(void)
{
timerMode = TIMER_UART_MODE; // Configure TimerA0 UART TX
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2 + ID_3; // SMCLK/8, continuous mode
P1SEL |= TXD + RXD; //
P1DIR |= TXD; //
}
// Function Transmits Character from TXByte
void Transmit()
{
BitCnt = 0xA; // Load Bit counter, 8data + ST/SP
while (CCR0 != TAR) // Prevent async capture
CCR0 = TAR; // Current state of TA counter
CCR0 += Bitime; // Some time till first bit
TXByte |= 0x100; // Add mark stop bit to TXByte
TXByte = TXByte << 1; // Add space start bit
CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle
while ( CCTL0 & CCIE ); // Wait for TX completion
}
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
if (timerMode == TIMER_UART_MODE)
{
CCR0 += Bitime; // Add Offset to CCR0
if (CCTL0 & CCIS0) // TX on CCI0B?
{
if ( BitCnt == 0)
CCTL0 &= ~ CCIE; // All bits TXed, disable interrupt
else
{
CCTL0 |= OUTMOD2; // TX Space
if (TXByte & 0x01)
CCTL0 &= ~ OUTMOD2; // TX Mark
TXByte = TXByte >> 1;
BitCnt --;
}
}
}
else
{
if (tempPolarity == TEMP_HOT)
LED_OUT |= LED1;
if (tempPolarity == TEMP_COLD)
LED_OUT |= LED0;
TACCTL0 &= ~CCIFG;
}
}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void ta1_isr(void)
{
TACCTL1 &= ~CCIFG;
if (applicationMode == APP_APPLICATION_MODE)
LED_OUT &= ~(LED0 + LED1);
else
LED_OUT ^= (LED0 + LED1);
}
void InitializeClocks(void)
{
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 8 = 1MHz
}
void InitializeButton(void) // Configure Push Button
{
BUTTON_DIR &= ~BUTTON;
BUTTON_OUT |= BUTTON;
BUTTON_REN |= BUTTON;
BUTTON_IES |= BUTTON;
BUTTON_IFG &= ~BUTTON;
BUTTON_IE |= BUTTON;
}
void InitializeLeds(void)
{
LED_DIR |= LED0 + LED1;
LED_OUT &= ~(LED0 + LED1);
}
/* *************************************************************
* 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;
BUTTON_IE &= ~BUTTON; /* Debounce */
WDTCTL = WDT_ADLY_250;
IFG1 &= ~WDTIFG; /* clear interrupt flag */
IE1 |= WDTIE;
if (applicationMode == APP_APPLICATION_MODE)
{
tempCalibrated = tempAverage;
calibrateUpdate = 1;
}
else
{
applicationMode = APP_APPLICATION_MODE; // Switch from STANDBY to APPLICATION MODE
__bic_SR_register_on_exit(LPM3_bits);
}
}
#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<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//延时
void DelayMS(uint x)
{
uchar t;
while(x--) for(t=0;t<120;t++);
}
//主程序
void main()
{
uchar i,wei=0x80;
while(1)
{
for(i=0;i<8;i++)
{
P2=0xff; //关闭显示
wei=_crol_(wei,1);
P0=DSY_CODE[i]; //发送数字段码
P2=wei; //发送位码
DelayMS(300);
}
}
}
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
//段码
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
//位码
uchar code DSY_Index[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
//待显示到各数码管的数字缓冲(开始仅在 0 位显示 0,其他黑屏)
uchar Display_Buffer[]={0,10,10,10,10,10,10,10};
//延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
void Show_Count_ON_DSY()
{
uchar i;
for(i=0;i<8;i++)
{
P0=0xff;
P0=DSY_CODE[Display_Buffer[i]];
P2=DSY_Index[i];
DelayMS(2);
}
}
//主程序
void main()
{
uchar i,Key_NO,Key_Counts=0;
P0=0xff;
P1=0xff;
P2=0x00;
while(1)
{
Show_Count_ON_DSY();
P1=0xff;
Key_NO=P1;
//P1 口按键状态分别为 K1-0xfe,K2-0xfd,K3-0xfb
switch(Key_NO)
{
case 0xfe: Key_Counts++;
if(Key_Counts>8) Key_Counts=8;
Display_Buffer[Key_Counts-1]=Key_Counts;
break;
case 0xfd: if(Key_Counts>0)Display_Buffer[--Key_Counts]=10;
break;
case 0xfb: Display_Buffer[0]=0;
for(i=1;i<8;i++) Display_Buffer[i]=10;
Key_Counts=0;
}
//若键未释放则仅刷新显示,不进行键扫描
while(P1!=0xff) Show_Count_ON_DSY();
}
}
//1ms太短了,人眼无法识别,可以改成100ms试试
本人想用定时器A每1ms产生产生一个中断,让P1.6电平转换,从而使LED2每隔1ms闪烁一次
#include "msp430g2553.h"
int main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1DIR=0x40;
P1OUT=0x00;
DCOCTL=0;
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ; //设置DCO为1MHZ
BCSCTL2 = SELM_1; //主时钟和从时钟都选择DCOCLK
TACCTL0 = CCIE; //CCR0中断使能
TACCR0 = 1000; //设置定时器A每1ms中断一次
TACTL |= TASSEL_2 + ID_0+MC_1; //设置定时器A的时钟源为MCLK,并设置为不分频(1MHZ),增计数模式
//打开全局中断
_EINT();
while(1)
{
}
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TimerA_ISR(void)
{
P1OUT^=0x40; //电平翻转
TACCTL0&=~CCIFG; //清除中断标志位
}
利用按键中断控制LED亮暗
#include <msp430x20x2.h>
#define LED0 BIT0
#define LED1 BIT6
#define BUTTON BIT3
unsigned char count;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 关看门狗
P1DIR |= (LED0 + LED1); // 设LED口为输出
P1OUT &= ~(LED0 + LED1); // 关LED先
P1IE |= BUTTON; // 按键中断使能
P1IFG &= ~BUTTON; // 清除按键中断标志
__enable_interrupt(); // enable all interrupts
for(;;)
{}
}
// P1中断服务函数
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if(count==0)
{
P1OUT =!(LED0 +LED1); // 关LED
count++;
}
else
{
P1OUT =(LED0 + LED1);
count = 0;
}
P1IFG &= ~BUTTON; // P1.3 中断标志清除
}
//同样的,使用lcd1602显示,这里不再多述其程序了,前面有
#include "lcd1602.h"
#define Num_of_Results 32
static uint results[Num_of_Results];
uchar a[10]="0123456789";
uchar b[16]="temperatu ";
unsigned int ad_value[3];
void main()
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
//主系统时钟切换为外部高速晶振
if (CALBC1_8MHZ == 0xFF || CALDCO_8MHZ == 0xFF)
{
while(1); // If calibration constants erased, trap CPU!!
}
// Configure Basic Clock
BCSCTL1 = CALBC1_8MHZ; // Set range
DCOCTL = CALDCO_8MHZ; // Set DCO step + modulation*/
P1SEL |= BIT0+BIT1+BIT2; // p1.0为A0
P1DIR&=~(BIT0+BIT1+BIT2);// p1.0为输入
ADC10CTL0= ADC10ON+REFON+ADC10SHT_3+MSC+ADC10IE+SREF_1;
// ADC12ON打开ADC;
//ADC10SHT_3设置采样时间,合适即可
//MSC设置多次采样
// 中断允许,IFG置位后会进入中断服务程序
ADC10CTL1= CONSEQ_3+INCH_10;
//CONSEQ_2单通道多次转换
// INCH_10选择内部通道A10
ADC10CTL0&=~ADC10IFG;//清除中断标志位
_EINT();//打开中断
init_lcd();
delay(10);
while(1)
{
while (ADC10CTL1 & BUSY);// Wait if ADC10 core is active
ADC10CTL0 |= ENC+ADC10SC;//使能转换并且开始转换
_NOP();
}
}
//ADC中断服务函数,在这里用多次平均的
#pragma vector=ADC10_VECTOR
__interrupt void ADC10ISR (void)
{
uint i;
uchar ptr[4];
P2SEL=0X00;
static uint index = 0;
results[index++] =ADC10MEM;
if(index == Num_of_Results)
{
unsigned long sum = 0,real;
index = 0;
for(i = 0; i < Num_of_Results; i++)
{
sum += results[i];
}
sum >>= 5; //除以32求得平均值
real=((1.5*sum/1023)-0.986)/0.00355;//扩大1000倍
ptr[0] = real / 100;
ptr[1] = (real - ptr[0]*100)/10;
ptr[2] = (real - ptr[0]*100 - ptr[1]*10);
for(i=0;i<3;i++)
b[i+11]=a[ptr[i]];
_NOP();
display_string(b,0xc0);
_NOP();
}
ADC10CTL0&=~ADC10IFG;//清除中断标志位
}
/*实验板MSP-EXP430G2
* 利用定时器编写PWM电路,驱动LED,并可以通过按键调节亮度
* MCLK=SMCLK=DCOCLK=32×ACLK=1.048576MHz,
*/
#include <msp430g2553.h>
void main(void)
{
P1DIR |= BIT6+BIT0;
P1DIR &=~BIT3; //P1.3作为按键输入
P1SEL |= BIT6; //P1.6作为PWM输出
P1IE |= BIT3; // P1.3 interrupt enabled
P1IES |= BIT3; // P1.3 Hi/lo edge
P1REN |= BIT3; // P1.3 pullup
P1OUT|=BIT0; //P1.0作为一个指示灯输出
_EINT();
CCR0 = 9;// PWM 周期 =(CCRO+1)/1048576,频率=1.048576MHz/(CCRO+1))
CCTL1 = OUTMOD_7;// CCR1 reset/set
CCR1 = 1;// CCR1 PWM 占空比% = (CCR1+1)/(CCRO+1)
TACTL = TASSEL_2 + MC_1+TACLR;// MCLK, up mode,适用于高频率
for (;;)
{
_BIS_SR(GIE); // 进入 LPM3
_NOP();
}
}
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
P1OUT ^= BIT0; //每读一次中断,指示灯状态取反
TACCR1++;
if(TACCR1==CCR0)
TACCR1=1;
P1IFG &= ~BIT3; // P1.3 IFG cleared
}
#include "msp430g2553.h"
unsigned char num=0;
void main (void)
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
BCSCTL3 |= LFXT1S_2; // Set LFXT1为vol时钟即12kHZ
CCR0 =6000;
// CCTL0|= CCIE; //设置捕获/比较控制寄存器,CCIE=0x0010,使能捕获比较中断
CCR1 =3000; //设置捕获/比较寄存器,初始值为12000,对于ACLK时钟频率为12khz的频率,相当于1s
// CCTL2=CCIE;
CCR2 = 1500;
TA0CTL = TASSEL_1 +TACLR+MC_1+TAIE; // 设置定时器A控制寄存器,
// TASSEL_1选择辅助时钟ACLK,TASSEL_2选择子系统时钟SMCLK,与dco有关;
// TACLR=0x0004,清除定时器A计数器
//TACTL |= MC0(MC_1); //设置定时器A控制寄存器,MC0=0x0010,使计数模式为增计数
P1DIR |=BIT6+BIT0+BIT3;
_EINT(); //使能中断,这是一个C编译器支持的内部过程。
while(1); //无限次while循环
}
#pragma vector=TIMER0_A1_VECTOR//固定的格式,必须为TIMERA1_VECTOR,
__interrupt void Timer_A (void) //定时器A的CC0中断处理程序 必须是没有返回值的
{
switch( TAIV )
{
case 2: P1OUT ^= BIT0; //优先级最高
//CCR1 += 3000; // 必须的,否则将重0计数到最大
break;
case 4: P1OUT ^= BIT6;
//CCR2 +=6000;// 必须的,否则将重0计数到最大
break;
case 10: num++;
P1OUT ^= BIT3;
if(num==5)
CCTL1=CCIE;
if(num==10)
CCTL2=CCIE;
if(num==15)
{
CCTL1=0;
CCTL2=0;
num=0;
}
break;
}
}
//要是使用的持续计数模式,则应该每次进入中断后CCRx +=6000,确保每次重指定的数值开始计数
//以下是使用增计数模式实现计数的,定时一秒
#include <msp430x22x4.h>
void main()
{
WDTCTL=WDTPW+WDTHOLD; // 停止看门狗程序
BCSCTL1 =CALBC1_1MHZ; //设定DCO为1MHZ
DCOCTL =CALBC1_1MHZ; //上面两句可设可不设,因为系统时钟选择的是ACLK,而不是DCO,只是为了提醒自己首先必须设置系统时钟,系统复位时默认的是DCO;
P1DIR|=BIT0;
P1OUT|=BIT0;
TACTL=TASSEL0+TACLR;
CCTL0=CCIE;
CCR0=32767;
TACTL|=MC0;
_EINT();
LPM0;
}
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A(void)
{
P1OUT^=BIT0;
}
//以下是用连续计数模式来实现定时的,由于连续计数模式不受CCR0计数值得影响,因此须在中断处设置中断标志
#include <msp430x22x4.h>
void main()
{
WDTCTL=WDTPW+WDTHOLD; // 停止看门狗程序
BCSCTL1 =CALBC1_8MHZ; //设定DCO为1MHZ
DCOCTL =CALBC1_8MHZ;
P1DIR|=BIT0;
P1OUT|=BIT0;
TACTL=TASSEL0+TACLR; // 选择ACLK,并且清除定时初值
CCR0=32767; //定时一秒
TACTL=MC1; //设置为连续计数模式,并开启定时器
_EINT(); //允许全局中断
LPM0; //低功耗,仅仅CPUOFF
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A(void)
{
P1OUT^=BIT0;
CCR0+=32767;
}
//以下是用看门狗定时器中断实现P1.0口每一秒两一次
#include <msp430x22x4.h>
void main()
{
WDTCTL=WDTPW+WDTHOLD; // 停止看门狗程序,此句最为重要
WDTCTL=WDTPW+WDTSSEL+WDTMSEL+WDTCNTCL;// 设置看门狗为定时器模式,且选择ACLK时钟,分频为1. 即定时一秒32768
BCSCTL1 =CALBC1_8MHZ; //设定DCO为1MHZ,可设可不设
DCOCTL =CALBC1_8MHZ;
P1DIR|=BIT0; //P1口输出高电平
P1OUT|=BIT0;
IE1=WDTIE; //允许看门狗中断
_EINT(); //全局中断
_BIS_SR(LPM3_bits);;//进入低功耗LPM3
}
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A(void)
{
P1OUT^=BIT0; //P1口取反
}
通常情况下拥有ADC模块的430都有内部温度传感器;我以msp430fe425为例:
1.传感的温度系数为:1.32v/K
2.最终的计算公式为:
DegC=(ADC采样值*9090)/65536-2730
3.功能程序模块为:
..........................
SD16CTL=SD16REFON+SD16VMIDON+SD16SSEL0;
//开启内部1.2v的基准源,开启缓冲器,ADC时钟选SMCLK
SD16CCTL0|=SD16SNGL+SD16IE+SD16DF;
//ADC0工作单次采样模式,开启中断,输出数据格式为符号
for(i=0;i<5000;i++);//延迟
DegC = ((long int)ADCresult *9090)/65536 - 2730;//计算摄氏温度