コード例 #1
0
ファイル: xxUart.c プロジェクト: tngsoft/musemcmx
int ReplyDataCom( void *Data, int size )
{
int len;
char *data, *Pchar;

    data = (char *)Data;
    Pchar = (char *)(DHO.Cmd.Command);
    Swapb( Pchar[0], Pchar[3] );
    Swapb( Pchar[1], Pchar[2] );
    DHO.FrameNumber = 0;
    DHO.Status &= (~stPacketDone); 
    DHO.mbRead = size;
    
    while( size > 0 ) {
        if( size > MaxComPacket ) len = MaxComPacket;
	else len = size;
        if( (size-len) <= 0 ) DHO.Status |= stPacketDone;	
	DHO.LenData = len;
        SendUart( &DHO, -sizeof( TMessageHeader) );
        SendUart( data, len );
        size -= len;
        data += len;
        DHO.FrameNumber++;
    }
    DHO.Status = 0;
    return 0;
}
コード例 #2
0
ファイル: main.c プロジェクト: bsfan/MK_BrushLess-Control
//############################################################################
//启动代码,pwm为启动时的占空比
char Anwerfen(unsigned char pwm)
  //############################################################################
{
  unsigned long timer = 300,i;
  DISABLE_SENSE_INT; //关掉模拟比较器中断
  PWM = 5;
  SetPWM();
  Manuell();
  //    Delay_ms(200);
  MinUpmPulse = SetDelay(300);
  /*
   * 延时300ms,期间不断检测电流,如果电流大于12A,关掉所有MOSFET,红灯闪10下
   */
  while(!CheckDelay(MinUpmPulse))
  {
    FastADConvert();
    if(Strom > 120)
    {
      STEUER_OFF; // Abschalten wegen Kurzschluss
      RotBlink(10);
      return(0);  // 启动失败
    }  
  }
  PWM = pwm; // pwm = 10
  while(1) // main starup program
  {
    for(i=0;i<timer; i++) // timer  = 300 
    {
      if(!UebertragungAbgeschlossen)  SendUart(); //UebertragungAbgeschlossen用来表示串口当前是否正忙,0不忙,1忙
      else DatenUebertragung();
      Wait(100);  // wait 100us
    }
    DebugAusgaben(); //将一些当前信息写到调试结构中去
    FastADConvert();
    if(Strom > 60) 
    {
      STEUER_OFF; // Abschalten wegen Kurzschluss
      RotBlink(10);
      return(0);
    }  

    timer-= timer/15+1; // actually, 14/15 of timer
    if(timer < 25) { if(TEST_MANUELL) timer = 25; else return(1); } // timer is going to converge, utiil it is less than 25, it stops.
    Manuell();
    Phase++;
    Phase %= 6;
    AdConvert(); //检测shunt上电流
    PWM = pwm;
    SetPWM();
    if(SENSE) //若模拟比较器中断位置标志,则此表达式为非零
    {
      PORTD ^= GRUEN;
    }
  }
}
コード例 #3
0
ファイル: xxUart.c プロジェクト: tngsoft/musemcmx
int SendDataCom( void *Data, int size,
    int command, int commandEx,
    int param1, int param2 )
{
int len;
char *data, *Pchar;

    data = (char *)Data;
    DHO.Cmd.Command[0] = command;
    DHO.Cmd.Command[1] = commandEx;
    Pchar = (char *)(DHO.Cmd.Command);
    Swapb( Pchar[0], Pchar[1] );
    Swapb( Pchar[2], Pchar[3] );
    DHO.FrameNumber = 0;
    DHO.WParam[0] = param1;
    DHO.WParam[1] = param2;
    DHO.Status &= (~stPacketDone); 
    DHO.mbRead = size;
    
    if( size > MaxComPacket ) DHO.UnicalNumber = Unical++;
    else DHO.UnicalNumber = 0;
    
    while( size > 0 ) {
        if( size > MaxComPacket ) len = MaxComPacket;
	else len = size;
        if( (size-len) <= 0 ) DHO.Status |= stPacketDone;	
	DHO.LenData = len;
        SendUart( &DHO, -sizeof( TMessageHeader) );
        SendUart( data, len );
        size -= len;
        data += len;
        DHO.FrameNumber++;
    }
    DHO.Status = 0;
    return 0;
}
コード例 #4
0
ファイル: main.c プロジェクト: bsfan/MK_BrushLess-Control
//############################################################################
//Hauptprogramm
int main (void)
  //############################################################################
{
  char altPhase = 0;
  int test = 0;
  unsigned int Blink,TestschubTimer;
  unsigned int Blink2,MittelstromTimer,DrehzahlMessTimer,MotorGestopptTimer;

  DDRC  = 0x08;  //PC3输出,控制红色led 端口C 数据方向寄存器
  PORTC = 0x08;  //PC3输出高电平,红色led亮
  DDRD  = 0x3A;  //10111010A-B-C-配置为输出,TXD,LED_GRN(PD7)配置为输出,MITTEL/RXD/INTO为输入
  PORTD = 0x00;
  DDRB  = 0x0E;
  PORTB = 0x31;

#if (MOTORADRESSE == 0)
  PORTB |= (ADR1 + ADR2);   // Pullups für Adresswahl
  for(test=0;test<500;test++);
  if(PINB & ADR1)
  {
    if (PINB & ADR2) MotorAdresse = 1;
    else MotorAdresse = 2;
  }
  else
  {
    if (PINB & ADR2) MotorAdresse = 3;
    else MotorAdresse = 4;
  }
  HwVersion = 11;
#else
  MotorAdresse  = MOTORADRESSE;
  HwVersion = 10;
#endif
  if(PIND & 0x80) {HwVersion = 12; IntRef = 0xc0;} //为1.2版本     
  DDRD  = 0xBA;
  UART_Init();
  Timer0_Init();
  sei();//Globale Interrupts Einschalten

  // Am Blinken erkennt man die richtige Motoradresse
  /*
     for(test=0;test<5;test++)
     {
     if(test == MotorAdresse) PORTD |= GRUEN;
     Delay_ms(150);
     PORTD &= ~GRUEN;
     Delay_ms(250);
     }      

     Delay_ms(500);
     */  
  // UART_Init();  // war doppelt
  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))
  {
    if(SollwertErmittlung()) break; // 一旦发现有信号,立刻停止延时
  }

  GRN_ON;
  PWM = 0;

  SetPWM();

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

  MinUpmPulse = SetDelay(10);
  DebugOut.Analog[1] = 1; // 填写一些调试信号
  PPM_Signal = 0;

  if(!SollwertErmittlung()) MotorTon();
  //MotorTon();    
  PORTB = 0x31; // Pullups wieder einschalten

  // zum Test der Hardware; Motor dreht mit konstanter Drehzahl ohne Regelung
  if(TEST_MANUELL)    Anwerfen(TEST_MANUELL);  // kommt von dort nicht wieder

  while (1)
  {
    //ShowSense();

    if(!TEST_SCHUB)   PWM = SollwertErmittlung();
    //I2C_TXBuffer = PWM; // Antwort über 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(250);  // Timeout, falls ein Motor stehen bleibt
      altPhase = Phase; // 旧相位 = 新相位
    }
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    if(!PWM)    // Sollwert == 0 在开机后主控板静默,并没有发任何I2C信号过来
    {
      MotorAnwerfen = 0;      // kein Startversuch MotorAnwerfen means motor start
      ZeitFuerBerechnungen = 0; // 指使一些操作的优先级用
      // nach 1,5 Sekunden den Motor als gestoppt betrachten
      if(CheckDelay(MotorGestopptTimer))
      {
        DISABLE_SENSE_INT;
        MotorGestoppt = 1;  
        STEUER_OFF;
      }
    }
    else
    {
      if(MotorGestoppt) MotorAnwerfen = 1;        // Startversuch
      MotorGestopptTimer = SetDelay(1500);
    }

    if(MotorGestoppt && !TEST_SCHUB) PWM = 0; //TEST_SCHUB 1为测试模式,0为正常模式
    SetPWM();
    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    if(!ZeitFuerBerechnungen++) //先!,后++ 
    {
      if(MotorGestoppt) // 马达停止
      {
        GRN_ON;
        FastADConvert();
      }
      if(SIO_DEBUG)
      {
        DebugAusgaben();  // welche Werte sollen angezeigt werden?
        if(!UebertragungAbgeschlossen)  SendUart();
        else DatenUebertragung();
      }
      // Berechnen des Mittleren Stroms zur (langsamen) Strombegrenzung
      if(CheckDelay(MittelstromTimer)) //254ms 
      {
        MittelstromTimer = SetDelay(50); // alle 50ms
        if(Mittelstrom <  Strom) Mittelstrom++;// Mittelwert des Stroms bilden 将mittelstorm平缓化
        else if(Mittelstrom >  Strom) Mittelstrom--;
        if(Strom > MAX_STROM) MaxPWM -= MaxPWM / 32;  //为什么电流大于最大电流的时候,PWM最大值要减小?            
        if((Mittelstrom > LIMIT_STROM))// Strom am Limit? 动态调整MaxPWM的值
        {
          if(MaxPWM) MaxPWM--;// dann die Maximale PWM herunterfahren
          PORTC |= ROT;
        }
        else
        {
          if(MaxPWM < MAX_PWM) MaxPWM++;
        }
      }

      if(CheckDelay(DrehzahlMessTimer))   // Ist-Drehzahl bestimmen 1005ms 
      {
        DrehzahlMessTimer = SetDelay(10);
        SIO_Drehzahl = CntKommutierungen;//(6 * CntKommutierungen) / (POLANZAHL / 2);
        CntKommutierungen = 0;
        // if(PPM_Timeout == 0) // keine PPM-Signale
        ZeitZumAdWandeln = 1;
      }

#if TEST_SCHUB == 1
      {
        if(CheckDelay(TestschubTimer))  
        {
          TestschubTimer = SetDelay(1500);
          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;
          }
        }
      }  
#endif
      // Motor Stehen geblieben
      if((CheckDelay(MinUpmPulse) && SIO_Drehzahl == 0) || MotorAnwerfen) // SIO_Drehzahl 为当前转速值 前面为判断意外停机
      {
        /* 下面三行代码给电机意外停转用*/
        MotorGestoppt = 1;    
        DISABLE_SENSE_INT; // 取消比较中断
        MinUpmPulse = SetDelay(100);        
        if(MotorAnwerfen)
        {
          PORTC &= ~ROT; //switch off red led
          Strom_max = 0; 
          MotorAnwerfen = 0;
          if(Anwerfen(10)) // 以PMW = 10触发启动程序,期间要换相32次,成功返回1
          {  
            GRN_ON; //绿灯打开
            MotorGestoppt = 0;  //  
            Phase--; // Phase = 1
            PWM = 1;
            SetPWM();
            SENSE_TOGGLE_INT; // ?????
            ENABLE_SENSE_INT;  // ????? 使能比较器中断
            MinUpmPulse = SetDelay(20);
            while(!CheckDelay(MinUpmPulse)); // kurz Synchronisieren
            PWM = 15;
            SetPWM();
            MinUpmPulse = SetDelay(300);
            while(!CheckDelay(MinUpmPulse)) // kurz Durchstarten
            {
              if(Strom > LIMIT_STROM/2)
              {
                STEUER_OFF; // Abschalten wegen Kurzschluss
                RotBlink(10);
                MotorAnwerfen = 1;
              }  
            }
            // Drehzahlmessung wieder aufsetzen
            DrehzahlMessTimer = SetDelay(50);
            altPhase = 7;
          }
          else if(SollwertErmittlung()) MotorAnwerfen = 1;
        }
      }
    } // ZeitFuerBerechnungen
  } // while(1) - Hauptschleife
}