信号機
信号機
信号機はPIC16F1933を使って、10個の信号機を点灯します。
PIC16F1933のコード
//***************************
//2021_0606
//***************************
#include <xc.h>
#define _XTAL_FREQ 4000000
#pragma config CPD = OFF
#pragma config BOREN = OFF
#pragma config IESO = OFF
#pragma config FOSC =INTOSC
#pragma config FCMEN = OFF
#pragma config MCLRE = OFF
#pragma config WDTE = OFF //ON
#pragma config CP = OFF
#pragma config LVP = OFF
#pragma config PWRTE = ON
#define ExtInt RB0
#define ExtData RB1
#define RED0 RA0
#define YEL0 RA1
#define GRN0 RA2
#define GRP0 RA3
#define GRP1 RA4
#define GRP2 RA5
#define GRP3 RC0
#define GRP4 RC1
#define GRP5 RC2
#define GRP6 RC3
#define GRP7 RC4
#define GRP8 RC5
#define GRP9 RC6
#define L_GRN 0b100
#define L_YEL 0b010
#define L_RED 0b001
int IntCount;
unsigned char bit_p;
unsigned char receive_data;
unsigned char data_p;
unsigned char RxData[128];
unsigned char send_data;
unsigned char busy;
unsigned char EnableBit[] = {1, 2, 4, 8, 16, 32, 64, 128};
unsigned char yard_req;
unsigned char yard_num;
unsigned char TrainCount;
unsigned char TrainPos[16];
unsigned char SignalPos[8];
unsigned char grp_chg_count;
unsigned char group;
unsigned char signal[10];
unsigned char sync;
unsigned char data_ready;
void signal_LED(unsigned char);
void Disp(void);
void led_off(void);
//********************************************************
void main(void) {
unsigned char rosen;
signed char d;
signed char d_min;
unsigned char n, p;
//最高速32MHz
OSCCONbits.SPLLEN = 1; //×4 PLL
OSCCONbits.IRCF = 14; //8MHz
ANSELA = 0; // アナログ入力 AN8からAN13 を無効
ANSELB = 0; // アナログ入力 AN0からAN7 を無効
PORTA = 0;
PORTB = 0;
PORTC = 0;
TRISA = 0;
TRISB = 0x03; // RB0,1 Input
TRISC = 0;
OPTION_REG = 0x0f; // WDT,Int Fall, pulup
OPTION_REGbits.nWPUEN = 1;
INTE = 1; // RB0 割り込み許可
GIE = 1; // 割り込み許可
SignalPos[0] = 1;
SignalPos[1] = 9;
SignalPos[2] = 0x10;
// SignalPos[0] = 0;
// SignalPos[1] = 1;
// SignalPos[2] = 2;
SignalPos[3] = 3;
SignalPos[4] = 4;
SignalPos[5] = 5;
SignalPos[6] = 6;
SignalPos[7] = 7;
SignalPos[8] = 8;
SignalPos[9] = 9;
__delay_ms(10); // 10msec
while (1) {
CLRWDT();
//列車位置設定
if (data_ready) {
data_ready = 0;
TrainCount = 0;
for (n = 0; n < 12; n++) {
p = n * 8;
if ((RxData[p] & 0xF0) == 0xA0) {
TrainPos[TrainCount++] = RxData[p + 6];
}
}
}
for (p = 0; p < 10; p++) {
d_min = 7;
rosen = SignalPos[p] & 0x38;
for (n = 0; n < TrainCount; n++) {
if ((TrainPos[n] & 0x38) == rosen) {
d = (TrainPos[n] & 7)-(SignalPos[p] & 7);
if (SignalPos[p] & 0x80)
d = -d; //シグナル向き逆方向
if (d < 0)
d += 8;
if (d < d_min)
d_min = d; //最小値を更新
}
}
if (d_min == 2) {
//黄信号
signal[p] = L_YEL;
} else if (d_min > 2) {
//青信号
signal[p] = L_GRN;
} else if (d_min < 2) {
//赤信号
signal[p] = L_RED;
}
Disp();
}
}
}
void __interrupt() ISR_ExtInt(void) {
unsigned char inp_bit;
inp_bit = ExtData;
INTF = 0; // 割り込みフラグクリア
IntCount++;
RB4 = 1;
if (ExtInt == 0) {
//--- IntCount 0 ---
IntCount = 0;
RB5 = 1;
}
grp_chg_count++;
//Group Change
if (grp_chg_count == 0x50) {
grp_chg_count = 0;
if (++group > 9)
group = 0;
sync = 1;
}
//受信
//TRISB1 = 1; //PortInput
data_p = (IntCount - 1) >> 3;
bit_p = EnableBit[(IntCount - 1) & 0b111];
RB3 = 1;
if (inp_bit)
receive_data |= bit_p;
else
receive_data &= ~bit_p;
if (bit_p == 0x80) {
RxData[data_p] = receive_data; //DataSet
if (data_p == 0x60) {
data_ready = 1;
}
}
PORTB = 0;
// RB4 = 0;
// RB5 = 0;
}
void Disp() {
if (sync) {
sync = 0;
led_off();
//signal_LED(signal[group]);
PORTA |= signal[group];
switch (group) {
case 0:
GRP0 = 0;
break;
case 1:
GRP1 = 0;
break;
case 2:
GRP2 = 0;
break;
case 3:
GRP3 = 0;
break;
case 4:
GRP4 = 0;
break;
case 5:
GRP5 = 0;
break;
case 6:
GRP6 = 0;
break;
case 7:
GRP7 = 0;
break;
case 8:
GRP8 = 0;
break;
case 9:
GRP9 = 0;
break;
}
}
}
void led_off() {
PORTA = 0b11111000;
PORTC = 0b1111111;
}


