|
本帖最后由 wuminhdu 于 2012-4-7 13:39 编辑
用的是有位置传感器的无刷直流电机,代码如下面,pic_sa是连着电机的一个位置传感器的,就是用PIC_SA引脚来确定电机的位置,电机转一圈,PIC_SA有4次高低电平切换,然后记录下4次电平切换的时间,也就是电机转一圈的时间,用示波器测PIC_SA引脚的电平变化很标准,没有毛刺,占空比50%,也就是没有问题,但是单片机经运算后的实际电机转速跳动很大(比如正常速度500左右,他可能会跳到1000多),是什么原因,使用T1捕捉功能也是如上问题,测速不准就谈不上电机控制了,很纠结,是我定时器配置有问题吗,或是是其他什么问题,求高手不吝赐教。
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
system.timer1cnt++;
}
void Timer_Init(void)//时钟初始化
{
OCR0 = 0x7C; //1ms
TCNT0 = 0x00;
TCCR0 = (1<<WGM01)|(1<<CS01)|(1<<CS00); // CTC 8M/64
TCCR1B = 0x01;//1:1预分频
TCNT1H = 0;
TCNT1L = 0;
ASSR = 0x00;
TIMSK = 0x02;//溢出中断使能
TIFR = 0x00;
}
void sys_readspeed(void)//求电机转速函数
{
u8 err = 0,j,k = 0;
u16 sum = 0;
do{
sum = speedonce();//求一次转速
if(sum == 0)
{
err++;
k++;
if(err >= 3){//如果电机3次测得速度为0,重启电机
sys_write_AD5320(0);
MC30335_CS = 1;
sys_write_AD5320(2000);
DogFeed();
sys_delay(30000);
MC30335_CS = 0;
DogFeed();
sys_delay(30000);
err = 0;
sys_beepcnt(90);
}
}
else
{
err = 0;
k = 0;
}
if(k >= 50)
break;
}while(sum == 0);
system.speed_current = sum;//当前电机转速赋值
}
u16 speedonce(void)//
{
u8 i;
static u32 result = 0;
u8 flag = FALSE;
union {
u16 data;
u8 regsiter[2];
}time;
TCNT1H = 0;
TCNT1L = 0;
if(testrun())
{
system.timer1cnt = 0;//T1溢出次数
TIFR = 0x04;//置0T1溢出中断标记
TIMSK = 0x06;//T1溢出使能,T0是CTC模式
flag = TRUE;
for(i=0;i<4;i++){//转一圈有4次电平切换
if(!testrun())
flag = FALSE;
}
if(flag){
time.regsiter[0] = TCNT1L;
time.regsiter[1] = TCNT1H;
TIMSK = 0x02;
if(system.timer1cnt >= 50)
result = 0;
else{
result = time.data+system.timer1cnt*65535;//T1定时器的时间
result = 480000000/result;//计算电机速度60/(1/(8M*result));
}
}
else{
result = 0;
}
}
return result;
}
u8 testrun(void)
{
u16 max_time = 50000;
u16 i,j,k;
u8 result = 0;
DogFeed();
for(i = 0;i< max_time;i++){
if(PIC_SA){
for(j = 0;j<max_time;j++){
if(!PIC_SA){
for(k = 0;k<max_time;k++){
if(PIC_SA){
result = 1;
break;
}
}
}
if(result)
break;
}
}
if(result)
break;
}
DogFeed();
return result;
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|