Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методичка (МПС)

.pdf
Скачиваний:
20
Добавлен:
04.06.2015
Размер:
1.2 Mб
Скачать

}

void timer0_init(void)

{

TCCR0 = 0x00;

TCNT0 = 0x00;

OCR0 = 0x00;

TCCR0 = 0x00;

}

void adc_init(void)

{

ADCSRA = 0x00;

ADMUX = 0x60;

ADCSRA = 0x00; ADCSRA = 0xCF;

}

0 " 00 " $ $$ , $ % $ 3* "

$ TCCR0 0x4B. " % 3*

" = ( /64)/256 = 488 .

$ -' " & 8-

% clk/128. ) $ & 8) ' 8).

4. ) ! " $

" while(1) % & %

. ' !

:

if((PINA&0x04)==0x04)

{

TCCR0=0x4B;

}

else

{

TCCR0=0x00;

TCNT0=0x00;

PORTB=0x00;

}

- ! , " 00, ! ,

& " 00 & PORTB.

5. ) $ & 8) ' ,

' adc_isr():

CLI(); adc_result=ADCH;

if(adc_result<=5) adc_result=5; else if(adc_result>=250) adc_result=250; OCR0=adc_result;

ADCSRA|=0x40;

SEI();

& & 8) $ ADCH$ $ & & ,

61

& " & " %. ) $ &

$ " 00 OCR0.

6. 0 " 00 ' $ TCNT0 # " "

$ '. : $

&$ 255, $

OCR0. ) TCNT0=OCR0 ' 00,

$ TCNT0 ' 00. ) 00

VT2 VT4, $ #,

VT1 VT3:

CLI(); if((PINA&0x02)==0x02)

{

PORTB=0x08;

}

else

{

PORTB=0x02;

}

SEI();

) 00

VT1 VT3, #. 0

' !-&

' % :

CLI(); if((PINA&0x02)==0x02)

{

PORTB=0x09;

}

else

{

PORTB=0x06;

}

SEI();

0, & 8) $ OCR0 5,

TCNT0=OCR0=5 % VT4,

", & TCNT0=255

VT1, " % TCNT0=5. 0

' % & $ % 2 = <;=; = 0,02, %

&.

) ) 5-"

'

) 4 1… 4. ) 1 4 ' 2 3.

62

& % 2 = 0,5 %

, % 2 = 1 – & % &,

% 2 = 0,5 – & & %.

# 2. & !-&

$ % . , % & $

, $ RP1

.

//------------------------------------------------------------------

//Входы:

//PA0 – сигнал задания на ШИП

//PA1 – задание направления вращения

//PA2 – разрешение на работу преобразователя //Выходы:

//PB0 – управление транзистором VT1 (вход А1)

//PB1 – управление транзистором VT2 (вход B1)

//PB2 – управление транзистором VT3 (вход C1)

//PB3 – управление транзистором VT4 (вход D1)

//Подключение стандартных бибилиотек:

#include <iom32v.h> #include <macros.h>

//Объявление переменных:

unsigned char adc_result=0; unsigned char delay=0;

//Функция инициализации портов ввода/вывода:

void port_init(void)

{

 

 

PORTA

= 0xFE;

//Порт А инициализируется на ввод данных

DDRA

= 0x00;

 

PORTB

= 0xF0;

//Порт В инициализируется на вывод данных

DDRB

= 0x0F;

 

PORTC

= 0xFF;

 

DDRC

= 0x00;

 

PORTD

= 0xFF;

 

DDRD

= 0x00;

 

}

 

 

//Функция инициализации таймера Т0 в режиме ШИМ:

void timer0_init(void)

{

TCCR0 = 0x00;

 

 

TCNT0

= 0x00;

 

 

OCR0

=

0x7F;

//В таймере Т0 задается среднее значение

127

TCCR0 =

0x00;

//Запуск таймера при записи TCCR0=0x4B

 

}

63

//Функция инициализации аналого-цифрового преобразователя:

void adc_init(void)

{

 

ADCSRA = 0x00;

 

ADMUX = 0x60;

 

ADCSRA = 0x00;

 

ADCSRA = 0xCF;

//АЦП в режиме однократного преобразования

}

//в 8-битном режиме с предделителем 128

//Обработка прерывания готовности АЦП:

#pragma interrupt_handler adc_isr:iv_ADC

void adc_isr(void)

 

{

 

CLI();

//Запрет всех прерываний

adc_result=ADCH;

//Считывание результата преобразования АЦП

adc_result>>=1;

//Деление результата пополам и ограничение

if(adc_result<=5)

adc_result=5;

//на минимальном

else if(adc_result>=122)

adc_result=122;

//и максимальном уровнях

if((PINA&0x02)==0x02)

//При движении «Вперед»

{

 

 

OCR0=0x7F+adc_result;

//уставка таймера больше 127

}

 

 

else

//При движении «Назад»

{

 

 

OCR0=0x7F-adc_result;

//уставка таймера меньше 127

}

 

 

ADCSRA|=0x40;

//Перезапуск АЦП

 

SEI();

//Разрешение всех прерываний

}

 

 

//Обработка прерывания по совпадению таймера Т0:

#pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP void timer0_comp_isr(void)

{

 

CLI();

//Запрет всех прерываний

PORTB=0x00;

//Выключение транзисторов

for(delay=0;delay<5;delay++) {;}

//Защита от короткого замыкания

PORTB=0x09;

//Включение VT1 и VT4

SEI();

//Разрешение всех прерываний

}

 

//Обработка прерывания по переполнению таймера Т0:

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF void timer0_ovf_isr(void)

{

 

CLI();

//Запрет всех прерываний

PORTB=0x00;

//Выключение транзисторов

for(delay=0;delay<5;delay++) {;}

//Защита от короткого замыкания

PORTB=0x06;

//Включение VT2 и VT3

SEI();

//Разрешение всех прерываний

64

}

//Функция инициализации периферийных устройств:

void init_devices(void)

{

 

 

CLI();

 

//Запрет всех прерываний

port_init();

//Вызов функции инициализации портов

timer0_init();

//Вызов функции инициализации таймера Т0

adc_init();

//Вызов функции инициализации АЦП

MCUCR

= 0x00;

 

GICR

= 0x00;

//Запрет внешних прерываний

TIMSK = 0x03;

//Разрешение прерываний по совпадению и

SEI();

 

//переполнению таймера Т0

}

 

 

//Основная функция программы:

void main(void)

 

{

 

 

init_devices();

//Вызов функции инициализации устройств

while(1)

 

{

 

if((PINA&0x04)==0x04)

//При подаче сигнала разрешения на работу

{

 

TCCR0=0x4B;

//Запуск таймера Т0

}

 

else

//Иначе

{

 

TCCR0=0x00;

//Остановка таймера Т0

TCNT0=0x00;

 

PORTB=0x00;

//И выключение транзисторов.

}

 

}

 

}

 

//-------------------------------------------------------------------

 

& " $"

&, & $

$ , & $ !$

$ .

65

+ ' - 7. # ! 1 !

5-" ', ' 67 ) "

)

/ " '

+ & $ 3*)-6)0

"

.

# ) '

1.( & " " 3*)- 6)0 .

2.& " $ "

3*)-6)0.

3., & $

& &

" .

# '

) $" & &

& % & , - " & $

$ $ .

0 % & & &

% " " , "

$ $ .

+ " % & "

& , "

" (" , , 2/+),

' $ $

.

" "

3*)-6)0 &$

.

#$ $ $ & &

Atmega32, % " « ». ) & $ $

, 56, $

" .

6 $ "

# " $ , $

ATmega32 « », $ "

. : $ & &$

66

( «Y» «3-& " &»)

' .

$ , & " $

, & %. ) "

.

# 1. , & $ $ $

" , &

% & " '' )*- $ .

//-------------------------------------------------------------------

//Входы:

//PA0 – сигнал задания на ШИП

//PA2 – разрешение на работу преобразователя

//PD3 – подключение сигнала обратной связи с выхода имп. датчика «Y» //Выходы:

//PB0 – управление транзистором VT1 (вход А1)

//PB1 – управление транзистором VT2 (вход B1)

//PB2 – управление транзистором VT3 (вход C1)

//PB3 – управление транзистором VT4 (вход D1)

//Подключение стандартных библиотек:

#include <iom32v.h> #include <macros.h>

//Объявление перменных:

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;

//Порт B инициализируется на вывод данных

PORTC

= 0xFF;

 

DDRC

= 0x00;

 

PORTD

= 0xFB;

//Бит PD2 готов для работы прерывания INT0

DDRD

= 0x00;

 

}

 

 

//Функция инициализации аналого-цифрового преобразователя

void adc_init(void)

{

67

ADCSRA = 0x00;

 

ADMUX = 0x60;

 

ADCSRA = 0x00;

 

ADCSRA = 0xCF;

//АЦП запускается в 8-битном режиме в режиме

}

//одиночного преобразования с предделителем

 

//clk/128

//Функция инициализации 8-разрядного таймера Т0 в режиме ШИМ:

void timer0_init(void)

{

TCCR0 = 0x00;

TCNT0 = 0x00;

OCR0 = 0x00;

TCCR0 = 0x00;

}

//Функция инициализации 16-разрядного таймера Т1:

void timer1_init(void)

{

 

 

TCCR1B = 0x00;

 

TCNT1H = 0x00;

 

TCNT1L = 0x00;

 

OCR1AH = 0x1F;

//Уставка 1 мс при использовании таймера в режиме

OCR1AL = 0x40;

//СТС без предделителя частоты

OCR1BH = 0x00;

 

OCR1BL = 0x00;

 

ICR1H

= 0x00;

 

ICR1L

= 0x00;

 

TCCR1A = 0x00;

 

TCCR1B = 0x09;

//Таймер запускается в режиме CTC без предделителя

}

 

//частоты

//Обработка прерывания по готовности АЦП:

#pragma interrupt_handler adc_isr:iv_ADC void adc_isr(void)

{

 

CLI();

//Запрет всех прерываний

Uvh=ADCH;

//Присвоение Uvh значения результата преобразования АЦП

ADCSRA|=0x40;

//Перезапуск АЦП

SEI();

//Разрешение всех прерываний

}

 

//Обработка прерывания по совпадению таймера Т1:

#pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP void timer0_comp_isr(void)

{

 

CLI();

//Запрет всех прерываний

PORTB=0x08;

//Включение транзистора VT4 и отключение VT1

SEI();

//Разрешение всех прерываний

}

 

68

//Обработка прерывания по переполнению таймера Т0:

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF void timer0_ovf_isr(void)

{

 

CLI();

//Запрет всех прерываний

PORTB=0x09;

//Включение транзистора VT1

SEI();

//Разрешение всех прерываний

}

 

//Обработка внешнего прерывания INT0 импульсного датчика скорости:

#pragma interrupt_handler int0_isr:iv_INT0 void int0_isr(void)

{

 

 

 

 

CLI();

//Запрет всех прерываний

 

pulse+=1;

//Инкремент счетчика импульсов датчика скорости

SEI();

//Разрешение всех прерываний

}

 

 

 

 

//Обработка прерывания по совпадению 16-разрядного таймера Т1:

#pragma interrupt_handler timer1_compa_isr:iv_TIM1_COMPA

void timer1_compa_isr(void)

 

 

{

 

 

 

 

CLI();

 

//Запрет всех прерываний

cycle_cnt+=1;

 

//Счет числа циклов срабатывания Т1

if(cycle_cnt==100)

//Когда cycle_cnt доходит до 100 (100 мс)

{

 

 

 

 

Uos=pulse;

 

//Выполняется подсчет скорости

Uos<<=2;

 

 

 

 

pulse=0;

 

//сбрасывается счетчик импульсов датчика скорости

cycle_cnt=0;

 

//сбрасывается счетчик циклов cycle_cnt

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);} //интегрирования

if((PINA&0x04)==0x00)

//Если сигнал разрешения убран

{

 

 

 

 

delta_i=0;

 

 

//обнуляется интегральный канал

Urs=Up;

 

 

//регулятора скорости

Urs_=0;

 

 

 

 

}

 

 

 

 

69

else //иначе

{

Urs=Up+delta_i+Urs_; //рассчитывается сигнал на выходе

Urs_=Urs-Up;

//ПИ-регулятра скорости

}

 

 

 

if(Urs>=250)

Urs=250;

//Выполняется ограничение сигнала

else if(Urs<=5)

Urs=5;

//на выходе регулятора

OCR0=Urs;

 

//и вывод результата на управление

}

 

 

//транзисторами

SEI();

 

 

//Разрешение всех прерываний

}

 

 

 

//Функция инициализации периферийных устройств контроллера:

void init_devices(void)

 

{

 

 

 

CLI();

 

//Запрет всех прерываний

port_init();

//Вызов функции инициализации портов

timer0_init();

//Вызов функции инициализации таймера Т0

timer1_init();

//Вызов функции инициализации таймера Т1

adc_init();

//Вызов функции инициализации АЦП

MCUCR

= 0x03;

 

 

GICR

= 0x40;

//Разрешение внешнего прерывания INT0

TIMSK = 0x13;

//Разрешение прерываний по совпадению Т0 и Т1

SEI();

 

//и по переполнению Т0

}

 

 

 

//Главная функция программы:

void main(void)

 

{

 

init_devices();

//Вызов функции инициализации устройств

while(1)

//Бесконечный цикл

{

 

if((PINA&0x04)==0x04)

//При подаче сигнала «Разрешение»

{

 

TCCR0=0x4B;

//Запуск таймера Т0

}

 

else

//иначе

{

 

TCCR0=0x00;

//Остановка таймера Т0

TCNT0=0x00;

 

PORTB=0x00;

//И выключение транзисторов

}

 

}

 

}

 

//-------------------------------------------------------------------

 

$ .

1. $ $

7 , & $ :

70