您好!
有个问题困扰好久了,我在做定时器的捕获实验,发现MSP430F1611在没有捕获事件发生时,TBR 的值也会保存到TBCCRx 中,可是MSP430用户指南里明确说明了当一个捕获被执行时,TBR 才会被复制到 TBCCRx 寄存器中,还有捕获测时间间隔,发现每次都少了60us,这是为什么呢???我的信号源是通过PWM输出的,很稳定。
弄了两天了,还没找到原因,拜托各位大神拯救一下菜鸟!!!!!!
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;
}