Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт
Шрифт:
Интервал:
Закладка:
Рис. 7.17. Результаты испытаний двигателя
Оптический кодер. Существует широкое разнообразие оптических кодеров для определения скорости вращения вала двигателя. Эти кодеры закрепляются непосредственно на валу, или могут быть связаны с валом какими-либо устройствами. При установке кодера на вращающийся вал, это устройство обеспечивает на выходе прямоугольное напряжение. Кодеры питаются от постоянного напряжения 5 В, и рассчитаны на максимальную скорость вращения в 12 000 об/мин. Мы используем оптические кодеры, чтобы обеспечить измерение скорости вращения двигателя, как описано в [11]. Установка для измерения частоты вращения показана на рис. 7.18.
Рис. 7.18. Установка для измерения скорости вращения двигателя
Прерывания в режиме реального времени. Мы используем в МК 68HC12 модуль меток реального времени (RTI), периодически прерывая работу 68HC12, чтобы измерить скорость двигателя и скорректировать коэффициент заполнения ШИМ, если это необходимо для стабилизации скорости вращения двигателя. Перед обсуждением программного кода для управления RTI, мы советуем Вам, возобновить в памяти информацию о сбросах и прерываниях. Ниже приведен краткий обзор действий, необходимых, чтобы инициализировать прерывание RTI:
• Инициализируют вектор прерывания по запросу RTI;
• Устанавливают масштабирующий коэффициент RTR[2:0];
• Устанавливают флаг RTIE разрешения прерываний от RTI в регистре RTICTL;
• Очищают флаг RTIF в регистре RTIFLG;
• Разрешают все маскируемые прерывания прерывания (команда CLI).
Приведенные ниже программный код поможет Вам ознакомиться с работой RTI. В этом примере, мы переходим к программе ISR обработки прерывания RTI, переключая флаг порта PORTP. Если вы исследуете возникающую в результате форму сигнала, показанного на рис. 7.19, с помощью осциллографа или логического анализатора, то сможете измерить период повторения системы RTI прерываний.
Рис. 7.19. Прерывания в режиме реального времени
//********************************************************************
//имя файла: RTI_test.с//
//Port P[0]: Конфигурируется как цифровой выходной порт, обеспечивающий TTL
// совместимые сигналы для управления затвором.
// авторы: Стив Барретт и Даниель Пак
//дата создания: Mar 10, 2003
//последняя редакция: Mar 10, 2004
//********************************************************************
#include <912b32.h>
#pragma interrupt_handler RTI_isr
//Функции-прототипы
//***************************************************
void initialize_ports(void); //инициализация портов
void RTI_isr(void);
void initialize_RTI(void);
//main program* *******************************************************
void main(void) {
//инициализация вектора сброса для B32
asm(".area vectors(abs)n"
" .org 0xFFF0n" // инициализация вектора прерывания RTI
" .word _RTI_isrn"
" .org 0xFFF8n" // инициализация вектора сброса для B32
" .word 0x8000, 0x8000, 0x8000, 0x8000n"
" .text");
initialize_RTI(); //инициализация модуля RTI
initialize_ports(); //инициализация портов
PORTP = 0x01; // разрешение PORTP вывод 0
asm("cli"); //разрешение всех маскируемых прерываний
.
.
.
}
//********************************************************************
// определения функций
// ********************************************************************
//Initialize_ports: начальная конфигурация
//для портов входа/выхода
// ********************************************************************
void initialize_ports(void) {
DDRP=0xFF; //порт PORTP устанавливается как выходной
}
// ********************************************************************
//RTI_isr: подпрограмма обслуживания прерываний по RTI
//*********************************************************************
void RTI_isr(void) {
RTIFLG = 0x80; //сбрасывается флаг RTIF
PORTP =~(PORTP); //переключить выходы PORTP
}
// ********************************************************************
// ********************************************************************
//initialize_RTI:конфигурирует модуль RTI
// ********************************************************************
void initialize_RTI(void) {
RTICTL = 0x86; // устанавливается таймер RTI
RTIFLG = 0x80; //сбрасывается флаг RTIF
}
// ********************************************************************
Аккумулятор импульсов. Число импульсов, поступающих от оптического кодера, подсчитывается аккумулятором импульсов (PA). Он инициализируется в начале программы и затем фиксирует текущее число импульсов за интервал каждого прерывания RTI. По известному интервалу времени между прерываниями RTI (32.768 мс) можно определить число импульсов, поступивших на PA между двумя прерываниями, и затем вывести на дисплей скорость вращения двигателя. Для конфигурации PA системы существует специальный код.
// **********************************************************************
//initialize_PA: инициализация модуля аккумулятора импульсов МК 68HC12
// **********************************************************************
void initialize_PA(void) {
TIOS = 0x00; //Конфигурировать канал 7 для работы счетчика импульсов
TCTL1 = 0x00; //кодера - 3 оператора
OC7M = 0x00;
TSCR = 0x80; //Установить бит разрешения таймера
PACTL = 0x70; //Разрешить работу PA, режим счета событий, событие
// по фронту импульса,
}
Объединим теперь эту программу с программой для RTI, чтобы подсчитать число импульсов кодера, появившихся за интервал прерывания. Получив, этот результат, преобразуем его в число об/мин и выведем полученное значение на ЖК индикатор.
// **********************************************************************
//имя файла: motor.с
//автор: Steve Barrett and Daniel Pack
//дата создания: Mar 10, 2003
//последняя редакция: Mar 25, 2004
// **********************************************************************
// включенные файлы *****************************************************
#include <912b32.h>
#pragma interrupt_handler RTI_isr //объявить подпрограмму прерывания по RTI
// функции-прототипы ****************************************************
void initialize_ports(void); //инициализировать порты
void RTI_isr(void); //подпрограмма обслуживания прерываний RTI
void initialize_RTI(void); // инициализировать систему RTI
void initialize_PA(void); //инициализировать аккумулятор импульсов (PA)
void initialize_LCD(void); // инициализировать ЖК индикатор
void display_count_LCD(unsigned int); //вывод текущего содержимого аккумулятора PA
// на ЖК индикатор
void putchars(unsigned char); //функция поддержки ЖКИ - вывести символ
void putcommands(unsigned char);// функция поддержки ЖКИ вывести команду
void delay_5ms(void); //задержка 5 мс
void delay_100us(void); //задержка 100 мкс
unsigned int old_count; //последнее значение, записанное в (PA)
int RTI_int_count =0; //используется для подсчета RTI прерываний
//главная программа****************************************************
void main(void) {
asm(" .area vectors(abs) n" //inline assembly statement
".org 0xFFF0n" //инициализация вектора прерываний RTI
".word _RTI_isrn"
" .org 0xFFF8n" // инициализация вектора reset для 68HC12 B32
" .word 0x8000, 0x8000, 0x8000, 0x8000n"
" .text");
void initialize_ports(void); // инициализация портов
initialize_LCD(); //инициализация ЖКИ
initialize_RTI(); //инициализация модуля RTI
initialize_PA(); //инициализация аккумулятора импульсов
asm("cli"); //разрешение глобального маскирования
//прерываний
while(1) //продолжение цикла до следующего прерывания
{
;
}
}
//********************************************************************
//********************************************************************
//initialize_ports: определяет направление передачи портов
//********************************************************************
void initialize_ports(void) {
DDRP = 0xFF; // порт PORTP устанавливается как выходной для ШИМ
DDRT = 0x00; // PORTT устанавливается как входной, вывод PORTT[7]
// в качестве входа аккумулятора импульсов PA
DDRB = 0xFF; // PORTB устанавливается как выходной - порт
// данных для ЖКД
DDRDLC = 0xFF; // PORT DLC устанавливается как выходной - сигналы
// управления для ЖКИ
}
//********************************************************************