#include // ******* Программа управления зажиганием CDI. V 4.2 ******* // ******* Лашманов А. (alash) 05.2007. ******* unsigned int rtcbw; unsigned int TimeToUp; unsigned int CompTime; unsigned int CompTimeK; unsigned int oldTime; unsigned int m; m1; unsigned int mAngle; unsigned int mAngle3; unsigned int mAngle6; const unsigned int LowRPM = 0xf800; unsigned int time1; unsigned int time2; signed long delta; unsigned long CompTimeLong; char InpP; char RgINP; REGISTER; char P1cutt; unsigned char k; unsigned char CompTH0; unsigned char CompTL0; //**************************************************************** void main(void) //********************* Main program body ************************ { //*********** Начальная установка переменных ******** RgINP = 10; CompTime = 0; oldTime = LowRPM; //*********** Начальная установка режима таймера "0" ******** TMOD = 0x11; TCON = 0x00; TL0 = 0x00; TH0 = 0x00; CompTH0 = 0xf8; CompTL0 = 0; P3 = 0; //*********** Бесконечный цикл, период около 100 мкс ******** while(1) { // Прочитать регистр входов InpP = P1; // Работать: или по спаду или по фронту if ((P1&0x40) != 0 ) InpP = ~InpP; // Секция интегрирования (накопления) входного сигнала // RgINP=25 - criteria if ((InpP & 0x80) !=0 ) { if (++RgINP > 20) RgINP = 20; if (RgINP == 14) RgINP = 25; } else { if (--RgINP < 10) RgINP = 10 ; if (RgINP == 16) { RgINP=7; P3=0;}; }; //===================== // Секция сравнения данных таймера с заданным значением. // Включение и выключение выходного сигнала. // Контроль переполнения таймера "Частота // входного сигнала ниже 23 Гц (1220 об/мин). if (TH0 >= 0xf8) { TCON = 0;} //Останов таймера else { if (TH0 > CompTH0) { P3 |= 0x01;} else { if (TH0 == CompTH0) if (TL0 > CompTL0) P3|=0x01;}; }; //===================== // Секция вспомогательного (контрольного) выхода P3.7 //if ((TH0 & 0x80) == 0x80) P3 |= 0x80; //else P3 &= 0x7f; //===================== // Секция операций при обнаружении сигнала входного датчика. // Вычисление и коррекция времени опережения зажигания. if (RgINP == 25) // То есть выполняется лишь однократно. { TCON = 0; // Остановить таймер k = TL0; rtcbw = TH0; TL0 = 0x00; TH0 = 0x00; TCON = 0x10; // Запустить таймер P3 |= 0x03; // Выход ВКЛ, оба бита rtcbw <<= 8; rtcbw += k; // Выбор кубатуры и назнач. коэфф. 18 16 14 12 тыс.об. // из расчета сопряжения с // макс.углом mAngle = (1/8-1/64) == 39 градусов. P1cutt = ~P1; P1cutt &= 0x30; if (P1cutt == 0x00) { time1 = 3333; time2 = 5925; }; if (P1cutt == 0x10) { time1 = 3750; time2 = 6666; }; if (P1cutt == 0x20) { time1 = 4286; time2 = 7619; }; if (P1cutt == 0x30) { time1 = 5000; time2 = 8888; }; // Секция арифметико-логического предсказания и коррекции delta = 0; delta += rtcbw; delta -= oldTime; oldTime = rtcbw; // Время до ВМТ из расчета 11,21 градусов (1/32 круга) // предустановки датчика. TimeToUp = rtcbw; TimeToUp >>= 5; TimeToUp += rtcbw; if ( rtcbw <= time1 ) {m=0;} else { if ( rtcbw < time2 ) { m1 = rtcbw; m1 -= time1; m1 >>= 2; }; m = ~P1; m &= 0x000f; m <<= 7; mAngle3 = rtcbw; mAngle3 >>= 3; mAngle6 = rtcbw; mAngle6 >>= 6; mAngle = mAngle3 + mAngle6; if (m > mAngle) m = mAngle ; if (m > m1) m = m1; }; //===== CompTimeLong = TimeToUp ; if (delta > 0) CompTimeLong += delta; CompTimeLong -= m; //======================================================== if (CompTimeLong > LowRPM) // Переполнение, обороты двиг. 1220 низки. {CompTime = LowRPM;} else { CompTime =(int) CompTimeLong;}; CompTimeK = CompTime; CompTL0 = (char) (CompTimeK & 0x00ff); CompTH0 = (char) (CompTimeK >> 8 ); } // После вычислений CompTime несет значение времени до очередного // импульса зажигания. Если CompTime = LowRPM, значит, обороты двигателя // ниже 1220 об/мин и импульсов опережения зажигания не вырабатывается, // зажигание будет синхронно с входным сигналом. } //*** end while *** } //************ End of file **************