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の部分をコメントアウト
