打印
[应用相关]

变频器/三相桥

[复制链接]
715|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
动机
现在有电气工程的各个分支已经是大量的预先配置的,模块化的和具有成本效益的开发环境,这要归功于其可用性测试系统或用于许多不同的应用原型通常可以相对迅速地实施。例如,这些包括以下领域的开发环境:
  • 微控制器(STM,Microchip,Atmel,...)
  • FPGA和DSP(Altera,Xilinx,TI,Analog Devices,......)
  • 发动机系统(Maxon Motors,Trinamic,Infineon,......)
  • 测量和传感器技术(Analog Devices,Linear Technology,...)
客观
该项目的目的是设计和生产通用三相桥。在这个开发的前景应该是一个强大的设计,以及桥架的灵活控制选项。
电流传感器
为实现所有3相的电流隔离电流测量,选择了电流传感器ACS770(Allegro Micro Systems)。这些传感器基于霍尔效应,在 ± 50A, ± 100A, ± 150A和 ± 200A 的测量范围内引脚兼容
转换器通过5V供电,并在输出端提供电流比例电压。
A / d转换器
由电流传感器测量的相电流将从电桥数字地传输到用于控制的目标系统。然后,目标系统可以使用这些测量来实现例如电流控制器(例如,用于磁场定向矢量控制),过零检测(例如,用于无编码器驱动)或过电流跳闸。为此,有必要,分钟。同时采样两相电流。A / D转换器AD7866(Analog Devices)非常适合此任务:
接线图
布局


沙发
antusheng|  楼主 | 2018-8-23 09:28 | 只看该作者
软件
/* Defines */
#define  F_PWM       10000                        
#define  MAX_CNT     ((SystemCoreClock / F_PWM) - 1)
#define  PI          3.141592

/* Globales Sinusarray */
uint16_t sin_arr[360];

/* Funktion initialisiert die 3-Phasen-PWM */
void init_3_phase_pwm( void )
{
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
   TIM_OCInitTypeDef  TIM_OCInitStructure;
   TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;

   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

   /* PWM-Funktion der Pins aktivieren */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM1);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_TIM1);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_TIM1);

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOB, &GPIO_InitStructure);
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_TIM1);
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_TIM1);

   /* Timer konfigurieren */
   TIM_TimeBaseStructure.TIM_Prescaler = 0;
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseStructure.TIM_Period = MAX_CNT;
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
   TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

   /* PWM 1,2 und 3 konfigurieren */
   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
   TIM_OCInitStructure.TIM_Pulse = 0;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
   TIM_OC1Init(TIM1, &TIM_OCInitStructure);
   TIM_OC2Init(TIM1, &TIM_OCInitStructure);
   TIM_OC3Init(TIM1, &TIM_OCInitStructure);

   /* Totzeit konfigurieren */
   TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
   TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
   TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
   TIM_BDTRInitStructure.TIM_DeadTime = 100;
   TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
   TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
   TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
   TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

   /* Timer einschalten */
   TIM_Cmd(TIM1, ENABLE);

   /* PWM-Ausgänge aktivieren */
   TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
/* Funktion füllt ein Sinusarray */
void init_sin_arr( void )
{
   int n;

   /* Sinusarray im Abstand von einem Grad füllen */
   for(n=0;n<360;n++)
   {
      /* Duty für den jeweiligen Winkel berechnen */
      sin_arr[n] = (uint16_t) ( MAX_CNT * 0.5 * (1.0 + sin( 2 * PI * n / 360) ) + 0.5 );
   }
}


使用特权

评论回复
板凳
antusheng|  楼主 | 2018-8-23 09:29 | 只看该作者
/* Funktion initialisiert den externen Interrupt */
void init_ext_int(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Externen Interrupt konfigurieren */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOB, &amp;GPIO_InitStruct);
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource0);

    /* Auf steigende Flanke triggern */
    EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_Init(&amp;EXTI_InitStruct);

    /* Interrupt einschalten */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&amp;NVIC_InitStruct);
}

/* ISR des externen Interrupts */
void EXTI0_IRQHandler( void )
{
   static int angle;
   if ( EXTI-&gt;PR &amp; EXTI_Line0 )                       
   {
          /* PWM 1 --&gt; sin(a + 0&deg;)             */
      TIM1-&gt;CCR1 = sin_arr[  angle         % 360 ] + 50;
      /* PWM 2 --&gt; sin(a + 120&deg;)           */          
      TIM1-&gt;CCR2 = sin_arr[ (angle + 120 ) % 360 ] + 50;
      /* PWM 3 --&gt; sin(a + 240&deg;)           */          
      TIM1-&gt;CCR3 = sin_arr[ (angle + 240 ) % 360 ] + 50;   
      /* Winkel um ein Grad inkrementieren */
      angle++;                                       

      if ( !(angle % 180) ) GPIOA-&gt;ODR ^= GPIO_Pin_5;
      if ( !(angle % 360) ) angle = 0;

      EXTI-&gt;PR = EXTI_Line0;                        
   }
}

使用特权

评论回复
地板
antusheng|  楼主 | 2018-8-23 09:29 | 只看该作者
/* AD9850 */
#define AD9850_RESET       GPIOC, GPIO_Pin_1
#define AD9850_SCK         GPIOC, GPIO_Pin_3
#define AD9850_DATA        GPIOC, GPIO_Pin_2
#define AD9850_LATCH       GPIOC, GPIO_Pin_0

void ad9850_init( void )
{
   GPIO_WriteBit(AD9850_SCK, Bit_RESET);
   GPIO_WriteBit(AD9850_LATCH, Bit_RESET);
   GPIO_WriteBit(AD9850_RESET, Bit_RESET);
   delay_ms(10);
   GPIO_WriteBit(AD9850_RESET, Bit_SET);
   delay_ms(10);
   GPIO_WriteBit(AD9850_RESET, Bit_RESET);

   GPIO_WriteBit(AD9850_LATCH, Bit_SET);
   delay_ms(10);
   GPIO_WriteBit(AD9850_LATCH, Bit_RESET);
   delay_ms(10);
}

void ad9850_write_byte( unsigned char b )
{
   unsigned char i;
   GPIO_WriteBit(AD9850_SCK, Bit_RESET);
   for (i=0; i&lt;8; i++)
   {
      GPIO_WriteBit(AD9850_DATA, (b&amp;0x01)?Bit_SET:Bit_RESET);
      b&gt;&gt;=1;
      GPIO_WriteBit(AD9850_SCK, Bit_RESET);
      GPIO_WriteBit(AD9850_SCK, Bit_SET);
   }
}

void ad9850_set_freq( double f )
{
   unsigned long int y;
   f/=1000000;
   f=f*(4294967295/125);
   y=f;

   GPIO_WriteBit(AD9850_LATCH, Bit_RESET);

   ad9850_write_byte( y &amp; 0xFF );
   y&gt;&gt;=8;
   ad9850_write_byte( y &amp; 0xFF );
   y&gt;&gt;=8;
   ad9850_write_byte( y &amp; 0xFF );
   y&gt;&gt;=8;
   ad9850_write_byte( y &amp; 0xFF );

   ad9850_write_byte( 0 );

   GPIO_WriteBit(AD9850_LATCH, Bit_SET);
   GPIO_WriteBit(AD9850_LATCH, Bit_RESET);
}

使用特权

评论回复
5
antusheng|  楼主 | 2018-8-23 09:30 | 只看该作者
int main(void)
{
   SystemInit();                    /* MCU initialisieren               */
   SystemCoreClockUpdate();         /* Kernfrequenz updaten             */
   delay_init();                    /* Delay-Funktionen initialisieren  */
   ports_init();                    /* Ports initialisieren             */
   init_sin_arr();                  /* Sinusarray vorbereiten           */
   init_3_phase_pwm();              /* 3-Phasen-PWM initialisieren      */
   if (SysTick_Config(SystemCoreClock / 1000)) while (1);

   ad9850_init();                   /* AD9850 initialisieren            */
   init_ext_int();                  /* Externen Interrupt konfigurieren */

   ad9850_set_freq( 10 * 360.0 );

   while(1)
   {
   }
}

使用特权

评论回复
6
guanjiaer| | 2018-8-23 09:48 | 只看该作者
感谢楼主分享

使用特权

评论回复
7
paotangsan| | 2018-8-23 10:03 | 只看该作者
太详细了 感谢分享

使用特权

评论回复
8
yiyigirl2014| | 2018-8-23 14:29 | 只看该作者
没看懂。

使用特权

评论回复
9
jiekou001| | 2018-8-23 17:18 | 只看该作者
模块化设计还是挺不错的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

82

主题

1447

帖子

5

粉丝