zht9961020 发表于 2008-8-15 11:24:20

feng_matrix电调程序的启动还是没看懂

/*############################################################################
+ Regler f黵 Brushless-Motoren
+ ATMEGA8 mit 8MHz
+ (c) 01.2007 Holger Buss
+ Nur f黵 den privaten Gebrauch
+ Keine Garantie auf Fehlerfreiheit
+ Kommerzielle Nutzung nur mit meiner Zustimmung
+ Der Code ist f黵 die Hardware BL_Ctrl V1.0 entwickelt worden
+ www.mikrocontroller.com
/############################################################################*/

#include "main.h"

unsigned intPWM = 0;
unsigned intStrom = 0; //ca. in 0,1A
unsigned char Strom_max = 0;
unsigned char Mittelstrom = 0; //Mittelstrom:平均电流
unsigned intDrehzahl = 0;// in 100UPM60 = 6000//Drehzahl:转速
unsigned intKommutierDelay = 10;//换向延时
unsigned intI2C_Timeout = 0;
unsigned char SIO_Timeout = 0;
unsigned intSollDrehzahl = 0;//额定转速,计算转速
unsigned intIstDrehzahl = 0;//实际转速
unsigned intDrehZahlTabelle;//vorberechnete Werte zur Drehzahlerfassung//转速表
unsigned char ZeitFuerBerechnungen = 1;//测算所用的时间
unsigned char MotorAnwerfen = 0;//电机启动,(加速)
unsigned char MotorGestoppt = 1;//电机停止
unsigned char MaxPWM = MAX_PWM;
unsigned intCntKommutierungen = 0;//??换向?
unsigned intSIO_Drehzahl = 0;
unsigned char ZeitZumAdWandeln = 1;//到AD转换的时间


//############################################################################
//
void SetPWM(void)
//############################################################################
{
    unsigned char tmp_pwm;
    tmp_pwm = PWM;
    if(tmp_pwm > MaxPWM)    // Strombegrenzung
      {
      tmp_pwm = MaxPWM;
      PORTC |= ROT;
      }
    if(Strom > MAX_STROM)   // Strombegrenzung
      {
      OCR1A = 0; OCR1B = 0; OCR2= 0;
      PORTC |= ROT;
      Strom--;
      }
    else
      {
      #ifdef_32KHZ
      OCR1A =tmp_pwm; OCR1B =tmp_pwm; OCR2= tmp_pwm;
      #endif

      #ifdef_16KHZ //16kHZ时T1用的是9位的pwm,所以赋值要加倍,T2用的是相位修正,不用加倍
      OCR1A = 2 * (int)tmp_pwm; OCR1B = 2 * (int)tmp_pwm; OCR2= tmp_pwm;
      #endif
      }
}

//############################################################################
//
void PWM_Init(void)
//############################################################################
{
    PWM_OFF;
    TCCR1B = (1 << CS10) | (0 << CS11) | (0 << CS12) | (1 << WGM12) |
             (0 << WGM13) | (0<< ICES1) | (0 << ICNC1);
}

//############################################################################
//
void Wait(unsigned char dauer)
//############################################################################
{
    dauer = (unsigned char)TCNT0 + dauer;
    while((TCNT0 - dauer) & 0x80);
}

//############################################################################
//
void Anwerfen(unsigned char pwm)
//############################################################################
/*补充注释:
开环启动算法
*/
{
    unsigned long timer = 300,i;
    DISABLE_SENSE_INT; //关比较器中断
    PWM = 5;
    SetPWM();   //T1和T2的比较捕捉寄存器赋值,设置pwm占空比
    Manuell();////////////////////////////////////
/*补充注释:
开环顺序换向算法,注意换向时必须同步修改比较器端口及触发沿
以便在反相感生电动势到达切换条件时,自动切换到闭环运转状态
*///////////////////////////////////////////////////
    Delay_ms(200);
    PWM = pwm;
    while(1)
      {
      for(i=0;i<timer; i++)
            {
            //if(!UebertragungAbgeschlossen)SendUart();
            //else DatenUebertragung();
            Wait(100);// warten
            }
      timer-= timer/15+1;
      if(timer < 25) { if(TEST_MANUELL) timer = 25; else return; }

      Manuell();
      Phase++;
      Phase %= 6;
      AdConvert();
      PWM = pwm;
      SetPWM();
      if(SENSE)
            {
            PORTD ^= GRUEN;
            }
      }
}

//############################################################################
//
unsigned char SollwertErmittlung(void)
//############################################################################
{
    static unsigned int sollwert = 0;
    //unsigned int ppm;
    if(!I2C_Timeout)   // bei Erreichen von 0 ist der Wert ung黮tig
      {
      if(SIO_Timeout)// es gibt g黮tige SIO-Daten
            {
            //sollwert =(MAX_PWM * (unsigned int) SIO_Sollwert) / 200;// skalieren auf 0-200 = 0-255
            }
      else
                /*
            if(PPM_Timeout)// es gibt g黮tige PPM-Daten
                {
                ppm = PPM_Signal;
                if(ppm > 300) ppm =   0;// ung黮tiges Signal
                if(ppm > 200) ppm = 200;
                if(ppm <= MIN_PPM) sollwert = 0;
                else
                  {
                  sollwert = (int) MIN_PWM + ((MAX_PWM - MIN_PWM) * (ppm - MIN_PPM)) / (190 - MIN_PPM);
                  }
                PORTC &= ~ROT;
                }
            else   // Kein g黮tiger Sollwert
                {*/
                if(!TEST_SCHUB) { if(sollwert) sollwert--; }   
                PORTC |= ROT; //#define ROT    0x08, LED_ROT亮
                /*}*/
                       
      }
    else // I2C-Daten sind g黮tig
      {
      sollwert = I2C_RXBuffer;
      PORTC &= ~ROT;
      }
    if(sollwert > MAX_PWM) sollwert = MAX_PWM;
    return(sollwert);
}

//############################################################################
//Hauptprogramm
int main (void)
//############################################################################
{
    char altPhase = 0;
    int test = 0;
    unsigned int MinUpmPulse,Blink,TestschubTimer;
    unsigned int Blink2,MittelstromTimer,DrehzahlMessTimer,MotorGestopptTimer;

    DDRC= 0x08;//PC3输出,控制led
    PORTC = 0x08;//PC3输出,控制led,输出高电平
    DDRD= 0xBA;//A-B-C-配置为输出,TXD,LED_GRN(PD7)配置为输出,其他为输入
    PORTD = 0x80;//LED_GRN高电平,灯亮
    DDRB= 0x0E;////A+B+C+配置为输出,其他为输入,ppm的ICP为输入
    PORTB = 0x31;//I2C总线为高电平,ICP上拉电阻使能,其他低电平,因为有三极管截止,所以p沟道不导通
   
    //UART_Init();
    Timer0_Init();
    sei ();//Globale Interrupts Einschalten
   
    // Am Blinken erkennt man die richtige Motoradresse //电流闪烁识别正确的电机地址,用于4轴的4个电调判断??
    for(test=0;test<5;test++)
      {
      if(test == MOTORADRESSE) PORTD |= GRUEN; //#define GRUEN0x80 , LED_GRN高电平,灯亮
      Delay_ms(150);
      PORTD &= ~GRUEN;//灯灭
      Delay_ms(250);
      }       

    Delay_ms(500);
   
    //UART_Init();
    PWM_Init();       

    InitIC2_Slave(0x50);                          
    //InitPPM();

    Blink             = SetDelay(101);   
    Blink2            = SetDelay(102);
    MinUpmPulse       = SetDelay(103);
    MittelstromTimer= SetDelay(254);
    DrehzahlMessTimer = SetDelay(1005);
    TestschubTimer    = SetDelay(1006);
    while(!CheckDelay(MinUpmPulse));
    PORTD |= GRUEN;        //LED_GRN高电平,灯亮
    PWM = 0;

    SetPWM();

    SFIOR = 0x08;// Analog Comperator ein
    ADMUX = 1;

    MinUpmPulse = SetDelay(10);
    //DebugOut.Analog = 1;
    //PPM_Signal = 0;

    // zum Test der Hardware; Motor dreht mit konstanter Drehzahl ohne Regelung///电机无规则恒转速转动
    if(TEST_MANUELL)    Anwerfen(TEST_MANUELL);// kommt von dort nicht wieder//到再次没有重建时
                                                //Anwerfen:启动,加速
    while (1)
      {
      if(!TEST_SCHUB)   PWM = SollwertErmittlung();//额定值计算
      //I2C_TXBuffer = PWM; // Antwort 黚er I2C-Bus
      if(MANUELL_PWM)   PWM = MANUELL_PWM;

      // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      if(Phase != altPhase)   // es gab eine Kommutierung im Interrupt如果相位不等于旧的相位,换向
            {
            MotorGestoppt = 0;
            ZeitFuerBerechnungen = 0;    // direkt nach einer Kommutierung ist Zeit 直接在某个之后计算实际时间
            MinUpmPulse = SetDelay(50);// Timeout, falls ein Motor stehen bleibt 暂停,电机停止
            altPhase = Phase;//旧相位=新相位
            }
      // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      if(!PWM)    // Sollwert == 0
            {
            MotorAnwerfen = 0;      // kein Startversuch无启动试验
            ZeitFuerBerechnungen = 0;//计算所用的时间
            // nach 1,5 Sekunden den Motor als gestoppt betrachten 在1,5瞬间之后电机停止检测
            if(CheckDelay(DrehzahlMessTimer))
                {
                DISABLE_SENSE_INT;
                MotorGestoppt = 1;//电机停止标志位?
                STEUER_OFF;
                }
            }
      else
            {
            if(MotorGestoppt) MotorAnwerfen = 1;        // Startversuch启动试验
            MotorGestopptTimer = SetDelay(1500);
            }

      if(MotorGestoppt && !TEST_SCHUB) PWM = 0;
      SetPWM();
      // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      if(!ZeitFuerBerechnungen++)//计算所用的时间
            {
            if(MotorGestoppt) PORTD |= GRUEN; //else PORTD &= ~GRUEN;//LED_GRN高电平,灯亮,否则灭
            if(SIO_DEBUG)
                {
                //DebugAusgaben();// welche Werte sollen angezeigt werden?
                //if(!UebertragungAbgeschlossen)SendUart();
                //else DatenUebertragung();
                }
            // Berechnen des Mittleren Stroms zur (langsamen) Strombegrenzung计算现在的平均电流(缓慢的)电流限制
            if(CheckDelay(MittelstromTimer))   
                {
                MittelstromTimer = SetDelay(50); // alle 50ms每个50ms
                if(Mittelstrom <Strom) Mittelstrom++;// Mittelwert des Stroms bilden平均电流形成
                else if(Mittelstrom >Strom) Mittelstrom--;
      
                if(Mittelstrom > LIMIT_STROM)// Strom am Limit?
                  {
                  MaxPWM--;// dann die Maximale PWM herunterfahren最大限度pwm关闭
                  PORTC |= ROT; //#define ROT    0x08, LED_ROT亮
                  }
                else
                  {
                  if(MaxPWM < MAX_PWM) MaxPWM++;
                  }
                }

            if(CheckDelay(DrehzahlMessTimer))   // Ist-Drehzahl bestimmen实际转速测定
                {
                DrehzahlMessTimer = SetDelay(10);
                SIO_Drehzahl = (6 * CntKommutierungen) / (POLANZAHL / 2);管子换向
                CntKommutierungen = 0;//管子换向=0
                //if(PPM_Timeout == 0) // keine PPM-Signale没有ppm信号
                //ZeitZumAdWandeln = 1;//到AD转换的时间
                }


            if(CheckDelay(TestschubTimer))
                {
                TestschubTimer = SetDelay(1500);
                if(TEST_SCHUB)   //   #define TEST_SCHUB    0不执行
                  {
                  switch(test)
                        {
                        case 0: PWM = 50; test++; break;
                        case 1: PWM = 130; test++; break;
                        case 2: PWM = 60;test++; break;
                        case 3: PWM = 140; test++; break;
                        case 4: PWM = 150; test = 0; break;
                        default: test = 0;
                        }
                  }
                }
            // Motor Stehen geblieben电机停止遗留
            if((CheckDelay(MinUpmPulse) && SIO_Drehzahl == 0) || MotorAnwerfen)
                {
                MotorGestoppt = 1;    //电机停止标志1
                DISABLE_SENSE_INT;
                MinUpmPulse = SetDelay(100);         
                if(MotorAnwerfen)
                  {
                  PORTC &= ~ROT; //LED_ROT灭
                  MotorAnwerfen = 0; //电机启动标志0
                  Anwerfen(10);//启动
                  PORTD |= GRUEN;//LED_GRN亮
                  MotorGestoppt = 0;    //电机停止标志0
                  Phase--;
                  PWM = 1;
                  SetPWM();
                  SENSE_TOGGLE_INT;//输出电平变化就中断
                  ENABLE_SENSE_INT;//开比较器中断
                  MinUpmPulse = SetDelay(100);
                  while(!CheckDelay(MinUpmPulse)); // kurz Synchronisieren
                  PWM = 10;
                  SetPWM();
                  MinUpmPulse = SetDelay(200);
                  while(!CheckDelay(MinUpmPulse)); // kurz Durchstarten
                  MinUpmPulse = SetDelay(1000);
                  altPhase = 7;
                  }
                }
            } // ZeitFuerBerechnungen
      } // while(1) - Hauptschleife
}

zht9961020 发表于 2008-8-15 11:41:48

主要是开环启动函数和主程序里的while()循环不太明白

还有频繁使用SetDelay()和CheckDelay()这两个函数的目的是什么?是计算从SetDelay()到CheckDelay()的时间吗,有何作用?

注释是照德语词典的解释理解的,很多地方都不太通,望指点一二

nomoneyiv 发表于 2008-8-15 14:24:49

顶!

qumushan2 发表于 2008-9-3 13:46:45

频繁使用SetDelay()和CheckDelay()这两个函数的目的是设置程序执行插入点。代码中有部分不是每次循环都要执行的,只有设置的时间到了才执行。这些代码即程序中要处理的慢速等事件。

qumushan2 发表于 2008-9-3 13:46:58

频繁使用SetDelay()和CheckDelay()这两个函数的目的是设置程序执行插入点。代码中有部分不是每次循环都要执行的,只有设置的时间到了才执行。这些代码即程序中要处理的慢速等事件。

elder60 发表于 2008-12-15 09:38:09

zht9961020&nbsp;&nbsp;你现在怎么样了?三个月了。我看了已经10天了。也是没看懂。

13590955160 发表于 2009-12-5 15:19:24

MARK
页: [1]
查看完整版本: feng_matrix电调程序的启动还是没看懂