打印
[PIC®/AVR®/dsPIC®产品]

大家都进来看下。。。。。

[复制链接]
1832|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ly168sos|  楼主 | 2013-7-24 21:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人是刚学画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();
}









沙发
yewuyi| | 2013-7-25 08:47 | 只看该作者
其它的没看,就只扫了一下代码,软件问题太多。

贵公司太不负责任了,怎么可以让你这样就进行所谓的项目?

稍提几点:
1、超过数十us的长延时不应该用delay这种消耗机器指令的方式实现。
2、中断函数中不应该出现任何的长延时,否则中断响应无从谈起。
3、马达转动时,其电流并不是一个稳定的数值,ADC电路和程序、软件判断堵转等都应该有相应的处理。

使用特权

评论回复
板凳
ly168sos|  楼主 | 2013-7-25 12:33 | 只看该作者
非常感谢楼上,本人刚毕业没多久。都没有什么实战经验。。。

使用特权

评论回复
地板
ly168sos|  楼主 | 2013-7-25 12:40 | 只看该作者
那我在程序中怎么处理马达的电流呢。。判断它在一个具体的范围内浮动就是正常运行,超过这个范围并达到堵转电流是就停止。。你看这样行不行?

使用特权

评论回复
5
yewuyi| | 2013-7-25 13:32 | 只看该作者
直流有刷马达在换相时有会较大的电流波动,你可以用示波器看看其波形

使用特权

评论回复
6
scxdh| | 2013-8-10 09:40 | 只看该作者
直流电机启动电流较大,做个滤波电路稳定一下然后进行AD采集。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

15

帖子

0

粉丝