【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练

文章目录

  • 开发环境
  • 板子介绍
  • 官网示例代码下载
  • MSP430普通IO口控制
  • IO口外部中断
  • MSP430时钟系统
  • MSP430不精确延时之delay_ms
  • MSP430定时器_CCR0溢出中断
  • MSP430定时器_定时器计数溢出中断
  • MSP430定时器_PWM波形产生
  • MSP430串口_收发
    • 9600波特率
    • 115200 波特率
  • MSP430ADC
  • MSP430 Flash读写

开发环境

CCS软件下载:https://www.ti.com/tool/download/CCSTUDIO
建议别搞太高版本。
【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第1张图片

板子介绍

P1.0 接了LED 输出低电平点亮小灯
P1.6 接了LED
P1.3 接了KEY 按键按下是低电平

【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第2张图片

【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第3张图片

官网示例代码下载

https://www.ti.com.cn/product/cn/MSP430G2553#software-development
【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第4张图片

MSP430普通IO口控制

使用按键控制灯。学习常用的IO口寄存器。

//******************************************************************************
//  MSP430G2xx3 Demo - Software Poll P1.4, Set P1.0 if P1.4 = 1
//
//  Description: Poll P1.4 in a loop, if hi P1.0 is set, if low, P1.0 reset.
//  ACLK = n/a, MCLK = SMCLK = default DCO
//
//               MSP430G2xx3
//            -----------------
//        /|\|              XIN|-
//         | |                 |
//         --|RST          XOUT|-
//     /|\   |                 |
//      --o--|P1.3         P1.0|-->LED
//     \|/
//
//  D. Dang
//  Texas Instruments, Inc
//  December 2010
//   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include 

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
    P1DIR |= BIT0;                            // Set P1.0 to output direction

    P1DIR &= ~BIT3;                            //输入
    P1REN |= BIT3;                            //上拉下拉使能
    P1OUT |= BIT3;                            //上拉

    while (1)                                 // Test P1.4
    {
        if ((BIT3 & P1IN) == 0) // 按键按下
            P1OUT |= BIT0;
        else
            P1OUT &= ~BIT0;
    }
}


WDTCTL = WDTPW + WDTHOLD;
这一行代码停止了看门狗定时器(Watchdog Timer),以防止系统复位。WDTCTL是一个特殊寄存器,用于配置和控制看门狗定时器。通过将WDTPW和WDTHOLD的值相加,可以将看门狗定时器设置为停止状态。

P1DIR |= BIT0;
这一行代码将P1.0引脚的方向设置为输出。P1DIR是P1端口的方向寄存器,BIT0是一个宏定义,表示二进制数1。使用按位或操作符(|=)可以将P1DIR寄存器的BIT0位置1,将P1.0设置为输出方向。

在循环中,程序通过检查P1.3引脚的输入状态来控制P1.0引脚的输出状态。如果P1.3引脚的输入为低电平(按键按下),则将P1.0引脚设置为高电平。如果P1.3引脚的输入为高电平(按键未按下),则将P1.0引脚设置为低电平。

IO口外部中断

IO口外部中断是一种特殊的中断,它允许外部事件触发微控制器的中断服务程序。它的存在有以下几个意义和用途:

事件检测和响应:外部中断可以用于检测和响应外部事件,例如按键按下、传感器状态变化、信号边沿等。当外部事件发生时,触发外部中断,微控制器可以立即中断当前任务,执行与事件相关的中断服务程序,从而及时响应外部事件。

节省处理器资源:通过使用外部中断,可以节省处理器资源。相比于不断地轮询输入状态,使用外部中断可以在外部事件发生时立即中断处理,避免了处理器不断轮询的浪费。这样,处理器可以继续执行其他任务,而无需关注外部事件,只有在事件发生时才会中断处理。

实时性和精确性:外部中断的响应速度很快,可以实现实时性要求高的应用。它可以在微秒级别的时间内检测到外部事件,并立即中断处理。这对于需要高精度和及时响应的应用非常重要,如控制系统、测量和采样系统等。

多任务处理:外部中断允许多任务处理。通过将不同的外部事件分配给不同的中断服务程序,可以同时处理多个任务。这样,可以在同一个微控制器上实现多个功能模块的并行处理,提高系统的效率和灵活性。

WDTCTL = WDTPW + WDTHOLD;:停止看门狗定时器。MSP430微控制器通常配备了一个看门狗定时器,用于在程序执行期间检测和防止系统锁死。
P1DIR |= BIT0;:将P1.0引脚设置为输出方向。这意味着P1.0被配置为输出引脚,可以控制外部设备。
P1IE |= BIT3;:启用P1.3引脚的中断功能。当发生与P1.3引脚相关的中断时,将触发相应的中断服务程序。
P1IES |= BIT3;:配置P1.3引脚的中断触发边沿。在本例中,配置为高电平到低电平的触发边沿。
P1REN |= BIT3;:启用P1.3引脚的上拉电阻。这意味着P1.3引脚与上拉电阻连接,可以检测外部连接的开关状态。
P1IFG &= ~BIT3;:清除P1.3引脚的中断标志位。确保在进入中断服务程序之前,将中断标志位重置为未触发状态。
__bis_SR_register(LPM4_bits + GIE);:将微控制器设置为低功耗模式4(LPM4),并启用全局中断(GIE)。进入低功耗模式后,微控制器将等待中断事件的发生。

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
P1OUT ^= BIT0; // P1.0 = toggle
P1IFG &= ~BIT3; // P1.3 IFG cleared
}
这是一个中断服务程序,是固有写法,其中PORT1_VECTOR是中断向量入口,Port_1是中断函数名称。

#include 

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
    P1DIR |= BIT0;                            // Set P1.0 to output direction
    P1IE |= BIT3;                            // P1.3 interrupt enabled
    P1IES |= BIT3;                            // P1.3 Hi/lo edge
    P1REN |= BIT3;							// Enable Pull Up on SW2 (P1.3)
    P1IFG &= ~BIT3;                           // P1.3 IFG cleared
                                              //BIT3 on Port 1 can be used as Switch2
    __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4 w/interrupt
}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
    P1OUT ^= BIT0;                            // P1.0 = toggle
    P1IFG &= ~BIT3;                           // P1.3 IFG cleared
}

MSP430时钟系统

基本时钟模块+支持低系统成本和超低功耗。使用三个内部时钟信号,用户可以选择性能和低功耗之间的最佳平衡。基本时钟模块+可以在完全软件控制下配置为不需要任何外部元件、一个外部电阻、一个或两个外部晶体,或者谐振器进行操作。

基本时钟模块+包括两个、三个或四个时钟源:
• LFXT1CLK:低频/高频振荡器,可与低频手表晶体或外部时钟源(32768 Hz)或标准晶体、谐振器或外部时钟源(400 kHz至16 MHz范围内)一起使用。
• XT2CLK:可选的高频振荡器,可与标准晶体、谐振器或外部时钟源(400 kHz至16 MHz范围内)一起使用。
• DCOCLK:内部数字控制振荡器(DCO)。
• VLOCLK:内部超低功耗低频振荡器,典型频率为12 kHz。

基本时钟模块+提供三个时钟信号:
• ACLK:辅助时钟。ACLK可在软件中选择LFXT1CLK或VLOCLK。ACLK可被1、2、4或8分频。ACLK可针对各个外设模块进行软件选择。
• MCLK:主时钟。MCLK可在软件中选择LFXT1CLK、VLOCLK、XT2CLK(如果芯片上可用)或DCOCLK。MCLK可被1、2、4或8分频。MCLK由CPU和系统使用。
• SMCLK:子主时钟。SMCLK可在软件中选择LFXT1CLK、VLOCLK、XT2CLK(如果芯片上可用)或DCOCLK。SMCLK可被1、2、4或8分频。SMCLK可针对各个外设模块进行软件选择。

【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第5张图片

【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第6张图片

该代码的作用是配置 MSP430G2xx3 微控制器的时钟信号输出,其中 P1.0 引脚输出 ACLK 时钟信号,P1.4 引脚输出 SMCLK 时钟信号,P1.1 引脚输出 MCLK/10 时钟信号。在无限循环中,不断地在 P1.1 引脚上输出高电平和低电平信号,形成一个方波输出,模拟了MCLK时钟快慢。

//******************************************************************************
//  MSP430G2xx3 Demo - Basic Clock, Output Buffered SMCLK, ACLK and MCLK/10
//
//  Description: Buffer ACLK on P1.0, default SMCLK(DCO) on P1.4 and MCLK/10 on
//  P1.1.
//  ACLK = LFXT1 = 32768, MCLK = SMCLK = default DCO
//  //* External watch crystal installed on XIN XOUT is required for ACLK *//	
//
//               MSP430G2xx3
//             -----------------
//         /|\|              XIN|-
//          | |                 | 32kHz
//          --|RST          XOUT|-
//            |                 |
//            |       P1.4/SMCLK|-->SMCLK = Default DCO
//            |             P1.1|-->MCLK/10 = DCO/10
//            |        P1.0/ACLK|-->ACLK = 32kHz
//
//  D. Dang
//  Texas Instruments Inc.
//  December 2010
//   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************


#include 

int main(void)
{
  WDTCTL = WDTPW +WDTHOLD;                  // Stop Watchdog Timer

 //1Mhz
  if (CALBC1_1MHZ==0xFF)					// If calibration constant erased
  {											
    while(1);                               // do not load, trap CPU!!	
  } 
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_1MHZ;                    // Set range
  DCOCTL = CALDCO_1MHZ;                     // Set DCO step + modulation */

/* //8Mhz
  if (CALBC1_8MHZ==0xFF)					// If calibration constant erased
  {											
    while(1);                               // do not load, trap CPU!!	
  }
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_8MHZ;                    // Set range
  DCOCTL = CALDCO_8MHZ;                     // Set DCO step + modulation */

/* //12Mhz
  if (CALBC1_12MHZ==0xFF)					// If calibration constant erased
  {											
    while(1);                               // do not load, trap CPU!!	
  }
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_12MHZ;                   // Set range
  DCOCTL = CALDCO_12MHZ;                    // Set DCO step + modulation*/

/* //16Mhz
  if (CALBC1_16MHZ==0xFF)					// If calibration constant erased
  {											
    while(1);                               // do not load, trap CPU!!	
  }
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_16MHZ;                   // Set range
  DCOCTL = CALDCO_16MHZ;                    // Set DCO step + modulation*/

  P1DIR |= 0x13;                            // P1.0,1 and P1.4 outputs
  P1SEL |= 0x11;                            // P1.0,4 ACLK, SMCLK output

  while(1)
  {
    P1OUT |= 0x02;    	                    // P1.1 = 1
    P1OUT &= ~0x02;                         // P1.1 = 0
  }
}

MSP430不精确延时之delay_ms

__delay_cycles是编译器内置的空指令运算,通过宏定义包装,成为不精确延时之delay_ms。

#include 

#define CPU_F ( (double) 16000000)
#define delay_us( x )   __delay_cycles( (long) (CPU_F * (double) x / 1000000.0) )
#define delay_ms( x )   __delay_cycles( (long) (CPU_F * (double) x / 1000.0) )

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                  // Stop Watchdog Timer
    //16Mhz
    if (CALBC1_16MHZ == 0xFF)				// If calibration constant erased
    {
        while (1)
            ;                               // do not load, trap CPU!!
    }
    DCOCTL = 0;                          // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_16MHZ;                   // Set range
    DCOCTL = CALDCO_16MHZ;                    // Set DCO step + modulation

    P1DIR |= BIT0;
    while (1)
    {
        P1OUT ^= BIT0;                    //亦或计算
        delay_ms(100);
    }
}

MSP430定时器_CCR0溢出中断

下面的设置是50ms的中断。

SMCLK是1MHZ,此时CCR0 = 50000,定时器计数到CCR0 即是等于50ms。

#include 

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    //1Mhz
    if (CALBC1_1MHZ == 0xFF)                   // If calibration constant erased
    {
        while (1)
            ;                               // do not load, trap CPU!!
    }
    DCOCTL = 0;                          // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_1MHZ;                    // Set range
    DCOCTL = CALDCO_1MHZ;                     // Set DCO step + modulation */

    P1DIR |= 0x01;                            // P1.0 output

    CCTL0 = CCIE;                             // CCR0 interrupt enabled
    CCR0 = 50000;
    TACTL = TASSEL_2 + MC_1;                  // SMCLK, Up to CCR0

    __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
}

// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{
    P1OUT ^= BIT0;                            // Toggle P1.0
}


下面是四种计数模式,我们刚才的选择是让其计数到CCR0就 产生溢出中断。

【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第7张图片

MSP430定时器_定时器计数溢出中断

定时器计数溢出中断的中断向量是TIMER0_A1_VECTOR,这个中断向量入口也是CCR1 、CCR2 溢出的入口,在内部依靠TA0IV 寄存器判断具体的中断来源。

#include 

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x01;                            // P1.0 output
  TACTL = TASSEL_2 + MC_2 + TAIE;           // SMCLK, contmode, interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
}

// Timer_A3 Interrupt Vector (TA0IV) handler
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A(void)
{
 switch( TA0IV )
 {
   case  2: break;                          // CCR1 not used
   case  4: break;                          // CCR2 not used
   case 10: P1OUT ^= 0x01;                  // overflow
            break;
 }
}

针对于CCR1之类的溢出也是不常用的,下面的代码看看就好。

#include 

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1SEL |= 0x06;                            // P1.1 - P1.2 option select
  P1DIR |= 0x07;                            // P1.0 - P1.2 outputs
  CCTL0 = OUTMOD_4 + CCIE;                  // CCR0 toggle, interrupt enabled
  CCTL1 = OUTMOD_4 + CCIE;                  // CCR1 toggle, interrupt enabled
  TACTL = TASSEL_2 +  MC_2 + TAIE;          // SMCLK, Contmode, int enabled

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupt
}

// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
  CCR0 += 200;                              // Add Offset to CCR0
}

// Timer_A2 Interrupt Vector (TA0IV) handler
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1(void)
{
  switch( TA0IV )
  {
  case  2: CCR1 += 1000;                    // Add Offset to CCR1
           break;
  case 10: P1OUT ^= 0x01;                   // Timer_A3 overflow
           break;
 }
}

MSP430定时器_PWM波形产生

PWM(Pulse Width Modulation,脉宽调制)波形在电子和控制系统中有着广泛的应用,它具有以下几个重要的作用:

模拟信号生成:PWM波形可以通过调整脉冲的占空比来模拟产生连续的模拟信号。通过改变脉冲的宽度(占空比),可以实现不同的平均电平值,从而生成与输入信号强度或控制信号相关的模拟输出。这使得PWM成为模拟电压和模拟电流控制的一种常见技术。

电机控制:PWM广泛应用于电机驱动和速度控制中。通过在电机绕组上施加PWM波形,可以控制电机的转速和扭矩。通过调整脉冲的占空比,可以改变电机驱动电压的平均值,从而控制电机的转速。

LED亮度控制:PWM被广泛用于LED亮度调节。通过改变PWM波形的占空比,可以控制LED的亮度。当PWM波形的占空比较大时,LED处于高亮度状态;当占空比较小时,LED处于低亮度状态。通过快速调整PWM波形的占空比,可以实现灯光的平滑过渡和精确亮度控制。

电源管理:PWM被用于电源管理和节能控制中。通过在开关电源中采用PWM控制,可以调整开关管的通断时间,从而调节输出电压或电流。这种方式可以提高电源的效率和稳定性,并减少功耗。

数字信号传输:PWM波形还可以用作数字信号传输的一种方式。在某些应用中,可以使用PWM波形来编码和传输数字信息。通过改变脉冲的频率或占空比,可以表示不同的数字值,从而实现简单的数字通信。

下面是MSP430的PMW输出模式:

【MSP430单片机】MSP430G2553程序,MSP430G2553单片机教程,MSP430G2553实战演练_第8张图片

下面的代码是让P1.2输出50%占空比的1kHZ波形。


//           |         P1.2/TA1|--> CCR1 - 50% PWM

#include 

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

    //1Mhz
    if (CALBC1_1MHZ == 0xFF)                   // If calibration constant erased
    {
        while (1)
            ;                               // do not load, trap CPU!!
    }
    DCOCTL = 0;                          // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_1MHZ;                    // Set range
    DCOCTL = CALDCO_1MHZ;                     // Set DCO step + modulation */

    P1DIR |= BIT2;
    P1SEL |= BIT2;
    CCR0 = 1000;                               // PWM Period/2
    CCTL1 = OUTMOD_7;                         // CCR1 toggle/set
    CCR1 = 500;                                // CCR1 PWM duty cycle
    TACTL = TASSEL_2 + MC_3;                  // SMCLK, up-down mode

    __bis_SR_register(LPM0_bits);             // Enter LPM0
}


MSP430串口_收发

9600波特率

//   MSP430G2xx3 Demo - USCI_A0, 9600 UART Echo ISR, DCO SMCLK
//
//   Description: Echo a received character, RX ISR used. Normal mode is LPM0.
//   USCI_A0 RX interrupt triggers TX Echo.
//   Baud rate divider with 1MHz = 1MHz/9600 = ~104.2
//   ACLK = n/a, MCLK = SMCLK = CALxxx_1MHZ = 1MHz
//
//                MSP430G2xx3
//             -----------------
//         /|\|              XIN|-
//          | |                 |
//          --|RST          XOUT|-
//            |                 |
//            |     P1.2/UCA0TXD|------------>
//            |                 | 9600 - 8N1
//            |     P1.1/UCA0RXD|<------------
//
//   D. Dang
//   Texas Instruments Inc.
//   February 2011
//   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include 

void Send_Byte(char data)
{
    while (!(IFG2 & UCA0TXIFG))
        ;                // USCI_A0 TX buffer ready?
    UCA0TXBUF = data;                    // TX -> RXed character
}

void Print_Str(char *s)
{
    while (*s != '\0')
    {
        Send_Byte(*s++);
    }
}

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    if (CALBC1_1MHZ == 0xFF)				// If calibration constant erased
    {
        while (1)
            ;                               // do not load, trap CPU!!	
    }
    DCOCTL = 0;                          // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
    DCOCTL = CALDCO_1MHZ;
    P1SEL = BIT1 + BIT2;                     // P1.1 = RXD, P1.2=TXD
    P1SEL2 = BIT1 + BIT2;                    // P1.1 = RXD, P1.2=TXD
    UCA0CTL1 |= UCSSEL_2;                     // SMCLK
    UCA0BR0 = 104;                            // 1MHz 9600
    UCA0BR1 = 0;                              // 1MHz 9600
    UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST;                   // **Initialize USCI state machine**
    IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

    __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}

//  Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG))
        ;                // USCI_A0 TX buffer ready?
    UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
}

115200 波特率

//   MSP430G2xx3 Demo - USCI_A0, 115200 UART Echo ISR, DCO SMCLK
//
//   Description: Echo a received character, RX ISR used. Normal mode is LPM0.
//   USCI_A0 RX interrupt triggers TX Echo.
//   Baud rate divider with 1MHz = 1MHz/115200 = ~8.7
//   ACLK = n/a, MCLK = SMCLK = CALxxx_1MHZ = 1MHz
//
//                MSP430G2xx3
//             -----------------
//         /|\|              XIN|-
//          | |                 |
//          --|RST          XOUT|-
//            |                 |
//            |     P1.2/UCA0TXD|------------>
//            |                 | 115200 - 8N1
//            |     P1.1/UCA0RXD|<------------
//
//   D. Dang
//   Texas Instruments Inc.
//   February 2011
//   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include 

void Send_Byte(char data)
{
    while (!(IFG2 & UCA0TXIFG))
        ;                // USCI_A0 TX buffer ready?
    UCA0TXBUF = data;                    // TX -> RXed character
}

void Print_Str(char *s)
{
    while (*s != '\0')
    {
        Send_Byte(*s++);
    }
}

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  if (CALBC1_1MHZ==0xFF)					// If calibration constant erased
  {											
    while(1);                               // do not load, trap CPU!!	
  }
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  P1SEL2 = BIT1 + BIT2;                      
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 8;                              // 1MHz 115200
  UCA0BR1 = 0;                              // 1MHz 115200
  UCA0MCTL = UCBRS2 + UCBRS0;               // Modulation UCBRSx = 5
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}

// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
  UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
}

MSP430ADC

下面是ADC单通道转换代码。多通道较为复杂,这里不叙述。

#include 

#define CPU_F ( (double) 1000000)
#define delay_us( x )	__delay_cycles( (long) (CPU_F * (double) x / 1000000.0) )
#define delay_ms( x )	__delay_cycles( (long) (CPU_F * (double) x / 1000.0) )

unsigned int volt;
int main(void)
{

    WDTCTL = WDTPW + WDTHOLD; /* Stop WDT */

    ADC10CTL0 = ADC10SHT_2 + ADC10ON ; // ADC10ON, interrupt enabled
    ADC10CTL1 = INCH_4;                       // input A4
    ADC10AE0 |= BIT4;                         // PA.4 ADC option select

    while (1)
    {
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        while ((ADC10IFG & ADC10CTL0)==0)
                    ;                   //MEM5触发IFG5  意味着有了新的转换结果
        volt = ADC10MEM;
        volt=volt*3.3*100/1024;
        delay_ms(100);
    }
}

MSP430 Flash读写

#include 

char  value;                                // 8-bit value to write to segment A

// Function prototypes
void write_SegC (char value);
void copy_C2D (void);

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  if (CALBC1_1MHZ==0xFF)					// If calibration constant erased
  {											
    while(1);                               // do not load, trap CPU!!	
  }
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz
  DCOCTL = CALDCO_1MHZ;
  FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
  value = 0;                                // initialize value

  while(1)                                  // Repeat forever
  {
    write_SegC(value++);                    // Write segment C, increment value
    copy_C2D();                             // Copy segment C to D
    __no_operation();                       // SET BREAKPOINT HERE
  }
}

void write_SegC (char value)
{
  char *Flash_ptr;                          // Flash pointer
  unsigned int i;

  Flash_ptr = (char *) 0x1040;              // 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<64; i++)
  {
    *Flash_ptr++ = value;                   // Write value to flash
  }

  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
}

void copy_C2D (void)
{
  char *Flash_ptrC;                         // Segment C pointer
  char *Flash_ptrD;                         // Segment D pointer
  unsigned int i;

  Flash_ptrC = (char *) 0x1040;             // Initialize Flash segment C pointer
  Flash_ptrD = (char *) 0x1000;             // Initialize Flash segment D pointer
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  FCTL3 = FWKEY;                            // Clear Lock bit
  *Flash_ptrD = 0;                          // Dummy write to erase Flash segment D
  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation

  for (i=0; i<64; i++)
  {
    *Flash_ptrD++ = *Flash_ptrC++;          // copy value segment C to segment D
  }

  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
}

PS: 有代码需要做可以私信。

你可能感兴趣的:(单片机,MSP430教程,MSP430实战,MSP430程序,单片机)