亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 復件 main.c

?? 基于ATMEGA48單片機的
?? C
?? 第 1 頁 / 共 2 頁
字號:

    // Find time since last commutation
	//紀錄最后一次換相的時間
    timeSinceCommutation = TCNT1;
    TCNT1 = COMMUTATION_CORRECTION;//修正零點采樣頻率

    // Filter the current ZC detection with earlier measurements through an IIR filter.
    filteredTimeSinceCommutation = (COMMUTATION_TIMING_IIR_COEFF_A * timeSinceCommutation
                                + COMMUTATION_TIMING_IIR_COEFF_B * filteredTimeSinceCommutation)
                                / (COMMUTATION_TIMING_IIR_COEFF_A + COMMUTATION_TIMING_IIR_COEFF_B);
    OCR1A = filteredTimeSinceCommutation;

    speedUpdated = TRUE;

    SET_TIMER1_INT_COMMUTATION;//(TIMSK1 = (1 << OCIE1A))//允許TC1中斷
    CLEAR_ALL_TIMER1_INT_FLAGS;//(TIFR1 = TIFR1)

    // Disable Timer/Counter0 overflow ISR.//(TIMSK0 = 0)//禁止TC0中斷
    DISABLE_ALL_TIMER0_INTS;

    // Read speed reference.

    // Make sure that a sample is not in progress.
	//確保沒有AD轉換在過程中
    while (ADCSRA & (1 << ADSC))
    {

    }
    // Change channel
    ADMUX = ADMUX_SPEED_REF;//選取參考速度輸入通道0X04

    // Start conversion manually.//手動開始單次轉換
    ADCSRA |= (1 << ADSC);

    // Wait for conversion to complete.
    while(ADCSRA & (1 << ADSC))
    {

    }
    speedReferenceADC = ADCH;

    // Read voltage reference.
    // Change ADC channel.
    ADMUX = ADMUX_REF_VOLTAGE;//選取參考電壓輸入通道0X05
    // Start conversion manually.
    ADCSRA |= (1 << ADSC);
    // Wait for conversion to complete.
    while((ADCSRA & (1 << ADSC)))
    {

    }
    referenceVoltageADC = ADCH;

    // Enable current measurements in ADC ISR.
    ADMUX = ADMUX_CURRENT;//選取電流輸入通道0X03
    ADCSRA |= (1 << ADATE) | (1 << ADIE) | ADC_PRESCALER;//ADC自動觸發使能,中斷使能
  }
  else
  {//零點采樣失敗,檢測電流并更新電流標志位
    unsigned char tempADMUX;

    tempADMUX = ADMUX;
    // Read current

    // Make sure that a sample is not in progress
    while (ADCSRA & (1 << ADSC))
    {

    }

    // Change channel
    ADMUX = ADMUX_CURRENT;

    // Start conversion manually.
    ADCSRA |= (1 << ADSC);
    // Wait for conversion to complete.
    while((ADCSRA & (1 << ADSC)))
    {

    }

    shuntVoltageADC = ADCH;
    currentUpdated = TRUE;

    // Restore ADC channel.
	//恢復ADMUX寄存器
    ADMUX = tempADMUX;
    //ADC自動觸發使能,中斷使能
    ADCSRA |= (1 << ADATE) | (1 << ADIE) | ADC_PRESCALER;
  }
}


/*! \brief Commutates and prepares for new zero-cross detection.
 *
 *  This interrupt service routine is triggered exactly when a commutation
 *  is scheduled. The commutation is performed instantly and Timer/counter0
 *  is reset to measure the delay between commutation and zero-cross detection.
 *
 *  Commutation causes large transients on all phases for a short while that could
 *  cause false zero-cross detections. A zero cross detection hold-off period is
 *  therefore used to avoid any false readings. This is performed by using Timer/counter1
 *  compare B. The compare is set to happen after the specified hold-off period.
 *  Timer/counter1 compare B interrupt handler then enables the zero-cross detection.
 */
 // HOLD OFF 之前的操作,之后可以使能零點檢測開始
SIGNAL(SIG_OUTPUT_COMPARE1A)
{
  // Commutate and clear commutation timer.
//換相并復位換相定時器
  DRIVE_PORT = nextDrivePattern;
  TCNT1 = 0;

  zcPolarity = nextCommutationStep & 0x01;

  // Set zero-cross detection holdoff time.
  CLEAR_ALL_TIMER1_INT_FLAGS;
  OCR1B = ZC_DETECTION_HOLDOFF_TIME_US;//==OCR1A/2
  SET_TIMER1_INT_HOLDOFF;//輸出比較器B中斷使能//使能ADC-HOLD OFF中斷

  //__watchdog_reset();
}


/*! \brief Enables zero-cross detection.
 *
 *  This interrupt service routine is triggered when the zero cross detection
 *  hold-off time after commutation is over. All Timer/counter1 interrupts are
 *  disabled and Timer/counter0 (PWM) overflow interrupt is enabled to allow
 *  the ADC readings to be used for zero-cross detection.
 */
// 檢測HOLD OFF完成,禁止TIMER1,使能TIMER0
SIGNAL(SIG_OUTPUT_COMPARE1B)
{
  // Enable TCNT0 overflow ISR.
  CLEAR_ALL_TIMER0_INT_FLAGS;
  CLEAR_ALL_TIMER1_INT_FLAGS;
  SET_TIMER0_INT_ZC_DETECTION;//TC0溢出中斷使能,準備過零點檢測
  DISABLE_ALL_TIMER1_INTS;    //TC1禁止

  // Set up ADC for zero-cross detection
  //測量FLOAING相的電壓
  ADMUX = ADMUXTable[nextCommutationStep];

  // Wait for ADC to complete
  while (!(ADCSRA & (1 << ADIF)))//等待ADIF置位(轉換完成,數據寄存器更新)
  {

  }
  ADCSRA &= ~(1 << ADIE);//ADC中斷禁止
  ADCSRA |= (1 << ADSC) | (1 << ADATE);//自動觸發和轉換開始使能

  // Rotate commutation step counter.
  nextCommutationStep++;
  if (nextCommutationStep >= 6)
  {
    nextCommutationStep = 0;
  }
  nextDrivePattern = driveTable[nextCommutationStep];
}


/* \brief ADC complete interrupt service routine, used for current measurements.
 *  ADC完成中斷服務程序,用于電流測量
 *  This interrupt service routine is only enabled when current measurements are
 *  只用與在PWM定時器溢出時,電流檢測自動觸發的情況下。
 *  auto-triggered by the PWM counter overflow. The measured value is simply
 *  copied to \ref shuntVoltageADC, the \ref currentUpdated flag is set and
 *  Timer0 (PWM timer) interrupt flags are cleared.
 */
SIGNAL(SIG_ADC)
{
  shuntVoltageADC = ADCH;
  currentUpdated = TRUE;
  CLEAR_ALL_TIMER0_INT_FLAGS;
}


/*! \brief Watchdog interrupt 看門狗中斷服務程序
 *
 *  This ISR is called before the watchdog timer resets the device because of a stall.
 *  It simply disables driving, but other tasks that must be done before a watchdog reset,
 *  such as storage of variables in non-volatile memory can be done here.
 */
/*
#pragma vector=WDT_vect
__interrupt void WatchdogISR()
{
  DISABLE_DRIVING;
  for(;;)
  {
    ;
  }
}
*/
/*! \brief Overcurrent interrupt 過電流檢測中斷服務程序
 *
 *  This interrupt service routine cuts power to the motor when an overcurrent situation
 *  is detected.
 */
SIGNAL(SIG_COMPARATOR)
{
  DISABLE_DRIVING;
  for(;;)
  {
    ;
  }
}



/*! \brief Generates a delay used during startup
 *
 *  This functions is used to generate a delay during the startup procedure.
 *  The length of the delay equals delay * STARTUP_DELAY_MULTIPLIER microseconds.
 *  Since Timer/Counter1 is used in this function, it must never be called when
 *  sensorless operation is running.
 */
//只用在啟動時,正常運轉時不調用。
void StartupDelay(unsigned int delay)
{
  CLEAR_ALL_TIMER1_INT_FLAGS;
  do
  {
    TCNT1 = 0xffff - STARTUP_DELAY_MULTIPLIER;
    // Wait for timer to overflow.
    while (!(TIFR1 & (1 << TOV1)))//如果TC1溢出則清中斷標志位
    {

    }

    CLEAR_ALL_TIMER1_INT_FLAGS;
    delay--;
  } while (delay);
}



#ifdef SPEED_CONTROL_CLOSED_LOOP
/*! \brief Controls the PWM duty cycle based on speed set-point and current consumption.
 *
 *  This function controls the PWM duty cycle by calling a speed controller and a
 *  current controller. The speed controller signal is directly applied to the duty
 *  cycle. The current controller signal is used to limit the maximum duty cycle.
 */
//通過調用速度控制信號調節PWM占空比;電流信號限制PWM最大占空比。
static void PWMControl(void)
{
  signed int speedCompensation;//速度改變量
  static unsigned char currentCompensation = 0;
  static signed int duty = STARTUP_PWM_COMPARE_VALUE;

  // Run speed control only if a new speed measurement is available.
 if (speedUpdated) //如果有新的速度給定
  {
    speedCompensation = SpeedControl();
    speedUpdated = FALSE;
    duty += speedCompensation;
  }

  // Run current control only if a new current measurement is available.
  if (currentUpdated) //如果有新的電流轉換完成
  {
     currentCompensation = CurrentControl();
     currentUpdated = FALSE;
  }

 // Keep duty cycle within limits.//控制占空比在范圍內
  if (duty < MIN_PWM_COMPARE_VALUE)
  {
    duty = MIN_PWM_COMPARE_VALUE;
  }
  if (duty > (MAX_PWM_COMPARE_VALUE - currentCompensation))
  {
    duty = MAX_PWM_COMPARE_VALUE - currentCompensation;
  }

  SET_PWM_COMPARE_VALUE((unsigned char)duty);//OCR0B=DUTY更改TOP值
}
#endif

#ifdef SPEED_CONTROL_OPEN_LOOP
static void PWMControl(void)
{
  // Only update duty cycle if a new speed reference measurement has been made. (Done right after speed measurement is ready)
  //只有在建立一個新的速度參考值時改變DUTY,可能是指通過調節SPEED REFERENCE來調節DUTY 
 if (speedUpdated)
  {
    // Calculate duty cycle from speed reference value.
    SET_PWM_COMPARE_VALUE(MIN_PWM_COMPARE_VALUE + speedReferenceADC * (MAX_PWM_COMPARE_VALUE - MIN_PWM_COMPARE_VALUE) / ADC_RESOLUTION);
  }
}
#endif


/*! \brief Calculates the current speed in electrical RPM.
 *
 *  This function calculates the current speed in electrical rotations per
 *  minute from the global variable \ref filteredTimeSinceCommutation.
 */
//讀出當前的速度
static unsigned long CalculateSpeed()
{
  // Copy used to minimize period where interrupts are disabled.
  unsigned int filteredTimeSinceCommutationCopy;
  unsigned long rotationPeriod;
  unsigned long speed;

  /*
  Disable interrupts to ensure that \ref filteredTimeSinceCommutation is accessed in
  an atomic operation.
  */
  //禁止中斷確保在極短的時間讀出該變量
  cli();
  filteredTimeSinceCommutationCopy = filteredTimeSinceCommutation;
  sei();

  /*
  filteredTimeSinceCommutation is one half commutation time. Must be multiplied by 12 to get
  one full rotation.
  */
  //要得到一個完整電周期需乘以12
  rotationPeriod = (unsigned long)filteredTimeSinceCommutationCopy * 12;
  speed = (TICKS_PER_MINUTE / rotationPeriod);

  return speed;
}


/*! \brief Calculates the speed set-point in electrical RPM.
 *
 *  This function calculates the speed set-point from the global variable
 *  speedReferenceADC.
 *
 *  In this implementation, the speed reference values from 0x00 to 0xff are
 *  linearly mapped into the allowable speed range, set by \ref MIN_SPEED and
 *  \ref MAX_SPEED.
 */
static unsigned long CalculateSpeedSetpoint()
{
  return (MIN_SPEED + ((MAX_SPEED - MIN_SPEED) * (unsigned int)speedReferenceADC) / ADC_RESOLUTION);
}


/*! \brief Calculates current consumption.
 *
 *  This function calculates the current consumption in milliAmperes from the
 *  global variable \ref shuntVoltageADC. The external know reference voltage
 *  is used to compensate for varying AREF voltage.
 */
static unsigned int CalculateCurrent()
{
  unsigned long ADCref;
  unsigned int current;

  // Calculate the voltage at AREF pin (scaled down motor supply voltage),
  // using the known reference voltage. (In milliVolts)
  ADCref = EXTERNAL_REF_VOLTAGE * 256UL / referenceVoltageADC;

  // Calculate the current through the shunt. (In milliAmperes)
  current = (unsigned int)((shuntVoltageADC * ADCref * 1000UL / 256UL) / SHUNT_RESISTANCE);

  return current;
}


/*! \brief Speed control loop
 *
 *  This function runs a simple P-regulator speed control loop. The duty cycle
 *  is only updated each time a new speed measurement is ready (on each zero-crossing).
 *  The time step is thus variable, so the P-gain of the P-regulator corresponds to
 *  a speed-varying P-gain for the continous system.
 */
static signed int SpeedControl(void)
{
  unsigned long speedSetpoint;
  unsigned long currentSpeed;
  signed long speedError;
  signed long dutyChange;



  speedSetpoint = CalculateSpeedSetpoint();
  currentSpeed = CalculateSpeed();
  speedError = (speedSetpoint - currentSpeed);
  dutyChange = speedError * P_REG_K_P / P_REG_SCALING;

  return dutyChange;
}


/*! \brief Current control loop
 *
 *  This function is called after the speed control loop. The desired duty cycle
 *  calculated by the speed control loop is available, and this function is
 *  responsible for adjusting the duty cycle to ensure that the current stays
 *  within limits.
 */
//電流控制程序
static unsigned char CurrentControl(void)
{
  unsigned int current;
  unsigned int overCurrentCorrection = 0;

  current = CalculateCurrent();

  // Cut power to motor if current is critically high.
  if (current > CURRENT_LIMITER_CRITICAL)
  {
    DRIVE_PORT = 0x00;
    for (;;)
    {
      // Stop and let watchdog timer reset part.
    }
  }

  if (current > CURRENT_LIMITER_START)
  {
    overCurrentCorrection = (current - CURRENT_LIMITER_START) * CURRENT_LIMITER_FACTOR;
  }

  if (overCurrentCorrection > 255)
  {
    return 255;
  }

  return overCurrentCorrection;
}

/*! \mainpage
 * \section Intro Introduction
 * This documents data structures, functions, variables, defines, enums, and
 * typedefs in the software for application note AVR444.
 *
 * \section CI Compilation Info
 * This software was written for the IAR Embedded Workbench 4.11A.
 *
 * To make project:
 * <ol>
 * <li> Add the file main.c to project.
 * <li> Under processor configuration, select device ATmega48, ATmega88
 * or ATmega168
 * <li> Enable bit definitions in I/O include files
 * <li> Under "C/C++ compiler->Code->Register utilization", select 5
 * registers (R11..R15) locked for global variables.
 * <li> High optimization on speed is recommended for best performance
 * </ol>
 *
 * \section DI Device Info
 * The included source code is written for ATmega48/88/168.
 */


?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品久久久久婷婷二区次| 麻豆精品久久久| 蜜臀国产一区二区三区在线播放| 国产福利一区在线观看| 欧美美女直播网站| 国产精品福利在线播放| 国产在线视频一区二区| 911精品国产一区二区在线| 亚洲桃色在线一区| 国内国产精品久久| 欧美一区二区三区视频免费 | 一区二区三区在线高清| 国产91精品一区二区| 精品国产一区二区精华| 日韩黄色片在线观看| 在线观看免费一区| 樱花影视一区二区| 99在线精品观看| 国产精品美女一区二区在线观看| 国产美女精品人人做人人爽| 欧美成人综合网站| 久久国产夜色精品鲁鲁99| 337p亚洲精品色噜噜噜| 一区二区三区久久久| 91黄色免费版| 亚洲成人自拍网| 欧美系列亚洲系列| 亚洲成av人片一区二区梦乃| 91行情网站电视在线观看高清版| 亚洲丝袜制服诱惑| 91福利精品视频| 亚洲成a人v欧美综合天堂| 欧美日韩国产系列| 日本va欧美va瓶| 日韩欧美国产午夜精品| 麻豆精品蜜桃视频网站| 久久美女高清视频| 高清国产一区二区| 亚洲视频中文字幕| 91国产视频在线观看| 日韩精品电影在线| 久久美女艺术照精彩视频福利播放 | 日本一区二区三区四区| 国产成人精品免费网站| 椎名由奈av一区二区三区| 日本韩国欧美一区二区三区| 亚洲国产视频一区二区| 欧美一卡二卡在线| 国产麻豆精品久久一二三| 亚洲欧洲av一区二区三区久久| 91高清在线观看| 日韩福利视频导航| 国产色综合一区| 日本道色综合久久| 看电视剧不卡顿的网站| 国产精品入口麻豆九色| 在线精品视频小说1| 美女网站视频久久| 亚洲欧洲一区二区三区| 6080yy午夜一二三区久久| 国产精品亚洲人在线观看| 亚洲女同ⅹxx女同tv| 91精品黄色片免费大全| 99久久精品国产精品久久| 三级欧美在线一区| 国产精品久久影院| 91.麻豆视频| 91一区一区三区| 久久精品国产第一区二区三区 | 精品福利在线导航| 99久久免费精品高清特色大片| 日韩激情在线观看| 亚洲欧洲av在线| 久久久一区二区三区| 91豆麻精品91久久久久久| 国内精品国产成人| 亚洲1区2区3区视频| 日本一区二区高清| 日韩欧美另类在线| 91成人免费网站| 成人ar影院免费观看视频| 日韩电影一区二区三区四区| 亚洲精品精品亚洲| 国产午夜精品理论片a级大结局| 欧美日韩中文字幕一区| www.亚洲人| 国产精品自拍一区| 免费国产亚洲视频| 亚洲国产日日夜夜| 亚洲精品综合在线| 国产精品网站在线| 久久伊99综合婷婷久久伊| 欧美一级日韩不卡播放免费| 色婷婷狠狠综合| 本田岬高潮一区二区三区| 国产福利91精品| 九九精品视频在线看| 肉色丝袜一区二区| 亚洲与欧洲av电影| 一区二区三区加勒比av| 亚洲欧洲精品一区二区三区 | 亚洲一区二区三区四区不卡| 国产欧美日韩激情| 国产亚洲欧美色| 久久这里都是精品| 久久久五月婷婷| 久久先锋影音av鲁色资源网| 日韩欧美一区二区免费| 欧美一区二区三区精品| 欧美日韩国产综合久久| 欧美日韩午夜在线视频| 欧美色偷偷大香| 欧美美女黄视频| 日韩免费视频一区二区| 日韩欧美在线观看一区二区三区| 91精品国产色综合久久不卡电影 | 欧美一卡二卡在线| 欧美第一区第二区| 26uuu久久天堂性欧美| 精品福利一二区| 国产欧美精品区一区二区三区| 久久久精品日韩欧美| 欧美国产成人精品| 亚洲视频图片小说| 亚洲电影你懂得| 麻豆成人在线观看| 国产激情偷乱视频一区二区三区| 国产伦精品一区二区三区免费迷 | 日韩精品成人一区二区三区| 蜜臂av日日欢夜夜爽一区| 久久69国产一区二区蜜臀| 国产一区二区91| 一本色道久久综合亚洲aⅴ蜜桃| 欧美色倩网站大全免费| 日韩一级片在线观看| 久久一区二区三区四区| 最新久久zyz资源站| 午夜久久久久久| 极品美女销魂一区二区三区免费| 成人午夜av电影| 欧美丝袜丝交足nylons| 精品伦理精品一区| 亚洲欧美另类综合偷拍| 天堂蜜桃91精品| 粉嫩一区二区三区在线看| 欧美视频一区在线| 久久亚洲综合色一区二区三区| 成人欧美一区二区三区1314| 午夜精品免费在线| 成人深夜福利app| 欧美一卡在线观看| 亚洲欧美日韩一区二区三区在线观看| 亚洲777理论| av亚洲精华国产精华| 日韩午夜激情av| 亚洲精品国产a| 国产一区二区三区av电影| 欧美日韩小视频| 国产精品久久777777| 人禽交欧美网站| 色8久久精品久久久久久蜜| 欧美精品一区二区三区视频 | 一区二区三区在线免费视频 | 国产精品乱人伦| 蜜桃视频一区二区| 91麻豆成人久久精品二区三区| 欧美va日韩va| 亚洲综合无码一区二区| www.亚洲色图.com| 久久久久久久久久看片| 男女性色大片免费观看一区二区| 91玉足脚交白嫩脚丫在线播放| 久久久久国产精品免费免费搜索| 天堂一区二区在线| 日本高清不卡视频| 亚洲特级片在线| 懂色中文一区二区在线播放| 2欧美一区二区三区在线观看视频| 亚洲午夜免费电影| 91蝌蚪国产九色| 国产精品视频一二| 国产盗摄女厕一区二区三区| 精品毛片乱码1区2区3区| 日日嗨av一区二区三区四区| 在线一区二区视频| 亚洲黄色免费电影| 色系网站成人免费| 亚洲乱码日产精品bd | 国产成a人亚洲精品| www久久精品| 国模一区二区三区白浆| 日韩欧美中文字幕公布| 美女一区二区视频| 日韩精品在线看片z| 美女视频黄 久久| 亚洲精品一区二区三区影院| 国产在线播精品第三| 国产香蕉久久精品综合网| 国产很黄免费观看久久| 国产欧美日韩在线视频|