⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mc_drv.c

📁 这是无刷直流电机的控制程序
💻 C
📖 第 1 页 / 共 2 页
字号:

/****************************************************************************
* file name: mc_drv.c
*
*****************************************************************************/

#include "config.h"

#include "mc_drv.h"
#include "mc_lib.h"
#include "mc_control.h"
#include "serial.h"

#include "adc_drv.h"
#include "dac_drv.h"
#include "amplifier_drv.h"
#include "pll_drv.h"
#include "comparator_drv.h"

#include "stdio.h"


U8 count = 1;     // variable "count" is use for calculate the "average" speed on 'n' samples
U16 average = 0;
U8 ovf_timer = 0; // variable "ovf_timer" is use to simulate a 16 bits timer with 8 bits timer

Bool g_mc_read_enable = FALSE;  // the speed can be read
Bool g_tic = FALSE;             //!< Use for control the sampling period value

Bool current_EOC = FALSE; //End Of Concersion Flag

S32 Num_turn = 0; //Used to count the number of motor revolutions
S32 Num_turn2 = 0;
U8 hall_state = 0;

char State = CONV_INIT; // State of the ADC scheduler
char ADC_State = FREE;  // ADC State : running = BUSY not running = FREE

/******************************************************************************************************************************/
/******************************************************************************************************************************/
/*                                            Hardware Initialization                                                         */
/******************************************************************************************************************************/
/******************************************************************************************************************************/

/**
* @brief init HW
* @pre set all functions mc_init_port(), mc_init_pwm()...
* @post initialization of hardware
*/
void mc_init_HW(void)
{
  mc_init_port();
  mc_init_IT();

  // Be careful : initialize DAC and Over_Current before PWM.
  init_dac();
  mc_set_Over_Current(100); // 5 => 1A ; 8 => 40A
  mc_init_pwm();

  mc_config_time_estimation_speed();
  mc_config_sampling_period();

  init_comparator0();
  init_comparator1();
  init_comparator2();
}

/**
* @brief init SW
* @pre none
* @post initialization of software
*/
void mc_init_SW(void)
{
  Enable_interrupt();
}

/**
* @brief Initialization of IO PORTS for AT90PWM3
* @pre none
* @post initialization of I/O Ports
*/
void mc_init_port(void)
{
  // Output Pin configuration
  // PD0 => H_A     PB7 => L_A
  // PC0 => H_B     PB6 => L_B
  // PB0 => H_C     PB1 => L_C

  //Do not modify PSCOUT Configuration
  // PORT B :
  DDRB = (1<<DDB7)|(1<<DDB6)|(1<<DDB1)|(1<<DDB0);
  // PORT C :
  DDRC = (1<<DDC0);
  // PORT D :
  DDRD = (1<<DDD0);


  // DDnx = 0:Input 1:Output    (n = B,C,D,E ; x = 0,1,2,3,4,5,6,7)
  // PB3 => EXT1                        PB4 => EXT2
  // PC1 => EXT3                        PC2 => EXT4
  // PB5 => EXT5/POT                    PE1 => EXT6
  // PD3 => EXT7/MOSI/LIN_TxD/TxD       PD4 => EXT8/MISO/LIN_RxD/RxD
  // PE0 => EXT9/NRES                   PD2 => EXT10/MISO

  // Modify DDnx according to your hardware implementation
  // PORT B :
  DDRB |= (0<<DDB5)|(1<<DDB4)|(0<<DDB3);
  // PORT C :
  DDRC |= (0<<DDC2)|(0<<DDC1);
    // PORT D :
  DDRD |= (0<<DDD4)|(0<<DDD3)|(0<<DDD2); // Becareful if using the UART interface or JTAGE ICE mkII.
  // PORT E :
  DDRE |= (1<<DDE2)|(0<<DDE1)|(0<<DDE0); // Becareful PE0 is you by JTAGE ICE mkII.


  // Warning Output Low for MOSFET Drivers
  PORTB &= ~(1<<PORTB7 | 1<<PORTB6 | 1<<PORTB1 | 1<<PORTB0);
  PORTC &= ~(1<<PORTC0);
  PORTD &= ~(1<<PORTD0);

  // pull up activation
  PORTC |= (1<<PORTC1);
  PORTD |= (1<<PORTD1);

  // Disable Digital Input for amplifier1
  // Digitals Inputs for comparators are not disable.
  DIDR0 = (0<<ADC6D)|(0<<ADC3D)|(0<<ADC2D);
  DIDR1 = (0<<ACMP0D)|(0<<ACMP1D)|(1<<AMP1PD)|(1<<AMP1ND);
}

/**
* @brief Initialization of PWM generators (PSC) for AT90PWM3
* @pre none
* @post initialization of PSC
*/
void mc_init_pwm()
{
  Start_pll_32_mega();
  Wait_pll_ready();

  // In Center Aligned Mode :
  // => PSCx_Init(Period_Half, Dutyx0_Half, Synchro, Dutyx1_Half)
  PSC0_Init(255,0,1,0);
  PSC1_Init(255,0,1,0);
  PSC2_Init(255,0,1,0);
}

/**
* @brief Initialization of AT90PWM3 External Interrupts
* @pre none
* @post External Interrupts (INT0, INT1, INT2, INT3) initialized
*/
void mc_init_IT(void)
{
  EICRA =(0<<ISC21)|(1<<ISC20)|(0<<ISC11)|(1<<ISC10)|(0<<ISC01)|(1<<ISC00);
  EIFR = (1<<INTF2)|(1<<INTF1)|(1<<INTF0); // clear possible IT due to config
  EIMSK=(1<<INT2)|(1<<INT1)|(1<<INT0);
}

// PSC initialization depend on the PSC mode
//  0- One ramp Mode
//  1- Two ramp Mode
//  2- Four ramp Mode
//  3- Center Aligned Mode

/**
* @brief Initialization of PWM generator PSC0
*/
void PSC0_Init ( unsigned int OCRnRB,
                 unsigned int OCRnSB,
                 unsigned int OCRnRA,
		 unsigned int OCRnSA)
{
  OCR0SAH = HIGH(OCRnSA);
  OCR0SAL = LOW(OCRnSA);
  OCR0RAH = HIGH(OCRnRA);
  OCR0RAL = LOW(OCRnRA);
  OCR0SBH = HIGH(OCRnSB);
  OCR0SBL = LOW(OCRnSB);
  OCR0RBH = HIGH(OCRnRB);
  OCR0RBL = LOW(OCRnRB);

  PCNF0 =  RAMP_MODE_NUMBER | (1<<PCLKSEL0) | OUTPUT_ACTIVE_HIGH ;
  PFRC0A = (1<<PELEV0A)|(1<<PFLTE0A)|(0<<PRFM0A3)|(1<<PRFM0A2)|(1<<PRFM0A1)|(1<<PRFM0A0);
  PFRC0B = 0;
  PSOC0 = (1<<PSYNC00); //Send signal on match with OCRnSA (during counting up of PSC)
  PCTL0 = (0<<PAOC0A)|(1<<PARUN0)|PRESC_NODIV; /* AUTORUN !! */
}

/**
* @brief Initialization of PWM generator PSC1
*/
void PSC1_Init ( unsigned int OCRnRB,
                 unsigned int OCRnSB,
                 unsigned int OCRnRA,
		 unsigned int OCRnSA)
{
  OCR1SAH = HIGH(OCRnSA);
  OCR1SAL = LOW(OCRnSA);
  OCR1RAH = HIGH(OCRnRA);
  OCR1RAL = LOW(OCRnRA);
  OCR1SBH = HIGH(OCRnSB);
  OCR1SBL = LOW(OCRnSB);
  OCR1RBH = HIGH(OCRnRB);
  OCR1RBL = LOW(OCRnRB);

  PCNF1 =  RAMP_MODE_NUMBER | (1<<PCLKSEL1) | OUTPUT_ACTIVE_HIGH ;
  PFRC1A = 0;
  PFRC1B = 0;
  PCTL1 = (0<<PAOC1A)|(1<<PARUN1)|PRESC_NODIV; /* AUTORUN !! */
}


/**
* @brief Initialization of PWM generator PSC2
*/
void PSC2_Init ( unsigned int OCRnRB,
                 unsigned int OCRnSB,
                 unsigned int OCRnRA,
		 unsigned int OCRnSA)
{
  OCR2SAH = HIGH(OCRnSA);
  OCR2SAL = LOW(OCRnSA);
  OCR2RAH = HIGH(OCRnRA);
  OCR2RAL = LOW(OCRnRA);
  OCR2SBH = HIGH(OCRnSB);
  OCR2SBL = LOW(OCRnSB);
  OCR2RBH = HIGH(OCRnRB);
  OCR2RBL = LOW(OCRnRB);

  PCNF2 =  RAMP_MODE_NUMBER | (1<<PCLKSEL2) | OUTPUT_ACTIVE_HIGH ;
  PFRC2A = 0;
  PFRC2B = 0;
  PCTL2 = (0<<PAOC2A)|(1<<PRUN2)|PRESC_NODIV; /* RUN !! */
}


/******************************************************************************************************************************/
/******************************************************************************************************************************/
/*                                    All functions for motor's phases commutation                                            */
/******************************************************************************************************************************/
/******************************************************************************************************************************/

/**
* @brief Get the value of hall sensors (1 to 6)
* @param return an unsigned char
*  value of hall sensor
* @pre configuration of port PB and PD
* @post new value of position
*/
U8 mc_get_hall(void)
{
  return HALL_SENSOR_VALUE();
}

/**
 * @brief External interruption
 *                 Sensor (A) mode toggle
 * @pre configuration of external interruption (initialization)
 * @post New value in Hall variable
 */
#pragma vector = HALL_A()
__interrupt void mc_hall_a(void)
{
  mc_switch_commutation(HALL_SENSOR_VALUE());
  //estimation speed on raising edge of Hall_A
  if (PIND&(1<<PORTD7))
  {
    mc_estimation_speed();
    g_mc_read_enable=FALSE; // Wait 1 period
  }
  else
  {
    g_mc_read_enable=TRUE;
  }


  switch(hall_state)
  {
  case 2 : Num_turn++;break;
  case 3 : Num_turn--;break;
  default: break;
  }
  hall_state = 1;
}

/**
 * @brief External interruption
 *                 Hall Sensor (B) mode toggle
 * @pre configuration of external interruption (initialization)
 * @post New value in Hall variable
 */
#pragma vector = HALL_B()
__interrupt void mc_hall_b(void)
{
  mc_switch_commutation(HALL_SENSOR_VALUE());

  switch(hall_state)
  {
  case 1 : Num_turn--;break;
  case 3 : Num_turn++;break;
  default: break;
  }
  hall_state = 2;
}

 /**
 * @brief External interruption
 *                 Hall Sensor (C) mode toggle
 * @pre configuration of external interruption (initialization)
 * @post New value in Hall variable
 */
#pragma vector = HALL_C()
__interrupt void mc_hall_c(void)
{
  mc_switch_commutation(HALL_SENSOR_VALUE());

  switch(hall_state)
  {
  case 2 : Num_turn--;break;
  case 1 : Num_turn++;break;
  default: break;
  }
  hall_state = 3;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -