Ale » 11 апр 2012, 09:29
Подскажите как сделать лучше
Я бы завел еще одно прерывание, по таймеру, в котором устанавливал флаг срабатывания таймера. И уже в основном цикле программы проверял этот флаг и регулирование бы делал только по флагу от таймера. Тогда регулирование пойдет через относительно равные промежутки времени, скажем, с частотой 1 КГц.
Вычисление нового значения для регулятора делать тоже не в прерывании, а непосредственно перед регулированием. Только тут надо ввести некую буферизацию, сто бы быть уверенным, что в момент вычисления не произойдет изменение значения энкодера
char TimerFlag;
int encod1, tmp_encod1;
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// тут проводим считывание с энкодера и вычисление нового значения в переменную
encod1
}
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TimerFlag=1; // устанавливаем флаг и вываливаемся из перывания
}
void main(
void)
{
if (TimerFlag>0)
{
TimerFlag=0; // сбрасываем флаг
cli(); // запрещаем прерывания
tmp_encod1 = encod1 // копируем данные энкодера для дальнейшего безопасного использования
sei(); // разрешаем перывания
// и дальше вычисляем все что надо для ПИД (делим, к примеру, на 5 величину tmp_encod1) и проводим регулирование
}
}
(Добавление)
естественно в процедуре main все делается внутри бесконечного цикла
void main(void)
{
while (1)
{
if (TimerFlag>0)
{
....