球球 发表于 2012-11-2 10:44:43

电调,mega8控制的问题,求指教

大概设计思路如下:
1、mega通过定时器的输入捕获获取主控的PPM信号(ppm信号的周期为2.2ms),计算得到对应PWM占空比从而控制电机的转速,通过输入捕获中断执行;
2、电机通过过零检测实行换相,使用的是mega8的模拟比较器,比较器正相输入端接中间电平,反相输入端接A、B、C端。通过比较器输出电平的变化进入模拟比较器的中断实行换相;


问题是:
1、对上述两个中断采取默认设置的话(既不实行中断嵌套),输入捕获进中断的周期为4.4ms(按理说其周期应同于PPM2.2ms),从而影响了电机的调速控制。我认为是模拟比较器的中断影响了输入捕获的中断。查阅datasheet,资料讲mega8一旦进入中断服务程序,则清零全局中断使能,从而所有的其他中断被挂起等待。而模拟比较器进中断的频率远高于输入捕获进中断的频率。
2、根据datasheet上讲明的,我在模拟比较器的中断服务程序一开始执行力sei指令(打开全局中断,从而其他中断可中断掉模拟比较器的中断服务程序,实现中断的嵌套),示波器测得输入捕获的中断的进入周期为2.2ms。但是接上电机后,发现电机不能正常换相了,是不是输入捕获的中断又影响了电机的换相?
3、这两者的中断该如何协调了?


还有一个问题是,我按照MK的电机启动代码进行的设置,发现了一个问题:在对电机多次进行通电、断电的实验时,前几次(大概在四次左右)电机能够顺利的进行启动转起来,后续的实验电机启动后就不能正常旋转了,需要等待一段时间再通电才能正常启动,旋转这又是为什么?

附上模块代码,希望能得到帮助:
1、启动模块代码:

//电机启动
uint8_t MotorStartUp(uint8_t pm)
{
        uint16_t i, timer = 300;
       
        DISABLE_SENSE_INT;         //关闭模拟比较器的中断
        DISABLE_ICP1;                  //关闭输入捕获的中断
       
        PWM = 5;
        SetPWM(PWM);               //设定PWM的值
       
       
        PWM = pm;
        Phase = 0;

        while(1)
        {
                for(i = 0; i < timer; i++)
                {
                        delay_us(100);        //Wait(100)=延时0.1ms
                }
       


                //timer每次减少1/15,若减少到一定程度则说明已经转起来了(经计算循环51次),返回1
                if(timer >= 25)timer -= timer/15 + 1;
                if(timer < 25)
                {
                        return 1;
                }

                Manual();
                Phase++;
                Phase %= 6;
                PWM = pm;
                SetPWM(PWM);

                //若比较器中断标志被置位
                if(SENSE)
                LEDGRN_ON;
        }
        return 0;
}


//根据当前的Phase值驱动相应的MOS管工作
void Manual()
{
        switch(Phase)
        {
                case 0:        //AB导通PWM
                PWM_A_ON;               //A相上桥臂通
                MUTEX_NEG_B_ON;          //B相下桥臂通
                SENSE_C;                     //比较器反相输入端检测C相
                SENSE_RISING_INT;       //比较器输出上升沿检测
                break;
                case 1:        //AC导通PWM
                PWM_A_ON;
                MUTEX_NEG_C_ON;
                SENSE_B;
                SENSE_FALLING_INT;
                break;
                case 2:        //BC导通PWM
                PWM_B_ON;
                MUTEX_NEG_C_ON;
                SENSE_A;
                SENSE_RISING_INT;
                break;
                case 3:        //BA导通PWM
                PWM_B_ON;
                MUTEX_NEG_A_ON;
                SENSE_C;
                SENSE_FALLING_INT;
                break;
                case 4:        //CA导通PWM
                PWM_C_ON;
                MUTEX_NEG_A_ON;
                SENSE_B;
                SENSE_RISING_INT;
                break;
                case 5:        //CB导通PWM
                PWM_C_ON;
                MUTEX_NEG_B_ON;
                SENSE_A;
                SENSE_FALLING_INT;
                break;
        }
}

//模拟比较器中断
SIGNAL(ANA_COMP_vect)
{
        //sei();
        uint8_t sense = 0;
       
        do
        {
                if(SENSE_H) sense = 1;
                else                sense = 0;

                switch(Phase)
                {
                        case 0:        //AB导通PWM
                        PWM_A_ON;
                        if(sense)
                        {
                                MUTEX_NEG_C_ON;       
                                SENSE_B;               
                                SENSE_FALLING_INT;
                                Phase++;
                        }
                        else
                        {
                                MUTEX_NEG_B_ON;
                        }
                        break;
                       
                        case 1:        //AC导通PWM
                        MUTEX_NEG_C_ON;
                        if(!sense)
                        {
                                PWM_B_ON;
                                SENSE_A;
                                SENSE_RISING_INT;
                                Phase++;
                        }
                        else
                        {
                                PWM_A_ON;
                        }
                        break;

                        case 2:        //BC导通PWM
                        PWM_B_ON;
                        if(sense)
                        {
                                MUTEX_NEG_A_ON;
                                SENSE_C;
                                SENSE_FALLING_INT;
                                Phase++;
                        }
                        else
                        {
                                MUTEX_NEG_C_ON;
                        }
                        break;

                        case 3:        //BA导通PWM
                        MUTEX_NEG_A_ON;
                        if(!sense)
                        {
                                PWM_C_ON;
                                SENSE_B;
                                SENSE_RISING_INT;
                                Phase++;
                        }
                        else
                        {
                                PWM_B_ON;
                        }
                        break;

                        case 4:        //CA导通PWM
                        PWM_C_ON;
                        if(sense)
                        {
                                MUTEX_NEG_B_ON;
                                SENSE_A;
                                SENSE_FALLING_INT;
                                Phase++;
                        }
                        else
                        {
                                MUTEX_NEG_A_ON;
                        }
                        break;

                        case 5:        //CB导通PWM
                        MUTEX_NEG_B_ON;
                        if(!sense)
                        {
                                PWM_A_ON;
                                SENSE_C;
                                SENSE_RISING_INT;
                                Phase=0;
                        }
                        else
                        {
                                PWM_C_ON;
                        }
                        break;
                }
                ACSR|=0x10;
                ENABLE_SENSE_INT;
                ACSR&=~0X04;
                TIFR|=1<<5;
        } while((SENSE_L && sense) || (SENSE_H && ! sense));
}


//输入捕获中断
SIGNAL(TIMER1_CAPT_vect)
{
        if(!cnt)
        {
                        PORTB|=0x40;
                        tim_alt_start=ICR1;
                        PPM_L;
                        TIFR|=1<<5;
                        flag_start=flag;
                        TimerOverflow=0;
                        cnt=1;
                       
        }
        else
        {
                tim_alt_end=ICR1;
                PPM_H;
                TIFR|=1<<5;
                flag_end=flag;
                cnt=0;
                switch (flag_start)
                {
                        case 0:
                                switch (flag_end)
                                {
                                        case 0:
                                                if (tim_alt_start>tim_alt_end)
                                                {
                                                        ppm=TimerOverflow*512-(tim_alt_start-tim_alt_end);
                                                }
                                                else
                                                {
                                                        ppm=TimerOverflow*512+(tim_alt_end-tim_alt_start);
                                                }
                                                break;
                                        case 1:
                                                ppm=TimerOverflow*512+(255-tim_alt_start)+(255-tim_alt_end);
                                                break;
                                }
                                break;
                        case 1:
                                switch (flag_end)
                                {
                                        case 0:
                                                ppm=TimerOverflow*512-(255-tim_alt_end)-(255-tim_alt_start);
                                                break;
                                        case 1:
                                                if (tim_alt_start<tim_alt_end)
                                                {
                                                        ppm=TimerOverflow*512-(tim_alt_end-tim_alt_start);
                                                }
                                                else
                                                        ppm=TimerOverflow*512+(tim_alt_start-tim_alt_end);
                                                break;
                                }                       
                }
                if(ppm<1500)
                        ppm=1000;
                if(ppm>2000)
                        ppm=2000;
                ppm-=1000;
                PPM_Signal=(PPM_Signal*47+ppm)/48;
                pwm_value=(uint8_t)((double)PPM_Signal*0.255);       
               
                //SetPWM(pwm_value);
                Usart_putchar(pwm_value);
                PORTB&=~0x40;
        }
}

已经被困惑了好几天了,希望得到帮助,谢谢!!!

xueyf.yz 发表于 2012-11-2 12:43:45

顶一下,

球球 发表于 2012-11-3 08:27:44

自己顶下,求关注!!!!!!!!!!!!!!!

初来乍到呢 发表于 2012-11-4 23:13:50

顶顶更健康,同时学习下
页: [1]
查看完整版本: 电调,mega8控制的问题,求指教