历史上的今天
返回首页

历史上的今天

今天是:2025年01月15日(星期三)

正在发生

2020年01月15日 | 浅谈msp430f5529入门(2)——时钟配置、例程分析

2020-01-15 来源:eefocus

前天写了关于DCO,FLL的一些问题,而其他的如XT1,XT2和1xx系列几乎没有区别,而且相比比较简单,就不另外讨论了。现在总结一下55系列的时钟配置,我以TI官网提供的例程为例子进行分析,只要肯折腾,收获是不会少的。而且我发现了例程里的注释有错误,可能会给大家带来学习时的困扰,我在下文会指出。


有人可能会问TI的例程怎么找,我在这里也说一下。在TI官网搜索需要的芯片,在结果的右边会有该芯片的资料,点进去后找到“工具和软件”,点它之后再软件的培训内容里可以找到例程下载,就是名字里有examples的zip。


呵呵,可能已经有人这么尝试过了,但F5529的这里并没有例程。不过这并不表明TI没有提供5529的例程。另辟蹊径吧骚年,我估摸着一个系列的例程都是通用的,于是就再搜了一遍5526,结果就在那里找到了55xx的例程,也就是我下面要分析的例程。


例程下载链接


-----------------------------------可以开宰了------------------------------------


包里有关时钟配置的例程一共有9个,其实弄好前面几个,后面只是大同小异而已。


(1)首先,第一个,最简单的一个,因为它根本就没有配置时钟......不过,它还是很有用,因为它给我们呈现了单片机上电后的时钟状况。


//   ACLK = REFO = 32.768kHz, MCLK = SMCLK = Default 1MHz

#include

 

int main(void)

{

  volatile unsigned int i;

 

  WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT

  P1DIR |= BIT1;                            // P1.1 output

 

  P1DIR |= BIT0;                            // ACLK set out to pins

  P1SEL |= BIT0;                            

  P2DIR |= BIT2;                            // SMCLK set out to pins

  P2SEL |= BIT2;                            

  P7DIR |= BIT7;                            // MCLK set out to pins

  P7SEL |= BIT7;                              

 

  while(1)

  {

    P1OUT ^= BIT1;

    __delay_cycles(60000);                  // Delay

  }

}


博主我刚开始学时就很纠结这PUC后的默认时钟状况:


After a PUC, the UCS module default configuration is:

• XT1 in LF mode is selected as the oscillator source for XT1CLK. XT1CLK is selected for ACLK.

• DCOCLKDIV is selected for MCLK.

• DCOCLKDIV is selected for SMCLK.

• FLL operation is enabled and XT1CLK is selected as the FLL reference clock, FLLREFCLK.

• On devices that have XIN and XOUT shared with general-purpose I/O, XIN and XOUT pins are set to

general-purpose I/Os and XT1 remains disabled until the I/O ports are configured for XT1 operation. If

XIN and XOUT are not shared with general-purpose I/O, XT1 is enabled.

• When available, XT2IN and XT2OUT pins are set to general-purpose I/Os and XT2 is disabled.


刚上电后,说是ACLK和FLL默认以XT1为源,但你又不打开XT1,那问题纠结了我很久,用示波器测试测得ACLK是大约327668Hz,但使用手册后面有说这两个时钟在XT1LF失效后会转向REFOCLK,它是内部的32768Hz的时钟(那时我还没看- -||)。


真相就是这么一回事:

这是我用CCS仿真调试时暂停截的图,图示程序已经执行到while(1)里了,打开寄存器窗口看到XT1LFOFFG和DCOFFG置1了。前者被置位就是因为ACLK和FLL处于默认状态一直在向XT1取源,而XT1被禁止失效所以XT1LFOFFG被置位了,而程序还能跑就是因为XT1LF失效时它们两个时钟暂时向REFOCLK取源。后者为什么也置1了呢?它没有向XT1取源啊。呵呵,上一章说过,默认状态的DCO由FLL稳定,而FLL的时钟源XT1出问题所以DCOFFG就置1了。


因此,即使大家不需要调整单片机的时钟,在程序的开头也请先配置一下时钟,养成这个习惯,至少把XT1打开,因为XT1比REFOCLK稳定多了。


(2)第二个例程,很值得去折腾,它设置了FLL来稳定DCO到8MHz。噢不!是16MHz.


//   ACLK = REFO = 32kHz, MCLK = SMCLK = 8MHz

#include

 

int main(void)

{

  volatile unsigned int i;

 

  WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT

  P1DIR |= BIT1;                            // P1.1 output

 

  P1DIR |= BIT0;                            // ACLK set out to pins

  P1SEL |= BIT0;                            

  P2DIR |= BIT2;                            // SMCLK set out to pins

  P2SEL |= BIT2;                            

  P7DIR |= BIT7;                            // MCLK set out to pins

  P7SEL |= BIT7;           

 

  UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO

  UCSCTL4 |= SELA_2;                        // Set ACLK = REFO

  UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx

 

  // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize

  do

  {

    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);

                                            // Clear XT2,XT1,DCO fault flags

    SFRIFG1 &= ~OFIFG;                      // Clear fault flags

  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

  __bis_SR_register(SCG0);                  // Disable the FLL control loop

  UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation

  UCSCTL2 |= 249;                           // Set DCO Multiplier for 8MHz

                                            // (N + 1) * FLLRef = Fdco

                                            // (249 + 1) * 32768 = 8MHz

  __bic_SR_register(SCG0);                  // Enable the FLL control loop

 

  // Worst-case settling time for the DCO when the DCO range bits have been

  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx

  // UG for optimization.

  // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle

  __delay_cycles(250000);

  while(1)

  {

    P1OUT ^= BIT0;                          // Toggle P1.0

    __delay_cycles(600000);                 // Delay

  }

}


18和19行,将这两个时钟的时钟源取为了REFO,这样,就没有任何时钟在向XT1请求时钟源,DCO也没有问题,故而下面的do{}while语句能通过。这个语句就是检测时钟有没有问题,如果晶体正在起振,还没有达到工作状态,会在这个循环里等待晶体起振完毕。XT2OFFG,XT1LFOFFG,DCOFFG,OFIFG都必须由软件清零。另外,POR后,OFIFG是被置位了的。


比如我把UCSCTL4 |= SELA_2;注释掉,这样,ACLK也会向REFO申请时钟源,但程序运行下来就并不一样了。

它会卡在这个循环里出不去,和上面(1)的情况一样,ACLK的寄存器里的默认值还是在向XT1申请时钟源,XT1不干活,XT1LFOFFG就置位了。


20行那里其实可以不配置,因为默认就已经是0x0000,而FLL会自动调整UCSCTL0。


这个程序的精髓就在于30-35这4行(啊咧?4行?),这是配置FLL的标准流程,在调整有关FLL的寄存器前,无比要先禁止FLL,不然可能会产生不可预料的结果。


上一章说到,用FLL稳定DCO,只要设置好FLL的时钟,再就是配置DCORSEL和FLLN就好了。利用公式:


·fDCOCLK= D × (N + 1) × (fFLLREFCLK÷ n)

·fDCOCLKDIV= (N + 1) × (fFLLREFCLK÷ n)


就可以计算出所需的值,纳尼?这和注释里的不一样?呵呵,是的,真的是注释错了。程序里(249 + 1) * 32768 = 8MHz计算的是fDCOCLKDIV!而不是注释里写的fDCOCLK!而注释里的那条看起来像公式的根本就不是个东西!


那为什么我测出来的真的是它说的大约8MHz呢?呵呵,因为它说错了,SMCLK并没有使用DCOCLK,它还是默认地使用了DCOCLKDIV,所以那条式子计算出来的的的确确是SMCLK的频率,但因为它错了两次,1.(N + 1) * FLLRef = Fdco.2.SMCLK使用DCOCLK。所以就被它绕回来了。没想到堂堂TI的例程,也会出错。被我这菜鸟抓到了。


为了揭穿TI的真面目,我把19行改为了


UCSCTL4 &= ~SELS_4;   //取消默认的SELS_4

UCSCTL4 |= SELA_2 + SELS_3;               //设置SMCLK = DCO


测了一下SMCLK,16.828MHz,是接近计算值,结论正确!所以大家在计算使用DCO时要注意DCODIV的存在,在我感觉,DCODIV更像是老大。


而后我把目光盯向了DCORSEL,因为看的资料一直在说只要把公式里面4个量设置好就可以得到想要的DCO或DCODIV频率。那还设置DCORSEL干嘛?


于是,我把UCSCTL1 = DCORSEL_5;注释掉了,RCORSEL默认值是RCORSEL_2,再调试了一遍。

发现DCOFFG被置位了,而SMCLK得频率只有2.456MHz,不是计算值呀!


DCORSEL的作用是设定DCO的频率范围,详见datasheet里的下面这表:

可以看到,DCORSEL = 2时,DCO最大最大也就7.38MHz,没有达到我们要的16点多MHz。


也就是说,就算是使用FLL来稳定DCO,DCO大概的范围即DCORSEL还是需要设置的!


于是,我有把DCORSEL = 3,调了一次

DCOOFFG还是被置位了,SMCLK频率只有4.654MHz,看表,DCORSLE = 3时DCO最大是14.0,还没有达到计算值。


在把DCORSEL设置为4之后,一切都正常了,5,6,7都试过没问题,计算值16.384MHz包含在这些范围里面。所以结论是正确的!还是那句话:就算是使用FLL来稳定DCO,DCO大概的范围即DCORSEL还是需要设置的!这个范围只需要包含目标值就行。


(3)例程2终于被我折腾完了,后面的例程不过是换了下时钟源换了下频率,已经没多少研究的价值,不过这些是我都看了一遍之后的结论。


在例程3和4里,还是设置FLL,不过是3里面换了下数值,do{}while放下面而已,还是使用DCODIV,注释还是错的......


4里面启用了XT1,用了这3句代码:


  P5SEL |= BIT4+BIT5;                       // Port select XT1

  UCSCTL6 &= ~(XT1OFF);                     // XT1 On

  UCSCTL6 |= XCAP_3;                        // Internal load cap


打开XIN和XOUT


置0XT1OFF


老实说电容我不知道怎么选,不过这里选了12pf,那就12pf吧。其实上电后XCAP里的值默认就是XCAP_3,所以这里可以不配置


启用了XT1别忘了要等它起振:


  // Loop until XT1 fault flag is cleared

  do

  {

    UCSCTL7 &= ~XT1LFOFFG;                  // Clear XT1 fault flags

  }while (UCSCTL7&XT1LFOFFG);               // Test XT1 fault flag

        其他的没什么了,说一下XT1的牛逼,这里ACLK和SMCLK的计算值分别是


ACLK = 32768Hz, SMCLK = 2457600Hz。


我测出来的是


ACLK = 32767.5Hz, SMCLK = 2457560Hz。


非常高的精密度,而且非常稳定,数值就没有变化过。相比起使用REFO时的频率总是会有百分之零点几到一点几的误差而且会有波动,当然是XT1更胜一筹。


(4)好了,写了这么多,能分享的就是这些了,关于时钟这一块,就到此结束吧。

推荐阅读

史海拾趣

Equator Technologies公司的发展小趣事

在发展过程中,Equator始终注重拓展国际市场。通过与全球各地的合作伙伴建立紧密的合作关系,Equator将其产品和服务推向了世界各地。特别是在亚洲市场,Equator凭借其卓越的技术实力和优质的产品赢得了众多客户的青睐。同时,公司还积极参加国际展会和交流活动,与全球同行进行技术交流和合作,不断提升自身的国际竞争力。

Elektron公司的发展小趣事

随着业务的不断拓展和市场的不断扩大,Elektron公司逐渐将目光投向了全球市场。公司在全球范围内设立了多个代表处和分支机构,与当地的合作伙伴建立了紧密的合作关系。通过全球化战略的实施,Elektron成功进入了焊接设备、等离子切割设备和电池服务设备的高端市场,并成为了世界市场的领导者之一。

思博科技(Cybermax)公司的发展小趣事

在2005年的一个阳光明媚的春天,思博科技(Cybermax)公司在硅谷正式成立。创始人李明,一位经验丰富的电子工程师,看准了当时电子市场蓬勃发展的机遇,决定创办自己的公司。起初,公司只有几名员工,主要致力于研发和生产高性能的电子元器件。通过不懈的努力和优质的产品,思博科技逐渐在市场上崭露头角。

振华(CEC)公司的发展小趣事

面对激烈的市场竞争,振华始终将技术创新作为企业发展的核心动力。公司投入大量资金进行技术研发,积极引进国内外先进技术,并与高校、科研机构建立紧密的合作关系。通过持续的技术创新,振华在电子产品领域取得了多项重要突破,推出了一系列具有自主知识产权的高新产品,引领了市场潮流。

BEKA Associates Ltd公司的发展小趣事

在快速发展的过程中,BCD Semi(Diodes)积极寻求风险投资和资本运作的支持。公司通过吸引国内外知名的投资机构参与投资,获得了大量的资金支持,为公司的研发、生产和市场拓展提供了有力的保障。同时,BCD Semi还通过并购、合作等方式,与行业内的其他企业实现资源共享和优势互补,进一步提升了公司的综合实力。

台湾岱恩(DAIN)公司的发展小趣事

随着全球电子市场的不断发展,BCD Semi(Diodes)积极寻求国际化拓展的机会。公司通过与国外知名企业的合作,成功进入了多个海外市场。在国际市场上,BCD Semi凭借其高品质的产品和专业的服务,赢得了客户的信赖和支持。同时,公司还积极参加国际电子展会和交流活动,与全球同行进行深入的交流与合作,不断提升自身的国际影响力。

问答坊 | AI 解惑

74HC595

void In_595() //将显示数据送入74HC595内部移位寄存器 {         uchar i;         for(i=0;i…

查看全部问答>

光刻为什么用光刻胶,可不可以直接刻蚀SiO2

光刻为什么用光刻胶,可不可以直接刻蚀SiO2…

查看全部问答>

WINCE+ARM的系统,把全局不变的数组加一个const修饰符能起到什么作用?减少内存的占用?提高程序执行速度?ARM下ROM可以当RAM使用吗?

WINCE+ARM的系统,把全局不变的数组加一个const修饰符能起到什么作用?减少内存的占用?提高程序执行速度?ARM下ROM可以当RAM使用吗?…

查看全部问答>

关于GPS接收程序中信息识别的设计方法

我本科毕业设计做GPS接收系统,现在该做$GPGGA、$GPRMC识别那部分了,因为GPS信息是信息流,不是事先存好的,编个子函数,有很多参数要传递,很麻烦,还有很多问题感觉不好解决,怎么识别这几个字符串大家有什么好的方法没?…

查看全部问答>

关于 ksthunk.sys ???

我开发一个video class upper flter driver, 用于处理从摄像头的device driver取得的frame。在64bit windows下, Image类已经有一个class upper filter driver 叫 “ksthunk.sys”. 我发现如果把我的filter driver 写在 ksthunk的后面,这样在devic ...…

查看全部问答>

求一个燃气报警系统的设计

本人想设计一个燃气报警系统可是感觉有点力不从心想请各位高手指点一下 不胜感激! 这是我设计的系统框图 传感器→放大器→A/D转换→AT89S52→ISD1420→喇叭(还可以再加个LCD) MQ-5     …

查看全部问答>

GBT 18488.1-2006电动汽车用电机及其控制器 第1部分:技术条件

GBT 18488.1-2006电动汽车用电机及其控制器 第1部分:技术条件…

查看全部问答>

stm32的串口是3+2那个+2是什么意思啊?

                                 000…

查看全部问答>

富士康被指强迫员工签署不自杀协议

   据国外媒体报道,为苹果生产iPhone和iPad的中国富士康工厂的员工,曾被强迫签署不自杀协议。据悉,富士康在出现十余名员工接连自杀的状况之后,要求员工签署不自杀协议。富士康的工厂被报道员工每周需要工作6天12小时,每月工作时间总 ...…

查看全部问答>