新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 利用MSP430调采集脉冲程序(疑问+解答)

利用MSP430调采集脉冲程序(疑问+解答)

作者:时间:2016-08-16来源:网络收藏

  在调试过程中利用CPU端口模拟周期为1.25S,脉冲宽度为20ms 40ms 60ms ,时采集数据,采集数据时的

本文引用地址:http://www.eepw.com.cn/article/201608/295564.htm

  问题:究竟采集多少个数据能够把一个周期的信号都采集到,

  方法是:利用大数组来采集根据实际读出的数据来计算一个周期需要采集的点数。

  根据DATASHEET利用SHT_0--15 来选择采样周期,再加上完成AD转换需13个ADC12CLK,依据此来计算与实际采到的数不符合,不知为什么,

  问题2:当时为得到2.4s 周期的脉冲,脉冲宽度为300ms ,按道理采集的数据应该多才对,但实际测试一个周期

  采集的数据确减少。(说明:当时模拟周期信号时用是ACLK,但当模拟2.4ms的周期信号时,把ACLK进

  行了2分频,但我感觉,因为AD采样采用不同的时钟,因些应该与分频没关系,但实际确不是这样,

  为什么?希望日后能发现这个问题)

  终于找到问题所在了: :::::::::::::::::

  msp430---------最大特色在于低功耗,然而低功耗确在于灵活时钟的应用。

  的灵魂在于----------CLK

  而造成上面出现问题的原因----------------------------就在于对基础时钟应用不当 ,下面具体解说:

  涉及的代码如下:

  void main(void)

  {

  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

  P6SEL |= 0x08; // Enable A/D channel inputs

  BCSCTL1 &= ~XT2OFF;

  BCSCTL2 = SELM_2; //select XT2;

  ADC12CTL0 = ADC12ON+MSC+SHT0_8+REFON+REF2_5V;

  // Turn on ADC12, extend sampling time

  ADC12CTL1 = SHP+CONSEQ_2 +ADC12DIV_7+ ADC12SSEL_2;

  // Use sampling timer, repeated sequence+ ADC12DIV_7

  ADC12MCTL0 = SREF_1+INCH_3;

  ADC12IE = 0X01;

  ADC12CTL0 |= ENC; // Enable conversions

  ADC12CTL0 |= ADC12SC; // Start conversion

  TACCTL0 |= CCIE ;

  TACCTL1 |= CCIE ;

  /*

  //按周期是1.25S来写的脉冲程序SH0_8 +ADC12DIV_7

  //TACCR1 = 0X9D70; //20mS 14/863/870 = 0.0162 20/1250=0.016

  //TACCR1 = 0X9AE0;//40mS 28/863/870=0.0324 40/1250=0.032

  //TACCR1 = 0x9851; //60mS 56/870

  //TACCR0 = 0XA000;

  */

  //为了写出周期为2.4S,脉冲为300MS的程序,需要修改的地方为

  BCSCTL1 = DIVA_1; //对ACLK进行2分频;

  //TACCR1 = 0x7334; //PULSE 600MS

  TACCR1 = 0x8667; //PULSE 300MS

  TACCR0 = 0X999A; //周斯2.4S

  /*

  //并且调试中发现,

  //如果采用SHT0_8+8分频的话,周斯为124, 300ms时,为15或16/124=0.125

  // 600ms时,31/124=0.25

  //如果采用SHT0_6+8分频的话,周斯为236, 300ms时,为29或30/235或236=0.125

  // 600ms时,59/236 = 0.25

  针对1.25S来写的脉冲程序SH0_8 +ADC12DIV_7

  计算:由于采用DCO = 800K , 且进行了8 分频,所以周期为10us.

  转换一个数需要的时间为:(SHT0_8)256+16个ADC12CLK , 也即为272*10=2.72ms

  所以对于周期为1.25S, 将会采集到1250/2.72=459.5 而实测为459,理论与实际符合,

  采样定时器占256个ADC12CLK

  同步占 3个ADC12CLK

  转换占13个ADC12CLK

  从上面程序可以看到执行下面两句目的是:打开外部晶振,并让主时钟选用外部晶体,然后让ADC选用主时钟,并进行8分频。

  BCSCTL1 &= ~XT2OFF;

  BCSCTL2 = SELM_2+DIVM_3; //select XT2;

  虽然写了上面的语句,但实际上上面的语句完全不起作用,

  After a PUC, the internal resistor is selected for the DC generator, RSELx =4, and DCOx = 3, allowing the DCO to start at a mid-range frequency. MCLK and SMCLK are sourced from DCOCLK.

  The basic clock module incorporates an oscillator-fault detection fail-safe feature. The oscillator fault detector is an analog circuit that monitors the LFXT1CLK (in HF mode) and the XT2CLK. An oscillator fault is detected when either clock signal is not present for approximately 50 µs. When an oscillator fault is detected, and when MCLK is sourced from either LFXT1 in HF mode or XT2, MCLK is automatically switched to the DCO for its clock source. This allows code execution to continue, even though the crystal oscillator has stopped

  从以上两段话可知及实际实验可知:

  正因为程序写的是用外部时钟,从而按外部时钟来计算时间,而程序执行时由于小于晶振起动时间,因些外部晶体没有起动,从而自动转入DCO来执行程序,从而造成假象。

  对程序中周期为2.4S的脉冲采样时,采到的数据反而小的解释如下:

  由于定时用ACLK,所以当定时超过2秒时,我对ACLK进行了2分频,从而程序先后执行了下面两条语句:

  BCSCTL1 &= ~XT2OFF;

  BCSCTL1 = DIVA_1; //对ACLK进行2分频;

  执行以上两句确实实现了2.4s的准确定时,但同时引入问题是:执行第二句时,是对其赋值0X10, 以至于把默认的RSELX = 4改为0,从而DCO由800K降为50K左右,从而采集到的数据大大减少,

  而正确的语句应为:BCSCTL1 | = DIVA_1; //对ACLK进行2分频;

  从实际测试数据反推:(((2400/124)/272)/8) 其倒数再乘以1000得114526,即114K,

  从DATASHEET图可以看出当DCOX=3 RSELX=4时,选取的是近110K的时钟,从而上面的奇怪现象得以解释。

  并且要使外部晶体正确起振:

  After a PUC, the basic clock module uses DCOCLK for MCLK. If required,

  MCLK may be sourced from LFXT1 or XT2.

  The sequence to switch the MCLK source from the DCO clock to the crystal

  clock (LFXT1CLK or XT2CLK) is:

  1) Switch on the crystal oscillator

  2) Clear the OFIFG flag

  3) Wait at least 50 µs

  4) Test OFIFG, and repeat steps 1-4 until OFIFG remains cleared.

  ; Select LFXT1 (HF mode) for MCLK

  BIC #OSCOFF,SR ; Turn on osc.

  BIS.B #XTS,&BCSCTL1 ; HF mode

  L1 BIC.B #OFIFG,&IFG1 ; Clear OFIFG

  MOV #0FFh,R15 ; Delay

  L2 DEC R15 ;

  JNZ L2 ;

  BIT.B #OFIFG,&IFG1 ; Re?test OFIFG

  JNZ L1 ; Repeat test if needed

  BIS.B #SELM1+SELM0,&BCSCTL2 ; Select LFXT1CLK

  其C语言为:

  Do

  {

  IFG1 &= ~OFIFG; //清除晶振失败标志

  for (i = 0xFF; i > 0; i--); // 等待8MHz晶体起振

  }

  while ((IFG1 & OFIFG)); // 晶振失效标志仍然存在?

  在调试程序中加入以上判别语句后,一切都下常起来。

  结论:一切不合理的现象皆是有原因的,发现它,找到它,掌握它。



关键词: MSP430 MCU

评论


相关推荐

技术专区

关闭