打印

【MSP430i2xx教程第二讲】时钟系统 & EUSCI_A_UART

[复制链接]
楼主: xlhtracy
手机看帖
扫描二维码
随时随地手机跟帖
181
偏爱番茄酱 发表于 2015-4-5 16:31
我的板子上引出了P1.1~P1.4等多个外接IO,均上拉,用于外部中断输入。我只打开其中某个IO中断(比如P1.1 ...

检查复位是否正常,可以添加点亮LED灯的程序判断复位是否正常和程序是否运行

使用特权

评论回复
182
偏爱番茄酱| | 2015-4-5 16:34 | 只看该作者
LPM3唤醒
for(;;)                           
    {      
        // Stop WDT
        WDTCTL = WDTPW + WDTHOLD;  
              
        // Enter LPM3 w/interrupt
        _BIS_SR(LPM3_bits + GIE);   
        
        // Start WDT
        WDTCTL = WDT_ARST_1000;  
      
        //SysLoopTask
        do_SysLoopTask();      
        
    }//for

    并且程序中使用了1秒定时器。在外接Jtag下载器时,程序运行一切正常,每隔1秒从睡眠中醒来,并且也能够响应外部IO中断;

但是,如果去掉下载器让板子单独运行,程序就睡眠而不被外部中断或者内部的定时器唤醒。

使用特权

评论回复
183
sharknarduo| | 2015-4-5 16:36 | 只看该作者
偏爱番茄酱 发表于 2015-4-5 16:34
LPM3唤醒
for(;;)                           
    {      

  for(;;)                           
    {      
          // Start WDT_timer
         WDTCTL = WDT_ARST_1000;  
              
        // Enter LPM3 w/interrupt
        _BIS_SR(LPM3_bits + GIE);   
        
      
        //SysLoopTask
        do_SysLoopTask();      
        
    }//for
IO复用看下!
建议多看看TI的手册和范例!430很简单!

使用特权

评论回复
184
sharknarduo| | 2015-4-5 16:49 | 只看该作者
MSP430有三个时钟源,三个时钟信号批发商,N个时钟用户。

1、时钟源

(1)DCO时钟,芯片内部时钟,系统启动时默认的工作时钟,但是不够稳定,容易随着电压和温度变化,不过,还好,芯片一般自带FLL锁相环装置,能够在一定程度上调整偏差。4系列处理器默认工作频率1.048576MHz,其他的处理器800kHz左右。

(2)LFXT1,外部低频时钟,一般接32768Hz的晶振,无需旁接电容(有内部电容,可以通过FLL_CTL0的XCAPxPF选择不同的电容值),相应的引脚为XTIN和XTOUT。如果非得让LFXT1工作在高频模式,那么需要将FLL_CTL0寄存器(地址0053)的XTS_FLL置位。

例如: FLL_CTL0 |= XCAP10PF + XTS_FLL ; //LFXT1内接10PF的电容 + LFXT1工作在高频

注:不同型号的芯片可以选择的电容值不同,具体查看芯片手册。

(3)XT2,外部高频时钟,该时钟需要外接谐振电容,引脚为XT2IN、XT2OUT。工作频率为450K-8MHz之间,可选的电容值一般为2pF左右。

注:无论是LFXT1还是XT2,晶振都要尽量靠近引脚,且用地线包围晶振信号线。

2、时钟信号批发商

时钟信号批发商把时钟源打包配置后,销售给各个时钟终端用户。

具体方式为,通过配置SCFQCTL、SCFI0、SCFI1、FLL_CTL0、FLL_CTL1将各个时钟进行分频,然后提供给mcu以及外围模块,并提供周到服务,保证时钟工作稳定,如果不稳定,免费提供更换服务,如:当检测到LFXT1失效时,自动切换到DCO,不过一般来说发生退货的可能性不大,所以不必太多考虑。

这三个批发商为ACKL、MCLK、SMCLK,分别称为辅助时钟、主时钟、sm时钟,别想歪了,SM是Sub Main 、Clock,不是………… :P 。

(1)ACLK只能做LFXT1的代理,它将LFXT1进行1/2/4/8分频之后,提供给外围模块。不用的时候还可以关闭,但是该时钟不可以被单独关闭。ACLK一般用于低速外设。

例如:MOV #OSCOFF, SR //关闭所有的晶振,一般关闭晶振osc的时候,必然同时关闭CPU,也就是低功耗6模式,但是关闭CPU,不一定关闭osc。

(2)MCLK的货源可以是LFXT1、XT2、DCO三者之一,包装后的频率可以是1/2/4/8/off。由于该时钟可以被关闭,所以可以用来降低功耗。

(3)SMCLK可以来自DCO和XT2,或者DCO和LFXT1,根据具体的芯片型号不同而有区别。SMCLK一般用于高速外设。

例如:MOV #SMCLKOFF, &FLL_CTL1 //关闭smclk时钟

MOV #XT2OFF + SELM0 + SELS + FLL_DIV_2, &FLL_CTL1

//关闭XT2晶振,MCLK选择DCO,SMCLK选择XT2,ACLK被2分频(来自LFXT1)

总结:系统每次启动后,默认使用DCO作为MCLK和SMCLK时钟来源,ACLK时钟来自LFXT1,这些配置可以在系统启动后在程序中修改。

使用特权

评论回复
185
偏爱番茄酱| | 2015-4-5 16:52 | 只看该作者
MSP430怎么将系统时钟输出?

使用特权

评论回复
186
sharknarduo| | 2015-4-5 16:54 | 只看该作者
偏爱番茄酱 发表于 2015-4-5 16:52
MSP430怎么将系统时钟输出?

看看哪个管脚是对应有时钟功能复用的,配置下io复用,用示波器一个点地,一个点到这个脚上就可以看了

使用特权

评论回复
187
sharknarduo| | 2015-4-5 16:56 | 只看该作者
1、CPU运行在VLO时钟下:
这是最慢的时钟,在约12千赫兹下运行。因此,我们将通过可视化的LED闪烁的红色慢慢地在约每3秒钟率。我们可以让时钟系统默认这种状态,设置专门来操作VLO。我们将不使用任何ALCK外设时钟在此实验室工作,但你应该认识到,ACLK来自VLO时钟。
#include <msp430g2231.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;           // 关闭看门狗定时器
P1DIR = 0x40;                          // P1.6 配置输出
P1OUT = 0;                            // 关闭LED
BCSCTL3 |= LFXT1S_2;                   // LFXT1 = VLO
IFG1 &= ~OFIFG;                       // 清除OSCFault 标志
__bis_SR_register(SCG1 + SCG0);          // 关闭 DCO
BCSCTL2 |= SELM_3 + DIVM_3;           // MCLK = VLO/8
while(1)
{
P1OUT = 0x40;                       // 开启LED
_delay_cycles(100);
P1OUT = 0;                          // 关闭 LED
_delay_cycles(5000);
}
}
2、CPU运行在晶振(32768Hz)时钟下:
晶体频率为32768赫兹,约3倍的VLO。如果我们在前面的代码中使用晶振,指示灯应闪烁大约每秒一次。你知道为什么32768赫兹是一个标准?这是因为这个数字是2的15次方,因此很容易用简单的数字计数电路,以每秒一次获得率 ——手表和其他时间时基。认识到ACLK来自外部晶振时钟。
#include <msp430g2231.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;        // 关闭看门狗定时器
P1DIR = 0x41;                       // P1.0 和P1.6配置输出
P1OUT = 0x01;                      // 开启P1.0
BCSCTL3 |= LFXT1S_0;                // LFXT1 = 32768Hz 晶振
while(IFG1 & OFIFG)
{
IFG1 &= ~OFIFG;                   // 清除 OSCFault 标志
_delay_cycles(100000);             // 为可见的标志延时
}
P1OUT = 0;                      // 关闭P1
__bis_SR_register(SCG1 + SCG0);     // 关闭 DCO
BCSCTL2 |= SELM_3 + DIVM_3;      // MCLK = 32768/8
while(1)
{
P1OUT = 0x40;                   // 开启 LED
_delay_cycles(100);
P1OUT = 0;                     / / 关闭LED
_delay_cycles(5000);
}
}
3、CPU运行在晶振(32768Hz)和DCO时钟下:
最慢的频率,我们可以运行DCO约在1MHz(这也是默认速度)。因此,我们将开始切换MCLK到DCO下。在大多数系统中,你会希望ACLK上运行的VLO或32768赫兹晶振。由于ACLK在我们目前的代码是在晶体上运行,我们会打开DCO计算。
#include <msp430g2231.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;            // 关闭看门狗定时器
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
{
while(1);                               // If cal const erased, 挂起
}
BCSCTL1 = CALBC1_1MHZ;                // Set range
DCOCTL = CALDCO_1MHZ;                //设置DCO模式
P1DIR = 0x41;                          // P1.0 和P1.6配置输出
P1OUT = 0x01;                         // P1.0 开启
BCSCTL3 |= LFXT1S_0;                   // LFXT1 = 32768Hz
while(IFG1 & OFIFG)
{
IFG1 &= ~OFIFG;                       // 清除OSCFault 标志
_delay_cycles(100000);                 // 为可见标志延时
}
P1OUT = 0;                           // P1.6 关闭
// __bis_SR_register(SCG1 + SCG0);       // 关闭DCO
BCSCTL2 |= SELM_0 + DIVM_3;          // MCLK = DCO
while(1)
{
P1OUT = 0x40;                       // P1.6 开启
_delay_cycles(100);
P1OUT = 0;                         / / P1.6 关闭
_delay_cycles(5000);
}
}
4、CPU运行在DCO时钟下:
最慢的频率,我们可以运行DCO约在1MHz(这也是默认速度)。因此,我们将开始切换MCLK到DCO下。在大多数系统中,你会希望在VLO或者是晶振下运行ACLK。由于ACLK在我们目前的代码是在VLO上运行,我们会打开DCO运行。
#include <msp430g2231.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;                // 关闭看门狗定时器
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
{
while(1);                                   // If cal const erased,挂起
}
BCSCTL1 = CALBC1_1MHZ;                     // Set range
DCOCTL = CALDCO_1MHZ;                     // 设置DCO模式
P1DIR = 0x40;                               // P1.6 配置输出
P1OUT = 0;                                 // P1关闭
BCSCTL3 |= LFXT1S_2;                        // LFXT1 = VLO
IFG1 &= ~OFIFG;                             // 清除 OSCFault 标志
//__bis_SR_register(SCG1 + SCG0);              // 关闭DCO
BCSCTL2 |= SELM_0 + DIVM_3;                 // MCLK = DCO/8
while(1)
{
P1OUT = 0x40;                          // P1.6 关闭
_delay_cycles(100);
P1OUT = 0;                            // P1.6 开启
_delay_cycles(5000);
}
}

使用特权

评论回复
188
sharknarduo| | 2015-4-5 16:57 | 只看该作者

MSP430的时钟周期(振荡周期)、机器周期、指令周期之间的关系

时钟周期也称为振荡周期:定义为时钟脉冲的倒数(时钟周期就是直接供内部CPU使用的晶振的倒数,例如12M的晶振,它的时钟周期就是1/12us),是计算机中的最基本的、最小的时间单位。在一个时钟周期内,CPU仅完成一个最基本的动作。时钟脉冲是计算机的基本工作脉冲,控制着计算机的工作节奏。时钟频率越高,工作速度就越快。


机器周期:在计算机中,常把一条指令的执行过程划分为若干个阶段,每一个阶段完成一项工作。每一项工作称为一个基本操作,完成一个基本操作所需要的时间称为机器周期。8051系列单片机的一个机器周期由6个S周期(状态周期)组成。一个S周期=2个时钟周期,所以8051单片机的一个机器周期=6个状态周期=12个时钟周期。


指令周期:执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期也不同。


专用知识:


在430中,一个时钟周期= MCLK晶振的倒数。如果MCLK是8M,则一个时钟周期为1/8us;


一个机器周期 =一个时钟周期,即430每个动作都能完成一个基本操作;


一个指令周期 = 1~6个机器周期,具体根据具体指令而定。


另:指令长度,只是一个存储单位与时间没有必然关系。

MSP430根据型号的不同最多可以选择使用3个振荡器。我们可以根据需要选择合适的振荡频率,并可以在不需要时随时关闭振荡器,以节省功耗。这3个振荡器分别为:

(1)DCO 数控RC振荡器。它在芯片内部,不用时可以关闭。DCO的振荡频率会受周围环境温度和MSP430工作电压的影响,且同一型号的芯片所产生的频率也不相同。但DCO的调节功能可以改善它的性能,他的调节分为以下3步:a:选择BCSCTL1.RSELx确定时钟的标称频率;b:选择DCOCTL.DCOx在标称频率基础上分段粗调;c:选择DCOCTL.MODx的值进行细调。


(2)LFXT1 接低频振荡器。典型为接32768HZ的时钟振荡器,此时振荡器不需要接负载电容。也可以接450KHZ~8MHZ的标准晶体振荡器,此时需要接负载电容。

(3)XT2 接450KHZ~8MHZ的标准晶体振荡器。此时需要接负载电容,不用时可以关闭。

低频振荡器主要用来降低能量消耗,如使用电池供电的系统,高频振荡器用来对事件做出快速反应或者供CPU进行大量运算。当然高端430还有锁频环(FLL)及FLL+等模块,但是初步不用考虑那么多。

MSP430的3种时钟信号:MCLK系统主时钟;SMCLK系统子时钟;ACLK辅助时钟。

(1)MCLK系统主时钟。除了CPU运算使用此时钟以外,外围模块也可以使用。MCLK可以选择任何一个振荡器所产生的时钟信号并进行1、2、4、8分频作为其信号源。

(2)SMCLK系统子时钟。供外围模块使用。并在使用前可以通过各模块的寄存器实现分频。SMCLK可以选择任何一个振荡器所产生的时钟信号并进行1、2、4、8分频作为其信号源。

(3)ACLK辅助时钟。供外围模块使用。并在使用前可以通过各模块的寄存器实现分频。但ACLK只能由LFXT1进行1、2、4、8分频作为信号源。

PUC复位后,MCLK和SMCLK的信号源为DCO,DCO的振荡频率默认为800KHZ。ACLK的信号源为LFXT1。

MSP430内部含有晶体振荡器失效监测电路,监测LFXT1(工作在高频模式)和XT2输出的时钟信号。当时钟信号丢失50us时,监测电路捕捉到振荡器失效。如果MCLK信号来自LFXT1或者XT2,那么MSP430自动把MCLK的信号切换为DCO,这样可以保证程序继续运行。但MSP430不对工作在低频模式的LFXT1进行监测。


为了实现具体的时钟可以设置跟时钟相关的寄存器,在低端430中是DCOCTL、BCSCTL1和BCSCTL2三个寄存器。而对于高端的430,则要考虑SCFI0、SCFQCTL、FLL_CTL0、FLL_CTL1和BTCTL等几个寄存器。具体设置,参看DataSheet。



单片机上电后,如果不对时钟系统进行设置,默认800 kHz的DCOCLK为MCLK和SMCLK的时钟源,LFXTl接32768 Hz晶体,工作在低频模式(XTS=O)作为ACLK的时钟源。CPU的指令周期由MCLK决定,所以默认的指令周期就是1/800 kHz="1".25μs。要得到lμs的指令周期需要调整DCO频率,即MCLK=1 MHz,只需进行如下设置:BCSCTLl=XT20FF+RSEL2;


//关闭XT2振荡器,设定DCO频率为1 MHz


DCOCTL=DCO2

使用特权

评论回复
189
稳稳の幸福| | 2015-4-5 21:46 | 只看该作者
我认真学习了教程后,对CS系统有一个很好的认识。

第一,关于时钟信号的来源,系统内部提供了DCO压控振荡器是第一个来源,第二个来源是CLKIN管脚的,使用第二个来源需要使用DCO的旁路模式,就是把DCO搞到一边去,旁路到一边去,没它什么事。
第二,所谓的MCLK,ACLK,SMCLK,以及供给SD24的LK,这四个都是从时钟信号源接收信号后经过分频处理获得不同频率,用于不同目的的信号分频与分配系统。
这些不能称为时钟源,只能叫做时钟信号源信号处理与分配器,这样更恰当,不好理解的请看时钟系统模块图。主贴已经给了那个手册的下载附件。
以上两点就是我对教程中CS的认识,谢谢。我是认真思考后才来参与回复的

使用特权

评论回复
190
稳稳の幸福| | 2015-4-5 22:00 | 只看该作者
关于第4章节的串口通信部分,我说一下我的看法,关于通信肯定需要时钟信号进行同步,本系列单片机的时钟信号来源有3种,SMCLK,ACLK,UCLK。
UCLK这个不仔细读教程和手册真不知道干啥的,手册说是,external eUSCI clock,也就是外部的eUSCI时钟。
查看封装图,可知道P1.1/UCA0CLK/SMCLK/TMS              P1.0/UCA0STE/MCLK/TCK
另外P1.3和P1.2分别是UART的TXD和RXD,也就是说,1.1和1.0具备输出SMCLK和输出MCLK的功能。
UCA0CLK:eUSCI_A0 clock input/output (direction controlled by eUSCI)。这一点就解释了部分朋友对如何获取这些时钟信号输出的问题了,这需要参考对应具体型号的数据手册,不同型号内部资源是不同的。

使用特权

评论回复
191
稳稳の幸福| | 2015-4-5 22:44 | 只看该作者
sharknarduo 发表于 2015-4-5 16:49
MSP430有三个时钟源,三个时钟信号批发商,N个时钟用户。

1、时钟源

呵呵,不知道你看没有看楼主的教程啊,你说的跟楼主讲的内容根本不沾边,这个可不是以前那种430单片机了,这个没有你说的那些东西的,这个是个新型号的MSP430,时钟系统跟从前的430不同。

使用特权

评论回复
192
稳稳の幸福| | 2015-4-5 22:52 | 只看该作者
我看有的朋友回答的跟楼主讲的内容不沾边,不知道是不是为了奖品啊,哈哈。
不过这也让我有了启发。
首先本课程是介绍的MSP430i2xx系列,虽然都是2系列,跟以往F2xx,以及超值G2xx系列还是有很大的不同的,重要的一点时钟系统,就很不同,这个i2系列为了保证系统的安全可靠的工业级,去掉了容易因为外部原因造成的时钟系统失败,比如晶振的问题。等等。我看了看,楼主的教程根本没有提到晶振,也就是该单片机根本不需要晶振,因为i2xx把晶振的震荡系统去掉了。毕竟好多单片机启动失败一大部分原因是晶振坏了,比如我买的USB声卡没用多久就坏了,检测就是晶振坏了,还有U盘,如果连接电脑无法识别也是晶振坏了。所以i2xx为了保证工业品质,去掉了容易出错了地方,特别采用了强化的DCO,该DCO跟以往的G2xx的DCO也是不同的,该DCO具备两种电阻匹配模式,一个内置的,一个外置的,从前的好像没有外置的,所以也就没有区分,我看了G2的手册做了对比,这个真没有,所以该i2xx系列独到之处就在于此,以前的DCO只能采用内部的电阻配合DCO起振,由于电阻具有热变效应,也就是温度不同阻抗会发生变化,所以MCU工作肯定发热,会影响到内部的电阻阻值,所以提供的外置接口ROSC,即芯片的第11个PIN,而且是非共用的PIN,这说明系统设计师对该端口多么的看重。
希望我的观点能够帮到大家,嘿嘿,另外求中奖,我是很认真学习过的。

使用特权

评论回复
193
稳稳の幸福| | 2015-4-6 13:58 | 只看该作者
 
MSP430G2x MCUs
Clock
Up  to 16 MHz CPU speed
Up  to 16 MHz CPU speed
Memory
Up  to 56 KB Flash,Up to 4 KB SRAM
Up  to 32 KB Flash
   
    Up to 2 KB RAM
Voltage
1.8  – 3.6V operation
2.2V  – 3.6V operation
Extended Temp
HT: -55°C to 150°C
-40C  to 105C
EP: Enhanced  Products -55°C to 125°C
T: Extended  Temperature -40°C to 105°C Applications
Low Power
220 μA / MHz active  mode
Power  Consumption
0.7 μA  real-time clock mode
– Active Mode  (AM):
0.4 μA  Standby mode (VLO)
350 μA/MHz at  16-MHz, 3.0 V, Flash Program Execution (Typical)
0.1 μA RAM  retention
– Standby Mode  (LPM3): Watchdog Timer Active, Full RAM Retention 175 μA at 3.0 V (Typical)
5. Ultra-Fast  Wake-Up From Standby Mode in <1 μs
– Wake-Up From  Standby Mode in 1 μs
Smart Analog  and Digital
Up  to four 24-Bit Sigma-Delta Analog-to-Digital Converters with Differential PGA  inputs

使用特权

评论回复
194
稳稳の幸福| | 2015-4-6 13:59 | 只看该作者
上面的表格是我查看官网后做的对比。

使用特权

评论回复
195
稳稳の幸福| | 2015-4-6 14:00 | 只看该作者
跟G2对比后还是有很大的差别的。

使用特权

评论回复
196
胡斯哲| | 2015-4-6 16:42 | 只看该作者
刚学的时候听别人说用默认的1000hz的时钟,也一直用默认的时钟。有次用12864液晶窜口打点用了8M时钟,结构显示有问题。估计是频率太快了。
看了这讲,设置频率还能省功耗。。。
学习了

使用特权

评论回复
197
songchenping| | 2015-4-6 19:11 | 只看该作者
anvy178 发表于 2015-4-3 08:57
这个很明显的  使用外部时钟  然后  再分频成32k  这样子 肯定比使用内部时钟省电,  但是从可靠性来说   ...

你以什么得出结论外部时钟比内部时钟省电啊?

使用特权

评论回复
198
songchenping| | 2015-4-6 20:05 | 只看该作者
根据要求写了课后作业,分别是串口发送和接收代码。

#define LED_OFF       0x00
#define LED_ON        0x01
#define LED_TEST    0x02

uint8_t  LED_Status = 0x00;
uint8_t  flag = 0x00;

Void UARTTRANSMIT(void)
{
//发送LED_ON指令,点亮LED
EUSCI_A_UART_ transmitData(EUSCI_A0_BASE, LED_ON);

// 发送空指令,等待串口接收指令并操作
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");


//发送LED_ON指令,点亮LED
EUSCI_A_UART_ transmitData(EUSCI_A0_BASE, LED_OFF);

// 发送空指令,等待串口接收指令并操作
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");


//发送LED_ON指令,点亮LED
EUSCI_A_UART_ transmitData(EUSCI_A0_BASE, LED_TEST);

// 发送空指令,等待串口接收指令并操作
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");

}

Void UARTRECEIVE(void)
{
Uint8_t  ReceData = 0x00;

//接收指令
ReceData = uint8_t EUSCI_A_UART_receiveData ( EUSCI_A0_BASE);

//判断接收值
Switch (ReceData)
{
//接收值为0x00,关掉LED,置标志位为0
Case 0x00:
{
GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN4);
flag = 0;
}break;

//接收值为0x01,开启LED,置标志位为1
Case 0x01:
{
GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN4);
flag = 1;
}break;

//接收值为0x02,根据标志位来设置LED_Status的值
Case 0x02:
{
If(flag==0)
{
LED_Status = 0x00;
}
Else
{
LED_Status = 0x01;
}
}break;
Default:break;
}
}

使用特权

评论回复
199
anvy178| | 2015-4-6 21:39 | 只看该作者
songchenping 发表于 2015-4-6 19:11
你以什么得出结论外部时钟比内部时钟省电啊?

搞错了  是内部的比外部的省电

使用特权

评论回复
200
112207301219| | 2015-4-6 22:12 | 只看该作者
以前用5438的时候测过,应该类似吧。

使用特权

评论回复
发新帖 本帖赏金 5.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则