PWM方式変更2

パルスOFFを同じTimer1のインタラプト内で行うと、インタラプトの期間が増えて

メイン処理の時間が減ります。なので、パルスOFFも別のTimerのインタラプトで行うようにします。

Harmonyの変更はTimer2とTimer3の追加です。

timer_int.cの変更
//
//
//2022_0423

#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 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;
    unsigned int sp_w1 = speed_pw[0];
    unsigned int sp_w2 = speed_pw[1];

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

    if (section1) {
        PLIB_TMR_Period16BitSet(TMR_ID_2, sp_w1);
        DRV_TMR1_Start(); //PULSE OFF TimerStart
    }
    if (section2) {
        PLIB_TMR_Period16BitSet(TMR_ID_4, sp_w2);
        DRV_TMR2_Start(); //PULSE OFF TimerStart
    }




    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];



}

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にします
    if (train_sou[sou]->speed == 0) {
        cont_t = 2; //減速早く 2
        if (d>-0x3)//-3
            d = -0x3; //-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] < 0x80) {
            if ((count_avr[sou] & 0xf) == 0) ext_pwr[sou]++;
        }
    } else {
        if (ext_pwr[sou] > 0) {
            ext_pwr[sou]--;
        }
    }


}

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

void timer2_int_func(char s) {

    if (s == 0) {
        if (section1) TRISB |= section1;
        DRV_TMR1_Stop();
    } else {
        if (section2) TRISB |= section2;
        DRV_TMR2_Stop();
    }

    debug1.INT = section1;
}

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

 

atc.hの変更
//
//2022_0423

#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 0x380      //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;

 

system_interrupt.cの変更
//
//2022_0423
//以下を最後に追加

void __ISR(_TIMER_2_VECTOR, ipl5AUTO) IntHandlerDrvTmrInstance1(void) {
    PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_TIMER_2);

    timer2_int_func(0);
}

void __ISR(_TIMER_4_VECTOR, ipl4AUTO) IntHandlerDrvTmrInstance2(void) {
    PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_TIMER_4);

    timer2_int_func(1);
}

 

未分類

前の記事

PWMの方式変更
2026版

次の記事

2026版New!!