Страница 1 из 1

Помогите с фазоимпульсным регулятором

Добавлено: Вс дек 01, 2013 20:46:50
Aselicon
Доброго здоровья!
Пробую писать регулятор для двигателя переменного тока 1ф.
Имеется обратная связь в виде 8и импульсов на один оборот ротора.
Идея элементарна:
-> измерить частоту вращения ротора
-> принять решение о необходимости изменения питающего напряжения
-> открыть симистор на нужный угол

В моей текущей реализации получается что регулятор работает по релейному закону, а хочется плавненько :)

Посоветуйте пожалуйста :write:

ПС. константы брал по протеусу. В железе проверял, работает абсолютно аналогично. Временные интервалы точно совпадают.
Спойлер

Код: Выделить всё

#include <mega8.h>

#define TRIAC_OUT PORTB.2     

 unsigned int n,p,t0,f,real_freq; 
          bit extint;     
 unsigned char ADC_TIMER; 
 unsigned int FREQ_VAL;


interrupt [EXT_INT0] void ext_int0_isr(void)    //Детектор перехода фазы через 0
{ 
 extint=1;   
} 

interrupt [EXT_INT1] void ext_int1_isr(void)    //Считаем импульсы
{
f++;
}    


interrupt [TIM1_COMPA] void timer1_compa_isr(void) //Считаем реальную частоту из расчета 8 импульсов на 1гц
{
 real_freq=f/8;
 f=0;
  TCNT1H=0;
  TCNT1L=0;
}

interrupt [ADC_INT] void adc_isr(void)            //Задаем частоту крутилкой 0-1275гц
{
FREQ_VAL=ADCH*5; 
}

void main(void)
{
PORTB=0x01;
DDRB=0x06;
PORTD=0x00;
DDRD=0x00;

TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;

ADMUX=0x65;                   
ADCSRA=0x8F; 

// INT0 Mode: Any change
// INT1 Mode: Falling Edge
GICR|=0xC0;
MCUCR=0x09;
GIFR=0xC0;

TIMSK=0x10;   

#asm("sei")   // Global enable interrupts

while (1)

      {  
      
       ADC_TIMER++;               // Запускаем АЦП
       if (ADC_TIMER==50)             
         {
          ADCSRA|=0x40;             
          ADC_TIMER=0;
         } 

      if ((real_freq<FREQ_VAL)&&(t0<600)) {t0++;}              //Если реальная частота ниже заданной то увеличиваем угол открытия,
      if ((real_freq>FREQ_VAL)&&(t0>0))   {t0--;}                //и наоборот
          
      if (extint==1) {n++;}                                    //Если пришло прерывание ext1 то начинаем считать,
      if ((extint==1)&&(n>=t0)) {TRIAC_OUT=1; n=0; extint=0;}  //когда досчитали - включаем симистор  (угол открытия привязанный к 0)
           
      if (PINB.2==1) {p++;}                                    //Если симистор включен то начинаем считать,
      if ((PINB.2==1)&&(p>=25)) {TRIAC_OUT=0; p=0;}            //когда досчитали - выключаем симистор (длительность импульса для открытия)

      }
}

Re: Помогите с фазоимпульсным регулятором

Добавлено: Вс дек 01, 2013 21:42:03
pcb
Юзай таймеры для определения частоты вращения двига.

Импульсы с энкодера заведи на ногу с внешним прерыванием.
Пришло прерывание, запускаешь таймер,
Пришло прерывание, берешь значение таймера и вычисляешь обороты.

Re: Помогите с фазоимпульсным регулятором

Добавлено: Пн дек 02, 2013 10:00:14
Aselicon
Вот скажите мне на радость, зачем Вы это написали? :) Вопрос в плавном регулировании, программа написана и работает, ознакомились хоть бы чтоли....

Re: Помогите с фазоимпульсным регулятором

Добавлено: Пн дек 02, 2013 11:57:38
zero648
Что есть "регулятор работает по релейному закону"? Объясните пжлста.

Re: Помогите с фазоимпульсным регулятором

Добавлено: Пн дек 02, 2013 17:46:19
Aselicon
Ну то симистор открыт полностью то закрыт полностью, я хочу чтобы он открывался на промежуточные величины тоже. это не позволяет сделать мой алгоритм

Re: Помогите с фазоимпульсным регулятором

Добавлено: Сб дек 07, 2013 18:00:16
Aselicon
ПИД регулятор помог! Чтото изначально я видимо перенапрягся :tea: