ron4256と申します。よろしくお願い致します。
現在、PICの18F24K20を使用してPID制御のプログラムを作って一応は動作させるところまで出来たのですが、
動作中に突然PICが止まります。
入力で接続しているのはAD変換用にポテンショメータとPIC12F1822からエンコーダの値をシリアル通信での取得のみです。
(シリアル通信で取得した値は利用していません)
出力はPID出力確認用でPORTBの0、1とPORTAの1、2、3にLEDを接続しています。
PIDの処理を追加してから問題が発生したので、ADとシリアル通信に絞って動作させたときは問題がありませんでした。
また、PIDの処理はArduino microで実装した時に問題がなかったので、計算値が問題なのか?ということまで考えたのですが、
お手上げ状態でここへ来た次第です。
前置きを長々と書きましたが、止まる原因が分からないため問題が起こる箇所の指摘等を頂きたいと考えています。
よろしくお願い致します。
PICのMPLAB X IDEでコンパイラはXC8を使用しています。
以下ソースコードです。
#include <xc.h> #include<stdlib.h> #include<math.h> // CONFIG1H #pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled) #pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled) // CONFIG2L #pragma config PWRT = ON // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled)) #pragma config BORV = 18 // Brown Out Reset Voltage bits (VBOR set to 1.8 V nominal) // CONFIG2H #pragma config WDTEN = OFF // Watchdog Timer Enable bit (WDT is always enabled. SWDTEN bit has no effect) // CONFIG3H #pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1) #pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset) #pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation) #pragma config HFOFST = OFF // HFINTOSC Fast Start-up (HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.) #pragma config MCLRE = OFF // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled) // CONFIG4L #pragma config STVREN = OFF// Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset) #pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled) #pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode)) // CONFIG5L #pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected) #pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected) // CONFIG5H #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected) #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected) // CONFIG6L #pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected) #pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected) // CONFIG6H #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected) #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected) #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected) // CONFIG7L #pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks) #pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks) // CONFIG7H #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #define _XTAL_FREQ 64000000 int enc_data = 0; unsigned char error_flag = 0; int AD_data = 0; // void interrupt Data_acquisition(void) { RCIE = 0; PEIE = 0; GIE = 0; error_flag = 0; //serial interrupt if(RCIF == 1) { if(RCSTAbits.FERR || RCSTAbits.OERR){ if(RCSTAbits.FERR == 1){ error_flag = 0xFE; } else if(RCSTAbits.OERR == 1){ error_flag = 0xFF; } RCSTA = 0; RCSTA = 0x90; } else{ enc_data = RCREG;//encoder data if(enc_data > 1000){ enc_data = 0; } } } RCIE = 1; PEIE = 1; GIE = 1; } void main(void) { int i = 0; float P = 4.0; float I = 1.0; float D = 1.0; int target = 512; //difference float diff1 = 0; float diff2 = 0; float diff3 = 0; float PID_calc = 0; int motor_on = 0; int motor_off = 0; unsigned char flag_p = 0; unsigned char flag_n = 0; //oscirator setting OSCCON = 0b01110000; //inter osc 64Mhz maybe OSCTUNEbits.PLLEN = 1; //PORTA setting ANSEL = 0x01; //PORTA 0pin analog TRISA = 0x01; //RA0 AD convert PORTA = 0; //AD setting ADCON0 = 0x01; //AN0 a/d ADON set ADCON1 = 0x00; // ADCON2 = 0b00111110;; //Fosc/64 ADCON2bits.ADFM = 1; //0 left justfited/ 1 right justfited //PORTB setting ANSELH = 0x00; //PORTB I/O digital TRISB = 0x00; PORTB = 0; //PORTC setting TRISC = 0x80; // RC7 input(rx)) PORTC = 0x00; //Serial setting TXSTA = 0x24; // TXEN = 1, BRGH = 1 RCSTA = 0x90; // SPEN = 1, CREN = 1 BAUDCON = 0x08; // 16bitmode // 16Bitmode SPBRG = 0x40; // 19.2k SPBRGH = 0x03; // 19.2k RCIF = 0; RCIE = 1; PEIE = 1; GIE = 1; while(1){ ADCON0bits.GO = 1; while(ADCON0bits.GO); AD_data = ADRESH * 256 + ADRESL; ///////// if (target > AD_data){ flag_p = 1; flag_n = 0; diff1 = target - AD_data; } else if (target < AD_data){ flag_p = 0; flag_n = 1; diff1 = AD_data - target; } else if(target == AD_data){ flag_p = 1; flag_n = 0; diff1 = 1; } PID_calc = P * (diff1 - diff2) + I * diff1 + D * (diff1 - 2.0 * diff2 + diff3); //float control = P * diff1; // return the distance for this axis: PID_calc = 100 * PID_calc / target; if (PID_calc > 100){ PID_calc = 99; } if (PID_calc< -100){ PID_calc = -99; } diff3 = diff2; diff2 = diff1; ////// //duty width on motor_on = abs(PID_calc); //duty width off motor_off = 100 - motor_on; if (flag_p == 1){ RA1 = 1; i = 0; for (i = 0; i < 100; i = i + 1){ if (motor_on > 0){ //select motor output port RB0 = 1; RB1 = 0; //select delay timer motor_on -= 1; } else if(motor_off > 0){ RB0 = 0; RB1 = 0; motor_off -= 1; } } RA1 = 0; } else if (flag_n == 1){ RA2 = 1; i = 0; for (i = 0; i < 100; i = i + 1){ if (motor_on > 0){ RB0 = 0; RB1 = 1; motor_on -= 1; } else if(motor_off > 0){ RB0 = 0; RB1 = 0; motor_off -= 1; } } RA2 = 0; } //maybe default else if(flag_n == 0 && flag_p == 0){ motor_on = 0; motor_off = 0; diff1 = 0; diff2 = 0; diff3 = 0; RA3 = 1; } RA3 = 0; } return; }
回答2件
あなたの回答
tips
プレビュー