本人是刚学画PCB..公司有个项目是关于一个控制3个直流电机的。具体情况:用PIC16F1939接光耦然后接电机驱动芯片来控制三个电机实现正反转。直流电机是18v的,同时在输出端串采样电阻,将采样电压送至单片机内部经AD转换。当直流电机被阻挡时。由于AD采样值超过程序中设定的额定值而是单片机输出信号关闭电机,然后稍微反转几圈。但现在遇到的问题是;按键按下后电机转一下就停止。只有在程序中延长时间后才开始正常工作。试验了好久都不能得到很好地解决,非常着急。请问各位大牛怎么解决,以及有什么需要改进的地方。下面上程序和图:(原理图不清晰分两张)
这是PCB图:
程序:
#include<htc.h>__CONFIG(0x09E4);
__CONFIG(0x09FF);
__EEPROM_DATA(0,0,0,0,0,0,0,0);
#define uchar unsigned char
#define uint unsigned int
#define threshold_up 900
#define threshold_down 100
uchar a;
uchar b=0;
uint result;
uint res;
uchar flag1=0;
uchar flag2=0;
uchar flag3=0;
//uchar TMR1_num;//TMR1中断溢出次数
void init(void);
uchar buff_read(uchar);
void buff_write(uchar,uchar);
uint ad_convert(uchar);
void interrupt ISR(void);
void delay_ms(uint);
void main(void)
{
init();
PORTC=0;
PORTE=0;
RD0=1;
NOP();
RD1=1;
a=buff_read(0x07);
while(b==1)
{
result=ad_convert(0);
if((result>threshold_up)||(result<threshold_down))
{
delay_ms(10);
if((result>threshold_up)||(result<threshold_down))
{
flag1=1;
RC0=0;
NOP();
RC1=0;
if(a==0)//这里是电机遇到阻挡后会停下判断放向后开始与原来方向相反转,实际中测试时用钳子捏住电机时有停止并反响转动100ms。但是如果套上公司的轴承到端点的话会停止在那不会反转,当再次按键后它有动。但是好像被卡住。。不能动。
{
RC0=0;
NOP();
RC1=1;
delay_ms(100);
RC0=0;
NOP();
RC1=0;
}
else if(a==1)
{
RC0=1;
NOP();
RC1=0;
delay_ms(100);
RC0=0;
NOP();
RC1=0;
}
}
}
result=ad_convert(1);
if((result>threshold_up)||(result<threshold_down))
{
delay_ms(10);
if((result>threshold_up)||(result<threshold_down))
{
flag2=1;
RC2=0;
NOP();
RC3=0;
if(a==0)
{
RC2=1;
NOP();
RC3=0;
delay_ms(100);
RC2=0;
NOP();
RC3=0;
}
else if(a==1)
{
RC2=0;
NOP();
RC3=1;
delay_ms(100);
RC2=0;
NOP();
RC3=0;
}
}
}
result=ad_convert(2);
if((result>threshold_up)||(result<threshold_down))
{
delay_ms(10);
if((result>threshold_up)||(result<threshold_down))
{
flag3=1;
RE0=0;
NOP();
RE1=0;
if(a==0)
{
RE0=1;
NOP();
RE1=0;
delay_ms(100);
RE0=0;
NOP();
RE1=0;
}
else if(a==1)
{
RE0=0;
NOP();
RE1=1;
delay_ms(100);
RE0=0;
NOP();
RE1=0;
}
}
}
if((flag1==1)&&(flag2==1)&&(flag3==1))
{
flag1=0;
flag2=0;
flag3=0;
b=0;
RD0=0;
NOP();
RD1=0;
}
}
}
void init(void)
{
APFCON=0;
OSCCON=0b01111010;
nWPUEN=0;
WPUB=0b00000010;
ANSELB=0;
ANSELD=0;
ANSELE=0;
TRISA=0b00000111;
TRISB=0b00000011;
TRISC=0;
TRISD=0;
TRISE=0;
IOCBP=0b00000000;
IOCBN=0b00000010;
INTCON=0b10001000;
IOCIF=0;
IOCBF1=0;
}
uchar buff_read(uchar addr)
{
while(WR);
return EEPROM_READ(addr);
}
void buff_write(uchar addr,uchar value)
{
EEPROM_WRITE(addr,value);
}
uint ad_convert(uchar chan)
{
TRISA=0b00000111;
ANSELA=0b00000111;
ADCON1=0b11010000;
ADCON0=(chan<<2);
ADON=1;
delay_ms(1);
ADGO=1;
while(ADGO);
res=ADRESH<<8;
res|=ADRESL;
ADON=0;
return(res);
}
void interrupt ISR(void)
{
if((IOCIF&IOCBF1)==1)
{
delay_ms(10);
if(RB1==0)
{
while(!RB1);
while(!RB1);
while(!RB1);
IOCIF=0;
IOCBF1=0;
if(a==0)
{
a=1;
buff_write(0x07,a);
PORTC=0;
PORTE=0;
PORTC=0b00000110;
PORTE=0b00000001;
RD0=0;
NOP();
RD1=1;
delay_ms(200);//在这里必须要延时200毫秒以上按键按下后才开始转。。否则如上述文字所说,不知道为什么
}
else if(a==1)
{
a=0;
buff_write(0x07,a);
PORTC=0;
PORTE=0;
PORTC=0b00001001;
PORTE=0b00000010;
RD0=1;
NOP();
RD1=0;
delay_ms(200);//在这里必须要延时200毫秒以上按键按下后才开始转。。否则如上述文字,不知道为什么
}
b=1;
}
}
}
void delay_ms(uint x)
{
uint y,z;
for(y=0;y<x;y++)
for(z=398;z>0;z--)
NOP();
}
|