Методичка (МПС)
.pdfif((PIND&0x04)==0x04) |
//Формирование угла на положительной |
|
{ |
//части сетевой синусоиды |
|
if((PINA&0x02)==0x02) |
{PORTB=0x01;} |
//Вперед |
else |
{PORTB=0x04;} |
//Назад |
} |
|
|
else |
//Формирование угла на отрицательной |
|
{ |
//части сетевой синусоиды |
|
if((PINA&0x02)==0x02) |
{PORTB=0x02;} |
//Вперед |
else |
{PORTB=0x08;} |
//Назад |
} |
|
|
SEI(); |
//Разрешение всех прерываний |
|
} |
|
|
//Функция инициализации периферийных устройств контроллера:
void init_devices(void) |
|
|
{ |
|
|
CLI(); |
|
//Запрет всех прерываний |
port_init(); |
//Вызов функции инициализации портов |
|
adc_init(); |
//Вызов функции инициализации АЦП |
|
timer1_init(); |
//Вызов функции инициализации таймера Т1 |
|
MCUCR |
= 0x01; |
|
GICR |
= 0x40; |
//Разрешение прерывания INT0 |
TIMSK = 0x10; |
//Разрешение прерывания по совпадению Т1 |
|
SEI(); |
|
//Разрешение всех прерываний |
} |
|
|
//Главная функция программы: |
||
void main(void) |
|
|
{ |
|
|
init_devices(); |
//Вызов функции инициализации устройств |
|
while(1) |
//Бесконечный цикл |
|
{ |
|
|
; |
|
|
} |
|
|
}
//------------------------------------------------------------------
$ .
1. $ $
7 , & $ :
#include <iom32v.h> #include <macros.h> unsigned int alpha=9722; unsigned char adc_result;
& alpha – $ , % " "; adc_result – & 8);
2. ) $ " ' main (),
" ' ' " "
init_devices ():
81
CLI(); port_init(); adc_init(); timer1_init(); MCUCR = 0x01; GICR = 0x40; TIMSK = 0x10; SEI();
: ' & ' , " 01, 8), % !$ INT0 (MCUCR = 0x01;
GICR = 0x40) " " (TIMSK = 0x10): void port_init(void)
{
PORTA = 0xFE; DDRA = 0x00; PORTB = 0xF0; DDRB = 0x0F; PORTC = 0xFF; DDRC = 0x00; PORTD = 0xFB; DDRD = 0x00;
}
void adc_init(void)
{
ADCSRA = 0x00;
ADMUX = 0x60; ADCSRA = 0x8E;
}
void timer1_init(void)
{
TCCR1B = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
OCR1AH = 0x00;
OCR1AL = 0x00;
OCR1BH = 0x00;
OCR1BL = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;
TCCR1A = 0x00;
TCCR1B = 0x00;
}
3.) $ "
while(1), " ".
4.) 8) adc_isr(),
& & " $
:
CLI(); adc_result=255-ADCH; alpha=adc_result*38;
82
ADCSRA|=0x40;
SEI();
5. ) " " $ ' !
" INT0 & $ " 01 $ ". - $ !
, " :
CLI();
PORTB&=0xF0;
OCR1A=alpha;
TCNT1=0; if((PINA&0x04)==0x04)
{
TCCR1B=0x02;
}
else
{
TCCR1B=0x00;
PORTB=0x00;
}
SEI();
6. , $ " 01 $ , '
" 01. )
" ' $ $
VS1…VS4, $
#.
CLI(); |
|
if((PIND&0x04)==0x04) |
|
{ |
|
if((PINA&0x02)==0x02) |
{PORTB=0x01;} |
else |
{PORTB=0x04;} |
} |
|
else |
|
{ |
|
if((PINA&0x02)==0x02) |
{PORTB=0x02;} |
else |
{PORTB=0x08;} |
} |
|
SEI(); |
|
" & "
$ , & &
$ .
83
+ ' - 10. # ! 1 !
', ' 67 ) "
)
/ " '
+ & $ 0)-6)0 "
.
# ) '
1.( & " " 0)-6)0
.
2.& " $ "
0)-6)0.
3., & $
& &
" .
# '
) $" & &
& % & , - " & $
$ $ .
0 % & & &
% " " , "
$ $ .
+ " % & "
& , "
" (" , , 2/+),
' $ $
.
" "
0)-6)0 &$
.
#$ $ $ & &
Atmega32, % " « ».$ $
" 59.
6 $ "
# " $ , $
ATmega32 « », $ "
. : $ & &$
( «Y» «0 " &») '
.
84
$ , & " $
, & %. ) "
.
# 1. , & $ $ $
" , &
% & " '' )*- $ .
//------------------------------------------------------------------
//Входы:
//PA0 – сигнал задания на ТП
//PA1 – задание направления вращения
//PA2 – разрешение на работу преобразователя //PD2 – сигнал синхронизации с сетью
//PD3 – вход импульсного датчика скорости //Выходы:
//PB0 – управление тиристорами VS1, VS4
//PB1 – управление тиристорами VS2, VS3
//PB2 – управление тиристорами VS6, VS7
//PB3 – управление тиристорами VS5, VS8
//Подключение стандартных библиотек:
#include <iom32v.h> #include <macros.h>
//Объявление переменных:
unsigned int alpha=9722; unsigned char adc_result; unsigned int pulse=0; unsigned char cycle_cnt=0; signed char Kp=-2; unsigned char Ti=6;
unsigned long int Uvh=0,Uos=0;
signed long int delta=0,delta_i=0,Up=0,Urs=0,Urs_=0;
//Функция инициализация портов ввода/вывода:
void port_init(void)
{
PORTA = 0xFE; DDRA = 0x00; PORTB = 0xF0; DDRB = 0x0F; PORTC = 0xFF; DDRC = 0x00; PORTD = 0xF3; DDRD = 0x00;
}
//Функция инициализации АЦП:
85
void adc_init(void)
{
ADCSRA = 0x00;
ADMUX = 0x60; ADCSRA = 0x8E;
}
//Функция инициализации таймера Т1 для счета угла управления:
void timer1_init(void)
{
TCCR1B = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
OCR1AH = 0x00;
OCR1AL = 0x00;
OCR1BH = 0x00;
OCR1BL = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;
TCCR1A = 0x00;
TCCR1B = 0x00;
}
//Обработка прерывания готовности АЦП:
#pragma interrupt_handler adc_isr:iv_ADC void adc_isr(void)
{ |
|
|
CLI(); |
//Запрет всех прерываний |
|
Uvh=ADCH; |
//Присвоение результата преобразования переменной Uvh |
|
ADCSRA|=0x40; |
//Перезапуск АЦП |
|
SEI(); |
//Разрешение всех прерываний |
|
} |
|
|
//Обработка внешнего прерывания INT0 (синхронизация с сетью): |
||
#pragma interrupt_handler int0_isr:iv_INT0 |
||
void int0_isr(void) |
|
|
{ |
|
|
CLI(); |
|
//Запрет всех прерываний |
PORTB&=0xF0; |
|
//Выключение импульсов управления |
cycle_cnt+=1; |
|
//Подсчет количества циклов |
if(cycle_cnt==10) |
//Когда оно равно 10 (100 мс) |
|
{ |
|
|
Uos=pulse; |
|
//Выполняется расчет скорости |
Uos<<=2; |
|
|
pulse=0; |
|
//Обнуляется счетчик импульсов датчика |
cycle_cnt=0; |
|
//и счетчик циклов |
delta=Uvh-Uos; |
|
//Рассчитывается ошибка на входе |
delta_i=delta; |
|
//регулятора скорости |
if(Kp==0) |
Up=0; |
//Которая затем умножается на |
else if(Kp==1) |
Up=delta; |
//коэффициент пропорционального |
else if(Kp==2) |
Up=delta<<1; |
//усиления регулятора скорости |
86
else if(Kp==4) |
Up=delta<<2; |
|
else if(Kp==8) |
Up=delta<<3; |
|
else if(Kp==-1) |
Up=delta; |
|
else if(Kp==-2) |
Up=delta>>1; |
|
else if(Kp==-4) |
Up=delta>>2; |
|
else if(Kp==-8) |
Up=delta>>3; |
|
if(Ti==0) |
{delta_i=0;} |
//Далее ошибка проходит |
else |
{delta_i>>=(Ti-1);} |
//Интегральный канал |
|
|
//регулятора |
if((PINA&0x04)==0x00) |
//В случае если разрешение |
|
{ |
|
//на работу отсутствует |
delta_i=0; |
|
//Интегральный канал |
Urs=Up; |
|
//обнуляется |
Urs_=0; |
|
|
} |
|
|
else |
|
//Иначе |
{ |
|
|
Urs=Up+delta_i+Urs_; |
//Выполняется расчет |
|
Urs_=Urs-Up; |
|
//сигнала ПИ-регулятора |
} |
|
|
if(Urs>=255) |
Urs=255; |
//Далее выполняется |
else if(Urs<=0) |
Urs=0; |
//ограничение сигнала, |
alpha=255-Urs; |
|
//его инверсия |
alpha*=38; |
|
//и расчет угла управления |
} |
|
|
OCR1A=alpha; |
|
//Выдача угла на таймер Т1 |
TCNT1=0; |
|
|
if((PINA&0x04)==0x04) |
//Если подано разрешение, |
|
{ |
|
|
TCCR1B=0x02; |
|
//выполняется запуск Т1 |
} |
|
|
else |
|
//Иначе |
{ |
|
|
TCCR1B=0x00; |
|
//таймер останавливается |
PORTB=0x00; |
|
//тиристоры выключаются |
} |
|
|
SEI(); |
|
//Разрешение всех прерываний |
} |
|
|
//Обработка внешнего прерывания INT1 (импульсный датчик): |
||
#pragma interrupt_handler int1_isr:iv_INT1 |
||
void int1_isr(void) |
|
|
{ |
|
|
CLI(); |
//Запрет всех прерываний |
|
pulse+=1; |
//Подсчет импульсов датчика скорости |
|
SEI(); |
//Разрешение всех прерываний |
|
} |
|
|
//Обработка прерывания по совпадению таймера Т1:
87
#pragma interrupt_handler timer1_compa_isr:iv_TIM1_COMPA void timer1_compa_isr(void)
{ |
|
|
CLI(); |
//Запрет всех прерываний |
|
if((PIND&0x04)==0x04) |
//Формирование угла на положительной |
|
{ |
//части сетевой синусоиды |
|
if((PINA&0x02)==0x02) |
{PORTB=0x01;} |
//Вперед |
else |
{PORTB=0x04;} |
//Назад |
} |
|
|
else |
//Формирование угла на отрицательной |
|
{ |
//части сетевой синусоиды |
|
if((PINA&0x02)==0x02) |
{PORTB=0x02;} |
//Вперед |
else |
{PORTB=0x08;} |
//Назад |
} |
|
|
SEI(); |
//Разрешение всех прерываний |
|
} |
|
|
//Функция инициализации периферийных устройств контроллера:
void init_devices(void)
{ |
|
|
CLI(); |
|
//Запрет всех прерываний |
port_init(); |
//Вызов функции инициализации портов |
|
adc_init(); |
//Вызов функции инициализации АЦП |
|
timer1_init(); |
//Вызов функции инициализации таймера Т1 |
|
MCUCR |
= 0x0D; |
|
GICR |
= 0xC0; |
//Разрешение внешних прерываний INT0, INT1 |
TIMSK = 0x10; |
//Разрешение прерывания по совпадению Т1 |
|
SEI(); |
|
//Разрешение всех прерываний |
} |
|
|
//Главная функция программы: |
||
void main(void) |
|
|
{ |
|
|
init_devices(); |
//Вызов функции инициализации устройств |
|
while(1) |
//Бесконечный цикл |
|
{ |
|
|
; |
|
|
}
}
//------------------------------------------------------------------
$ .
1. $ $
7 , & $ :
#include <iom32v.h> #include <macros.h> unsigned int alpha=9722; unsigned char adc_result; unsigned int pulse=0; unsigned char cycle_cnt=0; signed char Kp=-2;
88
unsigned char Ti=6;
unsigned long int Uvh=0,Uos=0;
signed long int delta=0,delta_i=0,Up=0,Urs=0,Urs_=0;
& alpha – $ , % " "; adc_result – & 8);
pulse – & ;
cycle_cnt – INT0;
Kp, Ti – '' &$
$&$ $ ;
Uvh, Uos – $ " $ ; delta, delta_i – $ ! $ ;
Up – $ &$ $ ;
Urs,Urs_ – $ $
# .
2. ) $ " ' main (),
" ' ' " "
init_devices ():
CLI(); port_init(); adc_init(); timer1_init(); MCUCR = 0x0D; GICR = 0xC0; TIMSK = 0x10; SEI();
: ' & ' , " 01, 8), % ! " INT0 INT1 (GICR =
0xC0;TIMSK = 0x10) " " (TIMSK = 0x10): void port_init(void)
{
PORTA = 0xFE; DDRA = 0x00; PORTB = 0xF0; DDRB = 0x0F; PORTC = 0xFF; DDRC = 0x00; PORTD = 0xF3; DDRD = 0x00;
}
void adc_init(void)
{
ADCSRA = 0x00;
ADMUX = 0x60; ADCSRA = 0x8E;
}
void timer1_init(void)
{
TCCR1B = 0x00;
TCNT1H = 0x00;
89
TCNT1L = 0x00; OCR1AH = 0x00; OCR1AL = 0x00; OCR1BH = 0x00; OCR1BL = 0x00; ICR1H = 0x00; ICR1L = 0x00; TCCR1A = 0x00; TCCR1B = 0x00;
}
3.) $ "
while(1), " ".
4.) 8) adc_isr(),
& $ Uvh
$ :
CLI();
Uvh=ADCH;
ADCSRA|=0x40;
SEI();
5. ) " " $ ' !
" INT0 & $ " 01 $ ". - $ !
, " . & %
$ " $ )*- $
:
CLI(); |
|
PORTB&=0xF0; |
|
cycle_cnt+=1; |
|
if(cycle_cnt==10) |
|
{ |
|
Uos=pulse; |
|
Uos<<=2; |
|
pulse=0; |
|
cycle_cnt=0; |
|
delta=Uvh-Uos; |
|
delta_i=delta; |
|
if(Kp==0) |
Up=0; |
else if(Kp==1) |
Up=delta; |
else if(Kp==2) |
Up=delta<<1; |
else if(Kp==4) |
Up=delta<<2; |
else if(Kp==8) |
Up=delta<<3; |
else if(Kp==-1) |
Up=delta; |
else if(Kp==-2) |
Up=delta>>1; |
else if(Kp==-4) |
Up=delta>>2; |
else if(Kp==-8) |
Up=delta>>3; |
if(Ti==0) |
{delta_i=0;} |
else |
{delta_i>>=(Ti-1);} |
90