MB89 (961746), страница 2
Текст из файла (страница 2)
Регистры выбора ШИМ1 и ШИМ2 (PWS1n + PWS2n) могут устанавливать выход контроллера ШД в состояние логического нуля, логической единицы, выхода импульсов ШИМ либо в высокоимпедансное состояние.
Название бита | Назначение | |||||||||||||||||||||
Бит 7,6 | Не используются |
| ||||||||||||||||||||
Биты 5..3 | P2..P0 Биты режима выхода P | Состояние выходов PWM1Pn определяется в соответствии с таблицей:
| ||||||||||||||||||||
Биты 2..0 | M2..M0 Биты режима выхода M | Состояние выходов PWM1Mn определяется в соответствии с таблицей:
|
Рис. 13 Назначение битов регистра выбора ШИМ
Название бита | Назначение | |||||||||||||||||||||
Бит 15 | Не используется |
| ||||||||||||||||||||
Бит 14 | BS | Этот бит предназначен для синхронизации настроек выходов ШИМ. Изменения в двух регистрах сравнения и двух регистрах выбора не вступят в силу до тех пор, пока бит BS установлен в «1». | ||||||||||||||||||||
Биты 13..11 | P2..P0 | Состояние выходов PWM2Pn определяется в соответствии с таблицей:
| ||||||||||||||||||||
Биты 10..8 | M2..M0 | Состояние выходов PWM2Mn определяется в соответствии с таблицей:
|
Рис. 15 Назначение битов регистра выбора ШИМ2
3 Примеры программ
В этом разделе приводятся и поясняются программные коды для управления стрелочным индикатором
3.1Таблица для организации микрошагов
************************************************************************************/
/* Этот программный пример предлагается «as is» и может быть изменён. Fujitsu */
/* Microelectronics не несёт никакой ответственности за возможные ошибки и */
/* вероятную несовместимость ни в каких случаях */
/* © Fujitsu Microelectronics Europe GmbH */
/* Таблица sin\cos для микрошагового режима */
unsigned char const SMC_TAB_CS[129]={
0, 3, 6, 9, 13, 16, 19, 22,
25, 28, 31, 34, 37, 41, 44, 47,
50, 53, 56, 59, 62, 65, 68, 71,
74, 77, 80, 83, 86, 89, 92, 95,
98,100,103,106,109,112,115,117,
120,123,126,128,131,134,136,139,
142,144,147,149,152,154,157,159,
162,164,167,169,171,174,176,178,
180,183,185,187,189,191,193,195,
197,199,201,203,205,207,208,210,
212,214,215,217,219,220,222,223,
225,226,228,229,231,232,233,234,
236,237,238,239,240,241,242,243,
244,245,246,247,247,248,249,249,
250,251,251,252,252,253,253,253,
254,254,254,255,255,255,255,255,
255 };
/*-------------------------------------------------------------------*/
/* Таблица для управления квадрантами */
unsigned char const smc_quad_a[4]={0x02, 0x10, 0x10, 0x02};
unsigned char const smc_quad_b[4]={0x50, 0x50, 0x42, 0x42};
/*-------------------------------------------------------------------*/
void smc_out(int ustp) {
int q,d,smc_a,smc_b; /* вспомогательные переменные*/
q=((ustp>>8) & 3); /* нормализуем диапазон разбиения до 1024 точек на полупериод */
d=((ustp>>1) & 127); /* сделаем нормализацию внутреннего разбиения до 512 точек на
полупериод, таким образом, бит 0 в ustp не влияет! */
smc_a=SMC_TAB_CS[d]; /* загрузим компонент sin */
smc_b=SMC_TAB_CS[128-d]; /* загрузим компонент cos
обратите внимание, что таблица увеличена и
используется с «обратной стороны» */
if ((q & 1)==1) { /* определим направление движения */
PWC10=smc_a; /* установим значение sin для катушки A */
PWC20=smc_b; /* установим значение cos для катушки B */
}
else { /* при вращении в обратную сторону сменим знак */
PWC10=smc_b; /* установим значение cos для катушки A */
PWC20=smc_a; /* установим значение sin для катушки B */
}
PWC0=0xE8; /* инициализация системы */
PWS10=smc_quad_a[q]; /* квадрантное управление катушкой A */
PWS20=smc_quad_b[q]; /* квадрантное управление катушкой B */
}
3.2 Фильтр низкой частоты
Эта подпрограмма организована таким образом, чтобы обеспечить оптимальный баланс между требованиями минимизации используемой памяти и хорошей читаемостью.
Ниже приведен пример программы ФНЧ второго порядка для управления шаговым двигателем.
/* Этот программный пример предлагается «as is» и может быть изменён. Fujitsu */
/* Microelectronics не несёт никакой ответственности за возможные ошибки и */
/* вероятную несовместимость ни в каких случаях */
/* © Fujitsu Microelectronics Europe GmbH */
void smc__lpf(void) { /* эти вычисления занимают небольшую часть от миллисекунды */
smc_old=smc_new; /* сохраним значение smc_old */
/* ФНЧ первого порядка */
*((int *)&smc_clc1+1)=smc_inp; /* нормализация входного значения */
smc_clc1=(smc_clc1>>smc_dn);
smc_clc2=(smc_pt1-(smc_pt1>>smc_dn));
smc_pt1=smc_clc2+smc_clc1;
/* ФНЧ второго порядка */
smc_clc2=(smc_pt2-(smc_pt2>>smc_dn));
smc_pt2=smc_clc2+(smc_pt1>>smc_dn);
smc_new=*((int *)&smc_pt2+1); /* новое выходное значение */
}
Данный ФНЧ 2-го порядка работает следующим образом:
Таким образом, нам нужно использовать простые ограничители скорости и ускорения в дополнение к ФНЧ второго порядка.
3.3 Пример подпрограммы обработки прерываний
Этот код должен исполняться в подпрограмме обработчика прерываний, вызываемой каждые несколько миллисекунд.
/* Этот программный пример предлагается «as is» и может быть изменён. Fujitsu */
/* Microelectronics не несёт никакой ответственности за возможные ошибки и */
/* вероятную несовместимость ни в каких случаях */
/* © Fujitsu Microelectronics Europe GmbH */
__interrupt void irq_stepper_srv (void) { /* «фоновая» задача контроля шагового двигателя*/
smc_out(smc_new); /* для уменьшения джиттера сначала выведем значение*/
smc__ido(); /* потом вычислим значение для следующего такта */
smc_avclip();
TMCSR1_UF = 0; /* сброс флага */
}
3.4 Ограничение до требуемых физических значений
/* Этот программный пример предлагается «as is» и может быть изменён. Fujitsu */
/* Microelectronics не несёт никакой ответственности за возможные ошибки и */
/* вероятную несовместимость ни в каких случаях */
/* © Fujitsu Microelectronics Europe GmbH */
void smc_avclip(void) { /* ограничение до требуемых физических значений */
smc_clc1=(smc_new-smc_old); /* действующее значение скорости */
if ( smc_clc1 < -smc_vmax ) { /* проверка режима движения вперёд */
/* исправление, т.к. скорость превышена */
smc_new=smc_old-smc_vmax; /* установим новую скорость */
smc_clc1=-smc_vmax; /* запомним новую скорость */
*((int *)&smc_pt2+1)=smc_new; /*установим новое выходное значение */
}
if ( smc_clc1 > smc_vmax ) { /* проверка режима обратного движения */
/* исправление, т.к. скорость превышена */
smc_new=smc_old+smc_vmax; /* установим новую скорость */
smc_clc1=smc_vmax; /* запомним новую скорость */
*((int *)&smc_pt2+1)=smc_new; /*установим новое выходное значение */
}
smc_acc=(smc_clc1-smc_velo); /* действующее значение ускорения */
if ( smc_acc < -smc_amax ) { /* проверка режима разгона */
/* исправление, т.к. ускорение превышено */
smc_clc1=smc_velo-smc_amax; /* установим новую скорость */
smc_new=smc_old+smc_clc1; /* пересчитаем выходное значение */
*((int *)&smc_pt2+1)=smc_new; /* установим новое выходное значение */
}
if ( smc_acc > smc_amax ) { /* проверка режима торможения */
/* исправление, т.к. ускорение превышено */
smc_clc1=smc_velo+smc_amax; /* установим новую скорость */
smc_new=smc_old+smc_clc1; /* пересчитаем выходное значение */
*((int *)&smc_pt2+1)=smc_new; /* установим новое выходное значение */
smc_acc =smc_clc1-smc_velo; /* запомним новые значения скорости */
smc_velo=smc_clc1; /* и ускорения для вычислений в след. цикле*/
}