This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
有个问题困扰好久了,我在做定时器的捕获实验,发现MSP430F1611在没有捕获事件发生时,TBR 的值也会保存到TBCCRx 中,可是MSP430用户指南里明确说明了当一个捕获被执行时,TBR 才会被复制到 TBCCRx 寄存器中,还有捕获测时间间隔,发现每次都少了60us,这是为什么呢???我的信号源是通过PWM输出的,很稳定。
弄了两天了,还没找到原因,拜托各位大神拯救一下菜鸟!!!!!!
您好,发现你帮我回答几次了,真的非常感谢!!!!那个很抱歉今天才回复,昨天晚上不知怎么回事,代码一直不能插入。
对于MSP430在没有发生捕获时,TBR的值也会保存在TBCCRX的问题,我知道原因了,我当时是在单步执行时检测TBCCRX的值,这种做法就是错的,因为虽然代码暂停运行了,但外部信号源还是在变化,所以此时测TBCCRX的值也就有问题了。
但是现在又不幸发现新的问题了,对于不同频率的信号源所测的时间间隔精确度不同,时钟源为4M,是不是定时器溢出的代码写的有问题呢??下表是在不同频率信号源下,测得TBCCRX误差个数
信号源频率 | 实际测得误差的个数(都是比计算值少测的个数) |
100hz | 20个 |
1khz | 120个 |
10khz | 1个 |
100khz | 0个 |
再次麻烦您帮我看一下了!!!感激不尽!!!! O(∩_∩)O
#include<msp430f1611.h> #define uchar unsigned char #define uint unsigned int uint width[15]={0}; uint i=0; double cap_ave=0; uint new_cap=0; uint old_cap=0; uint cap_diff=0; uint diff_array[16]; // RAM array for differences uint capture_array[16]; // RAM array for captures uchar index=0; uint count = 0; uint test=0; void main() { WDTCTL=WDTPW+WDTHOLD; //关闭看门狗 P4SEL |=BIT0; //P4.0 作为捕获模块功能的输入端输入方波 P4DIR &=~BIT0; P5SEL |=BIT4+BIT5;//SMCLK,MCLK频率输出 P5DIR |=BIT4+BIT5; //P1SEL |= BIT0; //P1DIR |=BIT0; //-------开晶振 XT2---------BCSCTL1&=~XT2OFF; //打开 XT2 振荡器 BCSCTL1&=~XT2OFF; do { IFG1 &= ~OFIFG; // 清除振荡器失效标志 for (i=256;i>0;i--); // 延时,等待 XT2 起振 } while ((IFG1 & OFIFG) != 0); // 判断 XT2 是否起振 BCSCTL2 =SELM_2+SELS; //选择 MCLK=SMCLK 为 XT2 //-----------------------------TBCCTL0&=~(CCIS1+CCIS0); // 捕获源为 P4.0,即 CCI0A(也是 CCI0B) TBCCTL0&=~(CCIS1+CCIS0); // 捕获源为 P4.0,即 CCI0A(也是 CCI0B) TBCCTL0|=CM_3+SCS+CAP; //下降沿捕获,同步捕获,工作在捕获模式 TBCCTL0|=CCIE; //允许捕获比较模块提出中断请求 // TBCTL|=ID_1; //8分频 ,MCLK 1Mhz TBCTL|=TBSSEL_2; //选择时钟 MCLK TBCTL|=TBCLR; //定时器清零, //定时器开始计数(连续计数模式 0~0xFFFF) TBCTL|=MC_2; _EINT(); while(1) { if(TBCTL&TBIFG) //定时器溢出清零 { TBCTL&=~TBIFG; count++; } if(TBCCTL0&COV) //二次捕获溢出逻辑清零 { TBCTL|=MC_0; TBCCTL0 &=~COV; TBCTL|=MC_2; } } } //―――――定时器 TB 的 CCR0 的中断:用于检测脉冲上升与下降沿―――― #pragma vector=TIMERB0_VECTOR __interrupt void TimerB0(void) { if( TBCCTL0 &CCIFG) { //下降沿检测 new_cap= TBCCR0+count*65536; //记录下结束时间 count=0; cap_diff = new_cap -old_cap; width[i++] = cap_diff; old_cap=new_cap; if(i==3) { for(uint n=1;n<i;n++) cap_ave +=(double)(width[n]); cap_ave =cap_ave/(i-1); i=0; cap_ave=0; } } TBCCTL0 &=~CCIFG; }