Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma config OSC = INTIO67 // внутренний осциллятор
- #pragma config WDT = OFF // сторожевой таймер выключен
- #pragma config LVP = OFF
- #include <p18f4520.h> // подключение заголовочных файлов
- void main () {
- int fuzA[][]={ {-500,-500,-150}.
- {-400,-232,-64},
- {-128,-64,0},
- {-32,0,32},
- {0,64,128},
- {64,232,400},
- {150,500,500} },
- fuzB[][]={ {-20,-20,-8}.
- {-14,8,-2},
- {-6,-3,0},
- {-1,0,1},
- {0,3,6},
- {2,8,14},
- {8,20,20} },
- fuzC[][]={ {-15,-15,-7}.
- {-12,-7,-2},
- {-6,-3,0},
- {-2,0,2},
- {0,3,6},
- {2,7,12},
- {7,15,15} };
- float mA[], mB[], x1, x2, x1_prev, tmp;
- double Hsens, Hfix;
- float numerator, denominator, control;
- x1=0;
- x2=0;
- OSCCON=0b11110011; // выбор осциллятора (внутренний, 8 МГц)
- LATC=0x00;
- TRISC=0b10000000 // 1 бит - PWM output, 6 - TX, 7 – RX USART
- //настройка АЦП
- ADCON1=0b00001110; // настройка выводов и опорного напряжения
- ADCON2=0b10111101; // правое выравнивание, Fosc/16 и 20 TAD
- ADCON0=0b00000001; // выбор канала AN0 и включение АЦП
- //настройка ШИП
- PR2=0x3F // установка периода PWM
- T2CON=0b00000100; // включение и настройка TIMER2
- CCP2CON=0b00001100; // включение и настройка модуля CCP2
- //настройка USART
- SPBRG=D’12’; // 9600 бод/с
- BAUDCON=0b01000001; // настройка
- TXSTA=0b10110010; // cинхронный режим, master, передача
- RCSTA=0b10000000; // одиночный прием
- while (1) {
- ADCON0bits.GO=1; // запуск преобразования
- while(ADCON0bits.GO); // ожидание конца преобразования
- // чтение результата преобразования и выражение его в метрах
- Hsens=6.636*(ADRESH*256+ADRESL);
- RCSTAbits.SREN=1; // разрешение приема
- while(!PIR1bits.RCIF); // ожидание конца приема старшего бита
- Hfix=RCREG;
- Hfix<<=8;
- RCSTAbits.SREN=1; // разрешение приема
- while(!PIR1bits.RCIF); // ожидание конца приема младшего бита
- Hfix+=RCREG;
- x1_prev = x1;
- x1 = Hfix-Hsens; // расчет ошибки по высоте
- x2 = x1 – x1_prev; // расчет производной ошибки по высоте
- //проверка на вхождение x1 и x2 в пределы значений входов регулятора
- if (x1>500) x1=500;
- if (x1<-500) x1=-500;
- if (x2>20) x1=20;
- if (x2<-20) x1=-20;
- // поиск степеней принадлежности x1 и x2 к термам соответствующих ЛП
- for (i=0;i!=7;i++) {
- if (fuzA[i][0] < x1 < fuzA[i][2])
- if (fuzA[i][0] < x1 < fuzA[i][1])
- mA[i] = (x1-fuzA[i][0])/(fuzA[i][1]-fuzA[i][0]);
- else
- mA[i] = (fuzA[i][2]-x1)/(fuzA[i][2]-fuzA[i][1]);
- if (fuzB[i][0] < x2 < fuzB[i][2])
- if (fuzB[i][0] < x2 < fuzB[i][1])
- mB[i] = (x2-fuzB[i][0])/(fuzB[i][1]-fuzB[i][0]);
- else
- mB[i] = (fuzB[i][2]-x2)/(fuzB[i][2]-fuzB[i][1]);
- };
- numerator = 0;
- denominator = 0;
- /* применение соответствующих правил, определение степеней активности. дефуззификация по среднему центру. */
- if (mA[0])
- for (k=0;k!=7;k++) {
- switch (k) {
- case 0: case 1: case 2:
- if (mB[k])
- {tmp = mA[0]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[0][1]};
- case 3: case 4:
- if (mB[k])
- {tmp = mA[0]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[1][1]};
- case 5:
- if (mB[k])
- {tmp = mA[0]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[2][1]};
- case 6:
- if (mB[k])
- {tmp = mA[0]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[3][1]};
- };
- };
- if (mA[1])
- for (k=0;k!=7;k++) {
- switch (k) {
- case 0: case 1:
- if (mB[k])
- {tmp = mA[1]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[0][1]};
- case 2: case 3:
- if (mB[k])
- {tmp = mA[1]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[1][1]};
- case 4:
- if (mB[k])
- {tmp = mA[1]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[2][1]};
- case 5:
- if (mB[k])
- {tmp = mA[1]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[3][1]};
- case 6:
- if (mB[k])
- {tmp = mA[1]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[4][1]};
- };
- };
- if (mA[2])
- for (k=0;k!=7;k++) {
- switch (k) {
- case 0:
- if (mB[k])
- {tmp = mA[2]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[0][1]};
- case 1: case 2:
- if (mB[k])
- {tmp = mA[2]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[1][1]};
- case 3:
- if (mB[k])
- {tmp = mA[2]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[2][1]};
- case 4:
- if (mB[k])
- {tmp = mA[2]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[3][1]};
- case 5:
- if (mB[k])
- {tmp = mA[2]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[4][1]};
- case 6:
- if (mB[k])
- {tmp = mA[2]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[5][1]};
- };
- };
- if (mA[3])
- for (k=0;k!=7;k++) {
- switch (k) {
- case 0: case 1:
- if (mB[k])
- {tmp = mA[3]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[1][1]};
- case 2:
- if (mB[k])
- {tmp = mA[3]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[2][1]};
- case 3:
- if (mB[k])
- {tmp = mA[3]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[3][1]};
- case 4:
- if (mB[k])
- {tmp = mA[3]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[4][1]};
- case 5: case 6:
- if (mB[k])
- {tmp = mA[3]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[5][1]};
- };
- };
- if (mA[4])
- for (k=0;k!=7;k++) {
- switch (k) {
- case 0:
- if (mB[k])
- {tmp = mA[4]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[1][1]};
- case 1:
- if (mB[k])
- {tmp = mA[4]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[2][1]};
- case 2:
- if (mB[k])
- {tmp = mA[4]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[3][1]};
- case 3:
- if (mB[k])
- {tmp = mA[4]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[4][1]};
- case 4: case 5:
- if (mB[k])
- {tmp = mA[4]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[5][1]};
- case 6:
- if (mB[k])
- {tmp = mA[4]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[6][1]};
- };
- };
- if (mA[5])
- for (k=0;k!=7;k++) {
- switch (k) {
- case 0:
- if (mB[k])
- {tmp = mA[5]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[2][1]};
- case 1:
- if (mB[k])
- {tmp = mA[5]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[3][1]};
- case 2:
- if (mB[k])
- {tmp = mA[5]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[4][1]};
- case 3: case 4:
- if (mB[k])
- {tmp = mA[5]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[5][1]};
- case 5: case 6:
- if (mB[k])
- {tmp = mA[5]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[6][1]};
- };
- };
- if (mA[6])
- for (k=0;k!=7;k++) {
- switch (k) {
- case 0:
- if (mB[k])
- {tmp = mA[6]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[3][1]};
- case 1:
- if (mB[k])
- {tmp = mA[6]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[4][1]};
- case 2: case 3:
- if (mB[k])
- {tmp = mA[6]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[5][1]};
- case 4: case 5: case 6:
- if (mB[k])
- {tmp = mA[6]*mB[k];
- denominator += tmp;
- numerator += tmp*fuzC[6][1]};
- };
- };
- // расчет выходного значения. передача его в ШИП и в передатчик USART
- control = numerator/denominator;
- CCPR2L = control;
- TXREG = control;
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement