发 帖  
[问答] MSP430 LaunchPAD学习笔记
362 MSP430 launchpad
分享

一:端口配置

   1:P1DIR   设置为1,相应管脚为输出。设置为0.相应管脚                              为输入状态。

   2:P1IE      设置为1,相应管脚具有中断功能。设置为0,                            相应管脚没有中断功能。

   3:P1IES   设置为1,选择下降沿触发方式,设置为0,选                            择上升沿触发方式。

   4:P1IFG    P1端口的中断标志寄存器,如果P1端口当某                            个管脚设置成中断管脚,当有中断触发时,想应比特为1 ;                              如果没有中断触发,相应比特为0.

5: P1IN   P1端口输入寄存器,在输入模式下,读取该寄                            存器相应管脚上的数据。

6: P1OUT   P1端口的输出去寄存器,在输出模式下,如                            果该寄存器相应比特设置为1时,相应管脚输出高电平;                            如果该寄存器相应比特为0时,相应管脚输出低电平。

7: P1SEL寄存器  P1端口功能选择寄存器,该寄存器主要                            控制P1端口的I/O管脚作为一般I/O还是外围模块的功能                            端口,该寄存器的相应比特为1时候,相应管脚为外围功能                           模块,当该寄存器为0时,相应管脚为一般I/O管脚。



二  LaunchPad 写程序的必要头文件和格式:

/*===================================================

#include"msp430g2553.h"

Void main()

{

    WDTCTL=WDTPW+WDTHOLD;//关闭看门狗。

    //WDTPW 是看门狗的密码,写错了会导致系统复位。

   **(程序)

}

=====================================================*/



三  点亮LED

  仅仅是对IO 口的输入输出操作。与51 很不相同。

P1DIR|=BIT0;//设置P1.0 为输出方向。===P1DIR|=0x01;

//{P1DIR=BIT0;是设置P1.0 为输出,其他全部为输入方向。}

//注意:LaunchPad 中很多操作是与,或,非等操作组成,时刻注意。

P1OUT|=BIT0;//这条指令就是设置P1.0 输出为高电平。

这样,就点亮了LED(接在P1.0 上的LED);

具体程序:

#include"msp430g2553.h"

Void main()

{

WDTCTL=WDTPW+WDTHOLD;

P1DIR|=BIT0;

P1OUT|=BIT0;

While(1);

}


四: 闪烁LED

LaunchPad 上面自带有2 个LED,一个接在P1.0 上,一个接在P1.6 上。

我们用2 个交替闪烁。

#include"msp430g2553.h"

Void main();第一个字母大写

{

WDTCTL=WDTPW+WDTHOLD;

P1DIR|=BIT0+BIT6;//设置P1.0 和P1.6 为输出

P1OUT|=BIT0;//线让LED0 亮。

While(1)

{

Unsigned int i=50000;

While(i--);

P1OUT^=0x41;//对P1.0 和P1.6 取反,所以LED0 和LED1 会交替闪烁。

}

}

五:中断系统

LaunchPad 的中断系统功能相当强大,51 只有5 个中断源,2 个定时,2 个外部,

一个串行口。但是LaunchPad 的中断源几乎是所有的引脚和所用的定时器。


在这里,最重要的就是中断向量的判断了。

定时器一般都是:

vector=TIMER0_A0_VECTOR

vector=TIMER0_A1_VECTOR

vector=TIMER1_A0_VECTOR

vector=TIMER1_A1_VECTOR

引脚中断的向量:

vector=PORT1_VECTOR;    P1 口的中断向量。

判断是哪个引脚的话,有2 种办法:

举例子:P1.3 和P1.4 都是中断的输入引脚。现在进了中断,我如何判断是那个引

脚引起的呢?

第一种方法:

vector=PORT1_VECTOR

__interruput void Port1 (void)

{

If(P1IFG&BIT3);判断的是P1.3 产生的中断。

{

;要执行的函数。

P1IFG=0x00;//清0 中断标志位。

}

If(P1IFG&BIT4)

{

;P1.4 产生的中端,执行相应的函数。

P1IFG=0x00;

}

}

第二种方法:

vector=PORT1_VECTOR

__interruput void Port1 (void)

{

P1IFG&=BIT3+BIT4;//因为只用到了P1.0 和P1.4,其他的中断标志全部清零。

(或者:P1IFG=P1IFG&0x18)

Switch(P1IFG)

{

Case 0x08: vector=3;break; //P1.3 产生的中断

Case 0x10:vector=4;break;//P1.4 产生的中断

}

}



切记:进入中断函数后要做的第一件事是,清除中断标志。

例程:

#include<msp430g2553.h>

Void main(void)
{

  WDTCTL=WDTPW+WDTHOLD;

  P1DIR|=BIT0;  //                            设置P1.0输出

  P1IES |=BIT3;  //     设置从高到底跳变触发

  P1IFG&=~BIT3//                清除中断标志位

  P1IE |=BIT3   //                   使P1.3能中断

  _BIS_SR(LPM_bits+GIE);//              启动LMP4节能模式

}

#proagma vector=PORT1_VECTOR

_interrupt  void Port_1(void)

{

   If(P1IFG&BIT3)

  {

P1OUT^=BIT0;   

P1IFG&=~BIT3;

  }

}

程序一开始

1   WDTCTL=WDTPW+WDTHOLD;  HOLD住看门狗

2   P1DIR|=BIT0;将P1.0              设置为输出口。lunchpad上的P1.O接有一个LED.


3. 接下来到P1IES |= BIT3; 在上一节中已经介绍了,P1IES 寄存器是中断沿选择寄存器。这里是选择位下降沿触发中断。


4. P1IFG &= ~BIT3; 为清除中断标志,保证程序正常运行,当然此句可以不写,这里只是做为例子


5. P1IE |= BIT3; 在上一节中已经介绍了,P1IE寄存器是使能中断事件发生的寄存器。


  • _BIS_SR(LPM4_bits + GIE);这里使程序进入最低功耗(LPM4)状态。靠中断来触发唤醒CPU,在文章开始已经介绍有,假如在中断函数中没有写有退出低功耗状态的指令,程序会在进入低功耗的下一句中卡死,不再运行下去。另外_BIS_SR(GIE); 为打开总中断的意思。

  • 接下来到中断函数的编写。以此为例,详细介绍中断函数的编写。如上所示,中断函数编写的规则为

[tr][td]
#pragma vector= 中断向量源

__interrupt void 函数名(void)


[/td][/tr]
[tr][td]

[/td][/tr]
摁住“Ctrl  +  左键”点击PORT1_VECTOR即可查看到所有的“中断向量”

在上面的中断向量中,加黑的位中断向量源,写入中断函数编写语法规则里面即可。而函数名则可以任意编写。比如我要编写一个有定时器1,CCR0寄存器溢出产生的中断,则可以这样编写


[tr][td]
#pragma vector= TIMER1_A0_VECTOR

__interrupt void T1A0Int(void)

{

//程序代码。。。

}


[/td][/tr]
假如是多IO输入中断,则如下所写。


[tr][td]
vector=PORT1_VECTOR

__interrupt void Port1()

{


[/td][td]
[/td][/tr]
[tr][td=2,1]
//以下为参考处理程序,不使用的端口应当删除其对于中断源的判断。

if((P1IFG&BIT0) == BIT0)

{

P2OUT&=~BIT0; //处理P1IN.0中断

P1IFG &= ~BIT0; //清除中断标志

//以下填充用户代码

}

else if((P1IFG&BIT1) ==BIT1)

{

P2OUT&=~BIT1; //处理P1IN.1中断

P1IFG &= ~BIT1; //清除中断标志

//以下填充用户代码

}

else if((P1IFG&BIT2) ==BIT2)

{

P2OUT&=~BIT2; //处理P1IN.2中断

P1IFG &= ~BIT2; //清除中断标志

//以下填充用户代码

}

else if((P1IFG&BIT3) ==BIT3)

{

//处理P1IN.3中断

P1IFG &= ~BIT3; //清除中断标志

//以下填充用户代码

}

else if((P1IFG&BIT4) ==BIT4)

{

P2OUT&=~BIT4; //处理P1IN.4中断

P1IFG &= ~BIT4; //清除中断标志

//以下填充用户代码

}

else if((P1IFG&BIT5) ==BIT5)

{

//处理P1IN.5中断

P1IFG &= ~BIT5; //清除中断标志

//以下填充用户代码

}

else if((P1IFG&BIT6) ==BIT6)

{

//处理P1IN.6中断

P1IFG &= ~BIT6; //清除中断标志

//以下填充用户代码


[tr][td]
}

else

{

//处理P1IN.7中断

P1IFG &= ~BIT7; //清除中断标志

//以下填充用户代码

}

LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽

}

[/td][/tr]

[/td][/tr]
六   定时器模块


文先,介绍几个英文缩写的意思以及一些注意的地方。

1. Timer0/1 定时器0/1,在User's Guide中用的是TimerA/B,所指的也是Timer0/1 。G2553Datasheet中用的是Timer0/1 ,本文以G2553Datasheet为准。全文以Timer0为例,Timer1类同。



2. TAxR(x = 0/1)定时器x对应的计数器,这是一个只读寄存器。硬件自动驱动计数。



  • EQUyy = 0/1/2)计数事件发生寄存器,当TAxR  =  TAxCCRyEQUy1

定时器简介

MSPG2553共有两个定时器,Timer0、Timer1,他们都是十六位的定时、计数器,内含三个捕获、比较寄存器。两个定时器均支持多个捕获、PWM输出、间歇性计时,定时器包含多个中断源,可以是计数溢出中断、捕获中断等等。

定时器包含:

同步十六位定时,计数器运行模式。

时钟源从MCLK、SMCLK、ACLK任意选择

三个比较,捕获寄存器。

中断向量寄存器能快速解码的所有定时器中断



Timer0组成框图

下面简要介绍一下该硬件框图的意思,从左上角看,首先是一个时钟源选择寄存器TASSELx,通过该寄存器选择定时器的时钟源,选择了时钟源后有一个分频器Divider,相应的设置寄存器是IDx,再过来就到一个定时器的核心部分,一个16位的定时器TAR。其右侧有一个定时器的计数模块,MCx寄存器用来设置计数模式。接下来,TAR正下方有三个横线,右侧标有CCR0、CCR1、CCR2,意思是CCR1、CCR0的框图和下方CCR2的框图是一样的。此处省略不写。在CCR中,左上角为一个捕获源选择寄存器。可以从CCI2A、CCI2B、GND或者VCC选择捕获源,选择捕获源后有一个选择捕获模式寄存器Capture Mode,然后过来有一个捕获溢出状态寄存器COV,SCS同步/异步捕获模式选择位,然后连接到捕获比较寄存器。下方为模式选择寄存器,具体设置可以查看相应的寄存器设置。

这里仅是大概介绍一下Timer0的寄存器,具体的设置使用还看参考相应的寄存器并结合例程慢慢学习理解。



定时器运行方式

下面简要重点介绍定时器计数模块的四种模式以及7种输出模式。

Timer0有一个在不断计数的只读寄存器TA0R。计数器的计数模式共有四种,


停止模式(Stop mode)、连续增计数模式(Up mode)、递增计数模式(continuous mode)、增减计数模式(Up/down mode)。由上图可知,这四种模式可以通过MCx寄存器进行设置。

以上四种模式可以由下图可以很好理解。




1. Stop模式计数器不工作。

2. 连续计数模式为计数器从零开始连续增计数一直到0xFFFF即65535,然后又重新从零开始计数。

3. 递增计数模式与连续计数模式仅有一点点区别,递增模式为计数器连续增加到TA0CCR0(即图中的CCR0)中的值后又重新从零开始计数。TA0CCR0的值时可以在程序中直接赋值的。

4. 递增递减模式也很好理解,计数器从零开始计数到CCR0后又自动减数,到零后又增计数,就像三角波一样。

每一个捕获比较模块都有一个输出单元,这个输出单元专门用来产生以下如PWM的波形信号,每一个输出单元都可以通过配置OUTMOD寄存器的值来设定八种信号输出模式,




接下来再介绍一下定时器的捕获/比较功能,具体应查看技术手册。

捕获模式

捕获模式可以用来速度计算或时间测量.CCIxA ,CCIxB的捕获源可以连接到外部引脚或者内部信号,可以设定CCIDx,CMx,位让寄存器捕获上升,下降,或者两个信号的边缘.输入信号的电平可以通过CCI位的读取.

当设置寄存器CAP=1时,使能捕获模块.

比较模式

比较模式设置CAP = 0的情况向,比较模式用于产生PWM信号。或者在指定时间里输出终端信号,当TAxR计数到TACCRx时


建立起CCIFG位


中断事件发生标志位EQUx=1


EQUx的隐含改变将影响输出模式

输入信号CCI被锁上SCCI






  • 增计数模式下的输出
   



2. 递增计数模式下的输出




*


  • 第增/第减计数模式下的输出



**************************************************************** /

  / ******************************************************************

   *                    TACTL寄存器,Timer_A 控制寄存器

   * TASSEL_x:TA时钟源选择寄存器

   *     00 TACLK

   *     01 ACLK

   *     10 SMCLK

   *     11 INCLK

   * IDx:     时钟源分频寄存器。为输入时钟分频选择

   *       00  /1

   *       01  /2

   *       10  /4

   *       11  /8

   *  * ************************************************************** /

   *              定时计数模块 =四中模式+7种输出方式

/ *****************************************************************

   *

   * MCx:    计数模式寄存器   模式控制,当TA不用于节省功耗时,将MCx=00h

   *     00  停止模式:定时器停止

   *     01  增模式  :定时器计数到TACCR0

   *     10  连续模式:定时器计数到0FFFFh

   *     11  增减模式:定时器计数到TACCR0 然后减到000h

   *

   * TACLR:  定时器清零。置位时会复位TAR,时钟分频和计数方向。

   *     TACLR位会自动复位并读出值为零。

   *

   * TAIE:   TA中断允许。改为允许TAIFG中断请求

   *     0 中断禁止

   *     1 中断允许

   * TAIFG:  TA中断标志位

   *     0 无中断挂起

   *     1 中断挂起

   * ************************************************************** /

/ *****************************************************************

*

*

   *             TACCTLx,捕获比较控制寄存器

   * CMx:  捕获模式

   *   00 不捕获

   *   01 上升沿捕获

   *   10 下降沿捕获

   *   11 上升和下降同时捕

   * CCISx: 捕获比较选择,改为选择TACCRx的输入信号

   *   00 CCIxA

   *   01 CCIxB

   *   10 GND

   *   11 VCC

   * SCS:  同步捕获源,改为用于将捕获通信和同步时钟

   *   0 异步捕获

   *   1 同步捕获

   * SCCI:同步的捕获/比较输入,所选择的输入信号由EQUx信号所存,

   *   并可通过该位读取

   * CAP:  捕获模式

   *   0 比较模式

   *   1 捕获模式


   *OUTMODx:输出模式位,对TACCR0无效

   *         000 OUT 位的值

   *         001 置位

   *         010 翻转/复位

   *         011 复位/复位

   *         100 翻转

   *         101 复位

   *         110 翻转/置位

   *         111 复位/置位

   * CCIE: 捕获比较中断允许位

   *   0 中断禁止

   *   1 中断允许

   * CCI:  捕获比较输入

   * OUT:  对于输出模式0,该位直接控制输出状态

   * COV:  捕获溢出位。该位表示一个捕获溢出发生,由软件复位

   * CCIFG:捕获比较中断标志位

   *   0 没有中断挂起

   *   1 有中断挂起

   * ***************************************************************/

#include <msp430g2553.h>


unsigned  int A=10,  B=20 ;  void main (void)

{

  WDTCTL = WDTPW + WDTHOLD;


  TACTL|=TASSEL_2+TACLR+MC_1+ID_3;  // SMCLK时钟 ;定时器清零;增模式   8分频

  CCTL0=CCIE;                       //捕获中断允许

  CCR0=B;                         //TACCR0 装载值

  CCTL1=OUTMOD_7;                   //输出模式复位

  CCR1=A;

// BCSCTL1

  P1DIR=BIT6;

  P1SEL=BIT6;


// _EINT();                          //使能所有中断

  while(1);

}


/*#pragma vector=TIMER0_A0_VECTOR

__interrupt void  ta0_isr(void)

{

  unsigned  int i;

  for(i=0;i<num;i++)

    pwm=i;

}*/




定时器中断

这里以定时器0为例,定时器1同。

定时器的中断可有定时器TA0CCR0溢出产生,也可由TA0CCRx(x =1/2)溢出产生、捕获/比较事件发生引起的中断,前者有一个专用的中断向量,TIMER0_A0_VECTOR,而后者用的TIMER0_A1_VECTOR,至于是哪一个中断时间发生,还要根据标志位来判断。




下面以官方例程LaunchPad Lab2为例介绍定时器A的操作。


例一


[tr][td]
#include <msp430g2553.h>

void main(void)

{

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)

{

while(1); // If calibration constants erased, trap CPU!!

}

BCSCTL1 = CALBC1_1MHZ; // Set range

DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation

BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO

P1DIR = 0x40; // P1.6 output (green LED)

P1OUT = 0; // LED off

IFG1 &= ~OFIFG; // Clear OSCFault flag

BCSCTL1 |= DIVA_3; // ACLK = VLO/8

BCSCTL2 |= SELM_3 + DIVM_3 + DIVS_3; // MCLK = DCO/8, SMCLK = DCO/8

// Configure TimerA

TACTL = TASSEL_1 + MC_1 + TAIE; // Source: ACLK, UP mode

CCR0 = 5100; //Timer count 5100

CCR1 = 2000; //Timer count 100

CCTL0 = CCIE; //CCR0 interrupt enabled

CCTL1 = CCIE; //CCR1 interrupt enabled

_BIS_SR(GIE);

for(;;);


[tr][td]
}

// Timer A0 interrupt service routine

#pragma vector=TIMER0_A0_VECTOR

__interrupt void Timer_A0 (void)

{

P1OUT |= BIT6; // P1.6 output High

}

// Timer A1 Interrupt Vector (TA0IV) handler

#pragma vector=TIMER0_A1_VECTOR

__interrupt void Timer_A1(void)

{

switch( TA0IV )

{

case 2: P1OUT &= ~BIT6; // P1.6 output Low


[tr][td]
break;

case 10:

break;

}

}

[/td][/tr]
[/td][/tr]

[/td][/tr]
程序一开始关闭看门狗,if语句作为时钟校准的范例,可以删去。BCSCTL3 |= LFXT1S_2; 选择超低频时钟源。然后设定输出口,清除中断标志,时钟源分频设定,接下里组建定时器A,即定时器0,在详细介绍代码之前,首先看头文件关于定时器相关寄存器的设定。


例二

  下面举一个无需中断服务函数、硬件自动实现产生两路PWM的例子。

代码很简单,初始化一下即可。


[tr][td]
#include<msp430g2553.h>

void Set_TimerB_PWM(void)

{

//使用系统初始化时的默认时钟1MHz,定时器B专门用于产生PWM 波形。

TA1CTL = TASSEL_2 + MC_1 + TACLR;//使用系统次主机SMCKL、增计数模式、清楚定时器B时钟

TA1CCR0 = 5001 - 1;//在1MHz的主频率下,1*10^6/5000=200Hz的中断频率

TA1CCR1 = 3751 - 2;//当寄存器TACCR1的值小于3750时,输出口保持高电平。5000*3/4=3750,此路产生3:1的PWM波形。

TA1CCR2 = 1251 - 2;//当寄存器TACCR1的值小于1250时,输出口保持高电平。5000*1/4=1250,产生1:3的PWM波

TA1CCTL1 = OUTMOD_7;//输出模式7,计数器计数到5000计数器自动置位,无需中断服务子函数。

TA1CCTL2 = OUTMOD_7;//输出模式7,计数器计数到5000计数器自动置位,无需中断服务子函数。

P2SEL |= BIT1 + BIT5;//只有这两路可选(为什么是这两路?在G2553Datasheet中有特别指明)。做第二功能使用(PWM输出)

P1DIR |= BIT6; //电机控制口CTL//这里与本例无关

P1OUT &= ~BIT6; //start with 0 -->IN2,4为1,灭//这里与本例无关

}


[/td][/tr]

  初始化时钟后直接调用该函数即可。

我这里使用的是定时器B(即Timer1)。详细的介绍见以上备注。  


七  时钟配置


  时钟源:


     外部晶体振荡器

     超低频率振荡器(VLO)

     数字控制振荡器(DCO)


  时钟信号:



     ACLK :Auxiliary clock.辅助时钟。

     MCLK :Master clock主时钟。

     SMCLK :Second Master clock次主机时钟。


内部晶体振荡器产生时钟后经过DCOR、SCG0、RSELx、DCO等各个寄存器为MCLK、SMCLK提供时钟源


内部时钟还有一个超低频率内置晶体振荡器(VLO)在上图的最上方。可作为低频时钟源。


另外一个部分是系统的外部时钟,外部晶振经过LFXT等各个寄存器设置后可以为MCLK、ACLK提供时钟源。

上图中SELM、SELS为时钟源选择寄存器。


上图中DIVA、DIVM、DIVS都是分频器,时钟源可以经过1/2/4/8分频后为CPU提供时钟,以降低功耗。


   




ADC10的时钟部分框图





Timer_A的结构框图


     Timer_A不能选择MCLK作为Timer_A的时钟




CPU是处理器的核心部分,它使用的时钟始终是MCLK。



上电后,系统默认使用的主系统时钟MCLK和子系统时钟SMCLK是同为DCOCLK产生的1MHz时钟,而辅助时钟ACLK则为内部VLOCLK产生的12KHz时钟


MSP430低功耗模式

    单片机中,功耗最低的单片机要MSP430单片机,这是做手持设备最优选择,MSP430中,用到5种低功耗,LPM0,LPM1,LPM2,LPM3,LPM4,这五种低功耗各种解释如下 :

LPM0:CPU停止工作,MCLK时钟停止,SMCLK、ACLK时钟还在工作。

LPM1:CPU停止工作,MCLK时钟停止,在活动模式如果DCO没有作为MCLK和SMCLK时钟时,则直流发生器被禁止,否则就保持活动状态,SMCLK、ACLK时钟依然还在工作。

LPM2:CPU停止工作,MCLK、SMCLK时钟停止工作,如果DCO没有作为MCLK、SMCLK,自动被禁止直流发生器保持有效,ACLK还处于工作中。

LPM3:CPU停止工作,MCLK、SMCLK时钟停止工作,DCO时钟也停止工作,仅ACLK时钟还处于工作状态。

LPM4:CPU停止工作,MCLK、SMCLK时钟停止工作,DCO时钟也停止工作,ACLK也停止工作。此时功耗最低。

一般情况下,处理器进入低功耗模式后,由中断来唤醒,外部中断或内部中断。

如果想进入低功耗1,则程序可以为:_BIS_SR(LPM1_bits + GIE);退出低功耗1,则程序可以为:LPM1_EXIT; 进入其他低功耗和退出低功耗一样。

低功耗执行的一个过程:程序从main函数入口开始执行程序,当遇到进入低功耗程序时,如:_BIS_SR(LPM1_bits + GIE);此时相当于下面的程序处于停止状态不再执行,当有一个中断来到,则会进入中断处理程序,自动退出低功耗,如果在中断中没有没有退出低功耗,当中断服务程序执行完成后,又会重新进入低功耗。



完整的Word格式文档电子发烧友下载地址:




0
2018-6-26 04:53:57   评论 邀请回答

只有小组成员才能发言,加入小组>>

97个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表