Harmonyの設定

ADC

I2C

TIMER

 

USART

System Services – Interrupts

Pin Diagram

Pin Settings

・コードの編集前に文字コードをShift-Jisに変更します。

・MainボードとSubボードのコードをコンパイラ擬似命令で切り替えます。ポートの設定が異なるのでsys_ports_static.cの以下の部分をコメントアウトしておいて、system_init.cで切り替えます。

 

・System init.cを編集します。

void SYS_Initialize の中にあります。

//
//
/* Initialize System Services */
    SYS_PORTS_Initialize();

#if ROSEN_NUM == 0
    _TRISB10 = 0;
#else
    PLIB_PORTS_RemapInput(PORTS_ID_0, INPUT_FUNC_INT1, INPUT_PIN_RPB10);
#endif

    /*** Interrupt Service Initialization Code ***/
    SYS_INT_Initialize();

#if ROSEN_NUM != 0
    /*Setup the INT_SOURCE_EXTERNAL_1 and Enable it*/
    SYS_INT_VectorPrioritySet(INT_VECTOR_INT1, INT_PRIORITY_LEVEL6);
    SYS_INT_VectorSubprioritySet(INT_VECTOR_INT1, INT_SUBPRIORITY_LEVEL0);
    SYS_INT_ExternalInterruptTriggerSet(INT_EXTERNAL_INT_SOURCE1, INT_EDGE_TRIGGER_FALLING);
    SYS_INT_SourceEnable(INT_SOURCE_EXTERNAL_1);
#endif
ソースファイルの追加

Header Files-Appに  “atc.h”  を追加

atc.h
//
//2022_0903
//
#define TR_COUNT 3      //列車数
#define ROSEN_NUM 0   //路線(ボード)番号
#define BOARD_COUNT 3     //ボード数

#define RX_BYTE 128     //RS232C受信バイト数
#define TX_BYTE 230     //RS232C送信バイト数
#define RX_DATA_BYTE 12 //1列車当たりの受信バイト数
#define TX_DATA_BYTE 12 //1列車当たりの送信バイト数
#define SPEED_MAX 0x3C0      //3C0 timer piriod

//I2C用変数    
DRV_HANDLE hi2c;
DRV_I2C_BUFFER_HANDLE bhi2c;
//USART用変数 
DRV_HANDLE handleUSART0;

bool ext_int_enable;

//16bitのINT型の上位H byte、下位L byte読み込み用共用体

union byte_access {
    int INT; // Int Access

    struct { // byte Access
        unsigned char L;
        unsigned char H;
    } BYTE;
};

//位置情報の構造体

struct PSI_BIT {
    unsigned char KUKAN : 3; /* 区間 Bit 0-2 */
    unsigned char ROSEN : 3; /* 路線 Bit 3-5 */
    unsigned char SOU : 1; /* 相   Bit 6   */
    unsigned char DIR : 1; /* 方向 Bit 7   */
};

struct STATUS_BIT {
    unsigned char CHG : 1; //区間変化
    unsigned char REV : 1; //逆転
    unsigned char SP_MANU : 1; //スピード制御
    unsigned char DUMY : 3; //DUMY
    unsigned char SLOW : 1; //減速
    unsigned char SAFE : 1; //安全
};
//列車の位置情報の構造体

struct st_position {
    //現在位置

    union { /* Position */
        unsigned char BYTE; /* Byte Access */
        struct PSI_BIT BIT; /* Bit  Access */
    } NOW;
    //前の位置

    union { /* Position */
        unsigned char BYTE; /* Byte Access */
        struct PSI_BIT BIT; /* Bit  Access */
    } BEFORE;

    //次の位置

    union { /* Position */
        unsigned char BYTE; /* Byte Access */
        struct PSI_BIT BIT; /* Bit  Access */
    } NEXT;

    //次々の位置

    union { /* Position */
        unsigned char BYTE; /* Byte Access */
        struct PSI_BIT BIT; /* Bit  Access */
    } ANEXT;

    union {
        unsigned char BYTE; /* Byte Access */
        struct STATUS_BIT BIT; /* Bit  Access */
    } STATUS;

    int speed;

    union byte_access speed_cont;

    int speed_err;
    int speed_peak;
    int err_th;

    int mascon;

    unsigned char henka;
    //unsigned char safe;
    union byte_access speed_ret; //読み取りスピード
    union byte_access speed_ret_rx; //読み取りスピード
    union byte_access speed_ret_tx; //読み取りスピード

    unsigned char point;
    unsigned char yard;

    union byte_access speed_rx;

    unsigned char REC_NOW;
    unsigned char REC_NEXT;
    unsigned char REC_BEFORE;
    
    
};


//監視区間設定用の共用体

union scan_port {
    unsigned char BYTE; /* Byte Access */

    struct {
        unsigned char DUMMY : 2; /* Bit 0-1 */
        unsigned char KUKAN : 3; /* Bit 2-4 監視区間*/
        unsigned char DISABLE : 1; /* Bit 5   */
        unsigned char B6 : 1; /* Bit 6   */
    } BIT;

};





unsigned char EnableBit[] = {1, 2, 4, 8, 16, 32, 64, 128};
unsigned int int_counter; //インタラプトカウンタ
unsigned int speed_pw[2]; //スピードパルス幅
struct st_position train[TR_COUNT]; //列車位置情報
struct st_position* train_sou[2];
unsigned char cont_train[2]; //制御する列車番号
unsigned char kukan[2]; //区間
unsigned char kanshi_now[2]; //スピード読み込み用
unsigned char kanshi_before[2]; //スピード読み込み用
union scan_port kanshi; //区間監視用

union byte_access adc_ret; //ADC値
union byte_access debug1; //ADC値
union byte_access debug2; //ADC値

int gnd_adc;

union byte_access gnd_level;

unsigned char rx_data[RX_BYTE];
unsigned char tx_data[TX_BYTE];

unsigned char receive_data; //通信用受信データ
unsigned char send_data; //通信用送信データ
unsigned char comm_data[128]; //通信用メモリ
unsigned int comm_counter; //通信用インタラプトカウンタ
unsigned char board_num; //ボード番号

unsigned char point_req; //ポイントリクエスト
unsigned char yard_req; //ポイントリクエスト

int err_buff[2][16]; 
union byte_access err_avr[2]; 
union byte_access timer_value; 
union byte_access log_1;
union byte_access log_2;
union byte_access osc_trg;
unsigned char chg_disable;
unsigned char same_dir;
unsigned int ext_time;
unsigned char same_dir_mode;
unsigned char inc_interval;
unsigned int ext_pwr[2];
unsigned char section1;
unsigned char section2;
union byte_access int_count1;
union byte_access int_count2;
unsigned char both_off;
int sp_w1;
int sp_w2;

・Souse Files – appに  “lcd.c”  を追加

lcd.c
//
//
//2022_0612  lcd.c

#include "system/common/sys_common.h"
#include "app.h"
#include "system_definitions.h"

#define ADR 0x7C
void LCD_cmd(char);
void LCD_int(void);
void LCD_str(char *);
void LCD_dat(char);
void LCD_hex(char);
void LCD_posyx(char, char);

void BSP_DelayMs(unsigned short);
void BSP_DelayUs(unsigned short);

uint8_t data[5];

//遅延調整用関数(ms)
void BSP_DelayMs(unsigned short milliseconds) {
    unsigned long time;
    time = _CP0_GET_COUNT(); //Read Core Timer
    time += (SYS_CLK_FREQ / 2 / 1000) * milliseconds; //calc the Stop Time
    while ((long) (time - _CP0_GET_COUNT()) > 0) {
    };
}

//遅延調整用関数(μs)
void BSP_DelayUs(unsigned short microseconds) {
    unsigned long time;
    time = _CP0_GET_COUNT(); //Read Core Timer
    time += (SYS_CLK_FREQ / 2 / 1000000) * microseconds; //calc the Stop Time
    while ((long) (time - _CP0_GET_COUNT()) > 0) {
    };
}

void LCD_cmd(char cmd) {
    data[0] = 0x80;
    data[1] = cmd;

    bhi2c = DRV_I2C_Transmit(hi2c, ADR, data, 2, NULL);//I2C送信
    while (DRV_I2C_TransferStatusGet(hi2c, bhi2c) != DRV_I2C_BUFFER_EVENT_COMPLETE); /*I2C完了待ち*/

    
    if (cmd & 0xFC) // LCDのコマンドにより待ち時間が違う
        BSP_DelayUs(60); // 60usec
    else
        BSP_DelayMs(3); // 3msec

}

void LCD_int(void) {
    BSP_DelayMs(100); 

    LCD_cmd(0x38);
    LCD_cmd(0x39);
    LCD_cmd(0x14);
    LCD_cmd(0x73); //7A(forAQM1602)
    LCD_cmd(0x56); //54(forAQM1602)
    LCD_cmd(0x6C);

    BSP_DelayMs(200);

    LCD_cmd(0x0C); //Disp ON/OFF
    LCD_cmd(0x01);// Clear Display

    BSP_DelayUs(1100);

}

//文字列表示
void LCD_str(char *str) {
    while (*str) //0x00まで繰り返し
        LCD_dat(*str++); //1文字表示
}

//1文字表示
void LCD_dat(char chr) {
    data[0] = 0x40;
    data[1] = chr;

    //I2C送信
    bhi2c = DRV_I2C_Transmit(hi2c, ADR, data, 2, NULL);
    while (DRV_I2C_TransferStatusGet(hi2c, bhi2c) != DRV_I2C_BUFFER_EVENT_COMPLETE); 
    
    BSP_DelayUs(60); // 60usec

}

//-------- 16進文字変換表示 ----------------
void LCD_hex(char c) {
    const char hexch[] = "0123456789ABCDEF";
    LCD_dat(hexch[c >> 4]); //上位4bit表示
    LCD_dat(hexch[c & 0xF]); //下位4bit表示
}

//--------3桁 10進文字表示 ----------------
void LCD_dec(int i) {
    const char decch[] = "0123456789 ";
    char n[3];

    n[2] = i / 100;
    n[1] = (i % 100) / 10;
    n[0] = i % 10;

    if (n[2] == 0){
        n[2] = 10;//100の桁は0ならスペース
        if (n[1] == 0){
            n[1] = 10;//100の桁0で10の桁0ならスペース
        }
    }
    
    LCD_dat(decch[n[2]]);
    LCD_dat(decch[n[1]]);
    LCD_dat(decch[n[0]]);


}
//-------- カーソル位置指定 --------------------------------------

void LCD_posyx(char ypos, char xpos) {
    unsigned char pcode;
    switch (ypos & 0x03) { // 縦位置を取得
        case 0: pcode = 0x80;
            break; // 1行目
        case 1: pcode = 0xC0;
            break; // 2行目
        case 2: pcode = 0x94;
            break; // 3行目
        case 3: pcode = 0xD4;
            break; // 4行目
    }
    LCD_cmd(pcode += xpos); // 横位置を加える
}
/*******************************************************************************
 End of File
 */

・Souse Files – appに  “timer_int.c”  を追加

timer_int.c
//
//2022_0903
//
#include "system/common/sys_common.h"
#include "app.h"
#include "system_definitions.h"


void kukan_ON(unsigned char, unsigned char);
void section_change_monitor(unsigned char, unsigned char); //区間変化監視
void next_section_on(unsigned char, unsigned char); //次区間ON
void read_generated_voltage(unsigned char, unsigned char);
void speed_cont(unsigned char);
void section_change(void);
void board_comm(unsigned char); //ボード間通信
void comm_data_set_tx(void); //通信データ設定TX
void comm_data_set_rx(void); //通信データ設定RX
void point_cont(void);
void yard_cont(void);
void set_on_section(unsigned char, unsigned char);
void set_on_next_section(unsigned char, unsigned char);
void timer2_int_func(char);
void PulseOffTimer_start(char);

void timer_int_func() {

    unsigned char rec_bit; //受信BIT用
    unsigned char send_flg; //送信PORT用

    rec_bit = _RB11;

#if ROSEN_NUM==0
    _RB10 = 0; //ext_int 同期パルス(master board))

#else
    //_RB14 = 1; //OSC
    DRV_TMR0_CounterValueSet(96);
#endif


    //通信用comm_counterはインタラプトを0-0x3ffでカウントします。
    if (++comm_counter > 0x3ff) {
        comm_counter = 0;
    } else {
#if ROSEN_NUM==0
        _RB10 = 1;
        _RB10 = 1;
#endif
    }



#if ROSEN_NUM!=0
    //子ボードは同期パルス幅が大きいときcomm_counterをリセット
    if (_RB10 == 0) {
        comm_counter = 0;
        _RB14 = 1; //OSC
    }
#endif
    //int_counterはcomm_counterの下位9bitの0-0x1ffでカウントします。
    int_counter = comm_counter & 0x1ff;

    _TRISB11 = 1;

    //osc_trg
#if ROSEN_NUM==0
    if (comm_counter == osc_trg.INT)_RB14 = 1;
#endif

    TRISB |= 0x10ff; //0x10ff

    //timer_value.INT = TMR_Counter16BitGet_In16BitRegister(TMR_ID_1);

    unsigned int t1 = 0x62;
    sp_w1 = speed_pw[0];
    sp_w2 = speed_pw[1];

    if (sp_w1 > t1) sp_w1 -= t1;
    if (sp_w2 > t1) sp_w2 -= t1;


    if (!same_dir_mode) {
        if (int_counter >= 0x10 && int_counter < 0x100) {
            //正転側区間ON
            kukan_ON(0, 0);
            kukan_ON(1, 0);
        } else if (int_counter >= 0x110 && int_counter <= 0x1ff) {
            //逆転側PWM ON
            kukan_ON(0, 1);
            kukan_ON(1, 1);
        }
    } else {
        //-----同方向-----
        if (int_counter >= 0x10 && int_counter < 0x100) {
            //
            kukan_ON(0, same_dir);
            kukan_ON(1, same_dir);
        } else {
            if (int_counter >= 0x110) {
                if (int_counter <= (ext_pwr[0] + 0x10f)) {
                    kukan_ON(0, same_dir);
                }
                if (int_counter <= (ext_pwr[1] + 0x10f)) {
                    kukan_ON(1, same_dir);
                }
            }
        }
    }




    switch (int_counter) {
        case 0:
            section_change();

            if (!same_dir_mode) {
                set_on_section(0, 0);
                set_on_section(1, 0);
            } else {
                set_on_section(0, same_dir);
                set_on_section(1, same_dir);
            }

            break;

        case 2:
            speed_cont(0);
            speed_cont(1);
            break;

        case 0x12:
            //インタラプトカウンタが0x2のときA相の区間変化監視(B相は0x102のとき)
            if (!same_dir_mode) {
                section_change_monitor(0, 0);
            } else {
                section_change_monitor(0, same_dir);
            }
            break;
        case 0x13:
            //インタラプトカウンタが0x2のときA相の区間変化監視(B相は0x102のとき)
            if (!same_dir_mode) {
                section_change_monitor(1, 0);
            } else {
                section_change_monitor(1, same_dir);
            }

            break;

        case 0x15:
            //インタラプトカウンタが3のときNEXT区間パルスON(B相は0x103のとき)
            //区間変化確認後に次区間もON
            if (!same_dir_mode) {
                set_on_next_section(0, 0);
                set_on_next_section(1, 0);
            } else {
                set_on_next_section(0, same_dir);
                set_on_next_section(1, same_dir);
            }

            break;

        case 0x100:
            //インタラプトカウンタが0x100のときB相のspeedパルスON
            if (!same_dir_mode) {
                set_on_section(0, 1);
                set_on_section(1, 1);
            }
            break;

        case 0x112:
            //区間変化監視
            if (!same_dir_mode) {
                section_change_monitor(0, 1);
            }
            break;
        case 0x113:
            //区間変化監視
            if (!same_dir_mode) {
                section_change_monitor(1, 1);
            }
            break;

        case 0x115:
            //区間変化確認後に次区間もON
            if (!same_dir_mode) {
                set_on_next_section(0, 1);
                set_on_next_section(1, 1);
            }
            break;

    }
    if (!same_dir_mode) {
        if (int_counter >= 0x8 && int_counter < 0xF) {
            read_generated_voltage(int_counter & 1, 1);
        }
        if (int_counter >= 0x108 && int_counter < 0x10F) {
            read_generated_voltage(int_counter & 1, 0);
        }
    } else {//same_dir_mode
        if (int_counter >= 0x8 && int_counter < 0xF) {
            read_generated_voltage(int_counter & 1, 1);
        }
        if (int_counter >= 0x1e8 && int_counter < 0x1eF) {
            read_generated_voltage(int_counter & 1, 0);
        }
    }



    switch (comm_counter) {
#if ROSEN_NUM == 0//-----ポイント yard 制御----------       
        case 0x3:
            point_cont();
            break;
        case 0x5:
            yard_cont();
            break;
#endif
        case 0x4:
            comm_data_set_tx();
            break;
        case 0x6:
            comm_data_set_rx();
            break;

    }


    //ボード間の通信
    board_comm(rec_bit);


#if ROSEN_NUM==0
    //幅広同期パルスOFF
    if (comm_counter == 0) {
        _RB10 = 1;
        _RB10 = 1;
    }

#endif


    _RB14 = 0; //OSC

    section1 = kukan[0];
    section2 = kukan[1];

    timer_value.INT = TMR_Counter16BitGet_In16BitRegister(TMR_ID_1);
    int w1 = sp_w1 - timer_value.INT;
    int w2 = sp_w2 - timer_value.INT;

    debug2.INT = w1;


    both_off = 0;

#define delay1 200 //このTimer0インタラプトが終わるまで待機する時間

    if (w1 > delay1 && w2 > delay1) {
        if (abs(w2 - w1) < 250) {
            //2列車のSpeedPulse幅の差がないときはどちらか早いほうのTimerでPulseOFF
            both_off = 1;
            if (w1 < w2) {
                PulseOffTimer_start(0);
            } else {
                PulseOffTimer_start(1);
            }
        } else {
            PulseOffTimer_start(0);
            PulseOffTimer_start(1);
        }
    } else {
        if (w1 > delay1) {
            PulseOffTimer_start(0);
        } else {
            timer2_int_func(0); //speed pulse短いときはここでOFF
            debug1.INT = 0xff00;
        }

        if (w2 > delay1) {
            PulseOffTimer_start(1);
        } else {
            timer2_int_func(1); //speed pulse短いときはここでOFF
            //debug1.INT = 0xff00;
        }
    }


}

//speed pulse off timer
void PulseOffTimer_start(char s) {
    int w;

    if (s == 0) {
        w = sp_w1 - TMR_Counter16BitGet_In16BitRegister(TMR_ID_1);
        PLIB_TMR_Period16BitSet(TMR_ID_2, w);
        DRV_TMR1_Start(); //PULSE OFF TimerStart
        int_count1.INT++;
    } else {
        w = sp_w2 - TMR_Counter16BitGet_In16BitRegister(TMR_ID_1);
        PLIB_TMR_Period16BitSet(TMR_ID_4, w);
        DRV_TMR2_Start(); //PULSE OFF TimerStart
        int_count2.INT++;
    }
}

void set_on_section(unsigned char sou, unsigned char dir) {

    if (train_sou[sou]) {
        if (train_sou[sou]->NOW.BIT.DIR == dir) {
            kukan[sou] = 0; //kukan clr

            if (train_sou[sou]->STATUS.BIT.SP_MANU == 1)
                speed_pw[sou] = train_sou[sou]->speed * SPEED_MAX / 256; //manual speed
            else
                speed_pw[sou] = train_sou[sou]->speed_cont.INT; //auto speed

            //区間メモリに現・前位置の区間を設定し区間ON
            if (train_sou[sou]->NOW.BIT.ROSEN == ROSEN_NUM) {
                if (speed_pw[sou] > 0)
                    kukan[sou] = EnableBit[train_sou[sou]->NOW.BIT.KUKAN];
                kanshi_now[sou] = train_sou[sou]->NOW.BIT.KUKAN;
            }
            if (train_sou[sou]->BEFORE.BIT.ROSEN == ROSEN_NUM) {
                if (speed_pw[sou] > 0)
                    kukan[sou] |= EnableBit[train_sou[sou]->BEFORE.BIT.KUKAN];
                kanshi_before[sou] = train_sou[sou]->BEFORE.BIT.KUKAN;
            }

        }
    }

}

void set_on_next_section(unsigned char sou, unsigned char dir) {

    if (train_sou[sou]) {
        if (train_sou[sou]->STATUS.BIT.SAFE) {
            //安全でないときは次区間に他の列車がかかっているのでONしない。
            if (train_sou[sou]->NOW.BIT.DIR == dir) {
                if (train_sou[sou]->NEXT.BIT.ROSEN == ROSEN_NUM) {
                    kukan[sou] |= EnableBit[train_sou[sou]->NEXT.BIT.KUKAN];
                }
            }
        }
    }
}


//区間ON用

void kukan_ON(unsigned char sou, unsigned char d) {
    if (train_sou[sou]) {
        if (train_sou[sou]->NOW.BIT.DIR == d) {
            // d=0:正回転, 1:負回転
            if (d == 0) {
                LATB |= kukan[sou];
                _LATB12 = 0; //Port RB12は共通側
            } else {
                LATB &= ~kukan[sou];
                _LATB12 = 1;
            }

            TRISB &= ~kukan[sou];
            _TRISB12 = 0;
        }
    }

}

void section_change_monitor(unsigned char sou, unsigned char dir) {
    static char sum_count;
    static int gnd_sum;

    if (train_sou[sou]) {
        if (train_sou[sou^1]) //相手変更中は変更しない
            if (train_sou[sou^1]->henka) return;

        if (train_sou[sou]->NOW.BIT.DIR == dir) {
            char chg_enable = 0;
            if (train_sou[sou^0x1]) {
                //向き合いの時区間変更許可
                if (train_sou[sou]->NOW.BIT.DIR != train_sou[sou^0x1]->NOW.BIT.DIR)
                    chg_enable = 1;
            }

            if (train_sou[sou]->STATUS.BIT.SAFE || chg_enable)
                if (!train_sou[sou]->henka) {
                    if (train_sou[sou]->NEXT.BIT.ROSEN == ROSEN_NUM) {
                        //次位置区間の監視
                        kanshi.BIT.KUKAN = train_sou[sou]->NEXT.BIT.KUKAN;
                        LATA &= 0xC3;
                        LATA |= kanshi.BYTE;

                        //ADC読み込み
                        BSP_DelayUs(1);
                        //_RB14 = 1;
                        PLIB_ADC_SamplingStart(ADC_ID_1);
                        while (!PLIB_ADC_ConversionHasCompleted(ADC_ID_1));
                        adc_ret.INT = PLIB_ADC_ResultGetByIndex(ADC_ID_1, 0);
                        //_RB14 = 0;

                        if (train_sou[sou]->NOW.BIT.DIR == 0) {
                            //正方向のとき
                            if (adc_ret.INT >= 0x280) {
                                train_sou[sou]->henka = 0x80; //区間変化

                            }
                            //if (sou == 0)debug1.INT = adc_ret.INT;
                            //else debug2.INT = adc_ret.INT;
                        } else {
                            //逆方向のとき
                            if (adc_ret.INT < 0x180) {
                                train_sou[sou]->henka = 0x80; //区間変化

                            }
                            //if (sou == 0)debug1.INT = adc_ret.INT;
                            //else debug2.INT = adc_ret.INT;

                        }

                        //区間変化でないときGND値とする。
                        //                        if (!train_sou[sou]->henka) {
                        //                            gnd_adc = adc_ret.INT;
                        //
                        //                            //区間変更なしのときのADC値をGND Levelにします。
                        //                            //16回たして4bit右シフトで平均をとります。
                        //                            gnd_sum += adc_ret.INT;
                        //                            if (sum_count++ == 15) {
                        //                                gnd_level.INT = gnd_sum >> 4;
                        //                                sum_count = 0;
                        //                                gnd_sum = 0;
                        //                            }
                        //
                        //                        }

                    }
                }
        }
    }

}

void next_section_on(unsigned char sou, unsigned char dir) {
    //次区間をON
    if (train_sou[sou]) {
        if (train_sou[sou]->NOW.BIT.DIR == dir) {
            if (train_sou[sou]->STATUS.BIT.SAFE) {
                //安全でないときは次区間に他の列車がかかっているのでONしない。
                if (train_sou[sou]->NEXT.BIT.ROSEN == ROSEN_NUM) {
                    kukan[sou] |= EnableBit[train_sou[sou]->NEXT.BIT.KUKAN];
                    //kukan_ON(kukan[sou], train_sou[sou]->NOW.BIT.DIR);
                }
            }
        }
    }
}

void read_generated_voltage(unsigned char n, unsigned char sou) {
    static unsigned char count[2], p[2], count_B[2];
    static int speed_buf[2][32]; //16
    static int read_speed[2];
    static int speed_sou[2]; //相手のスピード

    char m;

    if (train_sou[sou]) {

        char sou_b = 0;
        if (sou == 0) sou_b = 1;

        //現位置と前位置を交互に読み込み
        if (n == 0) {//n == 0
            kanshi.BIT.KUKAN = kanshi_now[sou];
            //kanshi.BIT.KUKAN = train_sou[sou]->NOW.BIT.KUKAN;
        } else {
            kanshi.BIT.KUKAN = kanshi_before[sou];
            //kanshi.BIT.KUKAN = train_sou[sou]->BEFORE.BIT.KUKAN;
        }

        //        LATA &= 0xC3;
        //        LATA |= kanshi.BYTE;
        PORTA = kanshi.BYTE;

        //BSP_DelayUs(1);

        //ADC読み込み
        PLIB_ADC_SamplingStart(ADC_ID_1);
        while (!PLIB_ADC_ConversionHasCompleted(ADC_ID_1));
        adc_ret.INT = PLIB_ADC_ResultGetByIndex(ADC_ID_1, 0);

        //ADC値からGND値を引いて絶対値をとります。
        adc_ret.INT = adc_ret.INT - gnd_level.INT;

        if (adc_ret.INT < 0)
            adc_ret.INT = -adc_ret.INT;

        //8回のピーク値をスピードデータにします。
        //        if (count[sou]++ == 7) {
        //            read_speed[sou] = adc_ret.INT;
        //            count[sou] = 0;
        //        } else if (adc_ret.INT > read_speed[sou]) {
        //            read_speed[sou] = adc_ret.INT;
        //            return; //ここで終了
        //        }


        //8回のピーク値をスピードデータにします。
        if (adc_ret.INT > read_speed[sou]) {
            read_speed[sou] = adc_ret.INT;
        }

        speed_sou[sou] = read_speed[sou];

        //        p[sou]++;
        //        if (p[sou] == 16) p[sou] = 0;
        //
        //        speed_buf[sou][p[sou]] = read_speed[sou]; //0xf
        speed_buf[sou][++p[sou] & 0xf] = read_speed[sou]; //0xf

        //peek reset
        if (++count[sou] == 8) {
            read_speed[sou] = adc_ret.INT;
            count[sou] = 0;
        }


        //移動平均
        //char m;
        unsigned long avr = 0;

        for (m = 0; m < 16; m++) {//16
            avr += speed_buf[sou][m];
        }

        avr >>= 4; //4
        //avr = read_speed[sou];

        //読み取り電圧補正
        //        if (volt_kb.INT < 0x100 || volt_kb.INT > 0x280)
        //            volt_kb.INT = 0x150;
        //
        //        avr = avr * volt_kb.INT;
        //        avr = avr / 0x100;

        //train_sou[sou]->speed_ret.INT = avr; //4


        if (count_B[sou]++ == 15) {
            count_B[sou] = 0;

            if (avr < train_sou[sou]->speed_ret.INT) {
                train_sou[sou]->speed_ret.INT--;
            } else if (avr > train_sou[sou]->speed_ret.INT)
                train_sou[sou]->speed_ret.INT++;
        }


        if (train_sou[sou]->NOW.BIT.ROSEN == ROSEN_NUM) {
            if (train_sou[sou]->NOW.BIT.ROSEN != train_sou[sou]->BEFORE.BIT.ROSEN) {
                if (train_sou[sou]->speed_ret_rx.INT > train_sou[sou]->speed_ret.INT) {
                    train_sou[sou]->speed_ret.INT = train_sou[sou]->speed_ret_rx.INT;
                }
            }
        }


    }
}

void speed_cont(unsigned char sou) {
    int err; //スピードのエラー
    //    int err_abs; //err絶対値

    int d; //エラー補正値

    static char count[2];
    static char count_avr[2];

    if (!train_sou[sou])return;

    // スピード設定値と実際スピードの比較
    err = train_sou[sou]->speed - train_sou[sou]->speed_ret.INT;

    err_buff[sou][count_avr[sou]++ & 0xF] = err;

    //---error avrage---
    int err_sum = 0;
    char c;
    for (c = 0; c < 16; c++) {
        err_sum += err_buff[sou][c];
    }
    err_avr[sou].INT = err_sum / 16;

    //    err_abs = err_avr[sou].INT;
    //    if (err_abs < 0)err_abs = -err_abs;

    //--test--
    //d = (err * err_avr[sou].INT) / 0x80;
    //d = err_avr[sou].INT / 0x10;
    d = err_avr[sou].INT / 4; // /10

    int d_max = 0x50; //+補正最大値
    //int d_max_m = 0x100; //-補正最大値
    char cont_t = 10; //制御間隔

    //動き出しを早く
    if (train_sou[sou]->speed_ret.INT < 10) {
        d_max = 0x100;
        cont_t = 2;
    }

    //    if (d > d_max)d = d_max;
    //    else if (d < -d_max_m)d = -d_max_m;


    //スピード設定が0のとき補正値が負でない場合
    //完全に停止させるため補正値を-1にします

#define d_zero -20
    if (train_sou[sou]->speed == 0) {
        cont_t = 2; //減速早く 2
        if (d > d_zero)//-3
            d = d_zero; //-0x3
    } else {
        //if (err_avr[sou].INT < train_sou[sou]->err_th)return;
        //if (err_abs < train_sou[sou]->err_th)return;
    }


    //if (d < 0) cont_t = 20; //減速は早く


    //スピードコントロール値をエラー補正値で補正
    if (++count[sou] > cont_t) {//10
        count[sou] = 0;
        train_sou[sou]->speed_cont.INT += d;
    } else {
        return;
    }


    //結果が負にならないようにする
    if (train_sou[sou]->speed_cont.INT < 0)
        train_sou[sou]->speed_cont.INT = 0;

    //接触不良時の制限
    if (train_sou[sou]->speed_ret.INT < 0x4) {
        int contact_fail = SPEED_MAX * 10 / 10; //max/2
        if (train_sou[sou]->speed_cont.INT > contact_fail)
            train_sou[sou]->speed_cont.INT = contact_fail;
    }

    //Speedの最大値を制限
    if (train_sou[sou]->speed_cont.INT > SPEED_MAX) {
        train_sou[sou]->speed_cont.INT = SPEED_MAX;
    }

    //extra_power
    if (train_sou[sou]->speed_cont.INT > SPEED_MAX - 0x20) {
        if (ext_pwr[sou] < 0xc0) {
            if ((count_avr[sou] & 0xf) == 0) ext_pwr[sou]++;
        }
    } else {
        if (ext_pwr[sou] > 0) {
            ext_pwr[sou]--;
        }
    }

    //ext_pwr[sou] = 0; //test

}

void section_change() {
    char n;
    // if (chg_disable) return;

    for (n = 0; n < TR_COUNT; n++) {
        if (train[n].STATUS.BIT.CHG == 1) {
            //受信データに置き換え
            train[n].BEFORE.BYTE = train[n].REC_BEFORE;
            train[n].NOW.BYTE = train[n].REC_NOW;
            train[n].NEXT.BYTE = train[n].REC_NEXT;

            if (cont_train[0] == n) {
                cont_train[0] = 0xff;
                train_sou[0] = NULL;
            }
            if (cont_train[1] == n) {
                cont_train[1] = 0xff;
                train_sou[1] = NULL;
            }

            if ((train[n].NOW.BIT.ROSEN == ROSEN_NUM)
                    || (train[n].NEXT.BIT.ROSEN == ROSEN_NUM)
                    || (train[n].BEFORE.BIT.ROSEN == ROSEN_NUM)) {
                //各相の列車登録
                cont_train[train[n].NOW.BIT.SOU] = n;
                train_sou[train[n].NOW.BIT.SOU] = &train[n];
            } else {
                train[n].speed_cont.INT = 0;
            }

            train[n].henka = 0;
            train[n].STATUS.BIT.CHG = 0;

        }
    }


    //kukan clr
    kukan[0] = 0;
    kukan[1] = 0;


    //check same dir
    if (train_sou[0] && train_sou[1]) {//両相ともON?
        if (train_sou[0]->NOW.BIT.DIR == train_sou[1]->NOW.BIT.DIR) {//same dir?
            if (same_dir_mode < 0x80 && inc_interval++ > 50) {
                same_dir_mode++;
                inc_interval = 0;
            }
            same_dir = train_sou[0]->NOW.BIT.DIR; //set dir
        } else {
            same_dir_mode = 0;
            inc_interval = 0;
        }
    } else {
        //one side only
        if (same_dir_mode < 0x80 && inc_interval++ > 50) {
            same_dir_mode++;
            inc_interval = 0;
        }
        if (train_sou[0]) {
            same_dir = train_sou[0]->NOW.BIT.DIR;
        }
        if (train_sou[1]) {
            same_dir = train_sou[1]->NOW.BIT.DIR;
        }
    }

}

void board_comm(unsigned char rec_bit) {
    unsigned char bit_p;
    unsigned int data_p;

    data_p = (comm_counter - 1) & 0x3ff;
    bit_p = EnableBit[data_p & 7]; //bit位置set
    data_p >>= 3;
    board_num = data_p;
    board_num >>= 4;

#if ROSEN_NUM == 0
    //親ボードのみポイントなどのボードに送信
    if (!(board_num == ROSEN_NUM || board_num == 6)) {
#else
    if (!(board_num == ROSEN_NUM)) {
#endif
        //データ受信
        _TRISB11 = 1;

        if (rec_bit)
            receive_data |= bit_p;
        else
            receive_data &= ~bit_p;

        if (bit_p == 0x80) {

            comm_data[data_p] = receive_data;
        }

    }


    //ボード間データ通信
    data_p = comm_counter & 0x3ff;
    bit_p = EnableBit[data_p & 7]; //bit位置set
    data_p >>= 3;
    board_num = data_p;
    board_num >>= 4;

#if ROSEN_NUM == 0
    //親ボードのみポイントなどのボードに送信
    if (board_num == ROSEN_NUM || board_num == 6) {
#else
    if (board_num == ROSEN_NUM) {
#endif
        //データ送信
        _TRISB11 = 0;

        send_data = comm_data[data_p];

        //送信PORTデータセット
        if (send_data & bit_p)
            _RB11 = 1;
        else
            _RB11 = 0;

    }
}

void comm_data_set_tx() {
    unsigned char n;
    unsigned int data_p;

    //comm_data 送信データSET
    data_p = ROSEN_NUM << 4;
    //A相
    n = cont_train[0];
    if (n != 0xff) {
        comm_data[data_p] = n + 0xA0;
        comm_data[data_p + 1] = train[n].speed_ret.BYTE.H; //speed_ret_tx
        comm_data[data_p + 2] = train[n].speed_ret.BYTE.L;
        comm_data[data_p + 3] = train[n].henka;
        comm_data[data_p + 4] = train[n].speed_cont.BYTE.H;
        comm_data[data_p + 5] = train[n].speed_cont.BYTE.L;

        comm_data[data_p + 6] = train[n].NOW.BYTE;

        comm_data[data_p + 7] = ext_pwr[0]; //same_dir_mode

    } else
        comm_data[data_p] = 0xFF;


    //B相
    n = cont_train[1];
    data_p += 0x8;

    if (n != 0xff) {
        comm_data[data_p] = n + 0xA0;
        comm_data[data_p + 1] = train[n].speed_ret.BYTE.H; //speed_ret_tx
        comm_data[data_p + 2] = train[n].speed_ret.BYTE.L;
        comm_data[data_p + 3] = train[n].henka;
        comm_data[data_p + 4] = train[n].speed_cont.BYTE.H;
        comm_data[data_p + 5] = train[n].speed_cont.BYTE.L;

        comm_data[data_p + 6] = train[n].NOW.BYTE;
    } else
        comm_data[data_p] = 0xFF;

}

void comm_data_set_rx() {
    //受信データSET
    unsigned char n;
    unsigned int data_p;

    for (board_num = 0; board_num < BOARD_COUNT; board_num++) {
        if (board_num != ROSEN_NUM) {
            //自ボード以外受信
            data_p = board_num << 4;
            //A相
            n = comm_data[data_p];
            if ((n & 0xF0) == 0xA0) {
                n &= 0xF;

                train[n].speed_ret_rx.BYTE.H = comm_data[data_p + 1];
                train[n].speed_ret_rx.BYTE.L = comm_data[data_p + 2];

                if (train[n].NOW.BIT.ROSEN != ROSEN_NUM) {
                    if (train[n].NOW.BIT.ROSEN == train[n].BEFORE.BIT.ROSEN)
                        //現位置および前位置が他路線のとき実スピード受信
                        train[n].speed_ret.INT = train[n].speed_ret_rx.INT;
                }

                if (ROSEN_NUM == 0)//Masterボードのみ区間変化受信
                    if (train[n].NEXT.BIT.ROSEN != 0) {
                        //NextがMasterボード以外のとき受信
                        if (train[n].NEXT.BIT.ROSEN == board_num)//次区間のボードの区間変化を受信
                            train[n].henka = comm_data[data_p + 3];
                    }


                train[n].speed_rx.BYTE.H = comm_data[data_p + 4];
                train[n].speed_rx.BYTE.L = comm_data[data_p + 5];

                if (train[n].NOW.BIT.ROSEN != ROSEN_NUM) {
                    if (train[n].NEXT.BIT.ROSEN == ROSEN_NUM)
                        //ポイント切り替え時次区間でspeed_cont渡し
                        train[n].speed_cont.INT = train[n].speed_rx.INT;
                }


            }
            //B相
            data_p += 0x8;
            n = comm_data[data_p];
            if ((n & 0xF0) == 0xA0) {
                n &= 0xF;

                train[n].speed_ret_rx.BYTE.H = comm_data[data_p + 1];
                train[n].speed_ret_rx.BYTE.L = comm_data[data_p + 2];

                if (train[n].NOW.BIT.ROSEN != ROSEN_NUM) {
                    if (train[n].NOW.BIT.ROSEN == train[n].BEFORE.BIT.ROSEN)
                        //現位置および前位置が他路線のとき実スピード受信
                        train[n].speed_ret.INT = train[n].speed_ret_rx.INT;
                }

                if (ROSEN_NUM == 0)//Masterボードのみ区間変化受信
                    if (train[n].NEXT.BIT.ROSEN != 0) {
                        //NextがMasterボード以外のとき受信
                        if (train[n].NEXT.BIT.ROSEN == board_num)//次区間のボードの区間変化を受信
                            train[n].henka = comm_data[data_p + 3];
                    }

                train[n].speed_rx.BYTE.H = comm_data[data_p + 4];
                train[n].speed_rx.BYTE.L = comm_data[data_p + 5];

                if (train[n].NOW.BIT.ROSEN != ROSEN_NUM) {
                    if (train[n].NEXT.BIT.ROSEN == ROSEN_NUM)
                        //ポイント切り替え時次区間でspeed_cont渡し
                        train[n].speed_cont.INT = train[n].speed_rx.INT;
                }


            }
        }
    }


#if ROSEN_NUM == 0
    //point_request
    if (point_req) {
        if (!comm_data[0x70]) {
            //ready
            comm_data[0x60] = point_req; //point_data
        } else
            //busy
            if (comm_data[0x60]) {
            //リクエストクリア
            point_req = 0;
            comm_data[0x60] = 0;
        }
    }

    //yardt_request
    if (yard_req) {
        if (!comm_data[0x71]) {
            //ready
            comm_data[0x61] = yard_req; //point_data
        } else
            //busy
            if (comm_data[0x61]) {
            //リクエストクリア
            yard_req = 0;
            comm_data[0x61] = 0;
        }
    }
#endif

}

//ポイント制御

void point_cont() {
    unsigned char n;

    if (!point_req) {
        for (n = 0; n < TR_COUNT; n++) {
            if ((train[n].point & 0x80) != 0) {
                point_req = train[n].point;
                train[n].point = 0;
                break;
            }
        }
    }
}

//ヤード制御

void yard_cont() {
    unsigned char n;

    if (!yard_req) {
        for (n = 0; n < TR_COUNT; n++) {
            if ((train[n].yard & 0x80) != 0) {
                yard_req = train[n].yard;
                train[n].yard = 0;
                break;
            }
        }
    }
}

//pulse off用インタラプトFunction
void timer2_int_func(char s) {

    if (s == 0) {//TM1
        if (section1) TRISB |= section1;
        DRV_TMR1_Stop();

        if (both_off) {//2列車のSpeedPulse幅の差がないときはどちらか早いほうのTimerでPulseOFF
            do {
                timer_value.INT = TMR_Counter16BitGet_In16BitRegister(TMR_ID_1);
            } while (timer_value.INT < sp_w2);
            if (section2) TRISB |= section2;
        }

    } else {//TM2
        if (section2) TRISB |= section2;
        DRV_TMR2_Stop();

        if (both_off) {//2列車のSpeedPulse幅の差がないときはどちらか早いほうのTimerでPulseOFF
            do {
                timer_value.INT = TMR_Counter16BitGet_In16BitRegister(TMR_ID_1);
            } while (timer_value.INT < sp_w1);
            if (section1) TRISB |= section1;
        }
    }
   
}

/* *****************************************************************************
 End of File
 */

・app.cを編集します。void APP_Tasks ( void )以下をすげ変えます。

//
//
//2022_0612 app.cすげ替え

/******************************************************************************
  Function:
    void APP_Tasks ( void )

  Remarks:
    See prototype in app.h.
 */

void ini_train(void);
void train_set(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char);

void APP_Tasks(void) {
    static unsigned char buf_p;

    /* Check the application's current state. */
    switch (appData.state) {
            /* Application's initial state. */
        case APP_STATE_INIT:
        {
            bool appInitialized = true;


            DRV_ADC_Open(); //Enable ADC

            //USART
            if (handleUSART0 == DRV_HANDLE_INVALID) {
                handleUSART0 = DRV_USART_Open(0, DRV_IO_INTENT_READWRITE | DRV_IO_INTENT_NONBLOCKING);
                appInitialized &= (DRV_HANDLE_INVALID != handleUSART0);
            }

            //I2C Open
            hi2c = DRV_I2C_Open(DRV_I2C_INDEX_0, DRV_IO_INTENT_READWRITE | DRV_IO_INTENT_NONBLOCKING);
            if (hi2c != DRV_HANDLE_INVALID) {
                //LCD初期化
                LCD_int();
                LCD_str("PC_REM");
            }


            gnd_level.INT = 0x200;

            DRV_TMR0_Start(); //TimerStart
#if ROSEN_NUM==0
            //DRV_TMR0_Start(); //TimerStart
#else
            //マスターボード以外はEXT_INT
            ext_int_enable = true;
            _TRISB14 = 0;
#endif

            //PLIB_TMR_Period16BitSet(TMR_ID_2, 0x7000);
            //DRV_TMR1_Start(); //PULSE OFF TimerStart

            //-----ATC-------
            cont_train[0] = 0xff;
            cont_train[1] = 0xff;

            train_sou[0] = NULL;
            train_sou[1] = NULL;

            ini_train();



            //列車A相
            //            train[0].mascon = 0x18; //スピードを変える時はここを変更
            //            train_set(0, 0, 1, 0, 0); //n,rosen,section,dir,sou

            //列車B相
            //            train[1].mascon = 0x1c; //スピードを変える時はここを変更
            //            train_set(1, 0, 5, 0, 1); //n,rosen,section,dir,sou


            if (appInitialized) {

                appData.state = APP_STATE_SERVICE_TASKS;
            }
            break;
        }

        case APP_STATE_SERVICE_TASKS:
        {
            unsigned char n, p;
            unsigned char ret;
            union byte_access time_out;
            long count;

            rx_data[0] = 0;
            rx_data[1] = 0;
            time_out.INT = 0;

            U1STAbits.OERR = 0; //受信バッファ・エラークリア

            ret = 0;
            while (ret != 0x55) {
                //0x55が来るまでずーと待つ
                while (!DRV_USART_ReceiverBufferIsEmpty(DRV_USART_INDEX_0)) {
                    ret = DRV_USART_ReadByte(DRV_USART_INDEX_0);
                }
            }


            for (n = 1; n < RX_BYTE; n++) {
                count = 0;
                while (DRV_USART_ReceiverBufferIsEmpty(DRV_USART_INDEX_0)) {
                    if (count++ > 0xfffff)break;
                }
                if (count > 0xfffff)break; //TimeOutで外へ

                rx_data[n] = DRV_USART_ReadByte(DRV_USART_INDEX_0);
            }

            chg_disable = 0; //INT中の変更禁止

            if (rx_data[1] == 0xAA) {
                //ヘッダー正常(0x55 0xAA)
                time_out.INT = count;

                for (n = 0; n < TR_COUNT; n++) {
                    p = n * RX_DATA_BYTE + 2;
                    train[n].mascon = rx_data[p];
                    train[n].speed = train[n].mascon;
                    train[n].REC_NOW = rx_data[p + 1];
                    train[n].REC_BEFORE = rx_data[p + 2];
                    train[n].REC_NEXT = rx_data[p + 3];
                    train[n].err_th = 0x10;

                    //区間変更フラグクリア
                    if (rx_data[p + 4] & 1) {
                        train[n].STATUS.BIT.CHG = 1;
                    }

                    //安全フラグ
                    if (rx_data[p + 4] & 0x80)
                        train[n].STATUS.BIT.SAFE = 0x1;
                    else
                        train[n].STATUS.BIT.SAFE = 0;

                    //MANU SPEED
                    if (rx_data[p + 4] & 0b10) {
                        train[n].STATUS.BIT.SP_MANU = 0x1;
                        train[n].speed = train[n].mascon * 0xE8 / 100;
                    } else
                        train[n].STATUS.BIT.SP_MANU = 0;



                    //point_request
                    if (rx_data[p + 5])
                        train[n].point = rx_data[p + 5];
                    //yard_request
                    if (rx_data[p + 6])
                        train[n].yard = rx_data[p + 6];


                }
                chg_disable = 0; //INT中の変更可

                //オシロスコープ用TRG
                osc_trg.BYTE.H = rx_data[100];
                osc_trg.BYTE.L = rx_data[101];

                ext_time = rx_data[102]*256;
                ext_time += rx_data[103];


                //232送信
                tx_data[0] = 0x55; //ヘッダー0x55,0xAA
                tx_data[1] = 0xAA;

                for (n = 0; n < TR_COUNT; n++) {
                    p = n * TX_DATA_BYTE + 2;
                    //区間変化情報の送信
                    tx_data[p + 2] = train[n].henka;
                    tx_data[p + 3] = train[n].point;
                    tx_data[p + 4] = train[n].yard;

                    //スピード読み取り値の送信


                    if (train[n].NOW.BIT.ROSEN == ROSEN_NUM) {
                        tx_data[p] = train[n].speed_ret.BYTE.H;
                        tx_data[p + 1] = train[n].speed_ret.BYTE.L;
                        tx_data[p + 5] = train[n].speed_cont.BYTE.H;
                        tx_data[p + 6] = train[n].speed_cont.BYTE.L;
                    } else {
                        //他のボードのときcomm_dataのcont_speedを送る
                        tx_data[p] = train[n].speed_ret_rx.BYTE.H;
                        tx_data[p + 1] = train[n].speed_ret_rx.BYTE.L;
                        tx_data[p + 5] = train[n].speed_rx.BYTE.H;
                        tx_data[p + 6] = train[n].speed_rx.BYTE.L;
                    }
                }



                for (n = 0; n < 128; n++) {
                    tx_data[100 + n] = comm_data[n];
                }

                //Degug
                tx_data[100 + 0x30] = 55;
                if (train_sou[0]) tx_data[100 + 0x31] = train_sou[0]->STATUS.BYTE;
                else tx_data[100 + 0x31] = 0xff;
                if (train_sou[1]) tx_data[100 + 0x32] = train_sou[1]->STATUS.BYTE;
                else tx_data[100 + 0x32] = 0xff;


                // 送信用メモリデータをPCに転送します
                for (n = 0; n < TX_BYTE; n++) {
                    DRV_USART_WriteByte(DRV_USART_INDEX_0, tx_data[n]);
                }

            }


            BSP_DelayMs(20);

            //Debug用LCD表示
            LCD_posyx(0, 0);

            //debug1.INT = gnd_level.INT;

            LCD_hex(int_count1.BYTE.H);
            LCD_hex(int_count1.BYTE.L);
            LCD_hex(int_count2.BYTE.H);
            LCD_hex(int_count2.BYTE.L);

            //LCD_hex(debug1.BYTE.H);
            //LCD_hex(debug1.BYTE.L);
            //LCD_hex(debug2.BYTE.H);
            //LCD_hex(debug2.BYTE.L);
            //LCD_hex(train[0].henka);

            union byte_access err_abs;
            err_abs.INT = err_avr[0].INT;
            if (err_abs.INT < 0)err_abs.INT = -err_abs.INT;

            //LCD_hex(err_abs.BYTE.H);
            //LCD_hex(err_abs.BYTE.L);


            //LCD_str(" ");
            LCD_hex(timer_value.BYTE.H);
            LCD_hex(timer_value.BYTE.L);
            //
            //            if (err_abs.INT < train[0].err_th)
            //                LCD_str(" OFF ");
            //            else
            //                LCD_str(" ON  ");

            LCD_posyx(1, 0);
            LCD_hex(train[0].NOW.BYTE);
            LCD_hex(train[0].NEXT.BYTE);

            LCD_hex(train[1].NOW.BYTE);
            LCD_hex(train[1].NEXT.BYTE);

            break;
        }
            /* TODO: implement your application state machine.*/


            /* The default state should never be executed. */
        default:
        {
            /* TODO: Handle error in application's state machine. */
            break;
        }
    }
}

void ini_train() {
    char n;

    for (n = 0; n < TR_COUNT; n++) {
        train[n].BEFORE.BYTE = 0x38;
        train[n].NOW.BYTE = 0x38;
        train[n].NEXT.BYTE = 0x38;
        train[n].ANEXT.BYTE = 0x38;
        train[n].STATUS.BYTE = 0;
        train[n].speed = 0;
        train[n].henka = 0;
    }

}

void train_set(unsigned char n, unsigned char rosen, unsigned char sec, unsigned char dir, unsigned char sou) {
    train[n].NOW.BIT.ROSEN = rosen;
    train[n].NOW.BIT.KUKAN = sec;
    train[n].NOW.BIT.DIR = dir;
    train[n].NOW.BIT.SOU = sou;

    train[n].BEFORE.BYTE = train[n].NOW.BYTE;
    train[n].NEXT.BYTE = train[n].NOW.BYTE;
    train[n].ANEXT.BYTE = train[n].NOW.BYTE;

    if (dir) {
        //逆転 
        train[n].BEFORE.BIT.KUKAN++;
        train[n].NEXT.BIT.KUKAN--;
        train[n].ANEXT.BIT.KUKAN = train[n].NOW.BIT.KUKAN - 2;
    } else {
        //正転
        train[n].BEFORE.BIT.KUKAN--;
        train[n].NEXT.BIT.KUKAN++;
        train[n].ANEXT.BIT.KUKAN += 2;
    }

    train[n].STATUS.BIT.CHG = 0;
    train[n].STATUS.BIT.SAFE = 1;

}


/*******************************************************************************
 End of File
 */

・system_interrupt.cの後ろのほうを編集します。

//
//
//2022_0903 system_interrupt.c 編集

void __ISR(_EXTERNAL_1_VECTOR, IPL6AUTO) _IntHandlerExternalInterruptInstance0(void)
{
    PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_EXTERNAL_1);
    
    if (ext_int_enable)
        timer_int_func();
}
 

void __ISR(_TIMER_1_VECTOR, ipl7AUTO) IntHandlerDrvTmrInstance0(void)
{
    PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_1);
    
    timer_int_func();
}
void __ISR(_TIMER_2_VECTOR, ipl5AUTO) IntHandlerDrvTmrInstance1(void)
{
    PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_2);
     timer2_int_func(0);
    int_count1.INT--;
    debug1.INT = 0xff;
    
}
void __ISR(_TIMER_4_VECTOR, ipl5AUTO) IntHandlerDrvTmrInstance2(void)
{
    PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_4);
    timer2_int_func(1);
    int_count2.INT--;
    
}
 /*******************************************************************************
 End of File
*/

・PicKit4で動かないときはConfiguration BitsのDEBUGの部分をコメントアウト