Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт
Шрифт:
Интервал:
Закладка:
// управления для ЖКИ
}
//********************************************************************
//RTI_isr: подпрограмма прерывания по RTI
//********************************************************************
void RTI_isr(void) {
unsigned int new_count;
unsigned int pulse_count;
float max_count = 65535.0;
new_count = PACNT; //передается текущее число импульсов, записанное в PA
if (new_count > old_count) //определяется приращение числа импульсов
pulse_count = new_count - old_count;
else pulse_count = (unsigned int)(max_count-(float)(old_count = new_count));
RTI_int_count = RTI_int_count + 1;// изменяется показание счетчика
//RTI-прерываний
if (RTI_int_count == 10) // изменяется показание ЖКД через
// каждые 10 прерываний
{
display_count_LCD(pulse_count); //изменяется ЖКИ
RTI_int_count = 0; //сбрасывается счетчик прерываний RTI
}
old_count = new_count;
RTIFLG = 0x80; //сбрасывается RTI
}
// ********************************************************************
// initialize_RTI:конфигурирует регистры, связанные с RTI
// - регистр RTICTL
// -- разрешает работу модуля RTI установкой бита RTIE
// -- период RTI в 32.768 мс
// - сбрасывает бит RTIF в регистре флагов (RTIFLG)
// ********************************************************************
void initialize_RTI(void) {
RTICTL = 0x86; // устанавливается период RTI на 32.768 мс
RTIFLG = 0x80; //сбрасывается флаг RTIF
}
// ********************************************************************
//initialize_PA: инициализация модуля аккумулятора импульсов
// ********************************************************************
void initialize_PA(void) {
TIOS = 0x00; // Конфигурирует канал 7 для работы
TCTL1 = 0x00; // счетчика импульсов оптического кодера
OC7M = 0x00;
TSCR = 0x80; // устанавливает бит разрешения работы таймера
PACTL = 0x70; // разрешает работу РА, режим счета событий,
// по фронту импульса,
}
/********************************************************************/
/* initialize_LCD: инициализации ЖКИ */
/* передает на ЖКИ стартовую последовательность команд управления */
/* - PORTDLC[3]: линия управления RS ЖКИ */
/* - PORTDLC[2]: линия управления E для ЖКИ */
/* - PORTB: двунаправленная магистраль данных для ЖКИ */
/********************************************************************/
void initialize_LCD(void) {
delay_5ms();
delay_5ms();
delay_5ms(); /*ожидание в течение 15 мс перед включением ЖКИ */
putcommands(0x38); /*разрядность данных интерфейса 8 бит */
delay_5ms(); /*задержка */
putcommands(0x38); /*интерфейс в 8 бит */
delay_100us(); /*задержка */
putcommands(0x38); /* разрядность данных интерфейса 8 бит */
putcommands(0x38); /* интерфейс в 8 бит */
putcommands(0x0C); /*включение дисплея */
putcommands(0x01); /*очистка дисплея */
putcommands(0x06); /*установка режима инкремента адреса */
putcommands(0x00);
putcommands(0x00);
putcommands(0xC0); /*курсор на линию 2 знакоместо 1 */
putchars('R'); /* вывести "PRM" - скорость */
/*в об/мин на строку 2 ЖКИ */
putchars('P');
putchars('M');
}
/********************************************************************/
/*putchars: функция посылает ASCII код для вывода на ЖКИ */
/********************************************************************/
void putchars(unsigned char c) {
PORTB = c; /*вывести на порт PORTB код символа */
PORTDLC = PORTDLC|0x08; /*установить RS в 1 для передачи данных */
PORTDLC = PORTDLC|0x04; /*установить E в 1 */
PORTDLC = 0x00; /* установить E и RS в 0 */
delay_100us(); delay_100us();
}
/********************************************************************/
/*putcommands: функция посылает команду управления ЖКИ */
/********************************************************************/
void putcommands(unsigned char d) {
PORTDLC = PORTDLC&0xF7; /*установить RS в 0 для передачи команды */
PORTDLC = PORTDLC|0x04; /*установить E в 1 */
PORTDLC = 0x00; /* установить E и RS в 0 */
delay_100us();
delay_100us();
}
/********************************************************************/
/* delay_5ms: программная задержка 5 мс */
/********************************************************************/
void delay_5ms(void) {
int i;
for (i=0; i<50; i++) {
delay_100us();
}
}
/********************************************************************/
/* delay_100us:программная задержка в 100 мс */
/********************************************************************/
void delay_100us(void) {
int i;
for(i=0; i<800; i++) {
asm("nop");/*выполнение команды nор ассемблера занимает 1 период*/
}
}
/********************************************************************/
/* display_count_LCD: преобразует целое число в ASCII символ */
/* для вывода на ЖКИ */
/********************************************************************/
void display_count_LCD(unsigned int count) {
unsigned int thousands_int;
unsigned int hundreds_int;
unsigned int tens_int;
unsigned int ones_int;
char thousands;
char hundreds;
char tens;
char ones;
/*выбирает и преобразует наибольшую значащую цифру в десятичное */
/* значение + 48, образуя ASCII код */
thousands_int = count/1000;
thousands = (char)(thousands_int + 48);
/*выбирает и преобразует следующую наибольшую значащую цифру */
/* в десятичное значение + 48, образуя ASCII код */
hundreds_int = (count - thousands_int*1000)/100;
hundreds = (char)(hundreds_int + 48);
/*выбирает и преобразует следующую наибольшую значащую цифру */
/* в десятичное значение + 48, образуя ASCII код */
tens_int = (count - thousands_int*10 0 0 - hundreds_int*100)/10;
tens = (char)(hundreds_int + 48);
/*выбирает и преобразует следующую наибольшую значащую цифру */
/* в десятичное значение + 48, образуя ASCII код */
ones_int = (count-thousands_int*1000-hundreds_int*100-tens_int*10);
ones = (char)(ones_int + 48);
/*выводит результат на ЖКИ*/
putcommands(0x80); /*курсор ЖКИ переводится на строку 1, позицию 1*/
putchars(thousands);
putchars(hundreds);
putchars(tens);
putchars(ones);
}
/********************************************************************/
/********************************************************************/
7.4.3. Анализ
В предыдущем разделе мы рассказали, как измерить скорость вращения двигателя и отобразить ее в оборотах в минуту. В этом разделе мы замкнем контур обратной связи. Для этого мы сравним мгновенную скорость вращения с опорным значением, чтобы затем скорректировать коэффициент заполнения ШИМ и стабилизировать скорость вращения двигателя на желательном уровне при изменении нагрузки двигателя.
Стабилизируем скорость двигателя на уровне 1600 об/мин. Чтобы сделать это, мы должны определить требуемый коэффициент заполнения ШИМ для 1600 об/мин. Из полученного нами графика (рис. 7.17) мы видим, что для обеспечения скорости вращения приблизительно в 1600 об/мин, необходимо подать на двигатель напряжение в 8 В. При питании двигателя от источника в 12 В соответствующий коэффициент заполнения ШИМ составит 66.7 % (8 В/ 12 В).
Чтобы достичь коэффициента заполнения ШИМ в 66.7%, установим значение периода ШИМ на 256 единиц, а коэффициент заполнения ШИМ на 172 единицы.
Как мы уже указывали при предыдущем обсуждении системы ШИМ, эти значения устанавливаются в регистрах PWPER0 и PWDTY0, соответственно.
Мы используем сигнал управления ШИМ с частотой 976 Гц. Для этого частоту таймера ШИМ, равную 8 МГц, необходимо поделить на 32. При этом мы получим частоту в 250 кГц (период 4 мкс) и используем ее в качестве синхронизирующей для системы ШИМ. Поскольку мы используем период в 256 импульсов, частота управления ШИМ будет равна 976 Гц (период = 4 мкс/импульс×256 импульсов).
Ниже приведен исходный текст программы, позволяющей изменять коэффициент заполнения ШИМ, чтобы стабилизировать скорость на уровне 1600 об/мин.
Эта функция используется начальной установки скорости вращения двигателя.
/********************************************************************/
/*init_PWM(): инициализация модуля ШИМ контроллера 68HC12 */