我这是普通的24v直流有刷电机,大概100w,用在车库门上面,电机带蜗轮减速的,电机转子轴上有磁环,有霍尔元件,电机转的时候会输出方波到单片机,单片机外部中断,计数那个边沿,通过计得的数来表示电机行程长短,电机可以正传,反转,停止,通过继电器切换。
前两天我在一位前辈的指导下,收获匪浅,使得电机如果自己从头走到尾的话,行程不错,
但是,车库门带遥控的,按下遥控,门的运行状态要反向,如果门走到半路停止,然后再返回来,如此循环几次后,会发现,门的起始位置漂移了,这个问题一直还么解决,现在我贴出来部分代码,请求哪位有空帮我分析分析
变量p表示电机的状态 p=1正传,p=3反转,p=0或2停止
switch(p) //修改电机运行方向
{
case 1:
{
PORTA=(1<<PA3);//开门继电器
PORTC&=~(1<<PC0);//运行灯亮
Count_allow=1;
if(Set_allow==0)
{
if(x==0)
Slowstart();
if(Idata2.countss<100)
{
x=1;
//slowstop();
OCR1B=0;Stop_flag=1;
}
}
}break;
case 3:
{
PORTA=(1<<PA2);//关门继电器
PORTC&=~(1<<PC0);//运行灯亮
Count_allow=3;
if(Set_allow==0)
{
if(x==0)
Slowstart();
if(Idata2.countss>Idata1.counter-100)
{
x=1;
//slowstop();
OCR1B=0;Stop_flag=1;
}
}
}break;
default:
{
if(Set_allow==1) //设置中
{
PORTC|=(1<<PC0);//运行灯灭
PORTA&=~((1<<PA2)|(1<<PA3));//释放两个继电器
OCR1B=0;
x=0;
Set_allow=0;
studyed=1;
//Count_allow=0;
}
else
{
if(Stop_allow>150)
{
PORTC|=(1<<PC0);//运行灯灭
PORTA&=~((1<<PA2)|(1<<PA3));//释放两个继电器
OCR1B=0;
x=0;
Stop_allow=0;
// Count_allow=0;
}
// else{}
}
}break;
}
那个p值在运行中可以通过遥控改变的,遥控有单独的高频板接受,输出个电平给单片机的一个管脚
下面这段是收到遥控信号后的处理:
if((PINA&0x10)==0x10) //收到高电平
{
Remote_flag=1;
if(Remote_allow==1)
{
Remote_allow=0;
if(p<3) p++;
else p=0;
if((p==1)||(p==3)) {Stop_flag=0;Stop_allow=0;}
if((p==0)||(p==2)) {m=0;OCR1B=0;Stop_flag=1;}
}
}
else Remote_flag=0;
Stop_flag=1后,开始t0计时,大概1s后,才允许下一次操作,目的是让电机完全停止,
在脉冲计数中断函数中根据p的值进行加计数或者减计数,目前,我只保留了这一个中断源,其他都是查询标志位来进行的
下面是中断函数:
void Int_INT2(void)
{
m=0;
if((p==1)||(p==2)) Idata2.countss--;
if((p==3)||(p==0)) Idata2.countss++;
}
我贴出以上部分,欢迎各位讨论,只讨论程序,不讨论硬件问题,硬件运行正常,不改动。我用的是avr的m16芯片 |