/* Логика пульта и индикации. cpu_timer1_isr_PULT выбирается * только для dsk_EPLT; для нагрузки работает обработчик из measure.c. * Lonely относится к активности обмена, не к задержке пуска СИФУ. * Не смешивать функции двух режимов при изменении общего таймера. */ #include "DSP2833x_Device.h" // DSP2833x Headerfile Include File #include "DSP2833x_SWPrioritizedIsrLevels.h" #include "RS485.h" #include "message.h" #include "filter_bat2.h" #include "measure.h" #include "package.h" #include "pulto.h" #include "kanal.h" #include "peripher.h" unsigned long isMask; int isNumb; int quaLamp = 6; unsigned long Lonely=0; void what_is() { static unsigned int count_blink; static int numb=0; if(++count_blink >= BLINK_TIME) { count_blink=0; numb++; if(numb==10) numb=0; isNumb = numb*1000 + numb*100 + numb*10 +numb; if(isMask) isMask = 0; else isMask = 0xFFFFFFFF; } } interrupt void cpu_timer1_isr_PULT(void) { static int cownt=0,count_bright; unsigned int light=0, i; unsigned int Alone = 20*READY_FREQ; static unsigned int test_lamp_hold_ticks = 0; // Считает длительность непрерывного нажатия GPIO26 в тиках READY_FREQ; насыщение на пороге исключает переполнение при долгом удержании. EALLOW; CpuTimer1.InterruptCount++; IER &= (MINT13 & ~M_INT13); // Сохраняет только ранее разрешённые источники по таблице TI и запрещает повторный Timer1, чтобы передача DATA/CLOCK завершилась без вложенного вызова. EINT; EDIS; // This is needed to disable write to EALLOW protected registers if(!cReset) ServiceDog(); if(++CanPowse >= CANPOWSE) { CanPowse = 0; CanGO = 1; } toggle_ONLINE(); toggle_RES_OUT_1(); // Формирует на резервном выходе 1 меандр с частотой READY_FREQ/2 (500 Гц) для контроля работы таймера пульта. toggle_RES_OUT_2(); // Дублирует переключения таймера на резервном выходе 2 с частотой READY_FREQ/2 (500 Гц) для контроля активности пульта. if(++Lonely > Alone) Lonely = Alone; if(++count_bright >= maximum_bright) count_bright = 0 ; for(i=0; i2) cownt=0; if(GpioDataRegs.GPADAT.bit.GPIO26) // Единица GPIO26 означает нажатие TESTLAMP, как и бит 4 Inputs; таймер измеряет удержание независимо от загрузки main. { // Накапливает время текущего нажатия перед включением местного теста ламп. if(test_lamp_hold_ticks < 2U * (unsigned int)READY_FREQ) // Две секунды при частоте READY_FREQ Гц соответствуют 2000 тикам текущего таймера 1000 Гц. test_lamp_hold_ticks++; // Добавляет один период таймера (1 мс); после достижения порога счётчик сохраняет значение до отпускания. } // Завершает обработку удерживаемой кнопки. else test_lamp_hold_ticks = 0; // При отпускании обнуляет время, чтобы отдельные короткие нажатия не складывались в длинное. bTestLamp = (test_lamp_hold_ticks >= 2U * (unsigned int)READY_FREQ); // Включает местный тест после 2 с удержания и выключает при отпускании; короткое нажатие остаётся сигналом сброса для основного контроллера. if(cTestLamp|bTestLamp) { what_is(); if(cownt == 0) kanal_Send(0,isNumb,4); if(cownt == 1) kanal_Send(1,isNumb,4); kanal_Send(2,isMask,0); if(cownt == 2) kanal_Send(3,isMask,0); } else if(cLiteFire) { if(cownt == 0) kanal_Send(0,8888,1); if(cownt == 1) kanal_Send(1,8888,1); kanal_Send(2,0xFFFF & light,0); if(cownt == 2) kanal_Send(3,0xFFFF,0); } else if((Lonely >= Alone)) { if(cownt == 0) kanal_Send(0,0,0); if(cownt == 1) kanal_Send(1,0,0); kanal_Send(2,0,0); if(cownt == 2) kanal_Send(3,0,0); } else { #if OBOROT == STRAIGHT if(cownt == 0) kanal_Send(0,modbus[0],1); if(cownt == 1) kanal_Send(1,modbus[1],1); #else if(cownt == 0) kanal_Send(0,modbus[1],1); if(cownt == 1) kanal_Send(1,modbus[0],1); #endif kanal_Send(2,modbus[2] & light,0); if(cownt == 2) kanal_Send(3,modbus[3],0); } }