我用定时器A做了,P2.3输出PWM波(控制直流电机),利用P1.3捕获脉冲宽度(测量电机的转速),但是捕获的值有时候会丢失溢出中断,这是为什么?(例如:电机转速本应该是13.11ms每转,但是捕获的值有时候是3.11ms每转),谁能告诉我错误出在哪里?
定时器的设定子函数:
void TA_Capture(void)
{
TACTL=TACLR+TASSEL_2+ID_3; //TAR清除,捕获时钟选择SMCLK,8分频(选择8Mhz/8=1Mhz)
TACTL|=TAIE; //打开溢出中断
TACCTL2=CM_1+CAP+SCS+CCIS_0; //CCTL2,上升沿捕获,捕获模式,同步捕获,捕获端口选取CCIxA
TACCR0=10000-1; //定时器溢出值
TACCR1=6000; //PWM翻转比较值(初始值)
TACCTL1=OUTMOD_2; //选择PWM波输出模式2_PWM翻转/复位
P2DIR|=BIT3; //将P2.3设定为输出
P2SEL|=BIT3; //将P2.3设定为PWM波输出端
P1SEL|=BIT3; //将P1.3设定为捕获端口
TACTL|=MC_1; //增计数模式
}
脉冲捕获和计算函数:
void pulse_calculate_function(void)
{
while((CCIFG&TACCTL2)==0);
TACCTL2&=~CCIFG;
overflow_count=0;
T_cap1=TACCR2;
while((CCIFG&TACCTL2)==0);
TACCTL2&=~CCIFG;
intermediate_overflow_count=overflow_count;
T_cap2=TACCR2;
T_wide=intermediate_overflow_count*10000-T_cap1+T_cap2; //脉冲宽度计算
}
中断函数:
#pragma vector = TIMERA1_VECTOR //捕获中断
__interrupt void TIMERA_2(void)
{
_EINT();
switch(TAIV) //读中断向量寄存器
{
case TAIV_TAIFG: ++overflow_count;
break;
default: break;
}
}
有没有哪位大侠指点一下错误所在?
此帖出自
小平头技术问答
转速理论上是不算快的,最快也就是几个毫秒。只是速度快了,一个周期可能要出现两次捕获中断和一次溢出中断。
硬件采用霍尔传感器,电机每转一周,出现一个方波。
我的计算没有在中断里啊,按理说中断执行周期应该比较快啊。电机的速度使用示波器看的,在12V电压的情况下13.11ms,基本稳定。
LCD显示的值一般都是13.10左右,但是偶尔会出现一次丢溢出中断,真郁闷啊
#pragma vector = TIMERA1_VECTOR //捕获中断
__interrupt void TIMERA(void)
{
switch(TAIV) //读中断向量寄存器
{
case 4: switch(cap_count) //捕获瞬间,读取TAR的值
{
case 0: T_cap1=TACCR2;
cap_count=1;
overflow_count=0;
break; //记录捕获值
case 1: T_cap2=TACCR2;
cap_count=0;
intermediate_overflow_count=overflow_count;
overflow_count=0;
break;
}
break;
case 10: overflow_count+=1;
break;
default: break;
}
}
这是我改写的在中断中读捕获值的程序,还是会偶尔出现丢溢出中断的问题。
我用定时器A同时实现了PWM波,溢出中断,还有方波宽度捕获,是不是定时器A资源用的太多了?
不过说实在的,我能回复你就算不错了,当然还是要道歉,误导比不回复可能更浪费了您的时间
看看这儿会不会出问题:
while((CCIFG&TACCTL2)==0);
//在这以前,TACCR2已经捕捉到值,假设恰好为9999,也即10000-1
TACCTL2&=~CCIFG;
//在执行下面一条指令前是否可能发生了TAIE中断?因为你的定时器时钟比较快为1M,不知道你的MCLK为多少?这个需要对比汇编看看运行周期数是否可能
overflow_count=0;
T_cap1=TACCR2;
您的意思是,捕获的时刻距离定时器溢出时刻比较近,在读取溢出值之前,出现了溢出现象,最终导致计算错误码?
一周热门 更多>