プロポソースコード

詳細はこちらをご覧ください(YouTube,公式ホームページ)→(準備中)

Compiler:XC8

C version:C90



// PIC18F23K22 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1H #pragma  config FOSC = INTIO67   // Oscillator Selection bits (Internal oscillator block) #pragma  config PLLCFG = OFF     // 4X PLL Enable (Oscillator used directly) #pragma  config PRICLKEN = ON    // Primary clock enable bit (Primary clock enabled) #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 PWRTEN = ON      // Power-up Timer Enable bit (Power up timer enabled) #pragma  config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled)) #pragma  config BORV = 190       // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)

// CONFIG2H #pragma  config WDTEN = OFF      // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.) #pragma  config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H #pragma  config CCP2MX = PORTC1  // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1) #pragma  config PBADEN = ON      // PORTB A/D Enable bit (PORTB<5:0> pins are configured as analog input channels on Reset) #pragma  config CCP3MX = PORTB5  // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5) #pragma  config HFOFST = OFF     // HFINTOSC Fast Start-up (HFINTOSC output and ready status are delayed by the oscillator stable status) #pragma  config T3CMX = PORTC0   // Timer3 Clock input mux bit (T3CKI is on RC0) #pragma  config P2BMX = PORTB5   // ECCP2 B output mux bit (P2B is on RB5) #pragma  config MCLRE = INTMCLR  // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled)

// CONFIG4L #pragma  config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset) #pragma  config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1) #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 (000200-000FFFh) not code-protected) #pragma  config CP1 = OFF        // Code Protection Block 1 (Block 1 (001000-001FFFh) not code-protected)

// CONFIG5H #pragma  config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0001FFh) 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 (000200-000FFFh) not write-protected) #pragma  config WRT1 = OFF       // Write Protection Block 1 (Block 1 (001000-001FFFh) 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-0001FFh) 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 (000200-000FFFh) not protected from table reads executed in other blocks) #pragma  config EBTR1 = OFF      // Table Read Protection Block 1 (Block 1 (001000-001FFFh) not protected from table reads executed in other blocks)

// CONFIG7H #pragma  config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) 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.
 #include  <xc.h> #define  _XTAL_FREQ 64000000

int wait = 1;
char ReadData1[5];       //受信データ格納先
int ReadCount1 = 0;      //受信バイト数カウント
int ReadError1 = 0;      //受信エラーフラグ
int ReadErrorCount1 = 0; //連続受信エラー回数
int cal_center[4];        //キャリブレーション
int speed;
int speed_max = 127;    //127以下
float motion_range = 30;  //サーボの可動域の半分(度)0?90 要調整
float motion_ratio;       //(サーボの可動域 × 1000) ÷ ジョイスティックの可動域
int ang;                //サーボの角度

void __interrupt () Interrupt();
void PICSetup();
void SerialSetup();
void TimerSetup();
void InterruptSetup();
void JoystickSetup();
/*unsigned*/ int adconv(int);
void SerialWrite1(int,int,int,int,int);

int main(){
   unsigned int num;
   PICSetup();
   SerialSetup();
   TimerSetup();                          //一時的後で消す!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
   InterruptSetup();
   JoystickSetup();
   motion_ratio = (motion_range*2)/1024;
   while(1){
       if(!PORTCbits.RC0){              //キャリブレーション
           __delay_ms(100);            //チャタリング防止
           while(!PORTCbits.RC0);      //指を放すまで待つ
           __delay_ms(500);            //チャタリング防止
           cal_center[0] = adconv(0);  //縦
           cal_center[1] = adconv(1);  //横
       }
       if(!PORTCbits.RC1){              //キャリブレーション
           __delay_ms(100);            //チャタリング防止
           while(!PORTCbits.RC0);      //指を放すまで待つ
           __delay_ms(500);            //チャタリング防止
           cal_center[2] = adconv(2);  //縦
           cal_center[3] = adconv(3);  //横
       }
       RC1IE = 1;           //受信割り込み許可
       SerialWrite1(speed,ang,0,0,127);
       //SerialWrite1(adconv(0)/4,adconv(1)/4,adconv(2)/4,adconv(3)/4,0);
       __delay_ms(20);     //タイムアウトまで待つ
       RC1IE = 0;          //受信割り込み禁止
       if(ReadError1 == 1 || !(ReadCount1 == 4)){      //受信エラーがある、もしくは受信データ数がおかしかったら
           ReadError1 = 0;                             //エラーフラグをリセット
           ReadErrorCount1++;                          //連続受信エラー回数
       }else{
           //データ入力
           ReadErrorCount1 = 0;                        //連続受信エラー回数リセット
       }
       ReadCount1 = 0;         //受信回数リセット
       wait = 1;               //待機状態にする
       speed = (adconv(2) - cal_center[2])/4;  //8bit符号付き(-127?128)に変換
       if(speed > -5 && speed < 5){        //speedの絶対値が5未満のときは0とみなす
           speed = 0;
       }
       if(speed > speed_max){             //最大より大きな値の場合
           speed = speed_max;
       }
       if(speed < speed_max*(-1)){
           speed = speed_max*(-1);
       }
       ang = (adconv(1) - cal_center[1])/4;
       if(ang > 125){
           ang = 125;
       }
       if(ang < -125){
           ang = -125;
       }
       while(wait);            //待機
//          __delay_ms(80); //一時的なもの!必ず消すこと!!!!!!!!!!!!!!!!!!!!
   }
}

void __interrupt () Interrupt(){
   GIE = 0;

   if(T0IF == 1){
       wait = 0;           //待機解除
       TMR0 = 59286;               //タイマー0レジスタの初期化 100msで割り込み
   }
   
   if( FERR1 || OERR1 ){               //uartエラー処理
   	CREN1   =   0;
   	NOP();
   	CREN1   =   1;
       while(FERR1){
           int trush;
           trush = RCREG1;
       }
       ReadError1 = 1;
   }else if(RC1IF == 1){ 
       if(ReadCount1 <= 4){//受信フラグが立ち、受信した回数が5回以下なら
           ReadData1[ReadCount1] = RCREG1 ;     // レジスタからデータを受信
           ReadCount1++;
       }else{
           int trush;
           trush = RCREG1;
           ReadError1 = 1;
       }
   }
   
   
   T0IF = 0;                 //フラグをリセット
   RC1IF = 0;
   GIE = 1;
}

void PICSetup(){
   OSCCON = 0b01110000;    //16MHz内部クロック使用
   OSCTUNEbits.PLLEN = 1;  //内部クロックをPLLで4逓倍 64MHz

   ANSELA = 0b00001111;    //AN0(2ピン)有効化
//    ANSELA = 0;  //一時的なもの!必ず消すこと!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   ANSELB = 0b00000000;
   ANSELC = 0b00000000;
   TRISA  = 0b00001111;
   TRISB  = 0b00000000;
   TRISC  = 0b10000011;
//    TRISC = 0;  //一時的なもの!必ず消すこと!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   LATA   = 0b00000000;
   LATB   = 0b00000000;
   LATC   = 0b00000000;
   
   ADCON0 = 0b00000001;    //AN0から読み込む アナログ変換有効
   ADCON1 = 0b00000000;    //リファレンス電圧をVDDにする
   ADCON2 = 0b10101001;
   __delay_us(8);
   
}

void SerialSetup(){
   TXSTA1   = 0b00100100;
   RCSTA1   = 0b10010000;
   BAUDCON1 = 0b00001000;
   SPBRG1   = 0b10001010;      //34 115200
   SPBRGH1  = 0b00000000;
   CREN1    = 1;   
}

void TimerSetup(){
   T0CON = 0b10000111;         //タイマー0有効 16μsで1カウント
   TMR0 = 59286;               //タイマー0レジスタの初期化 100msで割り込み
}

void InterruptSetup(){
   GIE = 1;                    //割り込み許可
   PEIE = 1;                   //周辺機器の割り込み許可 
   
   TMR0IF = 0;                 //タイマー0フラグ初期化
   TMR0IE = 1;                 //タイマー0割り込み許可
   
   RC1IF = 0;                  //uart1フラグ初期化
}

void JoystickSetup(){
   cal_center[0] = adconv(0);
   cal_center[1] = adconv(1);
   cal_center[2] = adconv(2);
   cal_center[3] = adconv(3);
}
/*unsigned*/ int adconv(int num){
   /*unsigned*/ int voltage;
   ADCON0 = (num << 2) | 1;
   GO_nDONE = 1;   //AD変換開始
   while(GO_nDONE);
   voltage = ADRESH;
   voltage = (voltage << 8) | ADRESL;
   
   return voltage;
}

void SerialWrite1(int data0,int data1,int data2,int data3,int data4){
   signed char WriteData1[5]; 
   WriteData1[0] = (signed char)data0;
   WriteData1[1] = (signed char)data1;
   WriteData1[2] = (signed char)data2;
   WriteData1[3] = (signed char)data3;
   WriteData1[4] = (signed char)data4;
   
   int i;
   for (i = 0;i <= 4;i++){         //data0からdata4まで順番に送信
       while(TX1IF == 0);          //送信可能になるまで待つ
       TXREG1 = WriteData1[i];      //iバイト目を送信
//        __delay_ms(5);
   }
   /*    while(TX1IF == 0);   //送信可能になるまで待つ
   TXREG1 = data0;      //0バイト目を送信
   __delay_us(1500);
   while(TX1IF == 0);   //送信可能になるまで待つ
   TXREG1 = data1;      //1バイト目を送信
   __delay_us(1500);
   while(TX1IF == 0);   //送信可能になるまで待つ
   TXREG1 = data2;      //2バイト目を送信
   __delay_us(1500);
   while(TX1IF == 0);   //送信可能になるまで待つ
   TXREG1 = data3;      //3バイト目を送信
   __delay_us(1500);
   while(TX1IF == 0);   //送信可能になるまで待つ
   TXREG1 = data4;      //4バイト目を送信*/
}

この記事が気に入ったらサポートをしてみませんか?